[Bf-blender-cvs] [ad75477] decklink: First working implementation of VideoDeckLink.
Benoit Bolsee
noreply at git.blender.org
Wed Mar 25 08:55:51 CET 2015
Commit: ad75477f1c8b43001641d9e8c8143ce5b77155aa
Author: Benoit Bolsee
Date: Wed Mar 25 08:53:36 2015 +0100
Branches: decklink
https://developer.blender.org/rBad75477f1c8b43001641d9e8c8143ce5b77155aa
First working implementation of VideoDeckLink.
Doc: TBD
BL_Shader: allows to pass partially defined shader (e.g fragment without
vertex)
===================================================================
M source/gameengine/Ketsji/BL_Shader.cpp
M source/gameengine/VideoTexture/Exception.h
M source/gameengine/VideoTexture/VideoDeckLink.cpp
M source/gameengine/VideoTexture/VideoDeckLink.h
===================================================================
diff --git a/source/gameengine/Ketsji/BL_Shader.cpp b/source/gameengine/Ketsji/BL_Shader.cpp
index a59c368..a7d42f2 100644
--- a/source/gameengine/Ketsji/BL_Shader.cpp
+++ b/source/gameengine/Ketsji/BL_Shader.cpp
@@ -285,11 +285,11 @@ void BL_Shader::UnloadShader()
bool BL_Shader::LinkProgram()
{
- int vertlen = 0, fraglen=0, proglen=0;
- int vertstatus=0, fragstatus=0, progstatus=0;
- unsigned int tmpVert=0, tmpFrag=0, tmpProg=0;
- int char_len=0;
- char *logInf =0;
+ int vertlen = 0, fraglen = 0, proglen = 0;
+ int vertstatus = 0, fragstatus = 0, progstatus = 0;
+ unsigned int tmpVert = 0, tmpFrag = 0, tmpProg = 0;
+ int char_len = 0;
+ char *logInf = 0;
if (mError)
goto programError;
@@ -298,67 +298,78 @@ bool BL_Shader::LinkProgram()
spit("Invalid GLSL sources");
return false;
}
- if ( !GLEW_ARB_fragment_shader) {
+ if (!GLEW_ARB_fragment_shader) {
spit("Fragment shaders not supported");
return false;
}
- if ( !GLEW_ARB_vertex_shader) {
+ if (!GLEW_ARB_vertex_shader) {
spit("Vertex shaders not supported");
return false;
}
-
- // -- vertex shader ------------------
- tmpVert = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
- glShaderSourceARB(tmpVert, 1, (const char**)&vertProg, 0);
- glCompileShaderARB(tmpVert);
- glGetObjectParameterivARB(tmpVert, GL_OBJECT_INFO_LOG_LENGTH_ARB,(GLint*) &vertlen);
-
- // print info if any
- if ( vertlen > 0 && vertlen < MAX_LOG_LEN) {
- logInf = (char*)MEM_mallocN(vertlen, "vert-log");
- glGetInfoLogARB(tmpVert, vertlen, (GLsizei*)&char_len, logInf);
- if (char_len >0) {
- spit("---- Vertex Shader Error ----");
- spit(logInf);
+ if (vertProg[0] != 0)
+ {
+ // -- vertex shader ------------------
+ tmpVert = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
+ glShaderSourceARB(tmpVert, 1, (const char**)&vertProg, 0);
+ glCompileShaderARB(tmpVert);
+ glGetObjectParameterivARB(tmpVert, GL_OBJECT_INFO_LOG_LENGTH_ARB, (GLint*)&vertlen);
+
+ // print info if any
+ if (vertlen > 0 && vertlen < MAX_LOG_LEN) {
+ logInf = (char*)MEM_mallocN(vertlen, "vert-log");
+ glGetInfoLogARB(tmpVert, vertlen, (GLsizei*)&char_len, logInf);
+ if (char_len > 0) {
+ spit("---- Vertex Shader Error ----");
+ spit(logInf);
+ }
+ MEM_freeN(logInf);
+ logInf = 0;
+ }
+ // check for compile errors
+ glGetObjectParameterivARB(tmpVert, GL_OBJECT_COMPILE_STATUS_ARB, (GLint*)&vertstatus);
+ if (!vertstatus) {
+ spit("---- Vertex shader failed to compile ----");
+ goto programError;
}
- MEM_freeN(logInf);
- logInf=0;
- }
- // check for compile errors
- glGetObjectParameterivARB(tmpVert, GL_OBJECT_COMPILE_STATUS_ARB,(GLint*)&vertstatus);
- if (!vertstatus) {
- spit("---- Vertex shader failed to compile ----");
- goto programError;
}
- // -- fragment shader ----------------
- tmpFrag = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
- glShaderSourceARB(tmpFrag, 1,(const char**)&fragProg, 0);
- glCompileShaderARB(tmpFrag);
- glGetObjectParameterivARB(tmpFrag, GL_OBJECT_INFO_LOG_LENGTH_ARB, (GLint*) &fraglen);
- if (fraglen >0 && fraglen < MAX_LOG_LEN) {
- logInf = (char*)MEM_mallocN(fraglen, "frag-log");
- glGetInfoLogARB(tmpFrag, fraglen,(GLsizei*) &char_len, logInf);
- if (char_len >0) {
- spit("---- Fragment Shader Error ----");
- spit(logInf);
+ if (fragProg[0] != 0)
+ {
+ // -- fragment shader ----------------
+ tmpFrag = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
+ glShaderSourceARB(tmpFrag, 1, (const char**)&fragProg, 0);
+ glCompileShaderARB(tmpFrag);
+ glGetObjectParameterivARB(tmpFrag, GL_OBJECT_INFO_LOG_LENGTH_ARB, (GLint*)&fraglen);
+ if (fraglen > 0 && fraglen < MAX_LOG_LEN) {
+ logInf = (char*)MEM_mallocN(fraglen, "frag-log");
+ glGetInfoLogARB(tmpFrag, fraglen, (GLsizei*)&char_len, logInf);
+ if (char_len > 0) {
+ spit("---- Fragment Shader Error ----");
+ spit(logInf);
+ }
+ MEM_freeN(logInf);
+ logInf = 0;
}
- MEM_freeN(logInf);
- logInf=0;
- }
- glGetObjectParameterivARB(tmpFrag, GL_OBJECT_COMPILE_STATUS_ARB, (GLint*) &fragstatus);
- if (!fragstatus) {
- spit("---- Fragment shader failed to compile ----");
- goto programError;
+ glGetObjectParameterivARB(tmpFrag, GL_OBJECT_COMPILE_STATUS_ARB, (GLint*)&fragstatus);
+ if (!fragstatus) {
+ spit("---- Fragment shader failed to compile ----");
+ goto programError;
+ }
}
-
+ if (!tmpFrag && !tmpVert)
+ {
+ spit("---- No shader given ----");
+ goto programError;
+ }
// -- program ------------------------
// set compiled vert/frag shader & link
tmpProg = glCreateProgramObjectARB();
- glAttachObjectARB(tmpProg, tmpVert);
- glAttachObjectARB(tmpProg, tmpFrag);
+ if (tmpVert)
+ glAttachObjectARB(tmpProg, tmpVert);
+ if (tmpFrag)
+ glAttachObjectARB(tmpProg, tmpFrag);
glLinkProgramARB(tmpProg);
glGetObjectParameterivARB(tmpProg, GL_OBJECT_INFO_LOG_LENGTH_ARB, (GLint*) &proglen);
glGetObjectParameterivARB(tmpProg, GL_OBJECT_LINK_STATUS_ARB, (GLint*) &progstatus);
@@ -382,8 +393,10 @@ bool BL_Shader::LinkProgram()
// set
mShader = tmpProg;
- glDeleteObjectARB(tmpVert);
- glDeleteObjectARB(tmpFrag);
+ if (tmpVert)
+ glDeleteObjectARB(tmpVert);
+ if (tmpFrag)
+ glDeleteObjectARB(tmpFrag);
mOk = 1;
mError = 0;
return true;
diff --git a/source/gameengine/VideoTexture/Exception.h b/source/gameengine/VideoTexture/Exception.h
index c3c27ab..2060f87 100644
--- a/source/gameengine/VideoTexture/Exception.h
+++ b/source/gameengine/VideoTexture/Exception.h
@@ -46,7 +46,7 @@
throw Exception (err, macroHRslt, __FILE__, __LINE__); \
}
-#define THRWEXCP(err,hRslt) throw Exception (err, hRslt, __FILE__, __LINE__);
+#define THRWEXCP(err,hRslt) throw Exception (err, hRslt, __FILE__, __LINE__)
#if defined WIN32
diff --git a/source/gameengine/VideoTexture/VideoDeckLink.cpp b/source/gameengine/VideoTexture/VideoDeckLink.cpp
index e0fceda..64ff864 100644
--- a/source/gameengine/VideoTexture/VideoDeckLink.cpp
+++ b/source/gameengine/VideoTexture/VideoDeckLink.cpp
@@ -37,12 +37,9 @@
#include <stdint.h>
#include <string.h>
-#include "VideoDeckLink.h"
-#include "dvpapi_gl.h"
-
#include "MEM_guardedalloc.h"
#include "PIL_time.h"
-
+#include "VideoDeckLink.h"
#include "Exception.h"
static struct
@@ -120,29 +117,503 @@ static struct
// sentinel
{ NULL }
};
-
+
+ExceptionID SourceVideoOnlyCapture, VideoDeckLinkBadFormat, VideoDeckLinkOpenCard, VideoDeckLinkInternalError, VideoDeckLinkDvpInternalError;
+ExpDesc SourceVideoOnlyCaptureDesc(SourceVideoOnlyCapture, "This video source only allows live capture");
+ExpDesc VideoDeckLinkBadFormatDesc(VideoDeckLinkBadFormat, "Invalid or unsupported capture format, should be <mode>/<pixel>[/3D]");
+ExpDesc VideoDeckLinkOpenCardDesc(VideoDeckLinkOpenCard, "Cannot open capture card, check if driver installed");
+ExpDesc VideoDeckLinkInternalErrorDesc(VideoDeckLinkInternalError, "DeckLink API internal error, please report");
+ExpDesc VideoDeckLinkDvpInternalErrorDesc(VideoDeckLinkDvpInternalError, "DVP API internal error, please report");
+
+
+#ifdef WIN32
+////////////////////////////////////////////
+// SynInfo
+//
+// Sets up a semaphore which is shared between the GPU and CPU and used to
+// synchronise access to DVP buffers.
+#define DVP_CHECK(cmd) if ((cmd) != DVP_STATUS_OK) THRWEXCP(VideoDeckLinkDvpInternalError, S_OK)
+
+struct SyncInfo
+{
+ SyncInfo(uint32_t semaphoreAllocSize, uint32_t semaphoreAddrAlignment)
+ {
+ mSemUnaligned = (uint32_t*)malloc(semaphoreAllocSize + semaphoreAddrAlignment - 1);
+
+ // Apply alignment constraints
+ uint64_t val = (uint64_t)mSemUnaligned;
+ val += semaphoreAddrAlignment - 1;
+ val &= ~((uint64_t)semaphoreAddrAlignment - 1);
+ mSem = (uint32_t*)val;
+
+ // Initialise
+ mSem[0] = 0;
+ mReleaseValue = 0;
+ mAcquireValue = 0;
+
+ // Setup DVP sync object and import it
+ DVPSyncObjectDesc syncObjectDesc;
+ syncObjectDesc.externalClientWaitFunc = NULL;
+ syncObjectDesc.sem = (uint32_t*)mSem;
+
+ DVP_CHECK(dvpImportSyncObject(&syncObjectDesc, &mDvpSync));
+
+ }
+ ~SyncInfo()
+ {
+ dvpFreeSyncObject(mDvpSync);
+ free((void*)mSemUnaligned);
+ }
+
+ volatile uint32_t* mSem;
+ volatile uint32_t* mSemUnaligned;
+ volatile uint32_t mReleaseValue;
+ volatile uint32_t mAcquireValue;
+ DVPSyncObjectHandle mDvpSync;
+};
+
+////////////////////////////////////////////
+// TextureTransferDvp
+////////////////////////////////////////////
+
+class TextureTransferDvp : public TextureTransfer
+{
+public:
+ TextureTransferDvp(DVPBufferHandle dvpTextureHandle, TextureDesc *pDesc, void *address)
+ {
+ DVPSysmemBufferDesc sysMemBuffersDesc;
+
+ if (!mBufferAddrAlignment)
+ {
+ DVP_CHECK(dvpGetRequiredConstantsGLCtx(&mBufferAddrAlignment, &mBufferGpuStrideAlignment,
+ &mSemaphoreAddrAlignment, &mSemaphoreAllocSize,
+ &mSemaphorePayloadOffset, &mSemaphorePayloadSize));
+ }
+ mExtSync = new SyncInfo(mSemaphoreAllocSize, mSemaphoreAddrAlignment);
+ mGpuSync = new SyncInfo(mSemaphoreAllocSize, mSemaphoreAddrAlignment);
+ sysMemBuffersDesc.width = pDesc->width;
+ sysMemBuffersDesc.height = pDesc->height;
+ sysMemBuffersDesc.stride = pDesc->stride;
+ if (pDesc->format == GL_RED_INTEGER)
+ {
+ sysMemBuffersDesc.format = DVP_RED_INTEGER;
+ sysMemBuffersDesc.type = DVP_UNSIGNED_INT;
+ }
+ else
+ {
+ sysMemBuffersDesc.format = DVP_BGRA;
+ sysMemBuffersDesc.type = (pDesc->type == GL_UNSIGNED_INT_8_8_8_8) ? DVP_UNSIGNED_INT_8_8_8_8 : DVP_UNSIGNED_INT_8_8_8_8_REV;
+ }
+ sysMemBuffersDesc.size = pDesc->width * pDesc->height * 4;
+ sysMemBuffersDesc.bufAddr = address;
+ DVP_CHECK(dvpCreateBuffer(&sysMemBuffersDesc, &mDvpSysMemHandle));
+ DVP_CHECK(dvpBindToGLCtx(mDvpSysMemHandle));
+ mDvpTextureHandle = dvpTextureHandle;
+ mTextureHeight = pDesc->height;
+ }
+ ~TextureTransferDvp()
+ {
+ DVP_CHECK(dvpUnbindFromGLCtx(mDvpSysMemHandle));
+ DVP_CHECK(dvpDestroyBuffer(mDvpSysMemHandle));
+ delete mExtSync;
+ delete mGpuSync;
+ }
+
+ virtual void PerformTransfer()
+ {
+ // perform the transfer
+ // tell DVP that the old texture buffer will no longer be used
+ dvpMapBufferEndAPI(mDvpTextureHandle);
+ // do we need this?
+ mGpuSync->mReleaseValue++;
+ dvpBegin();
+ // Copy from system memory to GPU texture
+ dvpMapBufferWaitDVP(
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list