[GPU/D3D12] Update tessellation enums

This commit is contained in:
Triang3l 2018-12-19 18:23:54 +03:00
parent cbba86fcf0
commit c84511a5f1
4 changed files with 23 additions and 23 deletions

View File

@ -1207,20 +1207,20 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type,
render_target_cache_->GetCurrentPipelineRenderTargets(); render_target_cache_->GetCurrentPipelineRenderTargets();
bool indexed = index_buffer_info != nullptr && index_buffer_info->guest_base; bool indexed = index_buffer_info != nullptr && index_buffer_info->guest_base;
// Per-edge tessellation requires an index buffer, but it contains per-edge // Adaptive tessellation requires an index buffer, but it contains per-edge
// tessellation factors (as floats) in it instead of control point indices. // tessellation factors (as floats) in it instead of control point indices.
bool per_edge_tessellation; bool adaptive_tessellation;
if (primitive_type == PrimitiveType::kTrianglePatch || if (primitive_type == PrimitiveType::kTrianglePatch ||
primitive_type == PrimitiveType::kQuadPatch) { primitive_type == PrimitiveType::kQuadPatch) {
TessellationMode tessellation_mode = TessellationMode tessellation_mode =
TessellationMode(regs[XE_GPU_REG_VGT_HOS_CNTL].u32 & 0x3); TessellationMode(regs[XE_GPU_REG_VGT_HOS_CNTL].u32 & 0x3);
per_edge_tessellation = tessellation_mode == TessellationMode::kPerEdge; adaptive_tessellation = tessellation_mode == TessellationMode::kAdaptive;
if (per_edge_tessellation && if (adaptive_tessellation &&
(!indexed || index_buffer_info->format != IndexFormat::kInt32)) { (!indexed || index_buffer_info->format != IndexFormat::kInt32)) {
return false; return false;
} }
// TODO(Triang3l): Implement all tessellation modes if games using any other // TODO(Triang3l): Implement all tessellation modes if games using any other
// than per-edge are found. The biggest question about them is what is being // than adaptive are found. The biggest question about them is what is being
// passed to vertex shader registers, especially if patches are drawn with // passed to vertex shader registers, especially if patches are drawn with
// an index buffer. // an index buffer.
// https://www.slideshare.net/blackdevilvikas/next-generation-graphics-programming-on-xbox-360 // https://www.slideshare.net/blackdevilvikas/next-generation-graphics-programming-on-xbox-360
@ -1229,26 +1229,26 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type,
// for triangles though. // for triangles though.
// - Continuous: fractional_even partitioning, factors // - Continuous: fractional_even partitioning, factors
// VGT_HOS_MAX_TESS_LEVEL + 1. // VGT_HOS_MAX_TESS_LEVEL + 1.
// - Per-edge: fractional_even partitioning, edge factors are float values // - Adaptive: fractional_even partitioning, edge factors are float values
// in the index buffer clamped to VGT_HOS_MIN_TESS_LEVEL and // in the index buffer clamped to VGT_HOS_MIN_TESS_LEVEL and
// VGT_HOS_MAX_TESS_LEVEL, plus one, inner factor appears to be // VGT_HOS_MAX_TESS_LEVEL, plus one, inner factor appears to be
// the minimum of the two edge factors (but without adding 1) in // the minimum of the two edge factors (but without adding 1) in
// each direction. This relies on memexport in games heavily for // each direction. This relies on memexport in games heavily for
// generation of the factor buffer, in Halo 3 the buffer is not // generation of the factor buffer, in Halo 3 the buffer is not
// initialized at all before the memexport pass. // initialized at all before the memexport pass.
// Per-edge partitional is likely fractional because this presentation, // Adaptive partitioning is likely fractional because this presentation,
// though only mentioning the Xbox 360, demonstrates adaptive tessellation // though only mentioning the Xbox 360, demonstrates adaptive tessellation
// using fractional partitioning: // using fractional partitioning:
// http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.221.4656&rep=rep1&type=pdf // http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.221.4656&rep=rep1&type=pdf
if (tessellation_mode != TessellationMode::kPerEdge) { if (tessellation_mode != TessellationMode::kAdaptive) {
XELOGE( XELOGE(
"Tessellation mode %u is not implemented yet, only per-edge is " "Tessellation mode %u is not implemented yet, only adaptive is "
"partially available now - report the game to Xenia developers!", "partially available now - report the game to Xenia developers!",
uint32_t(tessellation_mode)); uint32_t(tessellation_mode));
return false; return false;
} }
} else { } else {
per_edge_tessellation = false; adaptive_tessellation = false;
} }
// TODO(Triang3l): Non-indexed line loops (by movc'ing zero to the vertex // TODO(Triang3l): Non-indexed line loops (by movc'ing zero to the vertex
@ -1396,7 +1396,7 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type,
shared_memory_->UseForReading(); shared_memory_->UseForReading();
command_list->IASetIndexBuffer(&index_buffer_view); command_list->IASetIndexBuffer(&index_buffer_view);
SubmitBarriers(); SubmitBarriers();
if (per_edge_tessellation) { if (adaptive_tessellation) {
// Index buffer used for per-edge factors. // Index buffer used for per-edge factors.
command_list->DrawInstanced(index_count, 1, 0, 0); command_list->DrawInstanced(index_count, 1, 0, 0);
} else { } else {

View File

@ -423,7 +423,7 @@ PipelineCache::UpdateStatus PipelineCache::UpdateShaderStages(
} else { } else {
update_desc_.HS.pShaderBytecode = continuous_triangle_hs; update_desc_.HS.pShaderBytecode = continuous_triangle_hs;
update_desc_.HS.BytecodeLength = sizeof(continuous_triangle_hs); update_desc_.HS.BytecodeLength = sizeof(continuous_triangle_hs);
// TODO(Triang3l): True per-edge tessellation when memexport is added. // TODO(Triang3l): True adaptive tessellation when memexport is added.
} }
break; break;
case PrimitiveType::kQuadPatch: case PrimitiveType::kQuadPatch:
@ -433,7 +433,7 @@ PipelineCache::UpdateStatus PipelineCache::UpdateShaderStages(
} else { } else {
update_desc_.HS.pShaderBytecode = continuous_quad_hs; update_desc_.HS.pShaderBytecode = continuous_quad_hs;
update_desc_.HS.BytecodeLength = sizeof(continuous_quad_hs); update_desc_.HS.BytecodeLength = sizeof(continuous_quad_hs);
// TODO(Triang3l): True per-edge tessellation when memexport is added. // TODO(Triang3l): True adaptive tessellation when memexport is added.
} }
break; break;
default: default:

