From 2356d34f2ef2f8b85928278614dc7ec838278670 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 1 Mar 2023 12:37:06 +0100 Subject: [PATCH] [d3d11] Create video context resources on demand Saves another memory allocation that we will often not need. --- src/d3d11/d3d11_video.cpp | 129 +++++++++++++++++++++++--------------- src/d3d11/d3d11_video.h | 21 +++++-- 2 files changed, 93 insertions(+), 57 deletions(-) diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index 9202ca6d..47179394 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -348,56 +348,8 @@ namespace dxvk { D3D11VideoContext::D3D11VideoContext( D3D11ImmediateContext* pContext, const Rc& Device) - : m_ctx(pContext) { - SpirvCodeBuffer vsCode(d3d11_video_blit_vert); - SpirvCodeBuffer fsCode(d3d11_video_blit_frag); + : m_ctx(pContext), m_device(Device) { - const std::array fsBindings = {{ - { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, VK_IMAGE_VIEW_TYPE_MAX_ENUM, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_UNIFORM_READ_BIT, VK_TRUE }, - { VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_IMAGE_VIEW_TYPE_MAX_ENUM, VK_SHADER_STAGE_FRAGMENT_BIT, 0 }, - { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2, VK_IMAGE_VIEW_TYPE_2D, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_SHADER_READ_BIT }, - { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 3, VK_IMAGE_VIEW_TYPE_2D, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_SHADER_READ_BIT }, - }}; - - DxvkShaderCreateInfo vsInfo; - vsInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; - vsInfo.outputMask = 0x1; - m_vs = new DxvkShader(vsInfo, std::move(vsCode)); - - DxvkShaderCreateInfo fsInfo; - fsInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; - fsInfo.bindingCount = fsBindings.size(); - fsInfo.bindings = fsBindings.data(); - fsInfo.inputMask = 0x1; - fsInfo.outputMask = 0x1; - m_fs = new DxvkShader(fsInfo, std::move(fsCode)); - - DxvkSamplerCreateInfo samplerInfo; - samplerInfo.magFilter = VK_FILTER_LINEAR; - samplerInfo.minFilter = VK_FILTER_LINEAR; - samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; - samplerInfo.mipmapLodBias = 0.0f; - samplerInfo.mipmapLodMin = 0.0f; - samplerInfo.mipmapLodMax = 0.0f; - samplerInfo.useAnisotropy = VK_FALSE; - samplerInfo.maxAnisotropy = 1.0f; - samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - samplerInfo.compareToDepth = VK_FALSE; - samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS; - samplerInfo.reductionMode = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE; - samplerInfo.borderColor = VkClearColorValue(); - samplerInfo.usePixelCoord = VK_FALSE; - samplerInfo.nonSeamless = VK_FALSE; - m_sampler = Device->createSampler(samplerInfo); - - DxvkBufferCreateInfo bufferInfo; - bufferInfo.size = sizeof(UboData); - bufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; - bufferInfo.stages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; - bufferInfo.access = VK_ACCESS_UNIFORM_READ_BIT; - m_ubo = Device->createBuffer(bufferInfo, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); } @@ -1226,9 +1178,6 @@ namespace dxvk { rt.color[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; ctx->bindRenderTargets(std::move(rt), 0u); - ctx->bindShader(Rc(m_vs)); - ctx->bindShader(Rc(m_fs)); - ctx->bindUniformBuffer(VK_SHADER_STAGE_FRAGMENT_BIT, 0, DxvkBufferSlice(m_ubo)); DxvkInputAssemblyState iaState; iaState.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; @@ -1245,6 +1194,8 @@ namespace dxvk { void D3D11VideoContext::BlitStream( const D3D11VideoProcessorStreamState* pStreamState, const D3D11_VIDEO_PROCESSOR_STREAM* pStream) { + CreateResources(); + if (pStream->PastFrames || pStream->FutureFrames) Logger::err("D3D11VideoContext: Ignoring non-zero PastFrames and FutureFrames"); @@ -1322,6 +1273,11 @@ namespace dxvk { ctx->invalidateBuffer(m_ubo, uboSlice); ctx->setViewports(1, &viewport, &scissor); + + ctx->bindShader(Rc(m_vs)); + ctx->bindShader(Rc(m_fs)); + + ctx->bindUniformBuffer(VK_SHADER_STAGE_FRAGMENT_BIT, 0, DxvkBufferSlice(m_ubo)); ctx->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, 1, Rc(m_sampler)); for (uint32_t i = 0; i < cViews.size(); i++) @@ -1337,6 +1293,75 @@ namespace dxvk { } + void D3D11VideoContext::CreateUniformBuffer() { + DxvkBufferCreateInfo bufferInfo; + bufferInfo.size = sizeof(UboData); + bufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; + bufferInfo.stages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + bufferInfo.access = VK_ACCESS_UNIFORM_READ_BIT; + m_ubo = m_device->createBuffer(bufferInfo, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + } + + + void D3D11VideoContext::CreateSampler() { + DxvkSamplerCreateInfo samplerInfo; + samplerInfo.magFilter = VK_FILTER_LINEAR; + samplerInfo.minFilter = VK_FILTER_LINEAR; + samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + samplerInfo.mipmapLodBias = 0.0f; + samplerInfo.mipmapLodMin = 0.0f; + samplerInfo.mipmapLodMax = 0.0f; + samplerInfo.useAnisotropy = VK_FALSE; + samplerInfo.maxAnisotropy = 1.0f; + samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.compareToDepth = VK_FALSE; + samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS; + samplerInfo.reductionMode = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE; + samplerInfo.borderColor = VkClearColorValue(); + samplerInfo.usePixelCoord = VK_FALSE; + samplerInfo.nonSeamless = VK_FALSE; + m_sampler = m_device->createSampler(samplerInfo); + } + + + void D3D11VideoContext::CreateShaders() { + SpirvCodeBuffer vsCode(d3d11_video_blit_vert); + SpirvCodeBuffer fsCode(d3d11_video_blit_frag); + + const std::array fsBindings = {{ + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, VK_IMAGE_VIEW_TYPE_MAX_ENUM, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_UNIFORM_READ_BIT, VK_TRUE }, + { VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_IMAGE_VIEW_TYPE_MAX_ENUM, VK_SHADER_STAGE_FRAGMENT_BIT, 0 }, + { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2, VK_IMAGE_VIEW_TYPE_2D, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_SHADER_READ_BIT }, + { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 3, VK_IMAGE_VIEW_TYPE_2D, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_SHADER_READ_BIT }, + }}; + + DxvkShaderCreateInfo vsInfo; + vsInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; + vsInfo.outputMask = 0x1; + m_vs = new DxvkShader(vsInfo, std::move(vsCode)); + + DxvkShaderCreateInfo fsInfo; + fsInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; + fsInfo.bindingCount = fsBindings.size(); + fsInfo.bindings = fsBindings.data(); + fsInfo.inputMask = 0x1; + fsInfo.outputMask = 0x1; + m_fs = new DxvkShader(fsInfo, std::move(fsCode)); + } + + + void D3D11VideoContext::CreateResources() { + if (std::exchange(m_resourcesCreated, true)) + return; + + CreateSampler(); + CreateUniformBuffer(); + CreateShaders(); + } + + void D3D11VideoContext::UnbindResources() { m_ctx->EmitCs([] (DxvkContext* ctx) { ctx->bindRenderTargets(DxvkRenderTargets(), 0u); diff --git a/src/d3d11/d3d11_video.h b/src/d3d11/d3d11_video.h index fd3b3387..30288a58 100644 --- a/src/d3d11/d3d11_video.h +++ b/src/d3d11/d3d11_video.h @@ -588,15 +588,18 @@ namespace dxvk { VkBool32 isPlanar; }; - D3D11ImmediateContext* m_ctx; + D3D11ImmediateContext* m_ctx; - Rc m_sampler; - Rc m_vs; - Rc m_fs; - Rc m_ubo; + Rc m_device; + Rc m_vs; + Rc m_fs; + Rc m_sampler; + Rc m_ubo; VkExtent2D m_dstExtent = { 0u, 0u }; + bool m_resourcesCreated = false; + void ApplyColorMatrix(float pDst[3][4], const float pSrc[3][4]); void ApplyYCbCrMatrix(float pColorMatrix[3][4], bool UseBt709); @@ -608,6 +611,14 @@ namespace dxvk { const D3D11VideoProcessorStreamState* pStreamState, const D3D11_VIDEO_PROCESSOR_STREAM* pStream); + void CreateUniformBuffer(); + + void CreateSampler(); + + void CreateShaders(); + + void CreateResources(); + void UnbindResources(); };