[D3D12] Non-adaptive quad tessellation
This commit is contained in:
parent
e6068e0d64
commit
f83809f7a1
|
@ -1358,6 +1358,7 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type,
|
||||||
case PrimitiveType::kTrianglePatch:
|
case PrimitiveType::kTrianglePatch:
|
||||||
primitive_topology = D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST;
|
primitive_topology = D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST;
|
||||||
break;
|
break;
|
||||||
|
case PrimitiveType::kQuadList:
|
||||||
case PrimitiveType::kQuadPatch:
|
case PrimitiveType::kQuadPatch:
|
||||||
primitive_topology = D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST;
|
primitive_topology = D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -769,6 +769,19 @@ Shader::HostVertexShaderType PipelineCache::GetHostVertexShaderTypeIfValid()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case PrimitiveType::kQuadList:
|
||||||
|
switch (tessellation_mode) {
|
||||||
|
// Also supported by quad strips according to:
|
||||||
|
// https://www.khronos.org/registry/OpenGL/extensions/AMD/AMD_vertex_shader_tessellator.txt
|
||||||
|
// Would need to convert those to quad lists, but haven't seen any games
|
||||||
|
// using tessellated strips so far.
|
||||||
|
case xenos::TessellationMode::kContinuous:
|
||||||
|
// - Defender - retro screen and beams in the main menu - kQuadList.
|
||||||
|
return Shader::HostVertexShaderType::kQuadDomainConstant;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case PrimitiveType::kTrianglePatch:
|
case PrimitiveType::kTrianglePatch:
|
||||||
if (tessellation_mode == xenos::TessellationMode::kAdaptive) {
|
if (tessellation_mode == xenos::TessellationMode::kAdaptive) {
|
||||||
// - Banjo-Kazooie: Nuts & Bolts - water.
|
// - Banjo-Kazooie: Nuts & Bolts - water.
|
||||||
|
|
|
@ -530,6 +530,40 @@ void DxbcShaderTranslator::StartVertexOrDomainShader() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Shader::HostVertexShaderType::kQuadDomainConstant:
|
||||||
|
assert_true(register_count() >= 2);
|
||||||
|
if (register_count() >= 1) {
|
||||||
|
// Copy the domain location to r0.xy.
|
||||||
|
DxbcOpMov(uses_register_dynamic_addressing() ? DxbcDest::X(0, 0, 0b0011)
|
||||||
|
: DxbcDest::R(0, 0b0011),
|
||||||
|
DxbcSrc::VDomain());
|
||||||
|
// Control point indices according to the shader from the main menu of
|
||||||
|
// Defender, which starts from `cndeq r2, c255.xxxy, r1.xyzz, r0.zzzz`,
|
||||||
|
// where c255.x is 0, and c255.y is 1.
|
||||||
|
// r0.z for (1 - r0.x) * (1 - r0.y)
|
||||||
|
// r1.x for r0.x * (1 - r0.y)
|
||||||
|
// r1.y for r0.x * r0.y
|
||||||
|
// r1.z for (1 - r0.x) * r0.y
|
||||||
|
DxbcOpMov(
|
||||||
|
uses_register_dynamic_addressing() ? DxbcDest::X(0, 0, 0b0100)
|
||||||
|
: DxbcDest::R(0, 0b0100),
|
||||||
|
DxbcSrc::VICP(0, uint32_t(InOutRegister::kDSInControlPointIndex),
|
||||||
|
DxbcSrc::kXXXX));
|
||||||
|
if (register_count() >= 2) {
|
||||||
|
DxbcDest r1_dest(uses_register_dynamic_addressing()
|
||||||
|
? DxbcDest::X(0, 1)
|
||||||
|
: DxbcDest::R(1));
|
||||||
|
for (uint32_t i = 0; i < 3; ++i) {
|
||||||
|
DxbcOpMov(
|
||||||
|
r1_dest.Mask(1 << i),
|
||||||
|
DxbcSrc::VICP(1 + i,
|
||||||
|
uint32_t(InOutRegister::kDSInControlPointIndex),
|
||||||
|
DxbcSrc::kXXXX));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case Shader::HostVertexShaderType::kQuadDomainAdaptive:
|
case Shader::HostVertexShaderType::kQuadDomainAdaptive:
|
||||||
assert_true(register_count() >= 2);
|
assert_true(register_count() >= 2);
|
||||||
if (register_count() >= 1) {
|
if (register_count() >= 1) {
|
||||||
|
|
Loading…
Reference in New Issue