mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-06 13:54:14 +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,
|
m_module.setDebugName(varId,
|
||||||
str::format("cb", bufferId).c_str());
|
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.
|
// Compute the DXVK binding slot index for the buffer.
|
||||||
// D3D11 needs to bind the actual buffers to this slot.
|
// D3D11 needs to bind the actual buffers to this slot.
|
||||||
const uint32_t bindingId = computeResourceSlotId(
|
const uint32_t bindingId = computeResourceSlotId(
|
||||||
@ -548,6 +545,19 @@ namespace dxvk {
|
|||||||
m_module.decorateDescriptorSet(varId, 0);
|
m_module.decorateDescriptorSet(varId, 0);
|
||||||
m_module.decorateBinding(varId, bindingId);
|
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
|
// Store descriptor info for the shader interface
|
||||||
DxvkResourceSlot resource;
|
DxvkResourceSlot resource;
|
||||||
resource.slot = bindingId;
|
resource.slot = bindingId;
|
||||||
@ -683,11 +693,30 @@ namespace dxvk {
|
|||||||
m_module.setDebugName(varId,
|
m_module.setDebugName(varId,
|
||||||
str::format(isUav ? "u" : "t", registerId).c_str());
|
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) {
|
if (isUav) {
|
||||||
DxbcUav uav;
|
DxbcUav uav;
|
||||||
uav.type = DxbcResourceType::Typed;
|
uav.type = DxbcResourceType::Typed;
|
||||||
uav.imageInfo = typeInfo;
|
uav.imageInfo = typeInfo;
|
||||||
uav.varId = varId;
|
uav.varId = varId;
|
||||||
|
uav.specId = specConstId;
|
||||||
uav.sampledType = sampledType;
|
uav.sampledType = sampledType;
|
||||||
uav.sampledTypeId = sampledTypeId;
|
uav.sampledTypeId = sampledTypeId;
|
||||||
uav.imageTypeId = imageTypeId;
|
uav.imageTypeId = imageTypeId;
|
||||||
@ -698,6 +727,7 @@ namespace dxvk {
|
|||||||
res.type = DxbcResourceType::Typed;
|
res.type = DxbcResourceType::Typed;
|
||||||
res.imageInfo = typeInfo;
|
res.imageInfo = typeInfo;
|
||||||
res.varId = varId;
|
res.varId = varId;
|
||||||
|
res.specId = specConstId;
|
||||||
res.sampledType = sampledType;
|
res.sampledType = sampledType;
|
||||||
res.sampledTypeId = sampledTypeId;
|
res.sampledTypeId = sampledTypeId;
|
||||||
res.imageTypeId = imageTypeId;
|
res.imageTypeId = imageTypeId;
|
||||||
@ -711,17 +741,6 @@ namespace dxvk {
|
|||||||
res.structStride = 0;
|
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
|
// Store descriptor info for the shader interface
|
||||||
DxvkResourceSlot resource;
|
DxvkResourceSlot resource;
|
||||||
resource.slot = bindingId;
|
resource.slot = bindingId;
|
||||||
@ -785,11 +804,29 @@ namespace dxvk {
|
|||||||
? ins.imm[0].u32
|
? ins.imm[0].u32
|
||||||
: 0;
|
: 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) {
|
if (isUav) {
|
||||||
DxbcUav uav;
|
DxbcUav uav;
|
||||||
uav.type = resType;
|
uav.type = resType;
|
||||||
uav.imageInfo = typeInfo;
|
uav.imageInfo = typeInfo;
|
||||||
uav.varId = varId;
|
uav.varId = varId;
|
||||||
|
uav.specId = specConstId;
|
||||||
uav.sampledType = sampledType;
|
uav.sampledType = sampledType;
|
||||||
uav.sampledTypeId = sampledTypeId;
|
uav.sampledTypeId = sampledTypeId;
|
||||||
uav.imageTypeId = resTypeId;
|
uav.imageTypeId = resTypeId;
|
||||||
@ -800,6 +837,7 @@ namespace dxvk {
|
|||||||
res.type = resType;
|
res.type = resType;
|
||||||
res.imageInfo = typeInfo;
|
res.imageInfo = typeInfo;
|
||||||
res.varId = varId;
|
res.varId = varId;
|
||||||
|
res.specId = specConstId;
|
||||||
res.sampledType = sampledType;
|
res.sampledType = sampledType;
|
||||||
res.sampledTypeId = sampledTypeId;
|
res.sampledTypeId = sampledTypeId;
|
||||||
res.imageTypeId = resTypeId;
|
res.imageTypeId = resTypeId;
|
||||||
@ -809,16 +847,6 @@ namespace dxvk {
|
|||||||
m_textures.at(registerId) = res;
|
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
|
// Store descriptor info for the shader interface
|
||||||
DxvkResourceSlot resource;
|
DxvkResourceSlot resource;
|
||||||
resource.slot = bindingId;
|
resource.slot = bindingId;
|
||||||
@ -1873,7 +1901,7 @@ namespace dxvk {
|
|||||||
emitRegisterStore(ins.dst[0], result);
|
emitRegisterStore(ins.dst[0], result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxbcCompiler::emitBufferLoad(const DxbcShaderInstruction& ins) {
|
void DxbcCompiler::emitBufferLoad(const DxbcShaderInstruction& ins) {
|
||||||
// ld_raw takes three arguments:
|
// ld_raw takes three arguments:
|
||||||
// (dst0) Destination register
|
// (dst0) Destination register
|
||||||
@ -4263,6 +4291,7 @@ namespace dxvk {
|
|||||||
result.type = m_textures.at(registerId).type;
|
result.type = m_textures.at(registerId).type;
|
||||||
result.typeId = m_textures.at(registerId).imageTypeId;
|
result.typeId = m_textures.at(registerId).imageTypeId;
|
||||||
result.varId = m_textures.at(registerId).varId;
|
result.varId = m_textures.at(registerId).varId;
|
||||||
|
result.specId = m_textures.at(registerId).specId;
|
||||||
result.stride = m_textures.at(registerId).structStride;
|
result.stride = m_textures.at(registerId).structStride;
|
||||||
return result;
|
return result;
|
||||||
} break;
|
} break;
|
||||||
@ -4273,6 +4302,7 @@ namespace dxvk {
|
|||||||
result.type = m_uavs.at(registerId).type;
|
result.type = m_uavs.at(registerId).type;
|
||||||
result.typeId = m_uavs.at(registerId).imageTypeId;
|
result.typeId = m_uavs.at(registerId).imageTypeId;
|
||||||
result.varId = m_uavs.at(registerId).varId;
|
result.varId = m_uavs.at(registerId).varId;
|
||||||
|
result.specId = m_uavs.at(registerId).specId;
|
||||||
result.stride = m_uavs.at(registerId).structStride;
|
result.stride = m_uavs.at(registerId).structStride;
|
||||||
return result;
|
return result;
|
||||||
} break;
|
} break;
|
||||||
@ -4285,6 +4315,7 @@ namespace dxvk {
|
|||||||
getScalarTypeId(DxbcScalarType::Uint32),
|
getScalarTypeId(DxbcScalarType::Uint32),
|
||||||
spv::StorageClassWorkgroup);
|
spv::StorageClassWorkgroup);
|
||||||
result.varId = m_gRegs.at(registerId).varId;
|
result.varId = m_gRegs.at(registerId).varId;
|
||||||
|
result.specId = 0;
|
||||||
result.stride = m_gRegs.at(registerId).elementStride;
|
result.stride = m_gRegs.at(registerId).elementStride;
|
||||||
return result;
|
return result;
|
||||||
} break;
|
} break;
|
||||||
|
@ -198,6 +198,7 @@ namespace dxvk {
|
|||||||
DxbcResourceType type;
|
DxbcResourceType type;
|
||||||
uint32_t typeId;
|
uint32_t typeId;
|
||||||
uint32_t varId;
|
uint32_t varId;
|
||||||
|
uint32_t specId;
|
||||||
uint32_t stride;
|
uint32_t stride;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -35,8 +35,9 @@ namespace dxvk {
|
|||||||
* access a constant buffer.
|
* access a constant buffer.
|
||||||
*/
|
*/
|
||||||
struct DxbcConstantBuffer {
|
struct DxbcConstantBuffer {
|
||||||
uint32_t varId = 0;
|
uint32_t varId = 0;
|
||||||
uint32_t size = 0;
|
uint32_t specId = 0;
|
||||||
|
uint32_t size = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,6 +73,7 @@ namespace dxvk {
|
|||||||
DxbcResourceType type = DxbcResourceType::Typed;
|
DxbcResourceType type = DxbcResourceType::Typed;
|
||||||
DxbcImageInfo imageInfo;
|
DxbcImageInfo imageInfo;
|
||||||
uint32_t varId = 0;
|
uint32_t varId = 0;
|
||||||
|
uint32_t specId = 0;
|
||||||
DxbcScalarType sampledType = DxbcScalarType::Float32;
|
DxbcScalarType sampledType = DxbcScalarType::Float32;
|
||||||
uint32_t sampledTypeId = 0;
|
uint32_t sampledTypeId = 0;
|
||||||
uint32_t imageTypeId = 0;
|
uint32_t imageTypeId = 0;
|
||||||
@ -91,6 +93,7 @@ namespace dxvk {
|
|||||||
DxbcResourceType type = DxbcResourceType::Typed;
|
DxbcResourceType type = DxbcResourceType::Typed;
|
||||||
DxbcImageInfo imageInfo;
|
DxbcImageInfo imageInfo;
|
||||||
uint32_t varId = 0;
|
uint32_t varId = 0;
|
||||||
|
uint32_t specId = 0;
|
||||||
DxbcScalarType sampledType = DxbcScalarType::Float32;
|
DxbcScalarType sampledType = DxbcScalarType::Float32;
|
||||||
uint32_t sampledTypeId = 0;
|
uint32_t sampledTypeId = 0;
|
||||||
uint32_t imageTypeId = 0;
|
uint32_t imageTypeId = 0;
|
||||||
|
@ -1094,7 +1094,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||||
case VK_DESCRIPTOR_TYPE_STORAGE_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);
|
updatePipelineState |= bs.setBound(i);
|
||||||
|
|
||||||
m_descriptors[i].image.sampler = VK_NULL_HANDLE;
|
m_descriptors[i].image.sampler = VK_NULL_HANDLE;
|
||||||
|
@ -48,8 +48,9 @@ namespace dxvk {
|
|||||||
: m_vkd(vkd) {
|
: m_vkd(vkd) {
|
||||||
|
|
||||||
m_bindingSlots.resize(bindingCount);
|
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;
|
std::vector<VkDescriptorSetLayoutBinding> bindings;
|
||||||
|
|
||||||
|
@ -71,7 +71,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
for (auto ins : spirvCode) {
|
for (auto ins : spirvCode) {
|
||||||
if (ins.opCode() == spv::OpDecorate
|
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 oldBinding = ins.arg(3);
|
||||||
const uint32_t newBinding = mapping.getBindingId(oldBinding);
|
const uint32_t newBinding = mapping.getBindingId(oldBinding);
|
||||||
|
@ -238,6 +238,22 @@ namespace dxvk {
|
|||||||
m_typeConstDefs.putWord(constIds[i]);
|
m_typeConstDefs.putWord(constIds[i]);
|
||||||
return resultId;
|
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(
|
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(
|
void SpirvModule::memberDecorateBuiltIn(
|
||||||
uint32_t structId,
|
uint32_t structId,
|
||||||
uint32_t memberId,
|
uint32_t memberId,
|
||||||
|
@ -124,6 +124,9 @@ namespace dxvk {
|
|||||||
uint32_t constCount,
|
uint32_t constCount,
|
||||||
const uint32_t* constIds);
|
const uint32_t* constIds);
|
||||||
|
|
||||||
|
uint32_t specConstBool(
|
||||||
|
bool v);
|
||||||
|
|
||||||
void decorate(
|
void decorate(
|
||||||
uint32_t object,
|
uint32_t object,
|
||||||
spv::Decoration decoration);
|
spv::Decoration decoration);
|
||||||
@ -155,6 +158,10 @@ namespace dxvk {
|
|||||||
uint32_t object,
|
uint32_t object,
|
||||||
uint32_t location);
|
uint32_t location);
|
||||||
|
|
||||||
|
void decorateSpecId(
|
||||||
|
uint32_t object,
|
||||||
|
uint32_t specId);
|
||||||
|
|
||||||
void memberDecorateBuiltIn(
|
void memberDecorateBuiltIn(
|
||||||
uint32_t structId,
|
uint32_t structId,
|
||||||
uint32_t memberId,
|
uint32_t memberId,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user