RTX A5000 GPUDirect not support by DeckLink SDK12.2

Ask software engineering and SDK questions for developers working on Mac OS X, Windows or Linux.
  • Author
  • Message
Offline

tyxxybm

  • Posts: 7
  • Joined: Wed Aug 11, 2021 6:30 am
  • Real Name: King Tissy

RTX A5000 GPUDirect not support by DeckLink SDK12.2

PostSun Nov 28, 2021 8:13 am

Hi,

I downloaded the latest DeckLink SDK 12.2 and MODIFIED the sample named LoopThroughWithOpenGLCompositing to meet my requirement. As my capture card (decklink QUAD HDMI Recorder) supports only simplex mode and my target is to apply the input video as textures in my realtime 3D rendering scene. I removed all the output logic and added the drawing logic to make it works as expected. All the things gone as expected except that the latency is a litter bit higher.

I debug it and found that my NVIDIA RTX A5000 "Do Not support GPUDirect" in the sdk and finally I found that in the following code:

#71 at VideoFrameTransfer.cpp
Code: Select all
bool VideoFrameTransfer::isNvidiaDvpAvailable()
{
   // Look for supported graphics boards
   const GLubyte* renderer = glGetString(GL_RENDERER);
   bool hasDvp = (strstr((char*)renderer, "Quadro") != NULL);
   return hasDvp;
}


NVIDIA has changed its GL_RENDERER name rules and no "Quadro" in new Ampere quadro serial cards. My RTX A5000 show that renderer = "NVIDIA RTX A5000/PCIe/SSE2".

RTX-A5000 supports GPUDirect according to NVIDIA's official data sheet, ref: https://www.nvidia.com/content/dam/en-z ... asheet.pdf

It's not hard to make it correct like this:
Code: Select all
 
bool VideoFrameTransfer::isNvidiaDvpAvailable()
{
   // Look for supported graphics boards
   const GLubyte* renderer = glGetString(GL_RENDERER);
   bool hasDvp = (strstr((char*)renderer, "Quadro") != NULL ||
                   strstr((char*)renderer, "NVIDIA RTX A") != NULL ); // add for Ampere GPUs
   return hasDvp;
}


BUT I finally failed to make the sample work as I got BLACK textures via dvp transfer.
Any Idea?

Thank you in advance.
Offline

tyxxybm

  • Posts: 7
  • Joined: Wed Aug 11, 2021 6:30 am
  • Real Name: King Tissy

Re: RTX A5000 GPUDirect not support by DeckLink SDK12.2

PostSun Nov 28, 2021 8:19 am

I make a zip for my modified project to make it easy to reproduce.

Note that as my video source (laptop supports) is 8-bit RGBA 1920x1200 60p, (RGB 4:4:4), I've changed the YUV decoding shader to RGBA shader.
Attachments
LoopThroughWithOpenGLCompositing.zip
(105.42 KiB) Downloaded 177 times
Offline

tyxxybm

  • Posts: 7
  • Joined: Wed Aug 11, 2021 6:30 am
  • Real Name: King Tissy

Re: RTX A5000 GPUDirect not support by DeckLink SDK12.2

PostMon Nov 29, 2021 3:05 am

I noticed that in my situation, my data type is RGB 4:4:4 rather than UYVY 422, so in VideoFrameTransfer.cpp, Line#217, the relative lines of code are commented out but still without luck.

Code: Select all
   if (mUseDvp)
   {
      // Pin the memory
      if (! VirtualLock(mBuffer, mMemSize))
         throw std::runtime_error("Error pinning memory with VirtualLock");

      // Create necessary sysmem and gpu sync objects
      mExtSync = new SyncInfo(mSemaphoreAllocSize, mSemaphoreAddrAlignment);
      mGpuSync = new SyncInfo(mSemaphoreAllocSize, mSemaphoreAddrAlignment);

      // Register system memory buffers with DVP
      DVPSysmemBufferDesc sysMemBuffersDesc;
      sysMemBuffersDesc.width      = mWidth;
      sysMemBuffersDesc.height   = mHeight;
      sysMemBuffersDesc.stride   = mWidth * 4;
      sysMemBuffersDesc.format   = DVP_BGRA;
      sysMemBuffersDesc.type      = DVP_UNSIGNED_INT_8_8_8_8_REV;// DVP_UNSIGNED_BYTE;
      sysMemBuffersDesc.size      = mMemSize;
      sysMemBuffersDesc.bufAddr   = mBuffer;
#217
      //if (mDirection == CPUtoGPU)
      //{
      //   // A UYVY 4:2:2 frame is transferred to the GPU, rather than RGB 4:4:4, so width is halved
      //   sysMemBuffersDesc.width /= 2;
      //   sysMemBuffersDesc.stride /= 2;
      //}

      DVP_CHECK(dvpCreateBuffer(&sysMemBuffersDesc, &mDvpSysMemHandle));
      DVP_CHECK(dvpBindToGLCtx(mDvpSysMemHandle));
   }
   else
       {.....}
