[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