1
0
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:
Philip Rebohle 2017-12-20 23:50:39 +01:00
parent 6ff709513c
commit 109ce0a695
8 changed files with 255 additions and 17 deletions

View File

@ -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]

View File

@ -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: ",

View File

@ -328,6 +328,9 @@ namespace dxvk {
void emitVectorImul(
const DxbcShaderInstruction& ins);
void emitVectorShift(
const DxbcShaderInstruction& ins);
void emitVectorSinCos(
const DxbcShaderInstruction& ins);

View File

@ -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;

View File

@ -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 },

View File

@ -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
};

View File

@ -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;

View File

@ -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,