Create SRVs for all textures in the pool during initialization

This commit is contained in:
Cameron Gutman 2022-02-05 14:49:08 -06:00
parent 1942e72474
commit 04a0aca221
2 changed files with 66 additions and 35 deletions

View File

@ -91,6 +91,7 @@ D3D11VARenderer::D3D11VARenderer()
RtlZeroMemory(m_OverlayVertexBuffers, sizeof(m_OverlayVertexBuffers));
RtlZeroMemory(m_OverlayTextures, sizeof(m_OverlayTextures));
RtlZeroMemory(m_OverlayTextureResourceViews, sizeof(m_OverlayTextureResourceViews));
RtlZeroMemory(m_VideoTextureResourceViews, sizeof(m_VideoTextureResourceViews));
m_ContextLock = SDL_CreateMutex();
}
@ -102,6 +103,11 @@ D3D11VARenderer::~D3D11VARenderer()
SAFE_COM_RELEASE(m_VideoVertexBuffer);
SAFE_COM_RELEASE(m_VideoPixelShader);
for (int i = 0; i < ARRAYSIZE(m_VideoTextureResourceViews); i++) {
SAFE_COM_RELEASE(m_VideoTextureResourceViews[i][0]);
SAFE_COM_RELEASE(m_VideoTextureResourceViews[i][1]);
}
for (int i = 0; i < ARRAYSIZE(m_OverlayVertexBuffers); i++) {
SAFE_COM_RELEASE(m_OverlayVertexBuffers[i]);
}
@ -402,7 +408,7 @@ bool D3D11VARenderer::initialize(PDECODER_PARAMETERS params)
framesContext->height = FFALIGN(params->height, (params->videoFormat & VIDEO_FORMAT_MASK_H265) ? 128 : 16);
// We can have up to 16 reference frames plus a working surface
framesContext->initial_pool_size = 17;
framesContext->initial_pool_size = DECODER_BUFFER_POOL_SIZE;
AVD3D11VAFramesContext* d3d11vaFramesContext = (AVD3D11VAFramesContext*)framesContext->hwctx;
@ -416,6 +422,11 @@ bool D3D11VARenderer::initialize(PDECODER_PARAMETERS params)
err);
return false;
}
// Create SRVs for all textures in the decoder pool
if (!setupTexturePoolViews(d3d11vaFramesContext)) {
return false;
}
}
if (params->enableVsync && m_Windowed) {
@ -803,8 +814,6 @@ void D3D11VARenderer::updateColorConversionConstants(AVFrame* frame)
void D3D11VARenderer::renderVideo(AVFrame* frame)
{
HRESULT hr;
// Update our CSC constants if the colorspace has changed
updateColorConversionConstants(frame);
@ -813,43 +822,20 @@ void D3D11VARenderer::renderVideo(AVFrame* frame)
UINT offset = 0;
m_DeviceContext->IASetVertexBuffers(0, 1, &m_VideoVertexBuffer, &stride, &offset);
// Create shader resource views for the video texture
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
srvDesc.Texture2DArray.MostDetailedMip = 0;
srvDesc.Texture2DArray.MipLevels = 1;
srvDesc.Texture2DArray.FirstArraySlice = (uintptr_t)frame->data[1];
srvDesc.Texture2DArray.ArraySize = 1;
// Bind the luminance plane
ID3D11ShaderResourceView* luminanceTextureView;
srvDesc.Format = m_DecoderParams.videoFormat == VIDEO_FORMAT_H265_MAIN10 ? DXGI_FORMAT_R16_UNORM : DXGI_FORMAT_R8_UNORM;
hr = m_Device->CreateShaderResourceView((ID3D11Resource*)frame->data[0], &srvDesc, &luminanceTextureView);
if (FAILED(hr)) {
// Our indexing logic depends on a direct mapping into m_VideoTextureResourceViews
// based on the texture index provided by FFmpeg.
UINT textureIndex = (uintptr_t)frame->data[1];
SDL_assert(textureIndex < DECODER_BUFFER_POOL_SIZE);
if (textureIndex >= DECODER_BUFFER_POOL_SIZE) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"ID3D11Device::CreateShaderResourceView() failed: %x",
hr);
"Unexpected texture index: %u",
textureIndex);
return;
}
m_DeviceContext->PSSetShaderResources(0, 1, &luminanceTextureView);
luminanceTextureView->Release();
// Bind the chrominance plane
ID3D11ShaderResourceView* chrominanceTextureView;
srvDesc.Format = m_DecoderParams.videoFormat == VIDEO_FORMAT_H265_MAIN10 ? DXGI_FORMAT_R16G16_UNORM : DXGI_FORMAT_R8G8_UNORM;
hr = m_Device->CreateShaderResourceView((ID3D11Resource*)frame->data[0], &srvDesc, &chrominanceTextureView);
if (FAILED(hr)) {
luminanceTextureView->Release();
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"ID3D11Device::CreateShaderResourceView() failed: %x",
hr);
return;
}
m_DeviceContext->PSSetShaderResources(1, 1, &chrominanceTextureView);
chrominanceTextureView->Release();
// Bind video pixel shader
// Bind video pixel shader and SRVs for this frame
m_DeviceContext->PSSetShader(m_VideoPixelShader, nullptr, 0);
m_DeviceContext->PSSetShaderResources(0, 2, m_VideoTextureResourceViews[textureIndex]);
// Draw the video
m_DeviceContext->DrawIndexed(6, 0, 0);
@ -1307,3 +1293,44 @@ bool D3D11VARenderer::setupRenderingResources()
return true;
}
bool D3D11VARenderer::setupTexturePoolViews(AVD3D11VAFramesContext* frameContext)
{
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
srvDesc.Texture2DArray.MostDetailedMip = 0;
srvDesc.Texture2DArray.MipLevels = 1;
srvDesc.Texture2DArray.ArraySize = 1;
// Create luminance and chrominance SRVs for each texture in the pool
for (int i = 0; i < DECODER_BUFFER_POOL_SIZE; i++) {
HRESULT hr;
// Our rendering logic depends on the texture index working to map into our SRV array
SDL_assert(i == frameContext->texture_infos[i].index);
srvDesc.Texture2DArray.FirstArraySlice = frameContext->texture_infos[i].index;
srvDesc.Format = m_DecoderParams.videoFormat == VIDEO_FORMAT_H265_MAIN10 ? DXGI_FORMAT_R16_UNORM : DXGI_FORMAT_R8_UNORM;
hr = m_Device->CreateShaderResourceView(frameContext->texture_infos[i].texture, &srvDesc, &m_VideoTextureResourceViews[i][0]);
if (FAILED(hr)) {
m_VideoTextureResourceViews[i][0] = nullptr;
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"ID3D11Device::CreateShaderResourceView() failed: %x",
hr);
return false;
}
srvDesc.Format = m_DecoderParams.videoFormat == VIDEO_FORMAT_H265_MAIN10 ? DXGI_FORMAT_R16G16_UNORM : DXGI_FORMAT_R8G8_UNORM;
hr = m_Device->CreateShaderResourceView(frameContext->texture_infos[i].texture, &srvDesc, &m_VideoTextureResourceViews[i][1]);
if (FAILED(hr)) {
m_VideoTextureResourceViews[i][1] = nullptr;
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"ID3D11Device::CreateShaderResourceView() failed: %x",
hr);
return false;
}
}
return true;
}

View File

@ -28,6 +28,7 @@ private:
static void unlockContext(void* lock_ctx);
bool setupRenderingResources();
bool setupTexturePoolViews(AVD3D11VAFramesContext* frameContext);
void renderOverlay(Overlay::OverlayType type);
void updateColorConversionConstants(AVFrame* frame);
void renderVideo(AVFrame* frame);
@ -53,6 +54,9 @@ private:
ID3D11PixelShader* m_VideoPixelShader;
ID3D11Buffer* m_VideoVertexBuffer;
#define DECODER_BUFFER_POOL_SIZE 17
ID3D11ShaderResourceView* m_VideoTextureResourceViews[DECODER_BUFFER_POOL_SIZE][2];
SDL_SpinLock m_OverlayLock;
ID3D11Buffer* m_OverlayVertexBuffers[Overlay::OverlayMax];
ID3D11Texture2D* m_OverlayTextures[Overlay::OverlayMax];