73 lines
3.5 KiB
Plaintext
73 lines
3.5 KiB
Plaintext
VideoPlayerControl 에서 NVDEC 를 사용할 때, 전체 렌더링 파이프라인 흐름을 진단해줘.
|
||
|
||
|
||
1. [긴급] SimpleGPURenderer에 NV12 렌더링 파이프라인 추가 ⚠️
|
||
- RenderNV12Texture() 메서드 구현
|
||
- NV12 → RGB 변환 쉐이더 (compute 또는 pixel shader)
|
||
- VideoPlayerControl에서 호출 추가
|
||
2. [중요] CreateSharedHandle 최적화
|
||
- SetD3DDevice() 시점에 한 번만 생성
|
||
- 매 프레임 생성 제거
|
||
3. [권장] D3D12 리소스 state transition 추가
|
||
- NV12 텍스처 barrier 추가
|
||
- CUDA 쓰기 전/후 상태 전환
|
||
|
||
|
||
cudaExternalMemoryHandleDesc
|
||
cudaImportExternalMemory DXGI_FORMAT_NV12 cudaVideoSurfaceFormat_NV12
|
||
|
||
|
||
● cudaImportExternalMemory가 실패하고 있습니다. 에러 코드 1 (invalid argument)는 NV12 텍스처 포맷이 CUDA external
|
||
memory와 호환되지 않기 때문입니다.
|
||
|
||
문제: DXGI_FORMAT_NV12는 cudaExternalMemoryHandleTypeD3D12Resource와 함께 사용할 수 없습니다. CUDA는 단일 플레인
|
||
텍스처만 external memory로 import 가능합니다.
|
||
|
||
해결 방법: NV12 대신 별도의 Y, U, V 텍스처를 사용하거나, cudaExternalMemory 대신 D3D12-CUDA surface interop을
|
||
사용해야 합니다.
|
||
|
||
● Update(vav2\platforms\windows\applications\vav2player\Vav2Player\src\Rendering\SimpleGPURenderer.cpp)
|
||
⎿ Updated vav2\platforms\windows\applications\vav2player\Vav2Player\src\Rendering\SimpleGPURenderer.cpp with 3
|
||
additions and 2 removals
|
||
617 m_nv12Texture.Reset();
|
||
618
|
||
619 // Create NV12 texture for VavCore zero-copy decode (shared with CUDA)
|
||
620 - // NV12 format: Y plane (full resolution) + interleaved UV plane (half resolution)
|
||
620 + // IMPORTANT: Use R8_UNORM format instead of NV12 for CUDA external memory compatibility
|
||
621 + // Layout: Y plane (videoWidth × videoHeight) + UV plane (videoWidth × videoHeight/2)
|
||
622 D3D12_RESOURCE_DESC nv12Desc = {};
|
||
623 nv12Desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
||
624 nv12Desc.Width = videoWidth;
|
||
625 nv12Desc.Height = videoHeight + (videoHeight / 2); // Y plane + UV plane
|
||
626 nv12Desc.DepthOrArraySize = 1;
|
||
627 nv12Desc.MipLevels = 1;
|
||
628 - nv12Desc.Format = DXGI_FORMAT_NV12; // Native NV12 format
|
||
628 + nv12Desc.Format = DXGI_FORMAT_R8_UNORM; // Use R8 instead of NV12 for CUDA compatibility
|
||
629 nv12Desc.SampleDesc.Count = 1;
|
||
630 nv12Desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
||
631 nv12Desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; // Allow CUDA write access
|
||
|
||
● 이제 픽셀 셰이더도 R8 포맷에 맞춰 수정해야 합니다:
|
||
|
||
|
||
|
||
|
||
|
||
|
||
● 치명적인 제약: ROW_MAJOR layout은 YUV 포맷을 지원하지 않습니다!
|
||
|
||
에러:
|
||
When D3D12_RESOURCE_DESC::Layout is D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
|
||
the format cannot be YUV.
|
||
|
||
이제 명확해졌습니다. D3D12에서 NV12를 CUDA와 공유하려면:
|
||
- D3D12_TEXTURE_LAYOUT_UNKNOWN: D3D12가 자동으로 레이아웃 결정하지만, 할당 크기가 부족
|
||
- D3D12_TEXTURE_LAYOUT_ROW_MAJOR: YUV 포맷 사용 불가
|
||
- D3D12_TEXTURE_LAYOUT_64KB_STANDARD_SWIZZLE: GPU가 지원 안 함
|
||
|
||
근본적인 해결책: D3D12 NV12 대신 RGBA 텍스처를 사용하고, CUDA에서 YUV→RGB 변환을 수행해야 합니다.
|
||
|
||
하지만 먼저 UNKNOWN layout으로 돌아가서 할당 크기 문제를 다시 살펴보겠습니다:
|
||
|
||
|