mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 01:54:16 +01:00
[d3d9, dxso] Alias color and depth samplers and improve tracking
Takes me from 340 -> 460fps in A Hat in Time's main menu when CPU bound.
This commit is contained in:
parent
3f78bde928
commit
c0c1565cba
@ -3710,6 +3710,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);
|
||||
@ -5703,6 +5716,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)
|
||||
@ -5718,75 +5732,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;
|
||||
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, colorInfo.borderColor.float32);
|
||||
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());
|
||||
@ -5798,11 +5796,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;
|
||||
@ -5829,31 +5824,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;
|
||||
}
|
||||
|
||||
|
||||
@ -5914,15 +5904,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);
|
||||
|
||||
@ -5938,8 +5926,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();
|
||||
@ -6030,6 +6019,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);
|
||||
|
||||
@ -6720,6 +6713,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) {
|
||||
@ -7036,24 +7038,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++) {
|
||||
@ -7088,6 +7087,7 @@ namespace dxvk {
|
||||
UpdateSamplerSpecConsant(0u);
|
||||
UpdateBoolSpecConstantVertex(0u);
|
||||
UpdateBoolSpecConstantPixel(0u);
|
||||
UpdateSamplerDepthModeSpecConstant(0u);
|
||||
|
||||
return D3D_OK;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -21,6 +21,7 @@ namespace dxvk {
|
||||
float MipmapLodBias;
|
||||
DWORD MaxMipLevel;
|
||||
D3DCOLOR BorderColor;
|
||||
bool Depth;
|
||||
};
|
||||
|
||||
struct D3D9SamplerKeyHash {
|
||||
|
@ -16,7 +16,9 @@ namespace dxvk {
|
||||
|
||||
VertexShaderBools = 7,
|
||||
PixelShaderBools = 8,
|
||||
Fetch4 = 9
|
||||
Fetch4 = 9,
|
||||
|
||||
SamplerDepthMode = 10,
|
||||
};
|
||||
|
||||
}
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
constexpr uint32_t computeResourceSlotId(
|
||||
DxsoProgramType shaderStage,
|
||||
DxsoBindingType bindingType,
|
||||
uint32_t bindingIndex) {
|
||||
const uint32_t stageOffset = 8 * uint32_t(shaderStage);
|
||||
|
||||
uint32_t getSWVPBufferSlot();
|
||||
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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user