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

[d3d9, dxso] Implement FETCH4

This commit is contained in:
Joshua Ashton 2020-05-25 06:09:45 +01:00
parent 5d69898cbd
commit 8fdf9e67d3
5 changed files with 75 additions and 12 deletions

View File

@ -3507,6 +3507,16 @@ namespace dxvk {
m_dirtySamplerStates |= 1u << StateSampler;
else if (Type == D3DSAMP_SRGBTEXTURE)
BindTexture(StateSampler);
constexpr DWORD Fetch4Enabled = MAKEFOURCC('G', 'E', 'T', '4');
constexpr DWORD Fetch4Disabled = MAKEFOURCC('G', 'E', 'T', '1');
if (Type == D3DSAMP_MIPMAPLODBIAS) {
if (Value == Fetch4Enabled)
m_fetch4Enabled |= 1u << StateSampler;
else if (Value == Fetch4Disabled)
m_fetch4Enabled &= ~(1u << StateSampler);
}
}
return D3D_OK;
@ -5603,21 +5613,26 @@ namespace dxvk {
if (m_flags.test(D3D9DeviceFlag::DirtyInputLayout))
BindInputLayout();
auto UpdateSamplerTypes = [&](uint32_t types, uint32_t projections) {
auto UpdateSamplerTypes = [&](uint32_t types, uint32_t projections, uint32_t fetch4) {
if (m_lastSamplerTypeBitfield != types)
UpdateSamplerSpecConsant(types);
if (m_lastProjectionBitfield != projections)
UpdateProjectionSpecConstant(projections);
if (m_lastFetch4 != fetch4)
UpdateFetch4SpecConstant(fetch4);
};
if (likely(UseProgrammablePS())) {
UploadConstants<DxsoProgramTypes::PixelShader>();
uint32_t fetch4 = m_fetch4Enabled & (m_activeTextures & m_psShaderMasks.samplerMask);
if (GetCommonShader(m_state.pixelShader)->GetInfo().majorVersion() >= 2)
UpdateSamplerTypes(m_d3d9Options.forceSamplerTypeSpecConstants ? m_samplerTypeBitfield : 0u, 0u);
UpdateSamplerTypes(m_d3d9Options.forceSamplerTypeSpecConstants ? m_samplerTypeBitfield : 0u, 0u, fetch4);
else
UpdateSamplerTypes(m_samplerTypeBitfield, m_projectionBitfield); // For implicit samplers...
UpdateSamplerTypes(m_samplerTypeBitfield, m_projectionBitfield, fetch4); // For implicit samplers...
UpdateBoolSpecConstantPixel(
m_state.psConsts.bConsts[0] &
@ -5625,7 +5640,7 @@ namespace dxvk {
}
else {
UpdateBoolSpecConstantPixel(0);
UpdateSamplerTypes(0u, 0u);
UpdateSamplerTypes(0u, 0u, 0u);
UpdateFixedFunctionPS();
}
@ -6316,6 +6331,15 @@ namespace dxvk {
}
void D3D9DeviceEx::UpdateFetch4SpecConstant(uint32_t value) {
EmitCs([cBitfield = value](DxvkContext* ctx) {
ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::Fetch4, cBitfield);
});
m_lastFetch4 = value;
}
void D3D9DeviceEx::ApplyPrimitiveType(
DxvkContext* pContext,
D3DPRIMITIVETYPE PrimType) {

View File

@ -1036,6 +1036,9 @@ namespace dxvk {
uint32_t m_activeTextures = 0;
uint32_t m_activeTexturesToUpload = 0;
uint32_t m_fetch4Enabled = 0;
uint32_t m_lastFetch4 = 0;
uint32_t m_activeHazardsDS = 0;
uint32_t m_lastHazardsDS = 0;
@ -1189,6 +1192,8 @@ namespace dxvk {
void UpdateProjectionSpecConstant(uint32_t value);
void UpdateFetch4SpecConstant(uint32_t value);
};
}

View File

@ -17,6 +17,7 @@ namespace dxvk {
VertexShaderBools = 8,
PixelShaderBools = 9,
Fetch4 = 10
};
}

View File

@ -468,6 +468,10 @@ namespace dxvk {
}
}
m_ps.fetch4Spec = m_module.specConst32(m_module.defIntType(32, 0), 0);
m_module.decorateSpecId(m_ps.fetch4Spec, getSpecId(D3D9SpecConstantId::Fetch4));
m_module.setDebugName(m_ps.fetch4Spec, "s_fetch4");
this->setupRenderStateInfo();
this->emitPsSharedConstants();
@ -2766,12 +2770,22 @@ void DxsoCompiler::emitControlFlowGenericLoop(
}
}
uint32_t fetch4 = 0;
if (m_programInfo.type() == DxsoProgramType::PixelShader) {
fetch4 = m_module.opBitFieldUExtract(
m_module.defIntType(32, 0), m_ps.fetch4Spec,
m_module.consti32(samplerIdx), m_module.consti32(1));
fetch4 = m_module.opIEqual(m_module.defBoolType(), fetch4, m_module.constu32(1));
}
result.id = this->emitSample(
projDivider != 0,
typeId,
imageVarId,
texcoordVar.id,
reference,
fetch4,
imageOperands);
if (switchProjResult) {
@ -2783,6 +2797,7 @@ void DxsoCompiler::emitControlFlowGenericLoop(
imageVarId,
texcoordVar.id,
reference,
fetch4,
imageOperands);
uint32_t shouldProj = m_module.opBitFieldUExtract(
@ -3028,40 +3043,56 @@ void DxsoCompiler::emitControlFlowGenericLoop(
uint32_t sampledImage,
uint32_t coordinates,
uint32_t reference,
uint32_t fetch4,
const SpirvImageOperands& operands) {
const bool depthCompare = reference != 0;
const bool explicitLod =
(operands.flags & spv::ImageOperandsLodMask)
|| (operands.flags & spv::ImageOperandsGradMask);
uint32_t val;
// No Fetch 4
if (projected) {
if (depthCompare) {
if (explicitLod)
return m_module.opImageSampleProjDrefExplicitLod(resultType, sampledImage, coordinates, reference, operands);
val = m_module.opImageSampleProjDrefExplicitLod(resultType, sampledImage, coordinates, reference, operands);
else
return m_module.opImageSampleProjDrefImplicitLod(resultType, sampledImage, coordinates, reference, operands);
val = m_module.opImageSampleProjDrefImplicitLod(resultType, sampledImage, coordinates, reference, operands);
}
else {
if (explicitLod)
return m_module.opImageSampleProjExplicitLod(resultType, sampledImage, coordinates, operands);
val = m_module.opImageSampleProjExplicitLod(resultType, sampledImage, coordinates, operands);
else
return m_module.opImageSampleProjImplicitLod(resultType, sampledImage, coordinates, operands);
val = m_module.opImageSampleProjImplicitLod(resultType, sampledImage, coordinates, operands);
}
}
else {
if (depthCompare) {
if (explicitLod)
return m_module.opImageSampleDrefExplicitLod(resultType, sampledImage, coordinates, reference, operands);
val = m_module.opImageSampleDrefExplicitLod(resultType, sampledImage, coordinates, reference, operands);
else
return m_module.opImageSampleDrefImplicitLod(resultType, sampledImage, coordinates, reference, operands);
val = m_module.opImageSampleDrefImplicitLod(resultType, sampledImage, coordinates, reference, operands);
}
else {
if (explicitLod)
return m_module.opImageSampleExplicitLod(resultType, sampledImage, coordinates, operands);
val = m_module.opImageSampleExplicitLod(resultType, sampledImage, coordinates, operands);
else
return m_module.opImageSampleImplicitLod(resultType, sampledImage, coordinates, operands);
val = m_module.opImageSampleImplicitLod(resultType, sampledImage, coordinates, operands);
}
}
if (fetch4 && !depthCompare) {
uint32_t fetch4Val = m_module.opImageGather(resultType, sampledImage, coordinates, m_module.consti32(0), operands);
// B R G A swizzle... Funny D3D9 order.
const std::array<uint32_t, 4> indices = { 2, 0, 1, 3 };
fetch4Val = m_module.opVectorShuffle(resultType, fetch4Val, fetch4Val, indices.size(), indices.data());
val = m_module.opSelect(resultType, fetch4, fetch4Val, val);
}
return val;
}

View File

@ -157,6 +157,7 @@ namespace dxvk {
uint32_t functionId = 0;
uint32_t samplerTypeSpec = 0;
uint32_t projectionSpec = 0;
uint32_t fetch4Spec = 0;
//////////////
// Misc Types
@ -642,6 +643,7 @@ namespace dxvk {
uint32_t sampledImage,
uint32_t coordinates,
uint32_t reference,
uint32_t fetch4,
const SpirvImageOperands& operands);
///////////////////////////////