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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to