mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2025-07-03 16:25:54 +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_OverlayVertexBuffers, sizeof(m_OverlayVertexBuffers));
|
||||||
RtlZeroMemory(m_OverlayTextures, sizeof(m_OverlayTextures));
|
RtlZeroMemory(m_OverlayTextures, sizeof(m_OverlayTextures));
|
||||||
RtlZeroMemory(m_OverlayTextureResourceViews, sizeof(m_OverlayTextureResourceViews));
|
RtlZeroMemory(m_OverlayTextureResourceViews, sizeof(m_OverlayTextureResourceViews));
|
||||||
|
RtlZeroMemory(m_VideoTextureResourceViews, sizeof(m_VideoTextureResourceViews));
|
||||||
|
|
||||||
m_ContextLock = SDL_CreateMutex();
|
m_ContextLock = SDL_CreateMutex();
|
||||||
}
|
}
|
||||||
@ -102,6 +103,11 @@ D3D11VARenderer::~D3D11VARenderer()
|
|||||||
SAFE_COM_RELEASE(m_VideoVertexBuffer);
|
SAFE_COM_RELEASE(m_VideoVertexBuffer);
|
||||||
SAFE_COM_RELEASE(m_VideoPixelShader);
|
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++) {
|
for (int i = 0; i < ARRAYSIZE(m_OverlayVertexBuffers); i++) {
|
||||||
SAFE_COM_RELEASE(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);
|
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
|
// 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;
|
AVD3D11VAFramesContext* d3d11vaFramesContext = (AVD3D11VAFramesContext*)framesContext->hwctx;
|
||||||
|
|
||||||
@ -416,6 +422,11 @@ bool D3D11VARenderer::initialize(PDECODER_PARAMETERS params)
|
|||||||
err);
|
err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create SRVs for all textures in the decoder pool
|
||||||
|
if (!setupTexturePoolViews(d3d11vaFramesContext)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params->enableVsync && m_Windowed) {
|
if (params->enableVsync && m_Windowed) {
|
||||||
@ -803,8 +814,6 @@ void D3D11VARenderer::updateColorConversionConstants(AVFrame* frame)
|
|||||||
|
|
||||||
void D3D11VARenderer::renderVideo(AVFrame* frame)
|
void D3D11VARenderer::renderVideo(AVFrame* frame)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
// Update our CSC constants if the colorspace has changed
|
// Update our CSC constants if the colorspace has changed
|
||||||
updateColorConversionConstants(frame);
|
updateColorConversionConstants(frame);
|
||||||
|
|
||||||
@ -813,43 +822,20 @@ void D3D11VARenderer::renderVideo(AVFrame* frame)
|
|||||||
UINT offset = 0;
|
UINT offset = 0;
|
||||||
m_DeviceContext->IASetVertexBuffers(0, 1, &m_VideoVertexBuffer, &stride, &offset);
|
m_DeviceContext->IASetVertexBuffers(0, 1, &m_VideoVertexBuffer, &stride, &offset);
|
||||||
|
|
||||||
// Create shader resource views for the video texture
|
// Our indexing logic depends on a direct mapping into m_VideoTextureResourceViews
|
||||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
|
// based on the texture index provided by FFmpeg.
|
||||||
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
|
UINT textureIndex = (uintptr_t)frame->data[1];
|
||||||
srvDesc.Texture2DArray.MostDetailedMip = 0;
|
SDL_assert(textureIndex < DECODER_BUFFER_POOL_SIZE);
|
||||||
srvDesc.Texture2DArray.MipLevels = 1;
|
if (textureIndex >= DECODER_BUFFER_POOL_SIZE) {
|
||||||
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)) {
|
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"ID3D11Device::CreateShaderResourceView() failed: %x",
|
"Unexpected texture index: %u",
|
||||||
hr);
|
textureIndex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_DeviceContext->PSSetShaderResources(0, 1, &luminanceTextureView);
|
|
||||||
luminanceTextureView->Release();
|
|
||||||
|
|
||||||
// Bind the chrominance plane
|
// Bind video pixel shader and SRVs for this frame
|
||||||
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
|
|
||||||
m_DeviceContext->PSSetShader(m_VideoPixelShader, nullptr, 0);
|
m_DeviceContext->PSSetShader(m_VideoPixelShader, nullptr, 0);
|
||||||
|
m_DeviceContext->PSSetShaderResources(0, 2, m_VideoTextureResourceViews[textureIndex]);
|
||||||
|
|
||||||
// Draw the video
|
// Draw the video
|
||||||
m_DeviceContext->DrawIndexed(6, 0, 0);
|
m_DeviceContext->DrawIndexed(6, 0, 0);
|
||||||
@ -1307,3 +1293,44 @@ bool D3D11VARenderer::setupRenderingResources()
|
|||||||
|
|
||||||
return true;
|
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);
|
static void unlockContext(void* lock_ctx);
|
||||||
|
|
||||||
bool setupRenderingResources();
|
bool setupRenderingResources();
|
||||||
|
bool setupTexturePoolViews(AVD3D11VAFramesContext* frameContext);
|
||||||
void renderOverlay(Overlay::OverlayType type);
|
void renderOverlay(Overlay::OverlayType type);
|
||||||
void updateColorConversionConstants(AVFrame* frame);
|
void updateColorConversionConstants(AVFrame* frame);
|
||||||
void renderVideo(AVFrame* frame);
|
void renderVideo(AVFrame* frame);
|
||||||
@ -53,6 +54,9 @@ private:
|
|||||||
ID3D11PixelShader* m_VideoPixelShader;
|
ID3D11PixelShader* m_VideoPixelShader;
|
||||||
ID3D11Buffer* m_VideoVertexBuffer;
|
ID3D11Buffer* m_VideoVertexBuffer;
|
||||||
|
|
||||||
|
#define DECODER_BUFFER_POOL_SIZE 17
|
||||||
|
ID3D11ShaderResourceView* m_VideoTextureResourceViews[DECODER_BUFFER_POOL_SIZE][2];
|
||||||
|
|
||||||
SDL_SpinLock m_OverlayLock;
|
SDL_SpinLock m_OverlayLock;
|
||||||
ID3D11Buffer* m_OverlayVertexBuffers[Overlay::OverlayMax];
|
ID3D11Buffer* m_OverlayVertexBuffers[Overlay::OverlayMax];
|
||||||
ID3D11Texture2D* m_OverlayTextures[Overlay::OverlayMax];
|
ID3D11Texture2D* m_OverlayTextures[Overlay::OverlayMax];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user