mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-18 20:52:10 +01:00
[dxbc] Implemented shader resource declaration for images
This commit is contained in:
parent
939faeaf27
commit
7c03495d74
@ -1438,7 +1438,7 @@ namespace dxvk {
|
||||
: VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
|
||||
const uint32_t slotId = computeResourceSlotId(
|
||||
ShaderStage, DxbcBindingType::ImageSampler,
|
||||
ShaderStage, DxbcBindingType::ShaderResource,
|
||||
StartSlot + i);
|
||||
|
||||
if (resView != nullptr) {
|
||||
|
@ -24,6 +24,9 @@ namespace dxvk {
|
||||
case DxbcOpcode::DclConstantBuffer:
|
||||
return this->dclConstantBuffer(ins);
|
||||
|
||||
case DxbcOpcode::DclResource:
|
||||
return this->dclResource(ins);
|
||||
|
||||
case DxbcOpcode::DclSampler:
|
||||
return this->dclSampler(ins);
|
||||
|
||||
@ -39,7 +42,7 @@ namespace dxvk {
|
||||
return this->dclInterfaceVar(ins);
|
||||
|
||||
case DxbcOpcode::DclTemps:
|
||||
return this->dclTemps(ins);
|
||||
return this->dclTemps(ins);
|
||||
|
||||
case DxbcOpcode::Add:
|
||||
return this->opAdd(ins);
|
||||
@ -81,6 +84,9 @@ namespace dxvk {
|
||||
|
||||
|
||||
void DxbcCompiler::dclConstantBuffer(const DxbcInstruction& ins) {
|
||||
// dclConstantBuffer takes two operands:
|
||||
// 1. The buffer register ID
|
||||
// 2. The number of 4x32-bit constants
|
||||
auto op = ins.operand(0);
|
||||
|
||||
if (op.token().indexDimension() != 2)
|
||||
@ -93,7 +99,46 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxbcCompiler::dclSampler(const DxbcInstruction& ins) {
|
||||
void DxbcCompiler::dclResource(const DxbcInstruction& ins) {
|
||||
// dclResource takes two operands:
|
||||
// 1. The resource register ID
|
||||
// 2. The resource return type
|
||||
auto op = ins.operand(0);
|
||||
|
||||
if (op.token().indexDimension() != 1)
|
||||
throw DxvkError("DXBC: dclResource: Invalid index dimension");
|
||||
|
||||
const uint32_t index = op.index(0).immPart();
|
||||
|
||||
// Defines the type of the resource (texture2D, ...)
|
||||
auto resourceDim = static_cast<DxbcResourceDim>(
|
||||
bit::extract(ins.token().control(), 0, 4));
|
||||
|
||||
// Defines the type of a read operation. DXBC has the ability
|
||||
// to define four different types whereas SPIR-V only allows
|
||||
// one, but in practice this should not be much of a problem.
|
||||
const uint32_t ofs = op.length();
|
||||
|
||||
auto xType = static_cast<DxbcResourceReturnType>(
|
||||
bit::extract(ins.arg(ofs), 0, 3));
|
||||
auto yType = static_cast<DxbcResourceReturnType>(
|
||||
bit::extract(ins.arg(ofs), 4, 7));
|
||||
auto zType = static_cast<DxbcResourceReturnType>(
|
||||
bit::extract(ins.arg(ofs), 8, 11));
|
||||
auto wType = static_cast<DxbcResourceReturnType>(
|
||||
bit::extract(ins.arg(ofs), 12, 15));
|
||||
|
||||
if ((xType != yType) || (xType != zType) || (xType != wType))
|
||||
Logger::warn("DXBC: dclResource: Ignoring resource return types");
|
||||
|
||||
m_gen->dclResource(index, resourceDim, xType);
|
||||
}
|
||||
|
||||
|
||||
void DxbcCompiler::dclSampler(const DxbcInstruction& ins) {
|
||||
// dclSampler takes one operand:
|
||||
// 1. The sampler register ID
|
||||
// TODO implement sampler mode (default / comparison / mono)
|
||||
auto op = ins.operand(0);
|
||||
|
||||
if (op.token().indexDimension() != 1)
|
||||
@ -163,6 +208,9 @@ namespace dxvk {
|
||||
|
||||
|
||||
void DxbcCompiler::dclTemps(const DxbcInstruction& ins) {
|
||||
// dclTemps takes one operand:
|
||||
// 1. The number of temporary registers to
|
||||
// declare, as an immediate 32-bit integer.
|
||||
m_gen->dclTemps(ins.arg(0));
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,9 @@ namespace dxvk {
|
||||
void dclConstantBuffer(
|
||||
const DxbcInstruction& ins);
|
||||
|
||||
void dclResource(
|
||||
const DxbcInstruction& ins);
|
||||
|
||||
void dclSampler(
|
||||
const DxbcInstruction& ins);
|
||||
|
||||
|
@ -80,6 +80,99 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxbcCodeGen::dclResource(
|
||||
uint32_t registerId,
|
||||
DxbcResourceDim resourceType,
|
||||
DxbcResourceReturnType returnType) {
|
||||
uint32_t sampledTypeId = 0;
|
||||
|
||||
switch (returnType) {
|
||||
default: Logger::err(str::format("DXBC: Invalid sampled type: ", returnType));
|
||||
case DxbcResourceReturnType::Float: sampledTypeId = m_module.defFloatType(32); break;
|
||||
case DxbcResourceReturnType::Sint: sampledTypeId = m_module.defIntType (32, 1); break;
|
||||
case DxbcResourceReturnType::Uint: sampledTypeId = m_module.defIntType (32, 0); break;
|
||||
}
|
||||
|
||||
uint32_t resourceTypeId = 0;
|
||||
|
||||
switch (resourceType) {
|
||||
default:
|
||||
Logger::err(str::format(
|
||||
"DXBC: Invalid resource type: ",
|
||||
resourceType));
|
||||
|
||||
case DxbcResourceDim::Texture1D:
|
||||
resourceTypeId = m_module.defImageType(
|
||||
sampledTypeId, spv::Dim1D, 2, 0, 0, 1,
|
||||
spv::ImageFormatUnknown);
|
||||
break;
|
||||
|
||||
case DxbcResourceDim::Texture1DArr:
|
||||
resourceTypeId = m_module.defImageType(
|
||||
sampledTypeId, spv::Dim1D, 2, 1, 0, 1,
|
||||
spv::ImageFormatUnknown);
|
||||
break;
|
||||
|
||||
case DxbcResourceDim::Texture2D:
|
||||
resourceTypeId = m_module.defImageType(
|
||||
sampledTypeId, spv::Dim2D, 2, 0, 0, 1,
|
||||
spv::ImageFormatUnknown);
|
||||
break;
|
||||
|
||||
case DxbcResourceDim::Texture2DArr:
|
||||
resourceTypeId = m_module.defImageType(
|
||||
sampledTypeId, spv::Dim2D, 2, 1, 0, 1,
|
||||
spv::ImageFormatUnknown);
|
||||
break;
|
||||
|
||||
case DxbcResourceDim::Texture3D:
|
||||
resourceTypeId = m_module.defImageType(
|
||||
sampledTypeId, spv::Dim3D, 2, 0, 0, 1,
|
||||
spv::ImageFormatUnknown);
|
||||
break;
|
||||
|
||||
case DxbcResourceDim::TextureCube:
|
||||
resourceTypeId = m_module.defImageType(
|
||||
sampledTypeId, spv::DimCube, 2, 0, 0, 1,
|
||||
spv::ImageFormatUnknown);
|
||||
break;
|
||||
|
||||
case DxbcResourceDim::TextureCubeArr:
|
||||
resourceTypeId = m_module.defImageType(
|
||||
sampledTypeId, spv::DimCube, 2, 1, 0, 1,
|
||||
spv::ImageFormatUnknown);
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t resourcePtrType = m_module.defPointerType(
|
||||
resourceTypeId, spv::StorageClassUniformConstant);
|
||||
|
||||
uint32_t varId = m_module.newVar(resourcePtrType,
|
||||
spv::StorageClassUniformConstant);
|
||||
|
||||
m_module.setDebugName(varId,
|
||||
str::format("t", registerId).c_str());
|
||||
|
||||
m_resources.at(registerId).varId = varId;
|
||||
m_resources.at(registerId).sampledTypeId = sampledTypeId;
|
||||
m_resources.at(registerId).resourceTypeId = resourceTypeId;
|
||||
|
||||
// Compute the DXVK binding slot index for the resource.
|
||||
// D3D11 needs to bind the actual resource to this slot.
|
||||
uint32_t bindingId = computeResourceSlotId(m_shaderStage,
|
||||
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;
|
||||
resource.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
||||
m_resourceSlots.push_back(resource);
|
||||
}
|
||||
|
||||
|
||||
void DxbcCodeGen::dclSampler(uint32_t samplerId) {
|
||||
// The sampler type is opaque, but we still have to
|
||||
// define a pointer and a variable in oder to use it
|
||||
|
@ -45,6 +45,18 @@ namespace dxvk {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Shader resource binding
|
||||
*
|
||||
* Stores the sampler variable as well as
|
||||
*/
|
||||
struct DxbcShaderResource {
|
||||
uint32_t varId = 0;
|
||||
uint32_t sampledTypeId = 0;
|
||||
uint32_t resourceTypeId = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief DXBC code generator
|
||||
*
|
||||
@ -64,11 +76,16 @@ namespace dxvk {
|
||||
void dclTemps(uint32_t n);
|
||||
|
||||
void dclConstantBuffer(
|
||||
uint32_t bufferId,
|
||||
uint32_t registerId,
|
||||
uint32_t elementCount);
|
||||
|
||||
void dclResource(
|
||||
uint32_t registerId,
|
||||
DxbcResourceDim resourceType,
|
||||
DxbcResourceReturnType returnType);
|
||||
|
||||
void dclSampler(
|
||||
uint32_t samplerId);
|
||||
uint32_t registerId);
|
||||
|
||||
DxbcValue defConstScalar(uint32_t v);
|
||||
|
||||
@ -172,8 +189,9 @@ namespace dxvk {
|
||||
|
||||
std::vector<DxbcPointer> m_rRegs;
|
||||
|
||||
std::array<DxbcConstantBuffer, 16> m_constantBuffers;
|
||||
std::array<DxbcSampler, 16> m_samplers;
|
||||
std::array<DxbcConstantBuffer, 16> m_constantBuffers;
|
||||
std::array<DxbcSampler, 16> m_samplers;
|
||||
std::array<DxbcShaderResource, 128> m_resources;
|
||||
|
||||
std::vector<DxvkResourceSlot> m_resourceSlots;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user