mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2025-07-01 23:35:55 +00:00
Create SRVs for all textures in the pool during initialization
This commit is contained in:
parent
1942e72474
commit
04a0aca221
@ -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;
|
||||
}
|
||||
|
@ -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];
|
||||
|
Loading…
x
Reference in New Issue
Block a user