[Bf-blender-cvs] [cb21edd] decklink: BGE VideoLinck: add AMD pinned memory, fix OGL capture method.
Benoit Bolsee
noreply at git.blender.org
Fri May 1 18:39:59 CEST 2015
Commit: cb21edde3e55bf25337835a0834e9e2e72981a30
Author: Benoit Bolsee
Date: Fri May 1 18:36:25 2015 +0200
Branches: decklink
https://developer.blender.org/rBcb21edde3e55bf25337835a0834e9e2e72981a30
BGE VideoLinck: add AMD pinned memory, fix OGL capture method.
AMD_pinned_memory method implemented according to BMD sample file but
not tested (would need an ATI card).
Fix OGL method: needed to allocate texture data first.
===================================================================
M source/gameengine/VideoTexture/VideoDeckLink.cpp
M source/gameengine/VideoTexture/VideoDeckLink.h
===================================================================
diff --git a/source/gameengine/VideoTexture/VideoDeckLink.cpp b/source/gameengine/VideoTexture/VideoDeckLink.cpp
index 32fcb55..db81612 100644
--- a/source/gameengine/VideoTexture/VideoDeckLink.cpp
+++ b/source/gameengine/VideoTexture/VideoDeckLink.cpp
@@ -102,7 +102,7 @@ struct SyncInfo
};
////////////////////////////////////////////
-// TextureTransferDvp
+// TextureTransferDvp: transfer with GPUDirect
////////////////////////////////////////////
class TextureTransferDvp : public TextureTransfer
@@ -224,6 +224,10 @@ uint32_t TextureTransferDvp::mSemaphorePayloadSize;
#endif
+////////////////////////////////////////////
+// TextureTransferOGL: transfer using standard OGL buffers
+////////////////////////////////////////////
+
class TextureTransferOGL : public TextureTransfer
{
public:
@@ -265,6 +269,53 @@ private:
TextureDesc mDesc;
};
+////////////////////////////////////////////
+// TextureTransferPMB: transfer using pinned memory buffer
+////////////////////////////////////////////
+
+class TextureTransferPMD : public TextureTransfer
+{
+public:
+ TextureTransferPMD(GLuint texId, TextureDesc *pDesc, void *address)
+ {
+ memcpy(&mDesc, pDesc, sizeof(mDesc));
+ mTexId = texId;
+ mBuffer = address;
+
+ // as we cache transfer object, we will create one texture to hold the buffer
+ glGenBuffers(1, &mPinnedTextureBuffer);
+ // create a storage for it
+ glBindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, mPinnedTextureBuffer);
+ glBufferData(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, pDesc->size, address, GL_STREAM_DRAW);
+ glBindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, 0);
+ }
+ ~TextureTransferPMD()
+ {
+ glDeleteBuffers(1, &mPinnedTextureBuffer);
+ }
+
+ virtual void PerformTransfer()
+ {
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPinnedTextureBuffer);
+ glBindTexture(GL_TEXTURE_2D, mTexId);
+ // NULL for last arg indicates use current GL_PIXEL_UNPACK_BUFFER target as texture data
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mDesc.width, mDesc.height, mDesc.format, mDesc.type, NULL);
+ GLsync fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+ glClientWaitSync(fence, GL_SYNC_FLUSH_COMMANDS_BIT, 40 * 1000 * 1000); // timeout in nanosec
+ glDeleteSync(fence);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+ }
+private:
+ // intermediate texture to receive the buffer
+ GLuint mPinnedTextureBuffer;
+ // target texture to receive the image
+ GLuint mTexId;
+ // buffer
+ void *mBuffer;
+ // characteristic of the image
+ TextureDesc mDesc;
+};
+
bool TextureTransfer::_PinBuffer(void *address, u_int size)
{
#ifdef WIN32
@@ -324,6 +375,7 @@ mRefCount(1U),
#ifdef WIN32
mDvpCaptureTextureHandle(0),
#endif
+mTexId(0),
mBufferCacheSize(cacheSize)
{
pthread_mutex_init(&mMutex, NULL);
@@ -387,62 +439,54 @@ void PinnedMemoryAllocator::TransferBuffer(void* address, TextureDesc* texDesc,
if (!allocatedSize)
// internal error!!
return;
+ if (mTexId != texId)
+ {
+ // first time we try to send data to the GPU, allocate a buffer for the texture
+ glBindTexture(GL_TEXTURE_2D, texId);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ glTexImage2D(GL_TEXTURE_2D, 0, ((texDesc->format == GL_RED_INTEGER) ? GL_R32UI : GL_RGBA), texDesc->width, texDesc->height, 0, texDesc->format, texDesc->type, NULL);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ mTexId = texId;
+ }
#ifdef WIN32
if (mHasDvp)
{
if (!mDvpCaptureTextureHandle)
{
- // first time we try to send data to the GPU, allocate a buffer for the texture
- glBindTexture(GL_TEXTURE_2D, texId);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- glTexImage2D(GL_TEXTURE_2D, 0, ((texDesc->format == GL_RED_INTEGER) ? GL_R32UI : GL_RGBA), texDesc->width, texDesc->height, 0, texDesc->format, texDesc->type, NULL);
- glBindTexture(GL_TEXTURE_2D, 0);
// bind DVP to the OGL texture
DVP_CHECK(dvpCreateGPUTextureGL(texId, &mDvpCaptureTextureHandle));
}
- Lock();
- if (mPinnedBuffer.count(address) > 0)
- {
- pTransfer = mPinnedBuffer[address];
- }
- Unlock();
- if (!pTransfer)
- {
- pTransfer = new TextureTransferDvp(mDvpCaptureTextureHandle, texDesc, address, allocatedSize);
- if (pTransfer)
- {
- Lock();
- mPinnedBuffer[address] = pTransfer;
- Unlock();
- }
- }
}
- else
#endif
- if (mHasAMDPinnedMemory)
+ Lock();
+ if (mPinnedBuffer.count(address) > 0)
{
- pTransfer = NULL;
+ pTransfer = mPinnedBuffer[address];
}
- else
+ Unlock();
+ if (!pTransfer)
{
- Lock();
- if (mPinnedBuffer.count(address) > 0)
+#ifdef WIN32
+ if (mHasDvp)
+ pTransfer = new TextureTransferDvp(mDvpCaptureTextureHandle, texDesc, address, allocatedSize);
+ else
+#endif
+ if (mHasAMDPinnedMemory)
{
- pTransfer = mPinnedBuffer[address];
+ pTransfer = new TextureTransferPMD(texId, texDesc, address);
}
- Unlock();
- if (!pTransfer)
+ else
{
pTransfer = new TextureTransferOGL(texId, texDesc, address);
- if (pTransfer)
- {
- Lock();
- mPinnedBuffer[address] = pTransfer;
- Unlock();
- }
+ }
+ if (pTransfer)
+ {
+ Lock();
+ mPinnedBuffer[address] = pTransfer;
+ Unlock();
}
}
if (pTransfer)
diff --git a/source/gameengine/VideoTexture/VideoDeckLink.h b/source/gameengine/VideoTexture/VideoDeckLink.h
index 79a3db4..9043d1c 100644
--- a/source/gameengine/VideoTexture/VideoDeckLink.h
+++ b/source/gameengine/VideoTexture/VideoDeckLink.h
@@ -222,6 +222,8 @@ private:
#ifdef WIN32
DVPBufferHandle mDvpCaptureTextureHandle;
#endif
+ // target texture in GPU
+ GLuint mTexId;
u_int mBufferCacheSize;
};
More information about the Bf-blender-cvs
mailing list