diff --git a/src/d3d9/d3d9_constant_buffer.cpp b/src/d3d9/d3d9_constant_buffer.cpp index 523f5391..5bbd9a1d 100644 --- a/src/d3d9/d3d9_constant_buffer.cpp +++ b/src/d3d9/d3d9_constant_buffer.cpp @@ -13,7 +13,7 @@ namespace dxvk { DxsoProgramType ShaderStage, DxsoConstantBuffers BufferType, VkDeviceSize Size) - : D3D9ConstantBuffer(pDevice, GetShaderStage(ShaderStage), + : D3D9ConstantBuffer(pDevice, getBufferUsage(pDevice, ShaderStage, BufferType), GetShaderStage(ShaderStage), computeResourceSlotId(ShaderStage, DxsoBindingType::ConstantBuffer, BufferType), Size) { @@ -22,11 +22,13 @@ namespace dxvk { D3D9ConstantBuffer::D3D9ConstantBuffer( D3D9DeviceEx* pDevice, + VkBufferUsageFlags Usage, VkShaderStageFlags Stages, uint32_t ResourceSlot, VkDeviceSize Size) : m_device (pDevice) , m_binding (ResourceSlot) + , m_usage (Usage) , m_stages (Stages) , m_size (Size) , m_align (getAlignment(pDevice->GetDXVKDevice())) { @@ -98,12 +100,15 @@ namespace dxvk { // in the backend, so set both STORAGE and UNIFORM usage/access. DxvkBufferCreateInfo bufferInfo; bufferInfo.size = align(m_size, m_align); - bufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT - | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; - bufferInfo.access = VK_ACCESS_UNIFORM_READ_BIT - | VK_ACCESS_SHADER_READ_BIT; + bufferInfo.usage = m_usage; + bufferInfo.access = 0; bufferInfo.stages = util::pipelineStages(m_stages); + if (m_usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) + bufferInfo.access |= VK_ACCESS_UNIFORM_READ_BIT; + if (m_usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) + bufferInfo.access |= VK_ACCESS_SHADER_READ_BIT; + VkMemoryPropertyFlags memoryFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; @@ -130,4 +135,21 @@ namespace dxvk { device->properties().extRobustness2.robustUniformBufferAccessSizeAlignment); } + + VkBufferUsageFlags D3D9ConstantBuffer::getBufferUsage( + D3D9DeviceEx* pDevice, + DxsoProgramType ShaderStage, + DxsoConstantBuffers BufferType) { + VkBufferUsageFlags result = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; + + // We won't always need this, but the only buffer that + // this applies to is so large that it will not matter. + if (pDevice->CanSWVP() + && ShaderStage == DxsoProgramType::VertexShader + && BufferType == DxsoConstantBuffers::VSConstantBuffer) + result |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + + return result; + } + } diff --git a/src/d3d9/d3d9_constant_buffer.h b/src/d3d9/d3d9_constant_buffer.h index 980a7b1b..22abe222 100644 --- a/src/d3d9/d3d9_constant_buffer.h +++ b/src/d3d9/d3d9_constant_buffer.h @@ -29,6 +29,7 @@ namespace dxvk { D3D9ConstantBuffer( D3D9DeviceEx* pDevice, + VkBufferUsageFlags Usage, VkShaderStageFlags Stages, uint32_t ResourceSlot, VkDeviceSize Size); @@ -66,6 +67,7 @@ namespace dxvk { D3D9DeviceEx* m_device = nullptr; uint32_t m_binding = 0u; + VkBufferUsageFlags m_usage = 0u; VkShaderStageFlags m_stages = 0u; VkDeviceSize m_size = 0ull; VkDeviceSize m_align = 0ull; @@ -78,6 +80,11 @@ namespace dxvk { VkDeviceSize getAlignment(const Rc& device) const; + static VkBufferUsageFlags getBufferUsage( + D3D9DeviceEx* pDevice, + DxsoProgramType ShaderStage, + DxsoConstantBuffers BufferType); + }; } \ No newline at end of file diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 93554d0e..e8ef3012 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -5021,6 +5021,7 @@ namespace dxvk { if (m_usingGraphicsPipelines) { m_specBuffer = D3D9ConstantBuffer(this, + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, getSpecConstantBufferSlot(), sizeof(D3D9SpecializationInfo));