View File

@ -527,7 +527,7 @@ void DxbcShaderTranslator::StartVertexOrDomainShader() {
// When using indexable temps, copy through a r# because x# are apparently // When using indexable temps, copy through a r# because x# are apparently
// only accessible via mov. // only accessible via mov.
// TODO(Triang3l): Investigate what should be written for primitives (or // TODO(Triang3l): Investigate what should be written for primitives (or
// even control points) for non-per-edge tessellation modes (they may // even control points) for non-adaptive tessellation modes (they may
// possibly have an index buffer). // possibly have an index buffer).
uint32_t primitive_id_gpr_index = uint32_t primitive_id_gpr_index =
vertex_shader_type_ == VertexShaderType::kTriangleDomain ? 1 : 0; vertex_shader_type_ == VertexShaderType::kTriangleDomain ? 1 : 0;

View File

@ -36,23 +36,23 @@ enum class PrimitiveType : uint32_t {
kQuadList = 0x0D, kQuadList = 0x0D,
kQuadStrip = 0x0E, kQuadStrip = 0x0E,
kPolygon = 0x0F, kPolygon = 0x0F,
// These are from Adreno 2xx, and also exist on R600, but on Xenos, these k2DCopyRectListV0 = 0x10,
// don't exist or have different values ( k2DCopyRectListV1 = 0x11,
// k2DCopyRectListV0 = 0x10, k2DCopyRectListV2 = 0x12,
// k2DCopyRectListV1 = 0x11, k2DCopyRectListV3 = 0x13,
// k2DCopyRectListV2 = 0x12,
// k2DCopyRectListV3 = 0x13,
kTrianglePatch = 0x11,
kQuadPatch = 0x12,
k2DFillRectList = 0x14, k2DFillRectList = 0x14,
k2DLineStrip = 0x15, k2DLineStrip = 0x15,
k2DTriStrip = 0x16, k2DTriStrip = 0x16,
// Tessellation patches (D3DTPT) - reusing 2DCopyRectList types.
kLinePatch = 0x10,
kTrianglePatch = 0x11,
kQuadPatch = 0x12,
}; };
enum class TessellationMode : uint32_t { enum class TessellationMode : uint32_t {
kDiscrete = 0, kDiscrete = 0,
kContinuous = 1, kContinuous = 1,
kPerEdge = 2, kAdaptive = 2,
}; };
enum class Dimension : uint32_t { enum class Dimension : uint32_t {