mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-31 05:52:11 +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:
|
||||
return this->opRet(ins);
|
||||
|
||||
case DxbcOpcode::Sample:
|
||||
return this->opSample(ins);
|
||||
|
||||
default:
|
||||
Logger::err(str::format(
|
||||
"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 immPart;
|
||||
DxbcValue relPart;
|
||||
|
@ -63,6 +63,9 @@ namespace dxvk {
|
||||
void opRet(
|
||||
const DxbcInstruction& ins);
|
||||
|
||||
void opSample(
|
||||
const DxbcInstruction& ins);
|
||||
|
||||
DxbcValue getDynamicIndexValue(
|
||||
const DxbcOperandIndex& index);
|
||||
|
||||
|
@ -93,7 +93,7 @@ namespace dxvk {
|
||||
case DxbcResourceReturnType::Uint: sampledTypeId = m_module.defIntType (32, 0); break;
|
||||
}
|
||||
|
||||
uint32_t resourceTypeId = 0;
|
||||
uint32_t textureTypeId = 0;
|
||||
|
||||
switch (resourceType) {
|
||||
default:
|
||||
@ -102,50 +102,50 @@ namespace dxvk {
|
||||
resourceType));
|
||||
|
||||
case DxbcResourceDim::Texture1D:
|
||||
resourceTypeId = m_module.defImageType(
|
||||
sampledTypeId, spv::Dim1D, 2, 0, 0, 1,
|
||||
textureTypeId = m_module.defImageType(
|
||||
sampledTypeId, spv::Dim1D, 0, 0, 0, 1,
|
||||
spv::ImageFormatUnknown);
|
||||
break;
|
||||
|
||||
case DxbcResourceDim::Texture1DArr:
|
||||
resourceTypeId = m_module.defImageType(
|
||||
sampledTypeId, spv::Dim1D, 2, 1, 0, 1,
|
||||
textureTypeId = m_module.defImageType(
|
||||
sampledTypeId, spv::Dim1D, 0, 1, 0, 1,
|
||||
spv::ImageFormatUnknown);
|
||||
break;
|
||||
|
||||
case DxbcResourceDim::Texture2D:
|
||||
resourceTypeId = m_module.defImageType(
|
||||
sampledTypeId, spv::Dim2D, 2, 0, 0, 1,
|
||||
textureTypeId = m_module.defImageType(
|
||||
sampledTypeId, spv::Dim2D, 0, 0, 0, 1,
|
||||
spv::ImageFormatUnknown);
|
||||
break;
|
||||
|
||||
case DxbcResourceDim::Texture2DArr:
|
||||
resourceTypeId = m_module.defImageType(
|
||||
sampledTypeId, spv::Dim2D, 2, 1, 0, 1,
|
||||
textureTypeId = m_module.defImageType(
|
||||
sampledTypeId, spv::Dim2D, 0, 1, 0, 1,
|
||||
spv::ImageFormatUnknown);
|
||||
break;
|
||||
|
||||
case DxbcResourceDim::Texture3D:
|
||||
resourceTypeId = m_module.defImageType(
|
||||
sampledTypeId, spv::Dim3D, 2, 0, 0, 1,
|
||||
textureTypeId = m_module.defImageType(
|
||||
sampledTypeId, spv::Dim3D, 0, 0, 0, 1,
|
||||
spv::ImageFormatUnknown);
|
||||
break;
|
||||
|
||||
case DxbcResourceDim::TextureCube:
|
||||
resourceTypeId = m_module.defImageType(
|
||||
sampledTypeId, spv::DimCube, 2, 0, 0, 1,
|
||||
textureTypeId = m_module.defImageType(
|
||||
sampledTypeId, spv::DimCube, 0, 0, 0, 1,
|
||||
spv::ImageFormatUnknown);
|
||||
break;
|
||||
|
||||
case DxbcResourceDim::TextureCubeArr:
|
||||
resourceTypeId = m_module.defImageType(
|
||||
sampledTypeId, spv::DimCube, 2, 1, 0, 1,
|
||||
textureTypeId = m_module.defImageType(
|
||||
sampledTypeId, spv::DimCube, 0, 1, 0, 1,
|
||||
spv::ImageFormatUnknown);
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t resourcePtrType = m_module.defPointerType(
|
||||
resourceTypeId, spv::StorageClassUniformConstant);
|
||||
textureTypeId, spv::StorageClassUniformConstant);
|
||||
|
||||
uint32_t varId = m_module.newVar(resourcePtrType,
|
||||
spv::StorageClassUniformConstant);
|
||||
@ -153,9 +153,9 @@ namespace dxvk {
|
||||
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;
|
||||
m_textures.at(registerId).varId = varId;
|
||||
m_textures.at(registerId).sampledTypeId = sampledTypeId;
|
||||
m_textures.at(registerId).textureTypeId = textureTypeId;
|
||||
|
||||
// Compute the DXVK binding slot index for the resource.
|
||||
// D3D11 needs to bind the actual resource to this slot.
|
||||
@ -187,7 +187,8 @@ namespace dxvk {
|
||||
m_module.setDebugName(varId,
|
||||
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
|
||||
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(
|
||||
const DxbcProgramVersion& version,
|
||||
const Rc<DxbcIsgn>& isgn,
|
||||
|
@ -41,7 +41,8 @@ namespace dxvk {
|
||||
* Stores a sampler variable.
|
||||
*/
|
||||
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
|
||||
*/
|
||||
struct DxbcShaderResource {
|
||||
uint32_t varId = 0;
|
||||
uint32_t sampledTypeId = 0;
|
||||
uint32_t resourceTypeId = 0;
|
||||
uint32_t varId = 0;
|
||||
uint32_t sampledTypeId = 0;
|
||||
uint32_t textureTypeId = 0;
|
||||
};
|
||||
|
||||
|
||||
@ -149,6 +150,11 @@ namespace dxvk {
|
||||
const DxbcValue& val,
|
||||
DxbcComponentMask mask);
|
||||
|
||||
DxbcValue texSample(
|
||||
const uint32_t textureId,
|
||||
const uint32_t samplerId,
|
||||
const DxbcValue& coordinates);
|
||||
|
||||
virtual void dclInterfaceVar(
|
||||
DxbcOperandType regType,
|
||||
uint32_t regId,
|
||||
@ -191,7 +197,7 @@ namespace dxvk {
|
||||
|
||||
std::array<DxbcConstantBuffer, 16> m_constantBuffers;
|
||||
std::array<DxbcSampler, 16> m_samplers;
|
||||
std::array<DxbcShaderResource, 128> m_resources;
|
||||
std::array<DxbcShaderResource, 128> m_textures;
|
||||
|
||||
std::vector<DxvkResourceSlot> m_resourceSlots;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user