1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-15 07:29:17 +01:00

[d3d9] Use spec constants for bool constants

This commit is contained in:
Joshua Ashton 2020-01-26 17:42:49 +00:00 committed by Philip Rebohle
parent a43223256e
commit 720cdf383e
7 changed files with 95 additions and 19 deletions

View File

@ -14,7 +14,12 @@ namespace dxvk {
uint32_t floatSize() const { return floatCount * 4 * sizeof(float); } uint32_t floatSize() const { return floatCount * 4 * sizeof(float); }
uint32_t intSize() const { return intCount * 4 * sizeof(int); } uint32_t intSize() const { return intCount * 4 * sizeof(int); }
uint32_t bitmaskSize() const { return bitmaskCount * 1 * sizeof(uint32_t); } uint32_t bitmaskSize() const {
// Account for SWVP (non SWVP uses a spec constant)
return bitmaskCount != 1
? bitmaskCount * 1 * sizeof(uint32_t)
: 0;
}
uint32_t floatOffset() const { return 0; } uint32_t floatOffset() const { return 0; }
uint32_t intOffset() const { return floatOffset() + floatSize(); } uint32_t intOffset() const { return floatOffset() + floatSize(); }

View File

@ -4438,8 +4438,6 @@ namespace dxvk {
std::memcpy(dst->fConsts, Src.fConsts, constSet.meta->maxConstIndexF * sizeof(Vector4)); std::memcpy(dst->fConsts, Src.fConsts, constSet.meta->maxConstIndexF * sizeof(Vector4));
if (constSet.meta->maxConstIndexI) if (constSet.meta->maxConstIndexI)
std::memcpy(dst->iConsts, Src.iConsts, constSet.meta->maxConstIndexI * sizeof(Vector4i)); std::memcpy(dst->iConsts, Src.iConsts, constSet.meta->maxConstIndexI * sizeof(Vector4i));
if (constSet.meta->maxConstIndexB)
dst->bConsts[0] = Src.bConsts[0];
} }
@ -5422,9 +5420,18 @@ namespace dxvk {
GetVertexShaderPermutation()); GetVertexShaderPermutation());
} }
UploadConstants<DxsoProgramTypes::VertexShader>(); UploadConstants<DxsoProgramTypes::VertexShader>();
if (likely(!CanSWVP())) {
UpdateBoolSpecConstantVertex(
m_state.vsConsts.bConsts[0] &
GetCommonShader(m_state.vertexShader)->GetMeta().boolConstantMask);
} else
UpdateBoolSpecConstantVertex(0);
} }
else else {
UpdateBoolSpecConstantVertex(0);
UpdateFixedFunctionVS(); UpdateFixedFunctionVS();
}
if (m_flags.test(D3D9DeviceFlag::DirtyInputLayout)) if (m_flags.test(D3D9DeviceFlag::DirtyInputLayout))
BindInputLayout(); BindInputLayout();
@ -5444,8 +5451,13 @@ namespace dxvk {
UpdateSamplerTypes(m_d3d9Options.forceSamplerTypeSpecConstants ? m_samplerTypeBitfield : 0u, 0u); UpdateSamplerTypes(m_d3d9Options.forceSamplerTypeSpecConstants ? m_samplerTypeBitfield : 0u, 0u);
else else
UpdateSamplerTypes(m_samplerTypeBitfield, m_projectionBitfield); // For implicit samplers... UpdateSamplerTypes(m_samplerTypeBitfield, m_projectionBitfield); // For implicit samplers...
UpdateBoolSpecConstantPixel(
m_state.psConsts.bConsts[0] &
GetCommonShader(m_state.pixelShader)->GetMeta().boolConstantMask);
} }
else { else {
UpdateBoolSpecConstantPixel(0);
UpdateSamplerTypes(0u, 0u); UpdateSamplerTypes(0u, 0u);
UpdateFixedFunctionPS(); UpdateFixedFunctionPS();
@ -5764,7 +5776,8 @@ namespace dxvk {
? DetermineMaxCount(m_state.vertexShader) ? DetermineMaxCount(m_state.vertexShader)
: DetermineMaxCount(m_state.pixelShader); : DetermineMaxCount(m_state.pixelShader);
m_consts[ProgramType].dirty |= StartRegister < maxCount; if constexpr (ConstantType != D3D9ConstantType::Bool)
m_consts[ProgramType].dirty |= StartRegister < maxCount;
UpdateStateConstants<ProgramType, ConstantType, T>( UpdateStateConstants<ProgramType, ConstantType, T>(
&m_state, &m_state,
@ -6104,6 +6117,30 @@ namespace dxvk {
} }
void D3D9DeviceEx::UpdateBoolSpecConstantVertex(uint32_t value) {
if (value == m_lastBoolSpecConstantVertex)
return;
EmitCs([cBitfield = value](DxvkContext* ctx) {
ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::VertexShaderBools, cBitfield);
});
m_lastBoolSpecConstantVertex = value;
}
void D3D9DeviceEx::UpdateBoolSpecConstantPixel(uint32_t value) {
if (value == m_lastBoolSpecConstantPixel)
return;
EmitCs([cBitfield = value](DxvkContext* ctx) {
ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::PixelShaderBools, cBitfield);
});
m_lastBoolSpecConstantPixel = value;
}
void D3D9DeviceEx::UpdateSamplerSpecConsant(uint32_t value) { void D3D9DeviceEx::UpdateSamplerSpecConsant(uint32_t value) {
EmitCs([cBitfield = value](DxvkContext* ctx) { EmitCs([cBitfield = value](DxvkContext* ctx) {
ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::SamplerType, cBitfield); ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::SamplerType, cBitfield);
@ -6484,6 +6521,8 @@ namespace dxvk {
m_flags.set(D3D9DeviceFlag::DirtyInputLayout); m_flags.set(D3D9DeviceFlag::DirtyInputLayout);
UpdateSamplerSpecConsant(0u); UpdateSamplerSpecConsant(0u);
UpdateBoolSpecConstantVertex(0u);
UpdateBoolSpecConstantPixel(0u);
return D3D_OK; return D3D_OK;
} }

View File

@ -1014,6 +1014,9 @@ namespace dxvk {
uint32_t m_lastProjectionBitfield = 0; uint32_t m_lastProjectionBitfield = 0;
uint32_t m_projectionBitfield = 0; uint32_t m_projectionBitfield = 0;
uint32_t m_lastBoolSpecConstantVertex = 0;
uint32_t m_lastBoolSpecConstantPixel = 0;
uint32_t m_lastPointMode = 0; uint32_t m_lastPointMode = 0;
uint32_t m_activeRTs = 0; uint32_t m_activeRTs = 0;
@ -1162,6 +1165,10 @@ namespace dxvk {
bool UseProgrammablePS(); bool UseProgrammablePS();
void UpdateBoolSpecConstantVertex(uint32_t value);
void UpdateBoolSpecConstantPixel(uint32_t value);
void UpdateSamplerSpecConsant(uint32_t value); void UpdateSamplerSpecConsant(uint32_t value);
void UpdateProjectionSpecConstant(uint32_t value); void UpdateProjectionSpecConstant(uint32_t value);

View File

@ -14,6 +14,9 @@ namespace dxvk {
PointMode = 6, PointMode = 6,
ProjectionType = 7, ProjectionType = 7,
VertexShaderBools = 8,
PixelShaderBools = 9,
}; };
} }

View File

@ -294,10 +294,9 @@ namespace dxvk {
m_module.decorateArrayStride(members[0], 16); m_module.decorateArrayStride(members[0], 16);
m_module.decorateArrayStride(members[1], 16); m_module.decorateArrayStride(members[1], 16);
if (m_layout->bitmaskCount == 1) { const bool swvp = m_layout->bitmaskCount != 1;
members[2] = getScalarTypeId(DxsoScalarType::Uint32);
} if (swvp) {
else {
// Must be a multiple of 4 otherwise. // Must be a multiple of 4 otherwise.
members[2] = m_module.defArrayTypeUnique( members[2] = m_module.defArrayTypeUnique(
getVectorTypeId({ DxsoScalarType::Uint32, 4 }), getVectorTypeId({ DxsoScalarType::Uint32, 4 }),
@ -307,18 +306,22 @@ namespace dxvk {
} }
const uint32_t structType = const uint32_t structType =
m_module.defStructType(members.size(), members.data()); m_module.defStructType(swvp ? 3 : 2, members.data());
m_module.decorateBlock(structType); m_module.decorateBlock(structType);
m_module.memberDecorateOffset(structType, 0, m_layout->floatOffset()); m_module.memberDecorateOffset(structType, 0, m_layout->floatOffset());
m_module.memberDecorateOffset(structType, 1, m_layout->intOffset()); m_module.memberDecorateOffset(structType, 1, m_layout->intOffset());
m_module.memberDecorateOffset(structType, 2, m_layout->bitmaskOffset());
if (swvp)
m_module.memberDecorateOffset(structType, 2, m_layout->bitmaskOffset());
m_module.setDebugName(structType, "cbuffer_t"); m_module.setDebugName(structType, "cbuffer_t");
m_module.setDebugMemberName(structType, 0, "f"); m_module.setDebugMemberName(structType, 0, "f");
m_module.setDebugMemberName(structType, 1, "i"); m_module.setDebugMemberName(structType, 1, "i");
m_module.setDebugMemberName(structType, 2, "b");
if (swvp)
m_module.setDebugMemberName(structType, 2, "b");
m_cBuffer = m_module.newVar( m_cBuffer = m_module.newVar(
m_module.defPointerType(structType, spv::StorageClassUniform), m_module.defPointerType(structType, spv::StorageClassUniform),
@ -339,6 +342,13 @@ namespace dxvk {
resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM;
resource.access = VK_ACCESS_UNIFORM_READ_BIT; resource.access = VK_ACCESS_UNIFORM_READ_BIT;
m_resourceSlots.push_back(resource); m_resourceSlots.push_back(resource);
m_boolSpecConstant = m_module.specConst32(m_module.defIntType(32, 0), 0);
m_module.decorateSpecId(m_boolSpecConstant, getSpecId(
m_programInfo.type() == DxsoProgramType::VertexShader
? D3D9SpecConstantId::VertexShaderBools
: D3D9SpecConstantId::PixelShaderBools));
m_module.setDebugName(m_boolSpecConstant, "boolConstants");
} }
@ -897,6 +907,7 @@ namespace dxvk {
case DxsoRegisterType::ConstBool: case DxsoRegisterType::ConstBool:
m_meta.maxConstIndexB = std::max(m_meta.maxConstIndexB, reg.id.num + 1); m_meta.maxConstIndexB = std::max(m_meta.maxConstIndexB, reg.id.num + 1);
m_meta.maxConstIndexB = std::min(m_meta.maxConstIndexB, m_layout->boolCount); m_meta.maxConstIndexB = std::min(m_meta.maxConstIndexB, m_layout->boolCount);
m_meta.boolConstantMask |= 1 << reg.id.num;
break; break;
default: break; default: break;
@ -939,18 +950,25 @@ namespace dxvk {
uint32_t uintType = getScalarTypeId(DxsoScalarType::Uint32); uint32_t uintType = getScalarTypeId(DxsoScalarType::Uint32);
uint32_t uvec4Type = getVectorTypeId({ DxsoScalarType::Uint32, 4 }); uint32_t uvec4Type = getVectorTypeId({ DxsoScalarType::Uint32, 4 });
std::array<uint32_t, 2> indices = { m_module.constu32(2), m_module.constu32(reg.id.num / 128) }; // If not SWVP, spec const this
uint32_t bitfield;
if (m_layout->bitmaskCount != 1) {
std::array<uint32_t, 2> indices = { m_module.constu32(2), m_module.constu32(reg.id.num / 128) };
uint32_t indexCount = m_layout->bitmaskCount == 1 ? 1 : 2; uint32_t indexCount = m_layout->bitmaskCount == 1 ? 1 : 2;
uint32_t accessType = m_layout->bitmaskCount == 1 ? uintType : uvec4Type; uint32_t accessType = m_layout->bitmaskCount == 1 ? uintType : uvec4Type;
uint32_t ptrId = m_module.opAccessChain( uint32_t ptrId = m_module.opAccessChain(
m_module.defPointerType(accessType, spv::StorageClassUniform), m_module.defPointerType(accessType, spv::StorageClassUniform),
m_cBuffer, indexCount, indices.data()); m_cBuffer, indexCount, indices.data());
bitfield = m_module.opLoad(accessType, ptrId);
}
else
bitfield = m_boolSpecConstant;
uint32_t bitIdx = m_module.consti32(reg.id.num % 32); uint32_t bitIdx = m_module.consti32(reg.id.num % 32);
uint32_t bitfield = m_module.opLoad(accessType, ptrId);
if (m_layout->bitmaskCount != 1) { if (m_layout->bitmaskCount != 1) {
uint32_t index = (reg.id.num % 128) / 32; uint32_t index = (reg.id.num % 128) / 32;
bitfield = m_module.opCompositeExtract(uintType, bitfield, 1, &index); bitfield = m_module.opCompositeExtract(uintType, bitfield, 1, &index);

View File

@ -266,6 +266,8 @@ namespace dxvk {
SpirvModule m_module; SpirvModule m_module;
uint32_t m_boolSpecConstant;
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
// Resource slot description for the shader. This will // Resource slot description for the shader. This will
// be used to map D3D9 bindings to DXVK bindings. // be used to map D3D9 bindings to DXVK bindings.

View File

@ -34,6 +34,8 @@ namespace dxvk {
uint32_t maxConstIndexF = 0; uint32_t maxConstIndexF = 0;
uint32_t maxConstIndexI = 0; uint32_t maxConstIndexI = 0;
uint32_t maxConstIndexB = 0; uint32_t maxConstIndexB = 0;
uint32_t boolConstantMask = 0;
}; };
} }