mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 10:54:16 +01:00
[dxbc] Implemented sample_d and vector shift instructions
This commit is contained in:
parent
6ff709513c
commit
109ce0a695
@ -9,7 +9,7 @@ exe_wrapper = 'wine'
|
||||
c_args = ['-Og', '-ggdb']
|
||||
c_link_args = ['-static', '-static-libgcc']
|
||||
|
||||
cpp_args = ['-Og', '-gdwarf']
|
||||
cpp_args = ['-Og', '-gstabs']
|
||||
cpp_link_args = ['-static', '-static-libgcc', '-static-libstdc++']
|
||||
|
||||
[host_machine]
|
||||
|
@ -86,6 +86,9 @@ namespace dxvk {
|
||||
case DxbcInstClass::VectorImul:
|
||||
return this->emitVectorImul(ins);
|
||||
|
||||
case DxbcInstClass::VectorShift:
|
||||
return this->emitVectorShift(ins);
|
||||
|
||||
case DxbcInstClass::VectorSinCos:
|
||||
return this->emitVectorSinCos(ins);
|
||||
|
||||
@ -780,6 +783,7 @@ namespace dxvk {
|
||||
break;
|
||||
|
||||
case DxbcOpcode::IMad:
|
||||
case DxbcOpcode::UMad:
|
||||
dst.id = m_module.opIAdd(typeId,
|
||||
m_module.opIMul(typeId,
|
||||
src.at(0).id, src.at(1).id),
|
||||
@ -801,6 +805,18 @@ namespace dxvk {
|
||||
typeId, src.at(0).id);
|
||||
break;
|
||||
|
||||
///////////////////////////////////////
|
||||
// ALU operations on unsigned integers
|
||||
case DxbcOpcode::UMax:
|
||||
dst.id = m_module.opUMax(typeId,
|
||||
src.at(0).id, src.at(1).id);
|
||||
break;
|
||||
|
||||
case DxbcOpcode::UMin:
|
||||
dst.id = m_module.opUMin(typeId,
|
||||
src.at(0).id, src.at(1).id);
|
||||
break;
|
||||
|
||||
///////////////////////////////////////
|
||||
// Bit operations on unsigned integers
|
||||
case DxbcOpcode::And:
|
||||
@ -1157,6 +1173,57 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxbcCompiler::emitVectorShift(const DxbcShaderInstruction& ins) {
|
||||
// Shift operations have three operands:
|
||||
// (dst0) The destination register
|
||||
// (src0) The register to shift
|
||||
// (src1) The shift amount (scalar)
|
||||
const DxbcRegisterValue shiftReg = emitRegisterLoad(
|
||||
ins.src[0], ins.dst[0].mask);
|
||||
|
||||
DxbcRegisterValue countReg = emitRegisterLoad(
|
||||
ins.src[1], DxbcRegMask(true, false, false, false));
|
||||
|
||||
// Unlike in DXBC, SPIR-V shift operations allow different
|
||||
// shift amounts per component, so we'll extend the count
|
||||
// register to a vector.
|
||||
countReg = emitRegisterExtend(countReg, shiftReg.type.ccount);
|
||||
|
||||
DxbcRegisterValue result;
|
||||
result.type.ctype = ins.dst[0].dataType;
|
||||
result.type.ccount = ins.dst[0].mask.setCount();
|
||||
|
||||
switch (ins.op) {
|
||||
case DxbcOpcode::IShl:
|
||||
result.id = m_module.opShiftLeftLogical(
|
||||
getVectorTypeId(result.type),
|
||||
shiftReg.id, countReg.id);
|
||||
break;
|
||||
|
||||
case DxbcOpcode::IShr:
|
||||
result.id = m_module.opShiftRightArithmetic(
|
||||
getVectorTypeId(result.type),
|
||||
shiftReg.id, countReg.id);
|
||||
break;
|
||||
|
||||
case DxbcOpcode::UShr:
|
||||
result.id = m_module.opShiftRightLogical(
|
||||
getVectorTypeId(result.type),
|
||||
shiftReg.id, countReg.id);
|
||||
break;
|
||||
|
||||
default:
|
||||
Logger::warn(str::format(
|
||||
"DxbcCompiler: Unhandled instruction: ",
|
||||
ins.op));
|
||||
return;
|
||||
}
|
||||
|
||||
result = emitDstOperandModifiers(result, ins.modifiers);
|
||||
emitRegisterStore(ins.dst[0], result);
|
||||
}
|
||||
|
||||
|
||||
void DxbcCompiler::emitVectorSinCos(const DxbcShaderInstruction& ins) {
|
||||
// sincos has three operands:
|
||||
// (dst0) Destination register for sin(x)
|
||||
@ -1232,20 +1299,33 @@ namespace dxvk {
|
||||
const uint32_t textureId = textureReg.idx[0].offset;
|
||||
const uint32_t samplerId = samplerReg.idx[0].offset;
|
||||
|
||||
// FIXME implement properly
|
||||
DxbcRegMask coordArrayMask(true, true, true, true);
|
||||
DxbcRegMask coordLayerMask(true, true, true, true);
|
||||
|
||||
// Load the texture coordinates. SPIR-V allows these
|
||||
// to be float4 even if not all components are used.
|
||||
const DxbcRegisterValue coord = emitRegisterLoad(
|
||||
texCoordReg, DxbcRegMask(true, true, true, true));
|
||||
const DxbcRegisterValue coord = emitRegisterLoad(texCoordReg, coordArrayMask);
|
||||
|
||||
// Determine whether this is a depth-compare op
|
||||
// Load reference value for depth-compare operations
|
||||
const bool isDepthCompare = ins.op == DxbcOpcode::SampleC
|
||||
|| ins.op == DxbcOpcode::SampleClz;
|
||||
|
||||
// Load reference value for depth-compare operations
|
||||
const DxbcRegisterValue referenceValue = isDepthCompare
|
||||
? emitRegisterLoad(ins.src[3], DxbcRegMask(true, false, false, false))
|
||||
: DxbcRegisterValue();
|
||||
|
||||
// Load explicit gradients for sample operations that require them
|
||||
const bool explicitGradients = ins.op == DxbcOpcode::SampleD;
|
||||
|
||||
const DxbcRegisterValue explicitGradientX = explicitGradients
|
||||
? emitRegisterLoad(ins.src[3], coordLayerMask)
|
||||
: DxbcRegisterValue();
|
||||
|
||||
const DxbcRegisterValue explicitGradientY = explicitGradients
|
||||
? emitRegisterLoad(ins.src[4], coordLayerMask)
|
||||
: DxbcRegisterValue();
|
||||
|
||||
// Determine the sampled image type based on the opcode.
|
||||
// FIXME while this is in line what the officla glsl compiler
|
||||
// does, this might actually violate the SPIR-V specification.
|
||||
@ -1300,6 +1380,17 @@ namespace dxvk {
|
||||
referenceValue.id, imageOperands);
|
||||
} break;
|
||||
|
||||
// Sample operation with explicit gradients
|
||||
case DxbcOpcode::SampleD: {
|
||||
imageOperands.flags |= spv::ImageOperandsGradMask;
|
||||
imageOperands.sGradX = explicitGradientX.id;
|
||||
imageOperands.sGradY = explicitGradientY.id;
|
||||
|
||||
result.id = m_module.opImageSampleExplicitLod(
|
||||
getVectorTypeId(result.type), sampledImageId, coord.id,
|
||||
imageOperands);
|
||||
} break;
|
||||
|
||||
default:
|
||||
Logger::warn(str::format(
|
||||
"DxbcCompiler: Unhandled instruction: ",
|
||||
|
@ -328,6 +328,9 @@ namespace dxvk {
|
||||
void emitVectorImul(
|
||||
const DxbcShaderInstruction& ins);
|
||||
|
||||
void emitVectorShift(
|
||||
const DxbcShaderInstruction& ins);
|
||||
|
||||
void emitVectorSinCos(
|
||||
const DxbcShaderInstruction& ins);
|
||||
|
||||
|
@ -332,8 +332,8 @@ namespace dxvk {
|
||||
|
||||
DxbcShaderInstruction m_instruction;
|
||||
|
||||
std::array<DxbcRegister, 4> m_dstOperands;
|
||||
std::array<DxbcRegister, 4> m_srcOperands;
|
||||
std::array<DxbcRegister, 8> m_dstOperands;
|
||||
std::array<DxbcRegister, 8> m_srcOperands;
|
||||
std::array<DxbcImmediate, 4> m_immOperands;
|
||||
std::array<DxbcRegister, 12> m_indices;
|
||||
|
||||
|
@ -186,9 +186,17 @@ namespace dxvk {
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Sint32 },
|
||||
} },
|
||||
/* IShl */
|
||||
{ },
|
||||
{ 3, DxbcInstClass::VectorShift, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Sint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Sint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
} },
|
||||
/* IShr */
|
||||
{ },
|
||||
{ 3, DxbcInstClass::VectorShift, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Sint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Sint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
} },
|
||||
/* ItoF */
|
||||
{ 2, DxbcInstClass::VectorAlu, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
|
||||
@ -318,7 +326,14 @@ namespace dxvk {
|
||||
/* SampleL */
|
||||
{ },
|
||||
/* SampleD */
|
||||
{ },
|
||||
{ 6, DxbcInstClass::TextureSample, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
|
||||
} },
|
||||
/* SampleB */
|
||||
{ },
|
||||
/* Sqrt */
|
||||
@ -342,9 +357,17 @@ namespace dxvk {
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
} },
|
||||
/* ULt */
|
||||
{ },
|
||||
{ 3, DxbcInstClass::VectorCmp, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Uint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
} },
|
||||
/* UGe */
|
||||
{ },
|
||||
{ 3, DxbcInstClass::VectorCmp, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Uint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
} },
|
||||
/* UMul */
|
||||
{ 4, DxbcInstClass::VectorImul, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Uint32 },
|
||||
@ -353,13 +376,30 @@ namespace dxvk {
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
} },
|
||||
/* UMad */
|
||||
{ },
|
||||
{ 4, DxbcInstClass::VectorAlu, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Uint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
} },
|
||||
/* UMax */
|
||||
{ },
|
||||
{ 3, DxbcInstClass::VectorAlu, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Uint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
} },
|
||||
/* UMin */
|
||||
{ },
|
||||
{ 3, DxbcInstClass::VectorAlu, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Uint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
} },
|
||||
/* UShr */
|
||||
{ },
|
||||
{ 3, DxbcInstClass::VectorShift, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Uint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
} },
|
||||
/* UtoF */
|
||||
{ 2, DxbcInstClass::VectorAlu, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
|
||||
|
@ -40,6 +40,7 @@ namespace dxvk {
|
||||
VectorDot, ///< Dot product instruction
|
||||
VectorIdiv, ///< Component-wise integer division
|
||||
VectorImul, ///< Component-wise integer multiplication
|
||||
VectorShift, ///< Bit shift operations on vectors
|
||||
VectorSinCos, ///< Sine and Cosine instruction
|
||||
Undefined, ///< Instruction code not defined
|
||||
};
|
||||
|
@ -654,6 +654,51 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opShiftLeftLogical(
|
||||
uint32_t resultType,
|
||||
uint32_t base,
|
||||
uint32_t shift) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_code.putIns (spv::OpShiftLeftLogical, 5);
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(base);
|
||||
m_code.putWord(shift);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opShiftRightArithmetic(
|
||||
uint32_t resultType,
|
||||
uint32_t base,
|
||||
uint32_t shift) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_code.putIns (spv::OpShiftRightArithmetic, 5);
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(base);
|
||||
m_code.putWord(shift);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opShiftRightLogical(
|
||||
uint32_t resultType,
|
||||
uint32_t base,
|
||||
uint32_t shift) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_code.putIns (spv::OpShiftRightLogical, 5);
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(base);
|
||||
m_code.putWord(shift);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opConvertFtoS(
|
||||
uint32_t resultType,
|
||||
uint32_t operand) {
|
||||
@ -1136,6 +1181,40 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opUMax(
|
||||
uint32_t resultType,
|
||||
uint32_t a,
|
||||
uint32_t b) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_code.putIns (spv::OpExtInst, 7);
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(m_instExtGlsl450);
|
||||
m_code.putWord(spv::GLSLstd450UMax);
|
||||
m_code.putWord(a);
|
||||
m_code.putWord(b);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opUMin(
|
||||
uint32_t resultType,
|
||||
uint32_t a,
|
||||
uint32_t b) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_code.putIns (spv::OpExtInst, 7);
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(m_instExtGlsl450);
|
||||
m_code.putWord(spv::GLSLstd450UMin);
|
||||
m_code.putWord(a);
|
||||
m_code.putWord(b);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opFClamp(
|
||||
uint32_t resultType,
|
||||
uint32_t x,
|
||||
@ -1550,7 +1629,6 @@ namespace dxvk {
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(sampledImage);
|
||||
m_code.putWord(coordinates);
|
||||
m_code.putWord(spv::ImageOperandsLodMask);
|
||||
|
||||
putImageOperands(operands);
|
||||
return resultId;
|
||||
|
@ -253,6 +253,21 @@ namespace dxvk {
|
||||
uint32_t resultType,
|
||||
uint32_t operand);
|
||||
|
||||
uint32_t opShiftLeftLogical(
|
||||
uint32_t resultType,
|
||||
uint32_t base,
|
||||
uint32_t shift);
|
||||
|
||||
uint32_t opShiftRightArithmetic(
|
||||
uint32_t resultType,
|
||||
uint32_t base,
|
||||
uint32_t shift);
|
||||
|
||||
uint32_t opShiftRightLogical(
|
||||
uint32_t resultType,
|
||||
uint32_t base,
|
||||
uint32_t shift);
|
||||
|
||||
uint32_t opConvertFtoS(
|
||||
uint32_t resultType,
|
||||
uint32_t operand);
|
||||
@ -405,6 +420,16 @@ namespace dxvk {
|
||||
uint32_t a,
|
||||
uint32_t b);
|
||||
|
||||
uint32_t opUMax(
|
||||
uint32_t resultType,
|
||||
uint32_t a,
|
||||
uint32_t b);
|
||||
|
||||
uint32_t opUMin(
|
||||
uint32_t resultType,
|
||||
uint32_t a,
|
||||
uint32_t b);
|
||||
|
||||
uint32_t opFClamp(
|
||||
uint32_t resultType,
|
||||
uint32_t x,
|
||||
|
Loading…
x
Reference in New Issue
Block a user