1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-31 05:52:11 +01:00

[d3d9] Use generic constant buffers for SWVP

This commit is contained in:
Philip Rebohle 2022-07-14 15:31:29 +02:00 committed by Philip Rebohle
parent 08c3c45853
commit 4635c72e95
3 changed files with 31 additions and 43 deletions

View File

@ -40,13 +40,12 @@ namespace dxvk {
};
struct D3D9SwvpConstantBuffers {
Rc<DxvkBuffer> floatBuffer;
Rc<DxvkBuffer> intBuffer;
Rc<DxvkBuffer> boolBuffer;
D3D9ConstantBuffer intBuffer;
D3D9ConstantBuffer boolBuffer;
};
struct D3D9ConstantSets {
D3D9SwvpConstantBuffers swvpBuffers;
D3D9SwvpConstantBuffers swvp;
D3D9ConstantBuffer buffer;
DxsoShaderMetaInfo meta = {};
bool dirty = true;

View File

@ -4906,15 +4906,23 @@ namespace dxvk {
void D3D9DeviceEx::CreateConstantBuffers() {
constexpr VkDeviceSize DefaultConstantBufferSize = 1024ull << 10;
constexpr VkDeviceSize SmallConstantBufferSize = 64ull << 10;
if (!m_isSWVP) {
m_consts[DxsoProgramTypes::VertexShader].buffer = D3D9ConstantBuffer(this,
DxsoProgramType::VertexShader,
DxsoConstantBuffers::VSConstantBuffer,
DefaultConstantBufferSize);
}
m_consts[DxsoProgramTypes::VertexShader].buffer = D3D9ConstantBuffer(this,
DxsoProgramType::VertexShader,
DxsoConstantBuffers::VSConstantBuffer,
DefaultConstantBufferSize);
m_consts[DxsoProgramTypes::VertexShader].swvp.intBuffer = D3D9ConstantBuffer(this,
DxsoProgramType::VertexShader,
DxsoConstantBuffers::VSIntConstantBuffer,
SmallConstantBufferSize);
m_consts[DxsoProgramTypes::VertexShader].swvp.boolBuffer = D3D9ConstantBuffer(this,
DxsoProgramType::VertexShader,
DxsoConstantBuffers::VSBoolConstantBuffer,
SmallConstantBufferSize);
// SWVP constant buffers are created late based on the amount of constants set by the application
m_consts[DxsoProgramTypes::PixelShader].buffer = D3D9ConstantBuffer(this,
DxsoProgramType::PixelShader,
DxsoConstantBuffers::PSConstantBuffer,
@ -4975,14 +4983,13 @@ namespace dxvk {
const uint32_t intDataSize = std::min(constSet.meta.maxConstIndexI, m_vsIntConstsCount) * sizeof(Vector4i);
const uint32_t boolDataSize = divCeil(std::min(constSet.meta.maxConstIndexB, m_vsBoolConstsCount), 32u) * uint32_t(sizeof(uint32_t));
Rc<DxvkBuffer>& floatBuffer = constSet.swvpBuffers.floatBuffer;
// Max copy source size is 8192 * 16 => always aligned to any plausible value
// => we won't copy out of bounds
if (likely(constSet.meta.maxConstIndexF != 0 || floatBuffer == nullptr)) {
DxvkBufferSliceHandle floatBufferSlice = CopySoftwareConstants(DxsoConstantBuffers::VSFloatConstantBuffer, floatBuffer, Src.fConsts, floatDataSize, m_dxsoOptions.vertexFloatConstantBufferAsSSBO);
if (likely(constSet.meta.maxConstIndexF != 0)) {
auto mapPtr = CopySoftwareConstants(constSet.buffer, Src.fConsts, floatDataSize);
if (constSet.meta.needsConstantCopies) {
Vector4* data = reinterpret_cast<Vector4*>(floatBufferSlice.mapPtr);
Vector4* data = reinterpret_cast<Vector4*>(mapPtr);
auto& shaderConsts = GetCommonShader(m_state.vertexShader)->GetConstants();
@ -4993,42 +5000,24 @@ namespace dxvk {
}
}
Rc<DxvkBuffer>& intBuffer = constSet.swvpBuffers.intBuffer;
// Max copy source size is 2048 * 16 => always aligned to any plausible value
// => we won't copy out of bounds
if (likely(constSet.meta.maxConstIndexI != 0 || intBuffer == nullptr)) {
CopySoftwareConstants(DxsoConstantBuffers::VSIntConstantBuffer, intBuffer, Src.iConsts, intDataSize, false);
}
if (likely(constSet.meta.maxConstIndexI != 0))
CopySoftwareConstants(constSet.swvp.intBuffer, Src.iConsts, intDataSize);
Rc<DxvkBuffer>& boolBuffer = constSet.swvpBuffers.boolBuffer;
if (likely(constSet.meta.maxConstIndexB != 0 || boolBuffer == nullptr)) {
CopySoftwareConstants(DxsoConstantBuffers::VSBoolConstantBuffer, boolBuffer, Src.bConsts, boolDataSize, false);
}
if (likely(constSet.meta.maxConstIndexB != 0))
CopySoftwareConstants(constSet.swvp.boolBuffer, Src.bConsts, boolDataSize);
}
inline DxvkBufferSliceHandle D3D9DeviceEx::CopySoftwareConstants(DxsoConstantBuffers cBufferTarget, Rc<DxvkBuffer>& dstBuffer, const void* src, uint32_t size, bool useSSBO) {
uint32_t alignment = useSSBO ? m_robustSSBOAlignment : m_robustUBOAlignment;
alignment = std::max(alignment, 64u);
inline void* D3D9DeviceEx::CopySoftwareConstants(D3D9ConstantBuffer& dstBuffer, const void* src, uint32_t size) {
uint32_t alignment = dstBuffer.GetAlignment();
size = std::max(size, alignment);
size = align(size, alignment);
DxvkBufferSliceHandle slice;
if (unlikely(dstBuffer == nullptr || dstBuffer->info().size < size)) {
dstBuffer = CreateConstantBuffer(useSSBO, size, DxsoProgramType::VertexShader, cBufferTarget);
slice = dstBuffer->getSliceHandle();
} else {
slice = dstBuffer->allocSlice();
EmitCs([
cBuffer = dstBuffer,
cSlice = slice
] (DxvkContext* ctx) {
ctx->invalidateBuffer(cBuffer, cSlice);
});
}
std::memcpy(slice.mapPtr, src, size);
return slice;
auto mapPtr = dstBuffer.Alloc(size);
std::memcpy(mapPtr, src, size);
return mapPtr;
}

View File

@ -829,7 +829,7 @@ namespace dxvk {
inline void UploadSoftwareConstantSet(const D3D9ShaderConstantsVSSoftware& Src, const D3D9ConstantLayout& Layout);
inline DxvkBufferSliceHandle CopySoftwareConstants(DxsoConstantBuffers cBufferTarget, Rc<DxvkBuffer>& dstBuffer, const void* src, uint32_t copySize, bool useSSBO);
inline void* CopySoftwareConstants(D3D9ConstantBuffer& dstBuffer, const void* src, uint32_t size);
template <DxsoProgramType ShaderStage, typename HardwareLayoutType, typename SoftwareLayoutType, typename ShaderType>
inline void UploadConstantSet(const SoftwareLayoutType& Src, const D3D9ConstantLayout& Layout, const ShaderType& Shader);