mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-11-30 22:24:15 +01:00
[dxbc] Implemented Lod instruction
This commit is contained in:
parent
54108726d5
commit
b8a540d4ef
@ -88,6 +88,9 @@ namespace dxvk {
|
||||
case DxbcInstClass::TextureQuery:
|
||||
return this->emitTextureQuery(ins);
|
||||
|
||||
case DxbcInstClass::TextureQueryLod:
|
||||
return this->emitTextureQueryLod(ins);
|
||||
|
||||
case DxbcInstClass::TextureQueryMs:
|
||||
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) {
|
||||
// sampleinfo has two operands:
|
||||
// (dst0) The destination register
|
||||
@ -2624,11 +2673,6 @@ namespace dxvk {
|
||||
? emitRegisterLoad(ins.src[3], DxbcRegMask(true, false, false, false))
|
||||
: 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
|
||||
// not part of the actual operand token in SPIR-V.
|
||||
SpirvImageOperands imageOperands;
|
||||
@ -2647,14 +2691,9 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
// Combine the texture and the sampler into a sampled image
|
||||
const uint32_t sampledImageId = m_module.opSampledImage(
|
||||
sampledImageType,
|
||||
m_module.opLoad(
|
||||
m_textures.at(textureId).imageTypeId,
|
||||
m_textures.at(textureId).varId),
|
||||
m_module.opLoad(
|
||||
m_samplers.at(samplerId).typeId,
|
||||
m_samplers.at(samplerId).varId));
|
||||
const uint32_t sampledImageId = emitLoadSampledImage(
|
||||
m_textures.at(textureId), m_samplers.at(samplerId),
|
||||
isDepthCompare);
|
||||
|
||||
// Sampling an image always returns a four-component
|
||||
// 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(
|
||||
const DxbcRegister& operand) {
|
||||
// r# regs are indexed as follows:
|
||||
|
@ -524,6 +524,9 @@ namespace dxvk {
|
||||
void emitTextureQuery(
|
||||
const DxbcShaderInstruction& ins);
|
||||
|
||||
void emitTextureQueryLod(
|
||||
const DxbcShaderInstruction& ins);
|
||||
|
||||
void emitTextureQueryMs(
|
||||
const DxbcShaderInstruction& ins);
|
||||
|
||||
@ -659,6 +662,13 @@ namespace dxvk {
|
||||
DxbcRegisterValue value,
|
||||
DxbcOpModifiers modifiers);
|
||||
|
||||
///////////////////////////////////////
|
||||
// Image register manipulation methods
|
||||
uint32_t emitLoadSampledImage(
|
||||
const DxbcShaderResource& textureResource,
|
||||
const DxbcSampler& samplerResource,
|
||||
bool isDepthCompare);
|
||||
|
||||
////////////////////////
|
||||
// Address load methods
|
||||
DxbcRegisterPointer emitGetTempPtr(
|
||||
|
@ -536,7 +536,12 @@ namespace dxvk {
|
||||
/* Reserved0 */
|
||||
{ 0, DxbcInstClass::Undefined },
|
||||
/* Lod */
|
||||
{ },
|
||||
{ 4, DxbcInstClass::TextureQueryLod, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
|
||||
} },
|
||||
/* Gather4 */
|
||||
{ 4, DxbcInstClass::TextureGather, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
|
||||
|
@ -42,6 +42,7 @@ namespace dxvk {
|
||||
BufferStore, ///< Structured or raw buffer store
|
||||
ConvertFloat16, ///< 16-bit float packing/unpacking
|
||||
TextureQuery, ///< Texture query instruction
|
||||
TextureQueryLod, ///< Texture LOD query instruction
|
||||
TextureQueryMs, ///< Multisample texture query
|
||||
TextureFetch, ///< Texture fetch 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 resultType,
|
||||
uint32_t image) {
|
||||
|
@ -840,6 +840,11 @@ namespace dxvk {
|
||||
uint32_t resultType,
|
||||
uint32_t image);
|
||||
|
||||
uint32_t opImageQueryLod(
|
||||
uint32_t resultType,
|
||||
uint32_t sampledImage,
|
||||
uint32_t coordinates);
|
||||
|
||||
uint32_t opImageQuerySamples(
|
||||
uint32_t resultType,
|
||||
uint32_t image);
|
||||
|
Loading…
Reference in New Issue
Block a user