mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-29 17:52:18 +01:00
[dxvk] Implementing unbound resource handling (3/4)
The shader compiler will now generate specialization constants for shader resources, uniform access views, and constant buffers.
This commit is contained in:
parent
39b5d84d6a
commit
fe02c5d6b9
@ -536,9 +536,6 @@ namespace dxvk {
|
||||
m_module.setDebugName(varId,
|
||||
str::format("cb", bufferId).c_str());
|
||||
|
||||
m_constantBuffers.at(bufferId).varId = varId;
|
||||
m_constantBuffers.at(bufferId).size = elementCount;
|
||||
|
||||
// Compute the DXVK binding slot index for the buffer.
|
||||
// D3D11 needs to bind the actual buffers to this slot.
|
||||
const uint32_t bindingId = computeResourceSlotId(
|
||||
@ -548,6 +545,19 @@ namespace dxvk {
|
||||
m_module.decorateDescriptorSet(varId, 0);
|
||||
m_module.decorateBinding(varId, bindingId);
|
||||
|
||||
// Declare a specialization constant which will
|
||||
// store whether or not the resource is bound.
|
||||
const uint32_t specConstId = m_module.specConstBool(true);
|
||||
m_module.decorateSpecId(specConstId, bindingId);
|
||||
m_module.setDebugName(specConstId,
|
||||
str::format("cb", bufferId, "_bound").c_str());
|
||||
|
||||
DxbcConstantBuffer buf;
|
||||
buf.varId = varId;
|
||||
buf.specId = specConstId;
|
||||
buf.size = elementCount;
|
||||
m_constantBuffers.at(bufferId) = buf;
|
||||
|
||||
// Store descriptor info for the shader interface
|
||||
DxvkResourceSlot resource;
|
||||
resource.slot = bindingId;
|
||||
@ -683,11 +693,30 @@ namespace dxvk {
|
||||
m_module.setDebugName(varId,
|
||||
str::format(isUav ? "u" : "t", registerId).c_str());
|
||||
|
||||
// Compute the DXVK binding slot index for the resource.
|
||||
// D3D11 needs to bind the actual resource to this slot.
|
||||
const uint32_t bindingId = computeResourceSlotId(
|
||||
m_version.type(), isUav
|
||||
? DxbcBindingType::UnorderedAccessView
|
||||
: DxbcBindingType::ShaderResource,
|
||||
registerId);
|
||||
|
||||
m_module.decorateDescriptorSet(varId, 0);
|
||||
m_module.decorateBinding(varId, bindingId);
|
||||
|
||||
// Declare a specialization constant which will
|
||||
// store whether or not the resource is bound.
|
||||
const uint32_t specConstId = m_module.specConstBool(true);
|
||||
m_module.decorateSpecId(specConstId, bindingId);
|
||||
m_module.setDebugName(specConstId,
|
||||
str::format(isUav ? "u" : "t", registerId, "_bound").c_str());
|
||||
|
||||
if (isUav) {
|
||||
DxbcUav uav;
|
||||
uav.type = DxbcResourceType::Typed;
|
||||
uav.imageInfo = typeInfo;
|
||||
uav.varId = varId;
|
||||
uav.specId = specConstId;
|
||||
uav.sampledType = sampledType;
|
||||
uav.sampledTypeId = sampledTypeId;
|
||||
uav.imageTypeId = imageTypeId;
|
||||
@ -698,6 +727,7 @@ namespace dxvk {
|
||||
res.type = DxbcResourceType::Typed;
|
||||
res.imageInfo = typeInfo;
|
||||
res.varId = varId;
|
||||
res.specId = specConstId;
|
||||
res.sampledType = sampledType;
|
||||
res.sampledTypeId = sampledTypeId;
|
||||
res.imageTypeId = imageTypeId;
|
||||
@ -711,17 +741,6 @@ namespace dxvk {
|
||||
res.structStride = 0;
|
||||
}
|
||||
|
||||
// Compute the DXVK binding slot index for the resource.
|
||||
// D3D11 needs to bind the actual resource to this slot.
|
||||
const uint32_t bindingId = computeResourceSlotId(
|
||||
m_version.type(), isUav
|
||||
? DxbcBindingType::UnorderedAccessView
|
||||
: DxbcBindingType::ShaderResource,
|
||||
registerId);
|
||||
|
||||
m_module.decorateDescriptorSet(varId, 0);
|
||||
m_module.decorateBinding(varId, bindingId);
|
||||
|
||||
// Store descriptor info for the shader interface
|
||||
DxvkResourceSlot resource;
|
||||
resource.slot = bindingId;
|
||||
@ -785,11 +804,29 @@ namespace dxvk {
|
||||
? ins.imm[0].u32
|
||||
: 0;
|
||||
|
||||
// Compute the DXVK binding slot index for the resource.
|
||||
const uint32_t bindingId = computeResourceSlotId(
|
||||
m_version.type(), isUav
|
||||
? DxbcBindingType::UnorderedAccessView
|
||||
: DxbcBindingType::ShaderResource,
|
||||
registerId);
|
||||
|
||||
m_module.decorateDescriptorSet(varId, 0);
|
||||
m_module.decorateBinding(varId, bindingId);
|
||||
|
||||
// Declare a specialization constant which will
|
||||
// store whether or not the resource is bound.
|
||||
const uint32_t specConstId = m_module.specConstBool(true);
|
||||
m_module.decorateSpecId(specConstId, bindingId);
|
||||
m_module.setDebugName(specConstId,
|
||||
str::format(isUav ? "u" : "t", registerId, "_bound").c_str());
|
||||
|
||||
if (isUav) {
|
||||
DxbcUav uav;
|
||||
uav.type = resType;
|
||||
uav.imageInfo = typeInfo;
|
||||
uav.varId = varId;
|
||||
uav.specId = specConstId;
|
||||
uav.sampledType = sampledType;
|
||||
uav.sampledTypeId = sampledTypeId;
|
||||
uav.imageTypeId = resTypeId;
|
||||
@ -800,6 +837,7 @@ namespace dxvk {
|
||||
res.type = resType;
|
||||
res.imageInfo = typeInfo;
|
||||
res.varId = varId;
|
||||
res.specId = specConstId;
|
||||
res.sampledType = sampledType;
|
||||
res.sampledTypeId = sampledTypeId;
|
||||
res.imageTypeId = resTypeId;
|
||||
@ -809,16 +847,6 @@ namespace dxvk {
|
||||
m_textures.at(registerId) = res;
|
||||
}
|
||||
|
||||
// Compute the DXVK binding slot index for the resource.
|
||||
const uint32_t bindingId = computeResourceSlotId(
|
||||
m_version.type(), isUav
|
||||
? DxbcBindingType::UnorderedAccessView
|
||||
: DxbcBindingType::ShaderResource,
|
||||
registerId);
|
||||
|
||||
m_module.decorateDescriptorSet(varId, 0);
|
||||
m_module.decorateBinding(varId, bindingId);
|
||||
|
||||
// Store descriptor info for the shader interface
|
||||
DxvkResourceSlot resource;
|
||||
resource.slot = bindingId;
|
||||
@ -1873,7 +1901,7 @@ namespace dxvk {
|
||||
emitRegisterStore(ins.dst[0], result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DxbcCompiler::emitBufferLoad(const DxbcShaderInstruction& ins) {
|
||||
// ld_raw takes three arguments:
|
||||
// (dst0) Destination register
|
||||
@ -4263,6 +4291,7 @@ namespace dxvk {
|
||||
result.type = m_textures.at(registerId).type;
|
||||
result.typeId = m_textures.at(registerId).imageTypeId;
|
||||
result.varId = m_textures.at(registerId).varId;
|
||||
result.specId = m_textures.at(registerId).specId;
|
||||
result.stride = m_textures.at(registerId).structStride;
|
||||
return result;
|
||||
} break;
|
||||
@ -4273,6 +4302,7 @@ namespace dxvk {
|
||||
result.type = m_uavs.at(registerId).type;
|
||||
result.typeId = m_uavs.at(registerId).imageTypeId;
|
||||
result.varId = m_uavs.at(registerId).varId;
|
||||
result.specId = m_uavs.at(registerId).specId;
|
||||
result.stride = m_uavs.at(registerId).structStride;
|
||||
return result;
|
||||
} break;
|
||||
@ -4285,6 +4315,7 @@ namespace dxvk {
|
||||
getScalarTypeId(DxbcScalarType::Uint32),
|
||||
spv::StorageClassWorkgroup);
|
||||
result.varId = m_gRegs.at(registerId).varId;
|
||||
result.specId = 0;
|
||||
result.stride = m_gRegs.at(registerId).elementStride;
|
||||
return result;
|
||||
} break;
|
||||
|
@ -198,6 +198,7 @@ namespace dxvk {
|
||||
DxbcResourceType type;
|
||||
uint32_t typeId;
|
||||
uint32_t varId;
|
||||
uint32_t specId;
|
||||
uint32_t stride;
|
||||
};
|
||||
|
||||
|
@ -35,8 +35,9 @@ namespace dxvk {
|
||||
* access a constant buffer.
|
||||
*/
|
||||
struct DxbcConstantBuffer {
|
||||
uint32_t varId = 0;
|
||||
uint32_t size = 0;
|
||||
uint32_t varId = 0;
|
||||
uint32_t specId = 0;
|
||||
uint32_t size = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -72,6 +73,7 @@ namespace dxvk {
|
||||
DxbcResourceType type = DxbcResourceType::Typed;
|
||||
DxbcImageInfo imageInfo;
|
||||
uint32_t varId = 0;
|
||||
uint32_t specId = 0;
|
||||
DxbcScalarType sampledType = DxbcScalarType::Float32;
|
||||
uint32_t sampledTypeId = 0;
|
||||
uint32_t imageTypeId = 0;
|
||||
@ -91,6 +93,7 @@ namespace dxvk {
|
||||
DxbcResourceType type = DxbcResourceType::Typed;
|
||||
DxbcImageInfo imageInfo;
|
||||
uint32_t varId = 0;
|
||||
uint32_t specId = 0;
|
||||
DxbcScalarType sampledType = DxbcScalarType::Float32;
|
||||
uint32_t sampledTypeId = 0;
|
||||
uint32_t imageTypeId = 0;
|
||||
|
@ -1094,7 +1094,7 @@ namespace dxvk {
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
||||
if (res.imageView != nullptr && res.imageView->type() != binding.view) {
|
||||
if (res.imageView != nullptr && res.imageView->type() == binding.view) {
|
||||
updatePipelineState |= bs.setBound(i);
|
||||
|
||||
m_descriptors[i].image.sampler = VK_NULL_HANDLE;
|
||||
|
@ -48,8 +48,9 @@ namespace dxvk {
|
||||
: m_vkd(vkd) {
|
||||
|
||||
m_bindingSlots.resize(bindingCount);
|
||||
std::memcpy(m_bindingSlots.data(), bindingInfos,
|
||||
bindingCount * sizeof(DxvkDescriptorSlot));
|
||||
|
||||
for (uint32_t i = 0; i < bindingCount; i++)
|
||||
m_bindingSlots[i] = bindingInfos[i];
|
||||
|
||||
std::vector<VkDescriptorSetLayoutBinding> bindings;
|
||||
|
||||
|
@ -71,7 +71,8 @@ namespace dxvk {
|
||||
|
||||
for (auto ins : spirvCode) {
|
||||
if (ins.opCode() == spv::OpDecorate
|
||||
&& ins.arg(2) == spv::DecorationBinding) {
|
||||
&& ((ins.arg(2) == spv::DecorationBinding)
|
||||
|| (ins.arg(2) == spv::DecorationSpecId))) {
|
||||
|
||||
const uint32_t oldBinding = ins.arg(3);
|
||||
const uint32_t newBinding = mapping.getBindingId(oldBinding);
|
||||
|
@ -238,6 +238,22 @@ namespace dxvk {
|
||||
m_typeConstDefs.putWord(constIds[i]);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::specConstBool(
|
||||
bool v) {
|
||||
uint32_t typeId = this->defBoolType();
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
const spv::Op op = v
|
||||
? spv::OpSpecConstantTrue
|
||||
: spv::OpSpecConstantFalse;
|
||||
|
||||
m_typeConstDefs.putIns (op, 3);
|
||||
m_typeConstDefs.putWord (typeId);
|
||||
m_typeConstDefs.putWord (resultId);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
||||
void SpirvModule::decorate(
|
||||
@ -316,6 +332,16 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void SpirvModule::decorateSpecId(
|
||||
uint32_t object,
|
||||
uint32_t specId) {
|
||||
m_annotations.putIns (spv::OpDecorate, 4);
|
||||
m_annotations.putWord (object);
|
||||
m_annotations.putWord (spv::DecorationSpecId);
|
||||
m_annotations.putInt32(specId);
|
||||
}
|
||||
|
||||
|
||||
void SpirvModule::memberDecorateBuiltIn(
|
||||
uint32_t structId,
|
||||
uint32_t memberId,
|
||||
|
@ -124,6 +124,9 @@ namespace dxvk {
|
||||
uint32_t constCount,
|
||||
const uint32_t* constIds);
|
||||
|
||||
uint32_t specConstBool(
|
||||
bool v);
|
||||
|
||||
void decorate(
|
||||
uint32_t object,
|
||||
spv::Decoration decoration);
|
||||
@ -155,6 +158,10 @@ namespace dxvk {
|
||||
uint32_t object,
|
||||
uint32_t location);
|
||||
|
||||
void decorateSpecId(
|
||||
uint32_t object,
|
||||
uint32_t specId);
|
||||
|
||||
void memberDecorateBuiltIn(
|
||||
uint32_t structId,
|
||||
uint32_t memberId,
|
||||
|
Loading…
x
Reference in New Issue
Block a user