[dxbc] Implemented sampler declaration

This commit is contained in:
Philip Rebohle 2017-12-10 03:39:35 +01:00
parent 9c997120e1
commit 939faeaf27
4 changed files with 84 additions and 11 deletions

View File

@ -24,6 +24,9 @@ namespace dxvk {
case DxbcOpcode::DclConstantBuffer:
return this->dclConstantBuffer(ins);
case DxbcOpcode::DclSampler:
return this->dclSampler(ins);
case DxbcOpcode::DclInput:
case DxbcOpcode::DclInputSiv:
case DxbcOpcode::DclInputSgv:
@ -90,6 +93,17 @@ namespace dxvk {
}
void DxbcCompiler::dclSampler(const DxbcInstruction& ins) {
auto op = ins.operand(0);
if (op.token().indexDimension() != 1)
throw DxvkError("DxbcCompiler::dclSampler: Invalid index dimension");
const uint32_t index = op.index(0).immPart();
m_gen->dclSampler(index);
}
void DxbcCompiler::dclInterfaceVar(const DxbcInstruction& ins) {
auto op = ins.operand(0);
auto opcode = ins.token().opcode();

View File

@ -35,6 +35,9 @@ namespace dxvk {
void dclConstantBuffer(
const DxbcInstruction& ins);
void dclSampler(
const DxbcInstruction& ins);
void dclInterfaceVar(
const DxbcInstruction& ins);

View File

@ -40,29 +40,39 @@ namespace dxvk {
void DxbcCodeGen::dclConstantBuffer(
uint32_t bufferId,
uint32_t elementCount) {
// Uniform buffer data is stored as a fixed-size array
// of 4x32-bit vectors. SPIR-V requires explicit strides.
uint32_t arrayType = m_module.defArrayTypeUnique(
this->defValueType(DxbcValueType(DxbcScalarType::Float32, 4)),
m_module.constu32(elementCount));
uint32_t structType = m_module.defStructTypeUnique(1, &arrayType);
m_module.decorateArrayStride(arrayType, 16);
// SPIR-V requires us to put that array into a
// struct and decorate that struct as a block.
uint32_t structType = m_module.defStructTypeUnique(1, &arrayType);
m_module.memberDecorateOffset(structType, 0, 0);
m_module.decorateBlock(structType);
uint32_t varIndex = m_module.newVar(
// Variable that we'll use to access the buffer
uint32_t varId = m_module.newVar(
m_module.defPointerType(structType, spv::StorageClassUniform),
spv::StorageClassUniform);
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.
uint32_t bindingId = computeResourceSlotId(m_shaderStage,
DxbcBindingType::ConstantBuffer, bufferId);
m_module.setDebugName(varIndex, str::format("cb", bufferId).c_str());
m_module.decorateDescriptorSet(varIndex, 0);
m_module.decorateBinding(varIndex, bindingId);
m_constantBuffers.at(bufferId).varId = varIndex;
m_constantBuffers.at(bufferId).size = elementCount;
m_module.decorateDescriptorSet(varId, 0);
m_module.decorateBinding(varId, bindingId);
// TODO compute resource slot index
// Store descriptor info for the shader interface
DxvkResourceSlot resource;
resource.slot = bindingId;
resource.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
@ -70,6 +80,37 @@ namespace dxvk {
}
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
uint32_t samplerType = m_module.defSamplerType();
uint32_t samplerPtrType = m_module.defPointerType(
samplerType, spv::StorageClassUniformConstant);
// Define the sampler variable
uint32_t varId = m_module.newVar(samplerPtrType,
spv::StorageClassUniformConstant);
m_module.setDebugName(varId,
str::format("s", samplerId).c_str());
m_samplers.at(samplerId).varId = varId;
// Compute binding slot index for the sampler
uint32_t bindingId = computeResourceSlotId(m_shaderStage,
DxbcBindingType::ImageSampler, samplerId);
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_SAMPLER;
m_resourceSlots.push_back(resource);
}
DxbcValue DxbcCodeGen::defConstScalar(uint32_t v) {
DxbcValue result;
result.type = DxbcValueType(DxbcScalarType::Uint32, 1);

View File

@ -26,8 +26,8 @@ namespace dxvk {
/**
* \brief Constant buffer binding
*
* Stores information about
* a constant buffer.
* Stores information required to
* access a constant buffer.
*/
struct DxbcConstantBuffer {
uint32_t varId = 0;
@ -35,6 +35,16 @@ namespace dxvk {
};
/**
* \brief Sampler binding
*
* Stores a sampler variable.
*/
struct DxbcSampler {
uint32_t varId = 0;
};
/**
* \brief DXBC code generator
*
@ -57,6 +67,9 @@ namespace dxvk {
uint32_t bufferId,
uint32_t elementCount);
void dclSampler(
uint32_t samplerId);
DxbcValue defConstScalar(uint32_t v);
DxbcValue defConstVector(
@ -160,6 +173,8 @@ namespace dxvk {
std::vector<DxbcPointer> m_rRegs;
std::array<DxbcConstantBuffer, 16> m_constantBuffers;
std::array<DxbcSampler, 16> m_samplers;
std::vector<DxvkResourceSlot> m_resourceSlots;
uint32_t defScalarType(