Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/doitsujin/dxvk.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Ashton <joshua@froggi.es>2021-08-08 06:52:36 +0300
committerJoshua Ashton <joshua@froggi.es>2021-08-10 17:22:08 +0300
commit7772d55b4a6034df9f3682b3e782381d490351fd (patch)
treeaae721ef688297250a8d9c9ec2f4355e8c0654ed
parent13c952888778b81ea59df11ab626418ec762d36d (diff)
[d3d9, dxso] Alias color and depth samplers and improve trackingd3d9-aliased-depth-bindings
Takes me from 340 -> 460fps in A Hat in Time's main menu when CPU bound.
-rw-r--r--src/d3d9/d3d9_device.cpp166
-rw-r--r--src/d3d9/d3d9_device.h16
-rw-r--r--src/d3d9/d3d9_fixed_function.cpp2
-rw-r--r--src/d3d9/d3d9_sampler.cpp5
-rw-r--r--src/d3d9/d3d9_sampler.h1
-rw-r--r--src/d3d9/d3d9_spec_constants.h4
-rw-r--r--src/dxso/dxso_compiler.cpp83
-rw-r--r--src/dxso/dxso_compiler.h4
-rw-r--r--src/dxso/dxso_util.cpp33
-rw-r--r--src/dxso/dxso_util.h25
10 files changed, 162 insertions, 177 deletions
diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp
index f5d69b9e..0a50168a 100644
--- a/src/d3d9/d3d9_device.cpp
+++ b/src/d3d9/d3d9_device.cpp
@@ -3711,6 +3711,19 @@ namespace dxvk {
DWORD oldUsage = oldTexture != nullptr ? oldTexture->Desc()->Usage : 0;
DWORD newUsage = newTexture != nullptr ? newTexture->Desc()->Usage : 0;
+ if (newTexture != nullptr) {
+ const bool oldDepth = m_depthTextures & (1u << StateSampler);
+ const bool newDepth = newTexture->IsShadow();
+
+ if (oldDepth != newDepth) {
+ m_depthTextures &= ~(1u << StateSampler);
+ if (newDepth)
+ m_depthTextures |= 1u << StateSampler;
+
+ m_dirtySamplerStates |= 1u << StateSampler;
+ }
+ }
+
DWORD combinedUsage = oldUsage | newUsage;
TextureChangePrivate(m_state.textures[StateSampler], pTexture);
@@ -5704,6 +5717,7 @@ namespace dxvk {
key.MipmapLodBias = bit::cast<float>(state[D3DSAMP_MIPMAPLODBIAS]);
key.MaxMipLevel = state[D3DSAMP_MAXMIPLEVEL];
key.BorderColor = D3DCOLOR(state[D3DSAMP_BORDERCOLOR]);
+ key.Depth = m_depthTextures & (1u << Sampler);
if (m_d3d9Options.samplerAnisotropy != -1) {
if (key.MagFilter == D3DTEXF_LINEAR)
@@ -5719,75 +5733,59 @@ namespace dxvk {
auto samplerInfo = RemapStateSamplerShader(Sampler);
- const uint32_t colorSlot = computeResourceSlotId(
- samplerInfo.first, DxsoBindingType::ColorImage,
- samplerInfo.second);
-
- const uint32_t depthSlot = computeResourceSlotId(
- samplerInfo.first, DxsoBindingType::DepthImage,
+ const uint32_t slot = computeResourceSlotId(
+ samplerInfo.first, DxsoBindingType::Image,
samplerInfo.second);
EmitCs([this,
- cColorSlot = colorSlot,
- cDepthSlot = depthSlot,
- cKey = key
+ cSlot = slot,
+ cKey = key
] (DxvkContext* ctx) {
auto pair = m_samplers.find(cKey);
if (pair != m_samplers.end()) {
- ctx->bindResourceSampler(cColorSlot, pair->second.color);
- ctx->bindResourceSampler(cDepthSlot, pair->second.depth);
+ ctx->bindResourceSampler(cSlot, pair->second);
return;
}
auto mipFilter = DecodeMipFilter(cKey.MipFilter);
- DxvkSamplerCreateInfo colorInfo;
- colorInfo.addressModeU = DecodeAddressMode(cKey.AddressU);
- colorInfo.addressModeV = DecodeAddressMode(cKey.AddressV);
- colorInfo.addressModeW = DecodeAddressMode(cKey.AddressW);
- colorInfo.compareToDepth = VK_FALSE;
- colorInfo.compareOp = VK_COMPARE_OP_NEVER;
- colorInfo.magFilter = DecodeFilter(cKey.MagFilter);
- colorInfo.minFilter = DecodeFilter(cKey.MinFilter);
- colorInfo.mipmapMode = mipFilter.MipFilter;
- colorInfo.maxAnisotropy = float(cKey.MaxAnisotropy);
- colorInfo.useAnisotropy = cKey.MaxAnisotropy > 1;
- colorInfo.mipmapLodBias = cKey.MipmapLodBias;
- colorInfo.mipmapLodMin = mipFilter.MipsEnabled ? float(cKey.MaxMipLevel) : 0;
- colorInfo.mipmapLodMax = mipFilter.MipsEnabled ? FLT_MAX : 0;
- colorInfo.usePixelCoord = VK_FALSE;
-
- DecodeD3DCOLOR(cKey.BorderColor, colorInfo.borderColor.float32);
+ DxvkSamplerCreateInfo info;
+ info.addressModeU = DecodeAddressMode(cKey.AddressU);
+ info.addressModeV = DecodeAddressMode(cKey.AddressV);
+ info.addressModeW = DecodeAddressMode(cKey.AddressW);
+ info.compareToDepth = cKey.Depth;
+ info.compareOp = cKey.Depth ? VK_COMPARE_OP_LESS_OR_EQUAL : VK_COMPARE_OP_NEVER;
+ info.magFilter = DecodeFilter(cKey.MagFilter);
+ info.minFilter = DecodeFilter(cKey.MinFilter);
+ info.mipmapMode = mipFilter.MipFilter;
+ info.maxAnisotropy = float(cKey.MaxAnisotropy);
+ info.useAnisotropy = cKey.MaxAnisotropy > 1;
+ info.mipmapLodBias = cKey.MipmapLodBias;
+ info.mipmapLodMin = mipFilter.MipsEnabled ? float(cKey.MaxMipLevel) : 0;
+ info.mipmapLodMax = mipFilter.MipsEnabled ? FLT_MAX : 0;
+ info.usePixelCoord = VK_FALSE;
+
+ DecodeD3DCOLOR(cKey.BorderColor, info.borderColor.float32);
if (!m_dxvkDevice->features().extCustomBorderColor.customBorderColorWithoutFormat) {
// HACK: Let's get OPAQUE_WHITE border color over
// TRANSPARENT_BLACK if the border RGB is white.
- if (colorInfo.borderColor.float32[0] == 1.0f
- && colorInfo.borderColor.float32[1] == 1.0f
- && colorInfo.borderColor.float32[2] == 1.0f
+ if (info.borderColor.float32[0] == 1.0f
+ && info.borderColor.float32[1] == 1.0f
+ && info.borderColor.float32[2] == 1.0f
&& !m_dxvkDevice->features().extCustomBorderColor.customBorderColors) {
// Then set the alpha to 1.
- colorInfo.borderColor.float32[3] = 1.0f;
+ info.borderColor.float32[3] = 1.0f;
}
}
- DxvkSamplerCreateInfo depthInfo = colorInfo;
- depthInfo.compareToDepth = VK_TRUE;
- depthInfo.compareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
- depthInfo.magFilter = VK_FILTER_LINEAR;
- depthInfo.minFilter = VK_FILTER_LINEAR;
-
try {
- D3D9SamplerPair pair;
+ auto sampler = m_dxvkDevice->createSampler(info);
- pair.color = m_dxvkDevice->createSampler(colorInfo);
- pair.depth = m_dxvkDevice->createSampler(depthInfo);
+ m_samplers.insert(std::make_pair(cKey, sampler));
+ ctx->bindResourceSampler(cSlot, std::move(sampler));
m_samplerCount++;
-
- m_samplers.insert(std::make_pair(cKey, pair));
- ctx->bindResourceSampler(cColorSlot, pair.color);
- ctx->bindResourceSampler(cDepthSlot, pair.depth);
}
catch (const DxvkError& e) {
Logger::err(e.message());
@@ -5799,11 +5797,8 @@ namespace dxvk {
void D3D9DeviceEx::BindTexture(DWORD StateSampler) {
auto shaderSampler = RemapStateSamplerShader(StateSampler);
- uint32_t colorSlot = computeResourceSlotId(shaderSampler.first,
- DxsoBindingType::ColorImage, uint32_t(shaderSampler.second));
-
- uint32_t depthSlot = computeResourceSlotId(shaderSampler.first,
- DxsoBindingType::DepthImage, uint32_t(shaderSampler.second));
+ uint32_t slot = computeResourceSlotId(shaderSampler.first,
+ DxsoBindingType::Image, uint32_t(shaderSampler.second));
const bool srgb =
m_state.samplerStates[StateSampler][D3DSAMP_SRGBTEXTURE] & 0x1;
@@ -5830,31 +5825,26 @@ namespace dxvk {
if (commonTex != nullptr) {
EmitCs([
- cColorSlot = colorSlot,
- cDepthSlot = depthSlot,
- cDepth = commonTex->IsShadow(),
+ cSlot = slot,
cImageView = commonTex->GetSampleView(srgb)
](DxvkContext* ctx) {
- ctx->bindResourceView(cColorSlot, !cDepth ? cImageView : nullptr, nullptr);
- ctx->bindResourceView(cDepthSlot, cDepth ? cImageView : nullptr, nullptr);
+ ctx->bindResourceView(cSlot, cImageView, nullptr);
});
} else {
EmitCs([
- cColorSlot = colorSlot,
- cDepthSlot = depthSlot
+ cSlot = slot
](DxvkContext* ctx) {
- ctx->bindResourceView(cColorSlot, nullptr, nullptr);
- ctx->bindResourceView(cDepthSlot, nullptr, nullptr);
+ ctx->bindResourceView(cSlot, nullptr, nullptr);
});
}
}
- void D3D9DeviceEx::UndirtySamplers() {
- for (uint32_t dirty = m_dirtySamplerStates; dirty; dirty &= dirty - 1)
+ void D3D9DeviceEx::UndirtySamplers(uint32_t mask) {
+ for (uint32_t dirty = mask; dirty; dirty &= dirty - 1)
BindSampler(bit::tzcnt(dirty));
- m_dirtySamplerStates = 0;
+ m_dirtySamplerStates &= ~mask;
}
@@ -5915,15 +5905,13 @@ namespace dxvk {
FlushBuffer(vbo);
}
- uint32_t texturesToUpload = m_activeTexturesToUpload;
- texturesToUpload &= m_psShaderMasks.samplerMask | m_vsShaderMasks.samplerMask;
+ const uint32_t usedSamplerMask = m_activeTextures & (m_psShaderMasks.samplerMask | m_vsShaderMasks.samplerMask);
+ const uint32_t texturesToUpload = m_activeTexturesToUpload & usedSamplerMask;
if (unlikely(texturesToUpload != 0))
UploadManagedTextures(texturesToUpload);
- uint32_t texturesToGen = m_activeTexturesToGen;
- texturesToGen &= m_psShaderMasks.samplerMask | m_vsShaderMasks.samplerMask;
-
+ const uint32_t texturesToGen = m_activeTexturesToGen & usedSamplerMask;
if (unlikely(texturesToGen != 0))
GenerateTextureMips(texturesToGen);
@@ -5939,8 +5927,9 @@ namespace dxvk {
if (m_flags.test(D3D9DeviceFlag::DirtyViewportScissor))
BindViewportAndScissor();
- if (m_dirtySamplerStates)
- UndirtySamplers();
+ const uint32_t activeDirtySamplers = m_dirtySamplerStates & usedSamplerMask;
+ if (activeDirtySamplers)
+ UndirtySamplers(activeDirtySamplers);
if (m_dirtyTextures)
UndirtyTextures();
@@ -6031,6 +6020,10 @@ namespace dxvk {
UpdateFixedFunctionPS();
}
+ const uint32_t depthTextureMask = m_depthTextures & usedSamplerMask;
+ if (depthTextureMask != m_lastSamplerDepthMode)
+ UpdateSamplerDepthModeSpecConstant(depthTextureMask);
+
if (m_flags.test(D3D9DeviceFlag::DirtySharedPixelShaderData)) {
m_flags.clr(D3D9DeviceFlag::DirtySharedPixelShaderData);
@@ -6721,6 +6714,15 @@ namespace dxvk {
}
+ void D3D9DeviceEx::UpdateSamplerDepthModeSpecConstant(uint32_t value) {
+ EmitCs([cBitfield = value](DxvkContext* ctx) {
+ ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::SamplerDepthMode, cBitfield);
+ });
+
+ m_lastSamplerDepthMode = value;
+ }
+
+
void D3D9DeviceEx::ApplyPrimitiveType(
DxvkContext* pContext,
D3DPRIMITIVETYPE PrimType) {
@@ -7037,24 +7039,21 @@ namespace dxvk {
for (uint32_t i = 0; i < caps::MaxStreams; i++)
m_state.streamFreq[i] = 1;
- for (uint32_t i = 0; i < m_state.textures.size(); i++) {
+ for (uint32_t i = 0; i < m_state.textures.size(); i++)
TextureChangePrivate(m_state.textures[i], nullptr);
- DWORD sampler = i;
- auto samplerInfo = RemapStateSamplerShader(sampler);
- uint32_t colorSlot = computeResourceSlotId(samplerInfo.first, DxsoBindingType::ColorImage, uint32_t(samplerInfo.second));
- uint32_t depthSlot = computeResourceSlotId(samplerInfo.first, DxsoBindingType::DepthImage, uint32_t(samplerInfo.second));
-
- EmitCs([
- cColorSlot = colorSlot,
- cDepthSlot = depthSlot
- ](DxvkContext* ctx) {
- ctx->bindResourceView(cColorSlot, nullptr, nullptr);
- ctx->bindResourceView(cDepthSlot, nullptr, nullptr);
- });
- }
+ EmitCs([
+ cSize = m_state.textures.size()
+ ](DxvkContext* ctx) {
+ for (uint32_t i = 0; i < cSize; i++) {
+ auto samplerInfo = RemapStateSamplerShader(DWORD(i));
+ uint32_t slot = computeResourceSlotId(samplerInfo.first, DxsoBindingType::Image, uint32_t(samplerInfo.second));
+ ctx->bindResourceView(slot, nullptr, nullptr);
+ }
+ });
m_dirtyTextures = 0;
+ m_depthTextures = 0;
auto& ss = m_state.samplerStates;
for (uint32_t i = 0; i < ss.size(); i++) {
@@ -7089,6 +7088,7 @@ namespace dxvk {
UpdateSamplerSpecConsant(0u);
UpdateBoolSpecConstantVertex(0u);
UpdateBoolSpecConstantPixel(0u);
+ UpdateSamplerDepthModeSpecConstant(0u);
return D3D_OK;
}
diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h
index 3d5a741e..7dc5a386 100644
--- a/src/d3d9/d3d9_device.h
+++ b/src/d3d9/d3d9_device.h
@@ -82,11 +82,6 @@ namespace dxvk {
uint32_t instanceCount;
};
- struct D3D9SamplerPair {
- Rc<DxvkSampler> color;
- Rc<DxvkSampler> depth;
- };
-
struct D3D9BufferSlice {
DxvkBufferSlice slice = {};
void* mapPtr = nullptr;
@@ -840,7 +835,7 @@ namespace dxvk {
void BindTexture(DWORD SamplerSampler);
- void UndirtySamplers();
+ void UndirtySamplers(uint32_t mask);
void UndirtyTextures();
@@ -926,6 +921,9 @@ namespace dxvk {
D3D9DeviceFlags m_flags;
uint32_t m_dirtySamplerStates = 0;
uint32_t m_dirtyTextures = 0;
+ // Last state of depth textures. Doesn't update when NULL is bound.
+ // & with m_activeTextures to normalize.
+ uint32_t m_depthTextures = 0;
D3D9Adapter* m_adapter;
Rc<DxvkDevice> m_dxvkDevice;
@@ -1024,7 +1022,7 @@ namespace dxvk {
std::unordered_map<
D3D9SamplerKey,
- D3D9SamplerPair,
+ Rc<DxvkSampler>,
D3D9SamplerKeyHash,
D3D9SamplerKeyEq> m_samplers;
@@ -1063,6 +1061,8 @@ namespace dxvk {
uint32_t m_activeHazardsDS = 0;
uint32_t m_lastHazardsDS = 0;
+ uint32_t m_lastSamplerDepthMode = 0;
+
D3D9ShaderMasks m_vsShaderMasks = D3D9ShaderMasks();
D3D9ShaderMasks m_psShaderMasks = FixedFunctionMask;
@@ -1241,6 +1241,8 @@ namespace dxvk {
void UpdateFetch4SpecConstant(uint32_t value);
+ void UpdateSamplerDepthModeSpecConstant(uint32_t value);
+
};
}
diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp
index be71b9c6..e6cd68f3 100644
--- a/src/d3d9/d3d9_fixed_function.cpp
+++ b/src/d3d9/d3d9_fixed_function.cpp
@@ -2092,7 +2092,7 @@ namespace dxvk {
m_module.setDebugName(sampler.varId, name.c_str());
const uint32_t bindingId = computeResourceSlotId(DxsoProgramType::PixelShader,
- DxsoBindingType::ColorImage, i);
+ DxsoBindingType::Image, i);
sampler.bound = m_module.specConstBool(true);
m_module.decorateSpecId(sampler.bound, bindingId);
diff --git a/src/d3d9/d3d9_sampler.cpp b/src/d3d9/d3d9_sampler.cpp
index cc16ed46..6a68f220 100644
--- a/src/d3d9/d3d9_sampler.cpp
+++ b/src/d3d9/d3d9_sampler.cpp
@@ -9,6 +9,7 @@ namespace dxvk {
std::hash<D3DTEXTUREADDRESS> tahash;
std::hash<D3DTEXTUREFILTERTYPE> tfhash;
std::hash<float> fhash;
+ std::hash<bool> bhash;
state.add(tahash(key.AddressU));
state.add(tahash(key.AddressV));
@@ -20,6 +21,7 @@ namespace dxvk {
state.add(fhash (key.MipmapLodBias));
state.add(dhash (key.MaxMipLevel));
state.add(dhash (key.BorderColor));
+ state.add(bhash (key.Depth));
return state;
}
@@ -35,7 +37,8 @@ namespace dxvk {
&& a.MaxAnisotropy == b.MaxAnisotropy
&& a.MipmapLodBias == b.MipmapLodBias
&& a.MaxMipLevel == b.MaxMipLevel
- && a.BorderColor == b.BorderColor;
+ && a.BorderColor == b.BorderColor
+ && a.Depth == b.Depth;
}
} \ No newline at end of file
diff --git a/src/d3d9/d3d9_sampler.h b/src/d3d9/d3d9_sampler.h
index a6d0a4a6..44471094 100644
--- a/src/d3d9/d3d9_sampler.h
+++ b/src/d3d9/d3d9_sampler.h
@@ -21,6 +21,7 @@ namespace dxvk {
float MipmapLodBias;
DWORD MaxMipLevel;
D3DCOLOR BorderColor;
+ bool Depth;
};
struct D3D9SamplerKeyHash {
diff --git a/src/d3d9/d3d9_spec_constants.h b/src/d3d9/d3d9_spec_constants.h
index 106b78f7..7a8a33d5 100644
--- a/src/d3d9/d3d9_spec_constants.h
+++ b/src/d3d9/d3d9_spec_constants.h
@@ -16,7 +16,9 @@ namespace dxvk {
VertexShaderBools = 7,
PixelShaderBools = 8,
- Fetch4 = 9
+ Fetch4 = 9,
+
+ SamplerDepthMode = 10,
};
} \ No newline at end of file
diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp
index 758a5f7a..f656ce6e 100644
--- a/src/dxso/dxso_compiler.cpp
+++ b/src/dxso/dxso_compiler.cpp
@@ -362,6 +362,10 @@ namespace dxvk {
? D3D9SpecConstantId::VertexShaderBools
: D3D9SpecConstantId::PixelShaderBools));
m_module.setDebugName(m_boolSpecConstant, "boolConstants");
+
+ m_depthSpecConstant = m_module.specConst32(m_module.defIntType(32, 0), 0);
+ m_module.decorateSpecId(m_depthSpecConstant, getSpecId(D3D9SpecConstantId::SamplerDepthMode));
+ m_module.setDebugName(m_depthSpecConstant, "depthSamplers");
}
@@ -683,8 +687,11 @@ namespace dxvk {
DxsoTextureType type) {
m_usedSamplers |= (1u << idx);
- auto DclSampler = [this](
+ VkImageViewType viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM;
+
+ auto DclSampler = [this, &viewType](
uint32_t idx,
+ uint32_t bindingId,
DxsoSamplerType type,
bool depth,
bool implicit) {
@@ -694,7 +701,6 @@ namespace dxvk {
: m_samplers[idx].depth[type];
spv::Dim dimensionality;
- VkImageViewType viewType;
const char* suffix = "_2d";
@@ -736,31 +742,25 @@ namespace dxvk {
std::string name = str::format("s", idx, suffix, depth ? "_shadow" : "");
m_module.setDebugName(sampler.varId, name.c_str());
- const uint32_t bindingId = computeResourceSlotId(m_programInfo.type(),
- !depth ? DxsoBindingType::ColorImage : DxsoBindingType::DepthImage,
- idx);
-
m_module.decorateDescriptorSet(sampler.varId, 0);
m_module.decorateBinding (sampler.varId, bindingId);
-
- // Store descriptor info for the shader interface
- DxvkResourceSlot resource;
- resource.slot = bindingId;
- resource.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- resource.view = implicit ? VK_IMAGE_VIEW_TYPE_MAX_ENUM : viewType;
- resource.access = VK_ACCESS_SHADER_READ_BIT;
- m_resourceSlots.push_back(resource);
};
- if (m_programInfo.majorVersion() >= 2 && !m_moduleInfo.options.forceSamplerTypeSpecConstants) {
+ const uint32_t binding = computeResourceSlotId(m_programInfo.type(),
+ DxsoBindingType::Image,
+ idx);
+
+ const bool implicit = m_programInfo.majorVersion() < 2 || m_moduleInfo.options.forceSamplerTypeSpecConstants;
+
+ if (!implicit) {
DxsoSamplerType samplerType =
SamplerTypeFromTextureType(type);
- DclSampler(idx, samplerType, false, false);
+ DclSampler(idx, binding, samplerType, false, implicit);
if (samplerType != SamplerTypeTexture3D) {
// We could also be depth compared!
- DclSampler(idx, samplerType, true, false);
+ DclSampler(idx, binding, samplerType, true, implicit);
}
}
else {
@@ -769,33 +769,27 @@ namespace dxvk {
for (uint32_t i = 0; i < SamplerTypeCount; i++) {
auto samplerType = static_cast<DxsoSamplerType>(i);
- DclSampler(idx, samplerType, false, true);
+ DclSampler(idx, binding, samplerType, false, implicit);
if (samplerType != SamplerTypeTexture3D)
- DclSampler(idx, samplerType, true, true);
+ DclSampler(idx, binding, samplerType, true, implicit);
}
}
-
-
- // Declare a specialization constant which will
- // store whether or not the depth/color views are bound.
- const uint32_t colorBinding = computeResourceSlotId(m_programInfo.type(),
- DxsoBindingType::ColorImage, idx);
-
- const uint32_t depthBinding = computeResourceSlotId(m_programInfo.type(),
- DxsoBindingType::DepthImage, idx);
DxsoSampler& sampler = m_samplers[idx];
-
- sampler.colorSpecConst = m_module.specConstBool(true);
- sampler.depthSpecConst = m_module.specConstBool(true);
+ sampler.boundConst = m_module.specConstBool(true);
sampler.type = type;
- m_module.decorateSpecId(sampler.colorSpecConst, colorBinding);
- m_module.decorateSpecId(sampler.depthSpecConst, depthBinding);
- m_module.setDebugName(sampler.colorSpecConst,
- str::format("s", idx, "_useColor").c_str());
- m_module.setDebugName(sampler.depthSpecConst,
- str::format("s", idx, "_useShadow").c_str());
+ m_module.decorateSpecId(sampler.boundConst, binding);
+ m_module.setDebugName(sampler.boundConst,
+ str::format("s", idx, "_bound").c_str());
+
+ // Store descriptor info for the shader interface
+ DxvkResourceSlot resource;
+ resource.slot = binding;
+ resource.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+ resource.view = implicit ? VK_IMAGE_VIEW_TYPE_MAX_ENUM : viewType;
+ resource.access = VK_ACCESS_SHADER_READ_BIT;
+ m_resourceSlots.push_back(resource);
}
@@ -2882,21 +2876,28 @@ void DxsoCompiler::emitControlFlowGenericLoop(
uint32_t depthLabel = m_module.allocateId();
uint32_t endLabel = m_module.allocateId();
+ uint32_t typeId = m_module.defIntType(32, 0);
+ uint32_t offset = m_module.consti32(m_programInfo.type() == DxsoProgramTypes::VertexShader ? samplerIdx + 17 : samplerIdx);
+ uint32_t bitCnt = m_module.consti32(1);
+ uint32_t isDepth = m_module.opBitFieldUExtract(typeId, m_depthSpecConstant, offset, bitCnt);
+ isDepth = m_module.opIEqual(m_module.defBoolType(), isDepth, m_module.constu32(1));
+
m_module.opSelectionMerge(endLabel, spv::SelectionControlMaskNone);
- m_module.opBranchConditional(sampler.depthSpecConst, depthLabel, colorLabel);
+ m_module.opBranchConditional(isDepth, depthLabel, colorLabel);
m_module.opLabel(colorLabel);
- SampleImage(texcoordVar, sampler.color[samplerType], false, samplerType, sampler.colorSpecConst);
+ SampleImage(texcoordVar, sampler.color[samplerType], false, samplerType, sampler.boundConst);
m_module.opBranch(endLabel);
m_module.opLabel(depthLabel);
- SampleImage(texcoordVar, sampler.depth[samplerType], true, samplerType, 0); // already specc'ed
+ // No spec constant as if we are unbound we always fall down the color path.
+ SampleImage(texcoordVar, sampler.depth[samplerType], true, samplerType, 0);
m_module.opBranch(endLabel);
m_module.opLabel(endLabel);
}
else
- SampleImage(texcoordVar, sampler.color[samplerType], false, samplerType, sampler.colorSpecConst);
+ SampleImage(texcoordVar, sampler.color[samplerType], false, samplerType, sampler.boundConst);
};
if (m_programInfo.majorVersion() >= 2 && !m_moduleInfo.options.forceSamplerTypeSpecConstants) {
diff --git a/src/dxso/dxso_compiler.h b/src/dxso/dxso_compiler.h
index 27b722c1..193f248e 100644
--- a/src/dxso/dxso_compiler.h
+++ b/src/dxso/dxso_compiler.h
@@ -128,8 +128,7 @@ namespace dxvk {
DxsoSamplerInfo color[SamplerTypeCount];
DxsoSamplerInfo depth[SamplerTypeCount];
- uint32_t colorSpecConst;
- uint32_t depthSpecConst;
+ uint32_t boundConst;
DxsoTextureType type;
};
@@ -270,6 +269,7 @@ namespace dxvk {
SpirvModule m_module;
uint32_t m_boolSpecConstant;
+ uint32_t m_depthSpecConstant;
///////////////////////////////////////////////////////
// Resource slot description for the shader. This will
diff --git a/src/dxso/dxso_util.cpp b/src/dxso/dxso_util.cpp
index eeeaed01..16a75082 100644
--- a/src/dxso/dxso_util.cpp
+++ b/src/dxso/dxso_util.cpp
@@ -4,39 +4,6 @@
namespace dxvk {
- uint32_t computeResourceSlotId(
- DxsoProgramType shaderStage,
- DxsoBindingType bindingType,
- uint32_t bindingIndex) {
- const uint32_t stageOffset = 12 * uint32_t(shaderStage);
-
- if (shaderStage == DxsoProgramTypes::VertexShader) {
- switch (bindingType) {
- case DxsoBindingType::ConstantBuffer: return bindingIndex + stageOffset + 0; // 0 + 4 = 4
- case DxsoBindingType::ColorImage: return bindingIndex + stageOffset + 4; // 4 + 4 = 8
- case DxsoBindingType::DepthImage: return bindingIndex + stageOffset + 8; // 8 + 4 = 12
- default: Logger::err("computeResourceSlotId: Invalid resource type");
- }
- }
- else { // Pixel Shader
- switch (bindingType) {
- case DxsoBindingType::ConstantBuffer: return bindingIndex + stageOffset + 0; // 0 + 3 = 3
- // The extra sampler here is being reserved for DMAP stuff later on.
- case DxsoBindingType::ColorImage: return bindingIndex + stageOffset + 3; // 3 + 17 = 20
- case DxsoBindingType::DepthImage: return bindingIndex + stageOffset + 20; // 20 + 17 = 27
- default: Logger::err("computeResourceSlotId: Invalid resource type");
- }
- }
-
- return 0;
- }
-
- // TODO: Intergrate into compute resource slot ID/refactor all of this?
- uint32_t getSWVPBufferSlot() {
- return 39;
- }
-
-
dxvk::mutex g_linkerSlotMutex;
uint32_t g_linkerSlotCount = 0;
std::array<DxsoSemantic, 32> g_linkerSlots;
diff --git a/src/dxso/dxso_util.h b/src/dxso/dxso_util.h
index 307a28d9..fac03d73 100644
--- a/src/dxso/dxso_util.h
+++ b/src/dxso/dxso_util.h
@@ -9,8 +9,7 @@ namespace dxvk {
enum class DxsoBindingType : uint32_t {
ConstantBuffer,
- ColorImage,
- DepthImage // <-- We use whatever one is bound to determine whether an image should be 'shadow' sampled or not.
+ Image,
};
enum DxsoConstantBuffers : uint32_t {
@@ -26,12 +25,22 @@ namespace dxvk {
PSCount
};
- uint32_t computeResourceSlotId(
- DxsoProgramType shaderStage,
- DxsoBindingType bindingType,
- uint32_t bindingIndex);
-
- uint32_t getSWVPBufferSlot();
+ constexpr uint32_t computeResourceSlotId(
+ DxsoProgramType shaderStage,
+ DxsoBindingType bindingType,
+ uint32_t bindingIndex) {
+ const uint32_t stageOffset = 8 * uint32_t(shaderStage);
+
+ if (bindingType == DxsoBindingType::ConstantBuffer)
+ return bindingIndex + stageOffset;
+ else // if (bindingType == DxsoBindingType::Image)
+ return bindingIndex + stageOffset + (shaderStage == DxsoProgramType::PixelShader ? PSCount : VSCount);
+ }
+
+ // TODO: Intergrate into compute resource slot ID/refactor all of this?
+ constexpr uint32_t getSWVPBufferSlot() {
+ return 27; // From last pixel shader slot, above.
+ }
uint32_t RegisterLinkerSlot(DxsoSemantic semantic);