mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +01:00
[dxbc] oDepth no longer treated as standard output register
Fixes a crash in the shader compiler when starting up Tomb Raider.
This commit is contained in:
parent
f97ea7fcea
commit
64a74735f8
@ -207,81 +207,92 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
void DxbcCompiler::emitDclInterfaceReg(const DxbcShaderInstruction& ins) {
|
void DxbcCompiler::emitDclInterfaceReg(const DxbcShaderInstruction& ins) {
|
||||||
// dcl_input and dcl_output instructions
|
switch (ins.dst[0].type) {
|
||||||
// have the following operands:
|
case DxbcOperandType::Input:
|
||||||
// (dst0) The register to declare
|
case DxbcOperandType::Output: {
|
||||||
// (imm0) The system value (optional)
|
// dcl_input and dcl_output instructions
|
||||||
uint32_t regDim = 0;
|
// have the following operands:
|
||||||
uint32_t regIdx = 0;
|
// (dst0) The register to declare
|
||||||
|
// (imm0) The system value (optional)
|
||||||
|
uint32_t regDim = 0;
|
||||||
|
uint32_t regIdx = 0;
|
||||||
|
|
||||||
// In the vertex and fragment shader stage, the
|
// In the vertex and fragment shader stage, the
|
||||||
// operand indices will have the following format:
|
// operand indices will have the following format:
|
||||||
// (0) Register index
|
// (0) Register index
|
||||||
//
|
//
|
||||||
// In other stages, the input and output registers
|
// In other stages, the input and output registers
|
||||||
// may be declared as arrays of a fixed size:
|
// may be declared as arrays of a fixed size:
|
||||||
// (0) Array length
|
// (0) Array length
|
||||||
// (1) Register index
|
// (1) Register index
|
||||||
if (ins.dst[0].idxDim == 2) {
|
if (ins.dst[0].idxDim == 2) {
|
||||||
regDim = ins.dst[0].idx[0].offset;
|
regDim = ins.dst[0].idx[0].offset;
|
||||||
regIdx = ins.dst[0].idx[1].offset;
|
regIdx = ins.dst[0].idx[1].offset;
|
||||||
} else if (ins.dst[0].idxDim == 1) {
|
} else if (ins.dst[0].idxDim == 1) {
|
||||||
regIdx = ins.dst[0].idx[0].offset;
|
regIdx = ins.dst[0].idx[0].offset;
|
||||||
} else {
|
} else {
|
||||||
Logger::err(str::format(
|
Logger::err(str::format(
|
||||||
"DxbcCompiler: ", ins.op,
|
"DxbcCompiler: ", ins.op,
|
||||||
": Invalid index dimension"));
|
": Invalid index dimension"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This declaration may map an output register to a system
|
// This declaration may map an output register to a system
|
||||||
// value. If that is the case, the system value type will
|
// value. If that is the case, the system value type will
|
||||||
// be stored in the second operand.
|
// be stored in the second operand.
|
||||||
const bool hasSv =
|
const bool hasSv =
|
||||||
ins.op == DxbcOpcode::DclInputSgv
|
ins.op == DxbcOpcode::DclInputSgv
|
||||||
|| ins.op == DxbcOpcode::DclInputSiv
|
|| ins.op == DxbcOpcode::DclInputSiv
|
||||||
|| ins.op == DxbcOpcode::DclInputPsSgv
|
|| ins.op == DxbcOpcode::DclInputPsSgv
|
||||||
|| ins.op == DxbcOpcode::DclInputPsSiv
|
|| ins.op == DxbcOpcode::DclInputPsSiv
|
||||||
|| ins.op == DxbcOpcode::DclOutputSgv
|
|| ins.op == DxbcOpcode::DclOutputSgv
|
||||||
|| ins.op == DxbcOpcode::DclOutputSiv;
|
|| ins.op == DxbcOpcode::DclOutputSiv;
|
||||||
|
|
||||||
DxbcSystemValue sv = DxbcSystemValue::None;
|
DxbcSystemValue sv = DxbcSystemValue::None;
|
||||||
|
|
||||||
if (hasSv)
|
if (hasSv)
|
||||||
sv = static_cast<DxbcSystemValue>(ins.imm[0].u32);
|
sv = static_cast<DxbcSystemValue>(ins.imm[0].u32);
|
||||||
|
|
||||||
// In the pixel shader, inputs are declared with an
|
// In the pixel shader, inputs are declared with an
|
||||||
// interpolation mode that is part of the op token.
|
// interpolation mode that is part of the op token.
|
||||||
const bool hasInterpolationMode =
|
const bool hasInterpolationMode =
|
||||||
ins.op == DxbcOpcode::DclInputPs
|
ins.op == DxbcOpcode::DclInputPs
|
||||||
|| ins.op == DxbcOpcode::DclInputPsSiv;
|
|| ins.op == DxbcOpcode::DclInputPsSiv;
|
||||||
|
|
||||||
DxbcInterpolationMode im = DxbcInterpolationMode::Undefined;
|
DxbcInterpolationMode im = DxbcInterpolationMode::Undefined;
|
||||||
|
|
||||||
if (hasInterpolationMode)
|
if (hasInterpolationMode)
|
||||||
im = ins.controls.interpolation;
|
im = ins.controls.interpolation;
|
||||||
|
|
||||||
// Declare the actual input/output variable
|
// Declare the actual input/output variable
|
||||||
switch (ins.op) {
|
switch (ins.op) {
|
||||||
case DxbcOpcode::DclInput:
|
case DxbcOpcode::DclInput:
|
||||||
case DxbcOpcode::DclInputSgv:
|
case DxbcOpcode::DclInputSgv:
|
||||||
case DxbcOpcode::DclInputSiv:
|
case DxbcOpcode::DclInputSiv:
|
||||||
case DxbcOpcode::DclInputPs:
|
case DxbcOpcode::DclInputPs:
|
||||||
case DxbcOpcode::DclInputPsSgv:
|
case DxbcOpcode::DclInputPsSgv:
|
||||||
case DxbcOpcode::DclInputPsSiv:
|
case DxbcOpcode::DclInputPsSiv:
|
||||||
this->emitDclInput(regIdx, regDim, ins.dst[0].mask, sv, im);
|
this->emitDclInput(regIdx, regDim, ins.dst[0].mask, sv, im);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DxbcOpcode::DclOutput:
|
case DxbcOpcode::DclOutput:
|
||||||
case DxbcOpcode::DclOutputSgv:
|
case DxbcOpcode::DclOutputSgv:
|
||||||
case DxbcOpcode::DclOutputSiv:
|
case DxbcOpcode::DclOutputSiv:
|
||||||
this->emitDclOutput(regIdx, regDim, ins.dst[0].mask, sv, im);
|
this->emitDclOutput(regIdx, regDim, ins.dst[0].mask, sv, im);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Logger::err(str::format(
|
||||||
|
"DxbcCompiler: Unexpected opcode: ",
|
||||||
|
ins.op));
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Logger::err(str::format(
|
Logger::err(str::format(
|
||||||
"DxbcCompiler: Unexpected opcode: ",
|
"DxbcCompiler: Unsupported operand type declaration: ",
|
||||||
ins.op));
|
ins.dst[0].type));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1958,7 +1969,8 @@ namespace dxvk {
|
|||||||
// documentation, they are required to match the type of
|
// documentation, they are required to match the type of
|
||||||
// the render target.
|
// the render target.
|
||||||
for (auto e = m_osgn->begin(); e != m_osgn->end(); e++) {
|
for (auto e = m_osgn->begin(); e != m_osgn->end(); e++) {
|
||||||
if (e->systemValue == DxbcSystemValue::None) {
|
if (e->systemValue == DxbcSystemValue::None
|
||||||
|
&& e->registerId != 0xFFFFFFFF /* depth */) {
|
||||||
DxbcRegisterInfo info;
|
DxbcRegisterInfo info;
|
||||||
info.type.ctype = e->componentType;
|
info.type.ctype = e->componentType;
|
||||||
info.type.ccount = e->componentMask.setCount();
|
info.type.ccount = e->componentMask.setCount();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user