[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:
Philip Rebohle 2018-01-10 13:44:04 +01:00
parent 39b5d84d6a
commit fe02c5d6b9
8 changed files with 101 additions and 31 deletions

View File

@ -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;

View File

@ -198,6 +198,7 @@ namespace dxvk {
DxbcResourceType type;
uint32_t typeId;
uint32_t varId;
uint32_t specId;
uint32_t stride;
};

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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,

View File

@ -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,