Offline

Cameron Nichols

Blackmagic Design

  • Posts: 442
  • Joined: Mon Sep 04, 2017 4:05 am

Re: RTX A5000 GPUDirect not support by DeckLink SDK12.2

PostWed Dec 01, 2021 2:27 am

Hi King,

Can you confirm that the signal captured is RGB 4:4:4? You can run SDK sample DeviceStatus in parallel to check the incoming signal. Please be aware that the DeckLink API won't automatically perform the conversion from YCbCr 4:2:2 to RGB 4:4:4, you can use IDeckLinkVideoConversion interface to perform this (refer to CaptureStills sample).

However since you are using GPUDirect, you would be better to still use pinned memory for 4:2:2 frame and perform colorspace conversion to 4:4:4 in the GPU video pipeline.

Regards
Cameron
Offline

tyxxybm

  • Posts: 7
  • Joined: Wed Aug 11, 2021 6:30 am
  • Real Name: King Tissy

Re: RTX A5000 GPUDirect not support by DeckLink SDK12.2

PostThu Dec 02, 2021 1:41 am

hi Cameron,

Thank you for your reply.
After some code review, I noticed that I forgot to enable and bind the texture before drawing in dvp branch. It's working now.

I've attached my code as following. Hope this can help others.

Further more, the output(captured) pixel format can be set as RGB 4:4:4 or YUV by NVIDIA Control Panel in source machine. But RGB 4:4:4 requires more bandwidth and only 4K@30hz is supported in my Decklink Quad HDMI.

Code: Select all
void OpenGLComposite::VideoFrameArrived(IDeckLinkVideoInputFrame* inputFrame, bool hasNoInputSource)
{
   mHasNoInputSource = hasNoInputSource;
   if (mHasNoInputSource)
      return;                     

   EnterCriticalSection(&pMutex);

   long textureSize = inputFrame->GetRowBytes() * inputFrame->GetHeight();
   void* videoPixels;
   inputFrame->GetBytes(&videoPixels);

   wglMakeCurrent(hGLDC, hGLRC);      
   setupModelView();


   if (mFastTransferExtensionAvailable)
   {
      if (!mCaptureAllocator->transferFrame(videoPixels, mCaptureTexture))
         OutputDebugStringA("Capture: transferFrame() failed\n");

                // #notice that before drawing the box, glEnable and glBindTexture should be called.
      glEnable(GL_TEXTURE_2D);
      glBindTexture(GL_TEXTURE_2D, mCaptureTexture);
   }
   else
   {
      glEnable(GL_TEXTURE_2D);

      // Use a straightforward texture buffer
      glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mUnpinnedTextureBuffer);
      glBufferData(GL_PIXEL_UNPACK_BUFFER, textureSize, videoPixels, GL_DYNAMIC_DRAW);
      glBindTexture(GL_TEXTURE_2D, mCaptureTexture);

      // NULL for last arg indicates use current GL_PIXEL_UNPACK_BUFFER target as texture data
      glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mFrameWidth, mFrameHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
   }
   drawBox();

   if (!mFastTransferExtensionAvailable)
   {
      glBindTexture(GL_TEXTURE_2D, 0);
      glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
      glDisable(GL_TEXTURE_2D);
   }
   paintGL();
   LeaveCriticalSection(&pMutex);
}


Cameron Nichols wrote:Hi King,

Can you confirm that the signal captured is RGB 4:4:4? You can run SDK sample DeviceStatus in parallel to check the incoming signal. Please be aware that the DeckLink API won't automatically perform the conversion from YCbCr 4:2:2 to RGB 4:4:4, you can use IDeckLinkVideoConversion interface to perform this (refer to CaptureStills sample).

However since you are using GPUDirect, you would be better to still use pinned memory for 4:2:2 frame and perform colorspace conversion to 4:4:4 in the GPU video pipeline.

Regards
Cameron

Return to Software Developers

Who is online

Users browsing this forum: No registered users and 19 guests