1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-21 13:54:18 +01:00

[d3d9] Use generic constant buffer implementation

This commit is contained in:
Philip Rebohle 2022-07-14 14:29:52 +02:00 committed by Philip Rebohle
parent e8d5ce94ea
commit 08c3c45853
3 changed files with 55 additions and 120 deletions

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "d3d9_caps.h" #include "d3d9_caps.h"
#include "d3d9_constant_buffer.h"
#include "../dxvk/dxvk_buffer.h" #include "../dxvk/dxvk_buffer.h"
@ -46,7 +47,7 @@ namespace dxvk {
struct D3D9ConstantSets { struct D3D9ConstantSets {
D3D9SwvpConstantBuffers swvpBuffers; D3D9SwvpConstantBuffers swvpBuffers;
Rc<DxvkBuffer> buffer; D3D9ConstantBuffer buffer;
DxsoShaderMetaInfo meta = {}; DxsoShaderMetaInfo meta = {};
bool dirty = true; bool dirty = true;
}; };

View File

@ -4905,51 +4905,47 @@ namespace dxvk {
void D3D9DeviceEx::CreateConstantBuffers() { void D3D9DeviceEx::CreateConstantBuffers() {
constexpr VkDeviceSize DefaultConstantBufferSize = 1024ull << 10;
if (!m_isSWVP) { if (!m_isSWVP) {
m_consts[DxsoProgramTypes::VertexShader].buffer = m_consts[DxsoProgramTypes::VertexShader].buffer = D3D9ConstantBuffer(this,
CreateConstantBuffer(false, DxsoProgramType::VertexShader,
m_vsLayout.totalSize(), DxsoConstantBuffers::VSConstantBuffer,
DxsoProgramType::VertexShader, DefaultConstantBufferSize);
DxsoConstantBuffers::VSConstantBuffer);
} }
// SWVP constant buffers are created late based on the amount of constants set by the application // SWVP constant buffers are created late based on the amount of constants set by the application
m_consts[DxsoProgramTypes::PixelShader].buffer = m_consts[DxsoProgramTypes::PixelShader].buffer = D3D9ConstantBuffer(this,
CreateConstantBuffer(false, DxsoProgramType::PixelShader,
m_psLayout.totalSize(), DxsoConstantBuffers::PSConstantBuffer,
DxsoProgramType::PixelShader, DefaultConstantBufferSize);
DxsoConstantBuffers::PSConstantBuffer);
m_vsClipPlanes = m_vsClipPlanes = D3D9ConstantBuffer(this,
CreateConstantBuffer(false, DxsoProgramType::VertexShader,
caps::MaxClipPlanes * sizeof(D3D9ClipPlane), DxsoConstantBuffers::VSClipPlanes,
DxsoProgramType::VertexShader, caps::MaxClipPlanes * sizeof(D3D9ClipPlane));
DxsoConstantBuffers::VSClipPlanes);
m_vsFixedFunction = m_vsFixedFunction = D3D9ConstantBuffer(this,
CreateConstantBuffer(false, DxsoProgramType::VertexShader,
sizeof(D3D9FixedFunctionVS), DxsoConstantBuffers::VSFixedFunction,
DxsoProgramType::VertexShader, sizeof(D3D9FixedFunctionVS));
DxsoConstantBuffers::VSFixedFunction);
m_psFixedFunction = m_psFixedFunction = D3D9ConstantBuffer(this,
CreateConstantBuffer(false, DxsoProgramType::PixelShader,
sizeof(D3D9FixedFunctionPS), DxsoConstantBuffers::PSFixedFunction,
DxsoProgramType::PixelShader, sizeof(D3D9FixedFunctionPS));
DxsoConstantBuffers::PSFixedFunction);
m_psShared = m_psShared = D3D9ConstantBuffer(this,
CreateConstantBuffer(false, DxsoProgramType::PixelShader,
sizeof(D3D9SharedPS), DxsoConstantBuffers::PSShared,
DxsoProgramType::PixelShader, sizeof(D3D9SharedPS));
DxsoConstantBuffers::PSShared);
m_vsVertexBlend = m_vsVertexBlend = D3D9ConstantBuffer(this,
CreateConstantBuffer(true, DxsoProgramType::VertexShader,
CanSWVP() DxsoConstantBuffers::VSVertexBlendData,
? sizeof(D3D9FixedFunctionVertexBlendDataSW) CanSWVP()
: sizeof(D3D9FixedFunctionVertexBlendDataHW), ? sizeof(D3D9FixedFunctionVertexBlendDataSW)
DxsoProgramType::VertexShader, : sizeof(D3D9FixedFunctionVertexBlendDataHW));
DxsoConstantBuffers::VSVertexBlendData);
} }
@ -5059,36 +5055,12 @@ namespace dxvk {
const uint32_t intRange = caps::MaxOtherConstants * sizeof(Vector4i); const uint32_t intRange = caps::MaxOtherConstants * sizeof(Vector4i);
const uint32_t intDataSize = constSet.meta.maxConstIndexI * sizeof(Vector4i); const uint32_t intDataSize = constSet.meta.maxConstIndexI * sizeof(Vector4i);
uint32_t floatDataSize = floatCount * sizeof(Vector4); uint32_t floatDataSize = floatCount * sizeof(Vector4);
const uint32_t alignment = std::max(m_robustUBOAlignment, 64u); // Make sure we do not recreate the buffer because the new one has to be a tiny bit larger const uint32_t alignment = constSet.buffer.GetAlignment();
const uint32_t bufferSize = align(std::max(floatDataSize + intRange, alignment), alignment); const uint32_t bufferSize = align(std::max(floatDataSize + intRange, alignment), alignment);
floatDataSize = bufferSize - intRange; // Read additional floats for padding so we don't end up with garbage data floatDataSize = bufferSize - intRange;
VkDeviceSize& boundConstantBufferSize = ShaderStage == DxsoProgramType::VertexShader ? m_boundVSConstantsBufferSize : m_boundPSConstantsBufferSize; void* mapPtr = constSet.buffer.Alloc(bufferSize);
if (boundConstantBufferSize < bufferSize) { auto* dst = reinterpret_cast<HardwareLayoutType*>(mapPtr);
constexpr uint32_t slotId = computeResourceSlotId(ShaderStage, DxsoBindingType::ConstantBuffer, 0);
EmitCs([
cBuffer = constSet.buffer,
cSlotId = slotId,
cSize = bufferSize
] (DxvkContext* ctx) {
VkShaderStageFlagBits stage = GetShaderStage(ShaderStage);
ctx->bindResourceBuffer(stage, cSlotId,
DxvkBufferSlice(cBuffer, 0, cSize));
});
boundConstantBufferSize = bufferSize;
}
DxvkBufferSliceHandle slice = constSet.buffer->allocSlice();
EmitCs([
cBuffer = constSet.buffer,
cSlice = slice
] (DxvkContext* ctx) {
ctx->invalidateBuffer(cBuffer, cSlice);
});
auto* dst = reinterpret_cast<HardwareLayoutType*>(slice.mapPtr);
if (constSet.meta.maxConstIndexI != 0) if (constSet.meta.maxConstIndexI != 0)
std::memcpy(dst->iConsts, Src.iConsts, intDataSize); std::memcpy(dst->iConsts, Src.iConsts, intDataSize);
@ -5124,21 +5096,14 @@ namespace dxvk {
void D3D9DeviceEx::UpdateClipPlanes() { void D3D9DeviceEx::UpdateClipPlanes() {
m_flags.clr(D3D9DeviceFlag::DirtyClipPlanes); m_flags.clr(D3D9DeviceFlag::DirtyClipPlanes);
auto slice = m_vsClipPlanes->allocSlice(); auto mapPtr = m_vsClipPlanes.AllocSlice();
auto dst = reinterpret_cast<D3D9ClipPlane*>(slice.mapPtr); auto dst = reinterpret_cast<D3D9ClipPlane*>(mapPtr);
for (uint32_t i = 0; i < caps::MaxClipPlanes; i++) { for (uint32_t i = 0; i < caps::MaxClipPlanes; i++) {
dst[i] = (m_state.renderStates[D3DRS_CLIPPLANEENABLE] & (1 << i)) dst[i] = (m_state.renderStates[D3DRS_CLIPPLANEENABLE] & (1 << i))
? m_state.clipPlanes[i] ? m_state.clipPlanes[i]
: D3D9ClipPlane(); : D3D9ClipPlane();
} }
EmitCs([
cBuffer = m_vsClipPlanes,
cSlice = slice
] (DxvkContext* ctx) {
ctx->invalidateBuffer(cBuffer, cSlice);
});
} }
@ -6216,16 +6181,8 @@ namespace dxvk {
if (m_flags.test(D3D9DeviceFlag::DirtySharedPixelShaderData)) { if (m_flags.test(D3D9DeviceFlag::DirtySharedPixelShaderData)) {
m_flags.clr(D3D9DeviceFlag::DirtySharedPixelShaderData); m_flags.clr(D3D9DeviceFlag::DirtySharedPixelShaderData);
DxvkBufferSliceHandle slice = m_psShared->allocSlice(); auto mapPtr = m_psShared.AllocSlice();
D3D9SharedPS* data = reinterpret_cast<D3D9SharedPS*>(mapPtr);
EmitCs([
cBuffer = m_psShared,
cSlice = slice
] (DxvkContext* ctx) {
ctx->invalidateBuffer(cBuffer, cSlice);
});
D3D9SharedPS* data = reinterpret_cast<D3D9SharedPS*>(slice.mapPtr);
for (uint32_t i = 0; i < caps::TextureStageCount; i++) { for (uint32_t i = 0; i < caps::TextureStageCount; i++) {
DecodeD3DCOLOR(D3DCOLOR(m_state.textureStages[i][DXVK_TSS_CONSTANT]), data->Stages[i].Constant); DecodeD3DCOLOR(D3DCOLOR(m_state.textureStages[i][DXVK_TSS_CONSTANT]), data->Stages[i].Constant);
@ -6683,19 +6640,12 @@ namespace dxvk {
if (m_flags.test(D3D9DeviceFlag::DirtyFFVertexData)) { if (m_flags.test(D3D9DeviceFlag::DirtyFFVertexData)) {
m_flags.clr(D3D9DeviceFlag::DirtyFFVertexData); m_flags.clr(D3D9DeviceFlag::DirtyFFVertexData);
DxvkBufferSliceHandle slice = m_vsFixedFunction->allocSlice(); auto mapPtr = m_vsFixedFunction.AllocSlice();
EmitCs([
cBuffer = m_vsFixedFunction,
cSlice = slice
] (DxvkContext* ctx) {
ctx->invalidateBuffer(cBuffer, cSlice);
});
auto WorldView = m_state.transforms[GetTransformIndex(D3DTS_VIEW)] * m_state.transforms[GetTransformIndex(D3DTS_WORLD)]; auto WorldView = m_state.transforms[GetTransformIndex(D3DTS_VIEW)] * m_state.transforms[GetTransformIndex(D3DTS_WORLD)];
auto NormalMatrix = inverse(WorldView); auto NormalMatrix = inverse(WorldView);
D3D9FixedFunctionVS* data = reinterpret_cast<D3D9FixedFunctionVS*>(slice.mapPtr); D3D9FixedFunctionVS* data = reinterpret_cast<D3D9FixedFunctionVS*>(mapPtr);
data->WorldView = WorldView; data->WorldView = WorldView;
data->NormalMatrix = NormalMatrix; data->NormalMatrix = NormalMatrix;
data->InverseView = transpose(inverse(m_state.transforms[GetTransformIndex(D3DTS_VIEW)])); data->InverseView = transpose(inverse(m_state.transforms[GetTransformIndex(D3DTS_VIEW)]));
@ -6724,23 +6674,15 @@ namespace dxvk {
if (m_flags.test(D3D9DeviceFlag::DirtyFFVertexBlend) && vertexBlendMode == D3D9FF_VertexBlendMode_Normal) { if (m_flags.test(D3D9DeviceFlag::DirtyFFVertexBlend) && vertexBlendMode == D3D9FF_VertexBlendMode_Normal) {
m_flags.clr(D3D9DeviceFlag::DirtyFFVertexBlend); m_flags.clr(D3D9DeviceFlag::DirtyFFVertexBlend);
DxvkBufferSliceHandle slice = m_vsVertexBlend->allocSlice(); auto mapPtr = m_vsVertexBlend.AllocSlice();
EmitCs([
cBuffer = m_vsVertexBlend,
cSlice = slice
] (DxvkContext* ctx) {
ctx->invalidateBuffer(cBuffer, cSlice);
});
auto UploadVertexBlendData = [&](auto data) { auto UploadVertexBlendData = [&](auto data) {
for (uint32_t i = 0; i < std::size(data->WorldView); i++) for (uint32_t i = 0; i < std::size(data->WorldView); i++)
data->WorldView[i] = m_state.transforms[GetTransformIndex(D3DTS_VIEW)] * m_state.transforms[GetTransformIndex(D3DTS_WORLDMATRIX(i))]; data->WorldView[i] = m_state.transforms[GetTransformIndex(D3DTS_VIEW)] * m_state.transforms[GetTransformIndex(D3DTS_WORLDMATRIX(i))];
}; };
(m_isSWVP && indexedVertexBlend) (m_isSWVP && indexedVertexBlend)
? UploadVertexBlendData(reinterpret_cast<D3D9FixedFunctionVertexBlendDataSW*>(slice.mapPtr)) ? UploadVertexBlendData(reinterpret_cast<D3D9FixedFunctionVertexBlendDataSW*>(mapPtr))
: UploadVertexBlendData(reinterpret_cast<D3D9FixedFunctionVertexBlendDataHW*>(slice.mapPtr)); : UploadVertexBlendData(reinterpret_cast<D3D9FixedFunctionVertexBlendDataHW*>(mapPtr));
} }
} }
@ -6842,18 +6784,10 @@ namespace dxvk {
if (m_flags.test(D3D9DeviceFlag::DirtyFFPixelData)) { if (m_flags.test(D3D9DeviceFlag::DirtyFFPixelData)) {
m_flags.clr(D3D9DeviceFlag::DirtyFFPixelData); m_flags.clr(D3D9DeviceFlag::DirtyFFPixelData);
DxvkBufferSliceHandle slice = m_psFixedFunction->allocSlice(); auto mapPtr = m_psFixedFunction.AllocSlice();
EmitCs([
cBuffer = m_psFixedFunction,
cSlice = slice
] (DxvkContext* ctx) {
ctx->invalidateBuffer(cBuffer, cSlice);
});
auto& rs = m_state.renderStates; auto& rs = m_state.renderStates;
D3D9FixedFunctionPS* data = reinterpret_cast<D3D9FixedFunctionPS*>(slice.mapPtr); D3D9FixedFunctionPS* data = reinterpret_cast<D3D9FixedFunctionPS*>(mapPtr);
DecodeD3DCOLOR((D3DCOLOR)rs[D3DRS_TEXTUREFACTOR], data->textureFactor.data); DecodeD3DCOLOR((D3DCOLOR)rs[D3DRS_TEXTUREFACTOR], data->textureFactor.data);
} }
} }

View File

@ -1162,12 +1162,12 @@ namespace dxvk {
Rc<D3D9ShaderModuleSet> m_shaderModules; Rc<D3D9ShaderModuleSet> m_shaderModules;
Rc<DxvkBuffer> m_vsClipPlanes; D3D9ConstantBuffer m_vsClipPlanes;
Rc<DxvkBuffer> m_vsFixedFunction; D3D9ConstantBuffer m_vsFixedFunction;
Rc<DxvkBuffer> m_vsVertexBlend; D3D9ConstantBuffer m_vsVertexBlend;
Rc<DxvkBuffer> m_psFixedFunction; D3D9ConstantBuffer m_psFixedFunction;
Rc<DxvkBuffer> m_psShared; D3D9ConstantBuffer m_psShared;
D3D9BufferSlice m_upBuffer; D3D9BufferSlice m_upBuffer;
D3D9BufferSlice m_managedUploadBuffer; D3D9BufferSlice m_managedUploadBuffer;