1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-21 13:29:26 +01:00

[dxbc] Initial support for sample instruction

This commit is contained in:
Philip Rebohle 2017-12-10 12:08:20 +01:00
parent 7c03495d74
commit b4493d90d8
4 changed files with 95 additions and 25 deletions

View File

@ -65,6 +65,9 @@ namespace dxvk {
case DxbcOpcode::Ret: case DxbcOpcode::Ret:
return this->opRet(ins); return this->opRet(ins);
case DxbcOpcode::Sample:
return this->opSample(ins);
default: default:
Logger::err(str::format( Logger::err(str::format(
"DxbcCompiler::processInstruction: Unhandled opcode: ", "DxbcCompiler::processInstruction: Unhandled opcode: ",
@ -275,6 +278,33 @@ namespace dxvk {
} }
void DxbcCompiler::opSample(const DxbcInstruction& ins) {
// TODO support address offset
// TODO support more sample ops
auto dstOp = ins.operand(0);
auto coordOp = ins.operand(dstOp.length());
auto texture = ins.operand(dstOp.length() + coordOp.length());
auto sampler = ins.operand(dstOp.length() + coordOp.length() + texture.length());
if ((texture.token().indexDimension() != 1)
|| (sampler.token().indexDimension() != 1))
throw DxvkError("DXBC: opSample: Invalid operand index dimensions");
uint32_t textureId = texture.index(0).immPart();
uint32_t samplerId = sampler.index(0).immPart();
DxbcValue coord = this->loadOperand(coordOp,
DxbcComponentMask(true, true, true, true),
DxbcScalarType::Float32);
DxbcComponentMask mask = this->getDstOperandMask(dstOp);
DxbcValue value = m_gen->texSample(textureId, samplerId, coord);
value = this->selectOperandComponents(texture.token(), value, mask);
this->storeOperand(dstOp, value, mask);
}
DxbcValue DxbcCompiler::getDynamicIndexValue(const DxbcOperandIndex& index) { DxbcValue DxbcCompiler::getDynamicIndexValue(const DxbcOperandIndex& index) {
DxbcValue immPart; DxbcValue immPart;
DxbcValue relPart; DxbcValue relPart;

View File

@ -63,6 +63,9 @@ namespace dxvk {
void opRet( void opRet(
const DxbcInstruction& ins); const DxbcInstruction& ins);
void opSample(
const DxbcInstruction& ins);
DxbcValue getDynamicIndexValue( DxbcValue getDynamicIndexValue(
const DxbcOperandIndex& index); const DxbcOperandIndex& index);

View File

@ -93,7 +93,7 @@ namespace dxvk {
case DxbcResourceReturnType::Uint: sampledTypeId = m_module.defIntType (32, 0); break; case DxbcResourceReturnType::Uint: sampledTypeId = m_module.defIntType (32, 0); break;
} }
uint32_t resourceTypeId = 0; uint32_t textureTypeId = 0;
switch (resourceType) { switch (resourceType) {
default: default:
@ -102,50 +102,50 @@ namespace dxvk {
resourceType)); resourceType));
case DxbcResourceDim::Texture1D: case DxbcResourceDim::Texture1D:
resourceTypeId = m_module.defImageType( textureTypeId = m_module.defImageType(
sampledTypeId, spv::Dim1D, 2, 0, 0, 1, sampledTypeId, spv::Dim1D, 0, 0, 0, 1,
spv::ImageFormatUnknown); spv::ImageFormatUnknown);
break; break;
case DxbcResourceDim::Texture1DArr: case DxbcResourceDim::Texture1DArr:
resourceTypeId = m_module.defImageType( textureTypeId = m_module.defImageType(
sampledTypeId, spv::Dim1D, 2, 1, 0, 1, sampledTypeId, spv::Dim1D, 0, 1, 0, 1,
spv::ImageFormatUnknown); spv::ImageFormatUnknown);
break; break;
case DxbcResourceDim::Texture2D: case DxbcResourceDim::Texture2D:
resourceTypeId = m_module.defImageType( textureTypeId = m_module.defImageType(
sampledTypeId, spv::Dim2D, 2, 0, 0, 1, sampledTypeId, spv::Dim2D, 0, 0, 0, 1,
spv::ImageFormatUnknown); spv::ImageFormatUnknown);
break; break;
case DxbcResourceDim::Texture2DArr: case DxbcResourceDim::Texture2DArr:
resourceTypeId = m_module.defImageType( textureTypeId = m_module.defImageType(
sampledTypeId, spv::Dim2D, 2, 1, 0, 1, sampledTypeId, spv::Dim2D, 0, 1, 0, 1,
spv::ImageFormatUnknown); spv::ImageFormatUnknown);
break; break;
case DxbcResourceDim::Texture3D: case DxbcResourceDim::Texture3D:
resourceTypeId = m_module.defImageType( textureTypeId = m_module.defImageType(
sampledTypeId, spv::Dim3D, 2, 0, 0, 1, sampledTypeId, spv::Dim3D, 0, 0, 0, 1,
spv::ImageFormatUnknown); spv::ImageFormatUnknown);
break; break;
case DxbcResourceDim::TextureCube: case DxbcResourceDim::TextureCube:
resourceTypeId = m_module.defImageType( textureTypeId = m_module.defImageType(
sampledTypeId, spv::DimCube, 2, 0, 0, 1, sampledTypeId, spv::DimCube, 0, 0, 0, 1,
spv::ImageFormatUnknown); spv::ImageFormatUnknown);
break; break;
case DxbcResourceDim::TextureCubeArr: case DxbcResourceDim::TextureCubeArr:
resourceTypeId = m_module.defImageType( textureTypeId = m_module.defImageType(
sampledTypeId, spv::DimCube, 2, 1, 0, 1, sampledTypeId, spv::DimCube, 0, 1, 0, 1,
spv::ImageFormatUnknown); spv::ImageFormatUnknown);
break; break;
} }
uint32_t resourcePtrType = m_module.defPointerType( uint32_t resourcePtrType = m_module.defPointerType(
resourceTypeId, spv::StorageClassUniformConstant); textureTypeId, spv::StorageClassUniformConstant);
uint32_t varId = m_module.newVar(resourcePtrType, uint32_t varId = m_module.newVar(resourcePtrType,
spv::StorageClassUniformConstant); spv::StorageClassUniformConstant);
@ -153,9 +153,9 @@ namespace dxvk {
m_module.setDebugName(varId, m_module.setDebugName(varId,
str::format("t", registerId).c_str()); str::format("t", registerId).c_str());
m_resources.at(registerId).varId = varId; m_textures.at(registerId).varId = varId;
m_resources.at(registerId).sampledTypeId = sampledTypeId; m_textures.at(registerId).sampledTypeId = sampledTypeId;
m_resources.at(registerId).resourceTypeId = resourceTypeId; m_textures.at(registerId).textureTypeId = textureTypeId;
// Compute the DXVK binding slot index for the resource. // Compute the DXVK binding slot index for the resource.
// D3D11 needs to bind the actual resource to this slot. // D3D11 needs to bind the actual resource to this slot.
@ -187,7 +187,8 @@ namespace dxvk {
m_module.setDebugName(varId, m_module.setDebugName(varId,
str::format("s", samplerId).c_str()); str::format("s", samplerId).c_str());
m_samplers.at(samplerId).varId = varId; m_samplers.at(samplerId).varId = varId;
m_samplers.at(samplerId).typeId = samplerType;
// Compute binding slot index for the sampler // Compute binding slot index for the sampler
uint32_t bindingId = computeResourceSlotId(m_shaderStage, uint32_t bindingId = computeResourceSlotId(m_shaderStage,
@ -552,6 +553,36 @@ namespace dxvk {
} }
DxbcValue DxbcCodeGen::texSample(
const uint32_t textureId,
const uint32_t samplerId,
const DxbcValue& coordinates) {
// Combine the texture and the sampler into a sampled image
uint32_t sampledImageType = m_module.defSampledImageType(
m_textures.at(textureId).textureTypeId);
uint32_t sampledImageId = m_module.opSampledImage(
sampledImageType,
m_module.opLoad(
m_textures.at(textureId).textureTypeId,
m_textures.at(textureId).varId),
m_module.opLoad(
m_samplers.at(samplerId).typeId,
m_samplers.at(samplerId).varId));
// Sampling an image in SPIR-V always returns a four-component
// vector, so we need to declare the corresponding type here
// TODO infer sampled type properly
DxbcValue result;
result.type = DxbcValueType(DxbcScalarType::Float32, 4);
result.valueId = m_module.opImageSampleImplicitLod(
this->defValueType(result.type),
sampledImageId,
this->regExtract(coordinates, DxbcComponentMask(true, true, false, false)).valueId);
return result;
}
Rc<DxbcCodeGen> DxbcCodeGen::create( Rc<DxbcCodeGen> DxbcCodeGen::create(
const DxbcProgramVersion& version, const DxbcProgramVersion& version,
const Rc<DxbcIsgn>& isgn, const Rc<DxbcIsgn>& isgn,

View File

@ -41,7 +41,8 @@ namespace dxvk {
* Stores a sampler variable. * Stores a sampler variable.
*/ */
struct DxbcSampler { struct DxbcSampler {
uint32_t varId = 0; uint32_t varId = 0;
uint32_t typeId = 0;
}; };
@ -51,9 +52,9 @@ namespace dxvk {
* Stores the sampler variable as well as * Stores the sampler variable as well as
*/ */
struct DxbcShaderResource { struct DxbcShaderResource {
uint32_t varId = 0; uint32_t varId = 0;
uint32_t sampledTypeId = 0; uint32_t sampledTypeId = 0;
uint32_t resourceTypeId = 0; uint32_t textureTypeId = 0;
}; };
@ -149,6 +150,11 @@ namespace dxvk {
const DxbcValue& val, const DxbcValue& val,
DxbcComponentMask mask); DxbcComponentMask mask);
DxbcValue texSample(
const uint32_t textureId,
const uint32_t samplerId,
const DxbcValue& coordinates);
virtual void dclInterfaceVar( virtual void dclInterfaceVar(
DxbcOperandType regType, DxbcOperandType regType,
uint32_t regId, uint32_t regId,
@ -191,7 +197,7 @@ namespace dxvk {
std::array<DxbcConstantBuffer, 16> m_constantBuffers; std::array<DxbcConstantBuffer, 16> m_constantBuffers;
std::array<DxbcSampler, 16> m_samplers; std::array<DxbcSampler, 16> m_samplers;
std::array<DxbcShaderResource, 128> m_resources; std::array<DxbcShaderResource, 128> m_textures;
std::vector<DxvkResourceSlot> m_resourceSlots; std::vector<DxvkResourceSlot> m_resourceSlots;