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:
parent
7c03495d74
commit
b4493d90d8
@ -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;
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user