[dxbc] Implemented more tessellation-related declarations

This commit is contained in:
Philip Rebohle 2018-03-01 14:36:17 +01:00
parent feba1f0e88
commit 3dea58dabc
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
6 changed files with 124 additions and 5 deletions

View File

@ -260,6 +260,15 @@ namespace dxvk {
case DxbcOpcode::DclOutputControlPointCount:
return this->emitDclOutputControlPointCount(ins);
case DxbcOpcode::DclTessDomain:
return this->emitDclTessDomain(ins);
case DxbcOpcode::DclTessPartitioning:
return this->emitDclTessPartitioning(ins);
case DxbcOpcode::DclTessOutputPrimitive:
return this->emitDclTessOutputPrimitive(ins);
case DxbcOpcode::DclThreadGroup:
return this->emitDclThreadGroup(ins);
@ -1057,18 +1066,76 @@ namespace dxvk {
// dcl_max_output_vertex_count has one operand:
// (imm0) The maximum number of vertices
m_gs.outputVertexCount = ins.imm[0].u32;
m_module.setOutputVertices(m_entryPointId, m_gs.outputVertexCount);
}
void DxbcCompiler::emitDclInputControlPointCount(const DxbcShaderInstruction& ins) {
// dcl_input_control_points has the control point
// count embedded within the opcode token.
m_hs.vertexCountIn = ins.controls.controlPointCount;
}
void DxbcCompiler::emitDclOutputControlPointCount(const DxbcShaderInstruction& ins) {
m_module.setOutputVertices(m_entryPointId, ins.controls.controlPointCount);
// dcl_output_control_points has the control point
// count embedded within the opcode token.
m_hs.vertexCountOut = ins.controls.controlPointCount;
m_module.setOutputVertices(m_entryPointId, ins.controls.controlPointCount);
}
void DxbcCompiler::emitDclTessDomain(const DxbcShaderInstruction& ins) {
const spv::ExecutionMode executionMode = [&] {
switch (ins.controls.tessDomain) {
case DxbcTessDomain::Isolines: return spv::ExecutionModeIsolines;
case DxbcTessDomain::Triangles: return spv::ExecutionModeTriangles;
case DxbcTessDomain::Quads: return spv::ExecutionModeQuads;
default: throw DxvkError("Dxbc: Invalid tess domain");
}
}();
m_module.setExecutionMode(m_entryPointId, executionMode);
}
void DxbcCompiler::emitDclTessPartitioning(const DxbcShaderInstruction& ins) {
const spv::ExecutionMode executionMode = [&] {
switch (ins.controls.tessPartitioning) {
case DxbcTessPartitioning::Pow2:
case DxbcTessPartitioning::Integer: return spv::ExecutionModeSpacingEqual;
case DxbcTessPartitioning::FractOdd: return spv::ExecutionModeSpacingFractionalOdd;
case DxbcTessPartitioning::FractEven: return spv::ExecutionModeSpacingFractionalEven;
default: throw DxvkError("Dxbc: Invalid tess partitioning");
}
}();
m_module.setExecutionMode(m_entryPointId, executionMode);
}
void DxbcCompiler::emitDclTessOutputPrimitive(const DxbcShaderInstruction& ins) {
switch (ins.controls.tessOutputPrimitive) {
case DxbcTessOutputPrimitive::Point:
m_module.setExecutionMode(m_entryPointId, spv::ExecutionModePointMode);
break;
case DxbcTessOutputPrimitive::Line:
break;
case DxbcTessOutputPrimitive::TriangleCw:
m_module.setExecutionMode(m_entryPointId, spv::ExecutionModeVertexOrderCw);
break;
case DxbcTessOutputPrimitive::TriangleCcw:
m_module.setExecutionMode(m_entryPointId, spv::ExecutionModeVertexOrderCcw);
break;
default:
throw DxvkError("Dxbc: Invalid tess output primitive");
}
}

View File

@ -464,6 +464,15 @@ namespace dxvk {
void emitDclOutputControlPointCount(
const DxbcShaderInstruction& ins);
void emitDclTessDomain(
const DxbcShaderInstruction& ins);
void emitDclTessPartitioning(
const DxbcShaderInstruction& ins);
void emitDclTessOutputPrimitive(
const DxbcShaderInstruction& ins);
void emitDclThreadGroup(
const DxbcShaderInstruction& ins);

View File

@ -105,7 +105,9 @@ namespace dxvk {
m_instruction.modifiers.saturate = !!bit::extract(token, 13, 13);
m_instruction.modifiers.precise = !!bit::extract(token, 19, 22);
// Opcode controls. It will depend on the opcode itself which ones are valid.
// Opcode controls. It will depend on the
// opcode itself which ones are valid.
// TODO refactor this nonsense
m_instruction.controls.globalFlags =
static_cast<DxbcGlobalFlag>(bit::extract(token, 11, 14));
m_instruction.controls.zeroTest =
@ -124,6 +126,12 @@ namespace dxvk {
static_cast<DxbcPrimitiveTopology>(bit::extract(token, 11, 17));
m_instruction.controls.primitive =
static_cast<DxbcPrimitive>(bit::extract(token, 11, 16));
m_instruction.controls.tessDomain =
static_cast<DxbcTessDomain>(bit::extract(token, 11, 12));
m_instruction.controls.tessOutputPrimitive =
static_cast<DxbcTessOutputPrimitive>(bit::extract(token, 11, 13));
m_instruction.controls.tessPartitioning =
static_cast<DxbcTessPartitioning>(bit::extract(token, 11, 13));
m_instruction.controls.controlPointCount =
static_cast<uint32_t>(bit::extract(token, 11, 16));

View File

@ -251,6 +251,9 @@ namespace dxvk {
DxbcSamplerMode samplerMode;
DxbcPrimitiveTopology primitiveTopology;
DxbcPrimitive primitive;
DxbcTessDomain tessDomain;
DxbcTessOutputPrimitive tessOutputPrimitive;
DxbcTessPartitioning tessPartitioning;
uint32_t controlPointCount;
};

View File

@ -720,11 +720,11 @@ namespace dxvk {
/* DclOutputControlPointCount */
{ 0, DxbcInstClass::Declaration },
/* DclTessDomain */
{ },
{ 0, DxbcInstClass::Declaration },
/* DclTessPartitioning */
{ },
{ 0, DxbcInstClass::Declaration },
/* DclTessOutputPrimitive */
{ },
{ 0, DxbcInstClass::Declaration },
/* DclHsMaxTessFactor */
{ },
/* DclHsForkPhaseInstanceCount */

View File

@ -547,6 +547,38 @@ namespace dxvk {
};
/**
* \brief Tessellator domain
*/
enum class DxbcTessDomain : uint32_t {
Undefined = 0,
Isolines = 1,
Triangles = 2,
Quads = 3,
};
/**
* \brief Tessellator partitioning
*/
enum class DxbcTessPartitioning : uint32_t {
Undefined = 0,
Integer = 1,
Pow2 = 2,
FractOdd = 3,
FractEven = 4,
};
/**
* \brief Tessellator output primitive
*/
enum class DxbcTessOutputPrimitive : uint32_t {
Undefined = 0,
Point = 1,
Line = 2,
TriangleCw = 3,
TriangleCcw = 4,
};
/**
* \brief Custom data class
*