mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-02 22:29:16 +01:00
[dxbc] Implemented Lod instruction
This commit is contained in:
parent
54108726d5
commit
b8a540d4ef
@ -88,6 +88,9 @@ namespace dxvk {
|
|||||||
case DxbcInstClass::TextureQuery:
|
case DxbcInstClass::TextureQuery:
|
||||||
return this->emitTextureQuery(ins);
|
return this->emitTextureQuery(ins);
|
||||||
|
|
||||||
|
case DxbcInstClass::TextureQueryLod:
|
||||||
|
return this->emitTextureQueryLod(ins);
|
||||||
|
|
||||||
case DxbcInstClass::TextureQueryMs:
|
case DxbcInstClass::TextureQueryMs:
|
||||||
return this->emitTextureQueryMs(ins);
|
return this->emitTextureQueryMs(ins);
|
||||||
|
|
||||||
@ -2283,6 +2286,52 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxbcCompiler::emitTextureQueryLod(const DxbcShaderInstruction& ins) {
|
||||||
|
// All sample instructions have at least these operands:
|
||||||
|
// (dst0) The destination register
|
||||||
|
// (src0) Texture coordinates
|
||||||
|
// (src1) The texture itself
|
||||||
|
// (src2) The sampler object
|
||||||
|
const DxbcRegister& texCoordReg = ins.src[0];
|
||||||
|
const DxbcRegister& textureReg = ins.src[1];
|
||||||
|
const DxbcRegister& samplerReg = ins.src[2];
|
||||||
|
|
||||||
|
// Texture and sampler register IDs
|
||||||
|
const uint32_t textureId = textureReg.idx[0].offset;
|
||||||
|
const uint32_t samplerId = samplerReg.idx[0].offset;
|
||||||
|
|
||||||
|
// Load texture coordinates
|
||||||
|
const uint32_t imageCoordDim = getTexCoordDim(
|
||||||
|
m_textures.at(textureId).imageInfo);
|
||||||
|
|
||||||
|
const DxbcRegisterValue coord = emitRegisterLoad(
|
||||||
|
texCoordReg, DxbcRegMask::firstN(imageCoordDim));
|
||||||
|
|
||||||
|
// Query the LOD. The result is a two-dimensional float32
|
||||||
|
// vector containing the mip level and virtual LOD numbers.
|
||||||
|
const uint32_t sampledImageId = emitLoadSampledImage(
|
||||||
|
m_textures.at(textureId), m_samplers.at(samplerId), false);
|
||||||
|
|
||||||
|
const uint32_t queriedLodId = m_module.opImageQueryLod(
|
||||||
|
getVectorTypeId({ DxbcScalarType::Float32, 2 }),
|
||||||
|
sampledImageId, coord.id);
|
||||||
|
|
||||||
|
// Build the result array vector by filling up
|
||||||
|
// the remaining two components with zeroes.
|
||||||
|
const uint32_t zero = m_module.constf32(0.0f);
|
||||||
|
const std::array<uint32_t, 3> resultIds
|
||||||
|
= {{ queriedLodId, zero, zero }};
|
||||||
|
|
||||||
|
DxbcRegisterValue result;
|
||||||
|
result.type = DxbcVectorType { DxbcScalarType::Float32, 4 };
|
||||||
|
result.id = m_module.opCompositeConstruct(
|
||||||
|
getVectorTypeId(result.type),
|
||||||
|
resultIds.size(), resultIds.data());
|
||||||
|
|
||||||
|
emitRegisterStore(ins.dst[0], result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxbcCompiler::emitTextureQueryMs(const DxbcShaderInstruction& ins) {
|
void DxbcCompiler::emitTextureQueryMs(const DxbcShaderInstruction& ins) {
|
||||||
// sampleinfo has two operands:
|
// sampleinfo has two operands:
|
||||||
// (dst0) The destination register
|
// (dst0) The destination register
|
||||||
@ -2624,11 +2673,6 @@ namespace dxvk {
|
|||||||
? emitRegisterLoad(ins.src[3], DxbcRegMask(true, false, false, false))
|
? emitRegisterLoad(ins.src[3], DxbcRegMask(true, false, false, false))
|
||||||
: DxbcRegisterValue();
|
: DxbcRegisterValue();
|
||||||
|
|
||||||
// Determine the sampled image type based on the opcode.
|
|
||||||
const uint32_t sampledImageType = isDepthCompare
|
|
||||||
? m_module.defSampledImageType(m_textures.at(textureId).depthTypeId)
|
|
||||||
: m_module.defSampledImageType(m_textures.at(textureId).colorTypeId);
|
|
||||||
|
|
||||||
// Accumulate additional image operands. These are
|
// Accumulate additional image operands. These are
|
||||||
// not part of the actual operand token in SPIR-V.
|
// not part of the actual operand token in SPIR-V.
|
||||||
SpirvImageOperands imageOperands;
|
SpirvImageOperands imageOperands;
|
||||||
@ -2647,14 +2691,9 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Combine the texture and the sampler into a sampled image
|
// Combine the texture and the sampler into a sampled image
|
||||||
const uint32_t sampledImageId = m_module.opSampledImage(
|
const uint32_t sampledImageId = emitLoadSampledImage(
|
||||||
sampledImageType,
|
m_textures.at(textureId), m_samplers.at(samplerId),
|
||||||
m_module.opLoad(
|
isDepthCompare);
|
||||||
m_textures.at(textureId).imageTypeId,
|
|
||||||
m_textures.at(textureId).varId),
|
|
||||||
m_module.opLoad(
|
|
||||||
m_samplers.at(samplerId).typeId,
|
|
||||||
m_samplers.at(samplerId).varId));
|
|
||||||
|
|
||||||
// Sampling an image always returns a four-component
|
// Sampling an image always returns a four-component
|
||||||
// vector, whereas depth-compare ops return a scalar.
|
// vector, whereas depth-compare ops return a scalar.
|
||||||
@ -3501,6 +3540,20 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t DxbcCompiler::emitLoadSampledImage(
|
||||||
|
const DxbcShaderResource& textureResource,
|
||||||
|
const DxbcSampler& samplerResource,
|
||||||
|
bool isDepthCompare) {
|
||||||
|
const uint32_t sampledImageType = isDepthCompare
|
||||||
|
? m_module.defSampledImageType(textureResource.depthTypeId)
|
||||||
|
: m_module.defSampledImageType(textureResource.colorTypeId);
|
||||||
|
|
||||||
|
return m_module.opSampledImage(sampledImageType,
|
||||||
|
m_module.opLoad(textureResource.imageTypeId, textureResource.varId),
|
||||||
|
m_module.opLoad(samplerResource.typeId, samplerResource.varId));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DxbcRegisterPointer DxbcCompiler::emitGetTempPtr(
|
DxbcRegisterPointer DxbcCompiler::emitGetTempPtr(
|
||||||
const DxbcRegister& operand) {
|
const DxbcRegister& operand) {
|
||||||
// r# regs are indexed as follows:
|
// r# regs are indexed as follows:
|
||||||
|
@ -524,6 +524,9 @@ namespace dxvk {
|
|||||||
void emitTextureQuery(
|
void emitTextureQuery(
|
||||||
const DxbcShaderInstruction& ins);
|
const DxbcShaderInstruction& ins);
|
||||||
|
|
||||||
|
void emitTextureQueryLod(
|
||||||
|
const DxbcShaderInstruction& ins);
|
||||||
|
|
||||||
void emitTextureQueryMs(
|
void emitTextureQueryMs(
|
||||||
const DxbcShaderInstruction& ins);
|
const DxbcShaderInstruction& ins);
|
||||||
|
|
||||||
@ -659,6 +662,13 @@ namespace dxvk {
|
|||||||
DxbcRegisterValue value,
|
DxbcRegisterValue value,
|
||||||
DxbcOpModifiers modifiers);
|
DxbcOpModifiers modifiers);
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
// Image register manipulation methods
|
||||||
|
uint32_t emitLoadSampledImage(
|
||||||
|
const DxbcShaderResource& textureResource,
|
||||||
|
const DxbcSampler& samplerResource,
|
||||||
|
bool isDepthCompare);
|
||||||
|
|
||||||
////////////////////////
|
////////////////////////
|
||||||
// Address load methods
|
// Address load methods
|
||||||
DxbcRegisterPointer emitGetTempPtr(
|
DxbcRegisterPointer emitGetTempPtr(
|
||||||
|
@ -536,7 +536,12 @@ namespace dxvk {
|
|||||||
/* Reserved0 */
|
/* Reserved0 */
|
||||||
{ 0, DxbcInstClass::Undefined },
|
{ 0, DxbcInstClass::Undefined },
|
||||||
/* Lod */
|
/* Lod */
|
||||||
{ },
|
{ 4, DxbcInstClass::TextureQueryLod, {
|
||||||
|
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
|
||||||
|
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
|
||||||
|
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
|
||||||
|
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
|
||||||
|
} },
|
||||||
/* Gather4 */
|
/* Gather4 */
|
||||||
{ 4, DxbcInstClass::TextureGather, {
|
{ 4, DxbcInstClass::TextureGather, {
|
||||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
|
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
|
||||||
|
@ -42,6 +42,7 @@ namespace dxvk {
|
|||||||
BufferStore, ///< Structured or raw buffer store
|
BufferStore, ///< Structured or raw buffer store
|
||||||
ConvertFloat16, ///< 16-bit float packing/unpacking
|
ConvertFloat16, ///< 16-bit float packing/unpacking
|
||||||
TextureQuery, ///< Texture query instruction
|
TextureQuery, ///< Texture query instruction
|
||||||
|
TextureQueryLod, ///< Texture LOD query instruction
|
||||||
TextureQueryMs, ///< Multisample texture query
|
TextureQueryMs, ///< Multisample texture query
|
||||||
TextureFetch, ///< Texture fetch instruction
|
TextureFetch, ///< Texture fetch instruction
|
||||||
TextureGather, ///< Texture gather instruction
|
TextureGather, ///< Texture gather instruction
|
||||||
|
@ -2400,6 +2400,21 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t SpirvModule::opImageQueryLod(
|
||||||
|
uint32_t resultType,
|
||||||
|
uint32_t sampledImage,
|
||||||
|
uint32_t coordinates) {
|
||||||
|
uint32_t resultId = this->allocateId();
|
||||||
|
|
||||||
|
m_code.putIns (spv::OpImageQueryLod, 5);
|
||||||
|
m_code.putWord(resultType);
|
||||||
|
m_code.putWord(resultId);
|
||||||
|
m_code.putWord(sampledImage);
|
||||||
|
m_code.putWord(coordinates);
|
||||||
|
return resultId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t SpirvModule::opImageQuerySamples(
|
uint32_t SpirvModule::opImageQuerySamples(
|
||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
uint32_t image) {
|
uint32_t image) {
|
||||||
|
@ -840,6 +840,11 @@ namespace dxvk {
|
|||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
uint32_t image);
|
uint32_t image);
|
||||||
|
|
||||||
|
uint32_t opImageQueryLod(
|
||||||
|
uint32_t resultType,
|
||||||
|
uint32_t sampledImage,
|
||||||
|
uint32_t coordinates);
|
||||||
|
|
||||||
uint32_t opImageQuerySamples(
|
uint32_t opImageQuerySamples(
|
||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
uint32_t image);
|
uint32_t image);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user