From 2408b881a2fce6b46af2723d6db2e9fc3838fe3b Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 18 Feb 2020 18:28:06 +0000 Subject: [PATCH] [dxso] Use SSBOs for vertex constant buffers if we'd be outside of uniform range Impacts #1375 --- src/d3d9/d3d9_device.cpp | 9 +++++---- src/d3d9/d3d9_device.h | 2 +- src/dxso/dxso_compiler.cpp | 14 ++++++++++++-- src/dxso/dxso_options.cpp | 8 +++++++- src/dxso/dxso_options.h | 6 +++++- 5 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 78599b91b..21279e322 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -49,7 +49,6 @@ namespace dxvk { , m_multithread ( BehaviorFlags & D3DCREATE_MULTITHREADED ) , m_shaderModules ( new D3D9ShaderModuleSet ) , m_d3d9Options ( dxvkDevice, pParent->GetInstance()->config() ) - , m_dxsoOptions ( m_dxvkDevice, m_d3d9Options ) , m_isSWVP ( (BehaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) ? TRUE : FALSE ) { // If we can SWVP, then we use an extended constant set // as SWVP has many more slots available than HWVP. @@ -73,11 +72,13 @@ namespace dxvk { ctx->setLogicOpState(loState); }); - CreateConstantBuffers(); - if (!(BehaviorFlags & D3DCREATE_FPU_PRESERVE)) SetupFPU(); + m_dxsoOptions = DxsoOptions(this, m_d3d9Options); + + CreateConstantBuffers(); + m_availableMemory = DetermineInitialTextureMemory(); } @@ -4468,7 +4469,7 @@ namespace dxvk { void D3D9DeviceEx::CreateConstantBuffers() { m_consts[DxsoProgramTypes::VertexShader].buffer = - CreateConstantBuffer(false, + CreateConstantBuffer(m_dxsoOptions.vertexConstantBufferAsSSBO, m_vsLayout.totalSize(), DxsoProgramType::VertexShader, DxsoConstantBuffers::VSConstantBuffer); diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index c79bbcca7..3b0d3e7c5 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -992,7 +992,7 @@ namespace dxvk { D3D9UPBufferSlice m_upBuffer; const D3D9Options m_d3d9Options; - const DxsoOptions m_dxsoOptions; + DxsoOptions m_dxsoOptions; BOOL m_isSWVP; diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index d887b9819..134de1c3c 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -274,6 +274,9 @@ namespace dxvk { void DxsoCompiler::emitDclConstantBuffer() { + const bool asSsbo = m_moduleInfo.options.vertexConstantBufferAsSSBO && + m_programInfo.type() == DxsoProgramType::VertexShader; + std::array members = { // float f[256 or 224 or 8192] m_module.defArrayTypeUnique( @@ -309,7 +312,9 @@ namespace dxvk { const uint32_t structType = m_module.defStructType(swvp ? 3 : 2, members.data()); - m_module.decorateBlock(structType); + m_module.decorate(structType, asSsbo + ? spv::DecorationBufferBlock + : spv::DecorationBlock); m_module.memberDecorateOffset(structType, 0, m_layout->floatOffset()); m_module.memberDecorateOffset(structType, 1, m_layout->intOffset()); @@ -337,9 +342,14 @@ namespace dxvk { m_module.decorateDescriptorSet(m_cBuffer, 0); m_module.decorateBinding(m_cBuffer, bindingId); + if (asSsbo) + m_module.decorate(m_cBuffer, spv::DecorationNonWritable); + DxvkResourceSlot resource; resource.slot = bindingId; - resource.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + resource.type = asSsbo + ? VK_DESCRIPTOR_TYPE_STORAGE_BUFFER + : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; resource.access = VK_ACCESS_UNIFORM_READ_BIT; m_resourceSlots.push_back(resource); diff --git a/src/dxso/dxso_options.cpp b/src/dxso/dxso_options.cpp index ef402b0c5..41d5fb4c5 100644 --- a/src/dxso/dxso_options.cpp +++ b/src/dxso/dxso_options.cpp @@ -1,10 +1,14 @@ #include "dxso_options.h" +#include "../d3d9/d3d9_device.h" + namespace dxvk { DxsoOptions::DxsoOptions() {} - DxsoOptions::DxsoOptions(const Rc& device, const D3D9Options& options) { + DxsoOptions::DxsoOptions(D3D9DeviceEx* pDevice, const D3D9Options& options) { + const Rc device = pDevice->GetDXVKDevice(); + const Rc adapter = device->adapter(); const DxvkDeviceFeatures& devFeatures = device->features(); @@ -39,6 +43,8 @@ namespace dxvk { invariantPosition = options.invariantPosition; forceSamplerTypeSpecConstants = options.forceSamplerTypeSpecConstants; + + vertexConstantBufferAsSSBO = pDevice->GetVertexConstantLayout().totalSize() > devInfo.core.properties.limits.maxUniformBufferRange; } } \ No newline at end of file diff --git a/src/dxso/dxso_options.h b/src/dxso/dxso_options.h index 5a8e5c56a..efc877193 100644 --- a/src/dxso/dxso_options.h +++ b/src/dxso/dxso_options.h @@ -5,11 +5,12 @@ namespace dxvk { + class D3D9DeviceEx; struct D3D9Options; struct DxsoOptions { DxsoOptions(); - DxsoOptions(const Rc& device, const D3D9Options& options); + DxsoOptions(D3D9DeviceEx* pDevice, const D3D9Options& options); /// Use a SPIR-V extension to implement D3D-style discards bool useDemoteToHelperInvocation = false; @@ -41,6 +42,9 @@ namespace dxvk { /// Always use a spec constant to determine sampler type (instead of just in PS 1.x) /// Works around a game bug in Halo CE where it gives cube textures to 2d/volume samplers bool forceSamplerTypeSpecConstants; + + /// Should the VS constant buffer be an SSBO (swvp on NV) + bool vertexConstantBufferAsSSBO; }; } \ No newline at end of file