31 #define DVP_CHECK(cmd) { \ 32 DVPStatus hr = (cmd); \ 33 if (DVP_STATUS_OK != hr) { \ 34 OutputDebugStringA( #cmd " failed\n" ); \ 41 bool VideoFrameTransfer::mInitialized =
false;
42 bool VideoFrameTransfer::mUseDvp =
false;
43 unsigned VideoFrameTransfer::mWidth = 0;
44 unsigned VideoFrameTransfer::mHeight = 0;
45 GLuint VideoFrameTransfer::mCaptureTexture = 0;
50 uint32_t VideoFrameTransfer::mBufferAddrAlignment = 0;
51 uint32_t VideoFrameTransfer::mBufferGpuStrideAlignment = 0;
52 uint32_t VideoFrameTransfer::mSemaphoreAddrAlignment = 0;
53 uint32_t VideoFrameTransfer::mSemaphoreAllocSize = 0;
54 uint32_t VideoFrameTransfer::mSemaphorePayloadOffset = 0;
55 uint32_t VideoFrameTransfer::mSemaphorePayloadSize = 0;
58 bool VideoFrameTransfer::isNvidiaDvpAvailable()
61 const GLubyte* renderer = glGetString(GL_RENDERER);
62 bool hasDvp = (strstr((
char*)renderer,
"Quadro") != NULL);
66 bool VideoFrameTransfer::isAMDPinnedMemoryAvailable()
69 const GLubyte* strExt = glGetString(GL_EXTENSIONS);
70 bool hasAMDPinned = (strstr((
char*)strExt,
"GL_AMD_pinned_memory") != NULL);
76 return (isNvidiaDvpAvailable() || isAMDPinnedMemoryAvailable());
84 bool hasDvp = isNvidiaDvpAvailable();
85 bool hasAMDPinned = isAMDPinnedMemoryAvailable();
87 if (!hasDvp && !hasAMDPinned)
93 mCaptureTexture = captureTexture;
95 if (! initializeMemoryLocking(mWidth * mHeight * 4))
103 &mSemaphoreAddrAlignment, &mSemaphoreAllocSize,
104 &mSemaphorePayloadOffset, &mSemaphorePayloadSize));
116 bool VideoFrameTransfer::initializeMemoryLocking(
unsigned memSize)
119 static SIZE_T dwMin = 0, dwMax = 0;
120 HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_SET_QUOTA,
FALSE, GetCurrentProcessId());
125 if (!dwMin && !GetProcessWorkingSetSize(hProcess, &dwMin, &dwMax))
129 BOOL res = SetProcessWorkingSetSize(hProcess, memSize * 80 + dwMin, memSize * 80 + (dwMax-dwMin));
133 CloseHandle(hProcess);
141 SyncInfo(uint32_t semaphoreAllocSize, uint32_t semaphoreAddrAlignment);
144 volatile uint32_t* mSem;
145 volatile uint32_t mReleaseValue;
146 volatile uint32_t mAcquireValue;
150 SyncInfo::SyncInfo(uint32_t semaphoreAllocSize, uint32_t semaphoreAddrAlignment)
152 mSem = (uint32_t*)_aligned_malloc(semaphoreAllocSize, semaphoreAddrAlignment);
162 syncObjectDesc.
sem = (uint32_t*)mSem;
167 SyncInfo::~SyncInfo()
170 _aligned_free((
void*)mSem);
176 mDirection(direction),
185 if (! VirtualLock(mBuffer, mMemSize))
186 throw std::runtime_error(
"Error pinning memory with VirtualLock");
189 mExtSync =
new SyncInfo(mSemaphoreAllocSize, mSemaphoreAddrAlignment);
190 mGpuSync =
new SyncInfo(mSemaphoreAllocSize, mSemaphoreAddrAlignment);
194 sysMemBuffersDesc.
width = mWidth;
195 sysMemBuffersDesc.
height = mHeight;
196 sysMemBuffersDesc.
stride = mWidth * 4;
199 sysMemBuffersDesc.
size = mMemSize;
200 sysMemBuffersDesc.
bufAddr = mBuffer;
205 sysMemBuffersDesc.
width /= 2;
206 sysMemBuffersDesc.
stride /= 2;
219 glBindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, bufferHandle);
224 GLenum result = glGetError();
225 if (result != GL_NO_ERROR)
227 throw std::runtime_error(
"Error pinning memory with glBufferData(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, ...)");
231 mBufferHandle = bufferHandle;
245 VirtualUnlock(mBuffer, mMemSize);
261 mGpuSync->mReleaseValue++;
269 mDvpCaptureTextureHandle, mGpuSync->mDvpSync, mGpuSync->mReleaseValue, 0, mHeight);
277 mDvpSysMemHandle, mGpuSync->mDvpSync, mGpuSync->mReleaseValue, 0, mHeight);
289 glEnable(GL_TEXTURE_2D);
293 glBindTexture(GL_TEXTURE_2D, mCaptureTexture);
296 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mWidth/2, mHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
299 GLsync fence =
glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
303 glBindTexture(GL_TEXTURE_2D, 0);
305 glDisable(GL_TEXTURE_2D);
311 glReadPixels(0, 0, mWidth, mHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
314 GLsync fence =
glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
319 return (glGetError() == GL_NO_ERROR);
DVPAPI_INTERFACE dvpMapBufferEndDVP(DVPBufferHandle gpuBufferHandle)
DVPAPI_INTERFACE dvpGetRequiredConstantsGLCtx(uint32_t *bufferAddrAlignment, uint32_t *bufferGPUStrideAlignment, uint32_t *semaphoreAddrAlignment, uint32_t *semaphoreAllocSize, uint32_t *semaphorePayloadOffset, uint32_t *semaphorePayloadSize)
PFNGLFENCESYNCPROC glFenceSync
ext function
bool performFrameTransfer()
VideoFrameTransfer(unsigned long memSize, void *address, Direction direction)
uint64_t DVPSyncObjectHandle
DVPAPI_INTERFACE dvpImportSyncObject(DVPSyncObjectDesc *desc, DVPSyncObjectHandle *syncObject)
DVPAPI_INTERFACE dvpFreeSyncObject(DVPSyncObjectHandle syncObject)
#define DVP_TIMEOUT_IGNORED
DVPAPI_INTERFACE dvpMapBufferWaitAPI(DVPBufferHandle gpuBufferHandle)
DVPAPI_INTERFACE dvpMemcpyLined(DVPBufferHandle srcBuffer, DVPSyncObjectHandle srcSync, uint32_t srcAcquireValue, uint64_t timeout, DVPBufferHandle dstBuffer, DVPSyncObjectHandle dstSync, uint32_t dstReleaseValue, uint32_t startingLine, uint32_t numberOfLines)
DVPAPI_INTERFACE dvpMapBufferEndAPI(DVPBufferHandle gpuBufferHandle)
DVPAPI_INTERFACE dvpBegin()
DVPAPI_INTERFACE dvpDestroyBuffer(DVPBufferHandle hBuf)
PFNGLBUFFERDATAARBPROC glBufferData
DVPAPI_INTERFACE dvpSyncObjClientWaitComplete(DVPSyncObjectHandle syncObject, uint64_t timeout)
PhidgetLCD_Font int * width
PFNGLCLIENTWAITSYNCPROC glClientWaitSync
ext function
DVPAPI_INTERFACE dvpCreateGPUTextureGL(GLuint texID, DVPBufferHandle *bufferHandle)
PFNGLDELETEBUFFERSARBPROC glDeleteBuffers
#define DVP_DEVICE_FLAGS_SHARE_APP_CONTEXT
void waitForTransferComplete()
DVPStatus(* externalClientWaitFunc)(DVPSyncObjectHandle sync, uint32_t value, bool GEQ, uint64_t timeout)
PhidgetLCD_Font int int * height
static void beginTextureInUse(Direction direction)
static bool checkFastMemoryTransferAvailable()
static bool initialize(unsigned width, unsigned height, GLuint captureTexture, GLuint playbackTexture)
DVPAPI_INTERFACE dvpMapBufferWaitDVP(DVPBufferHandle gpuBufferHandle)
DVPAPI_INTERFACE dvpInitGLContext(uint32_t flags)
DVPAPI_INTERFACE dvpBindToGLCtx(DVPBufferHandle hBuf)
DVPAPI_INTERFACE dvpCreateBuffer(DVPSysmemBufferDesc *desc, DVPBufferHandle *hBuf)
static void endTextureInUse(Direction direction)
PFNGLDELETESYNCPROC glDeleteSync
ext function
PFNGLBINDBUFFERARBPROC glBindBuffer
PFNGLGENBUFFERSARBPROC glGenBuffers
DVPAPI_INTERFACE dvpEnd()
DVPAPI_INTERFACE dvpUnbindFromGLCtx(DVPBufferHandle hBuf)