From c84511a5f12d7b401b77055aceb2e53727a8bc37 Mon Sep 17 00:00:00 2001 From: Triang3l Date: Wed, 19 Dec 2018 18:23:54 +0300 Subject: [PATCH] [GPU/D3D12] Update tessellation enums --- .../gpu/d3d12/d3d12_command_processor.cc | 22 +++++++++---------- src/xenia/gpu/d3d12/pipeline_cache.cc | 4 ++-- src/xenia/gpu/dxbc_shader_translator.cc | 2 +- src/xenia/gpu/xenos.h | 18 +++++++-------- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/xenia/gpu/d3d12/d3d12_command_processor.cc b/src/xenia/gpu/d3d12/d3d12_command_processor.cc index bbd41da63..f4f88d061 100644 --- a/src/xenia/gpu/d3d12/d3d12_command_processor.cc +++ b/src/xenia/gpu/d3d12/d3d12_command_processor.cc @@ -1207,20 +1207,20 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type, render_target_cache_->GetCurrentPipelineRenderTargets(); 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. - bool per_edge_tessellation; + bool adaptive_tessellation; if (primitive_type == PrimitiveType::kTrianglePatch || primitive_type == PrimitiveType::kQuadPatch) { TessellationMode tessellation_mode = TessellationMode(regs[XE_GPU_REG_VGT_HOS_CNTL].u32 & 0x3); - per_edge_tessellation = tessellation_mode == TessellationMode::kPerEdge; - if (per_edge_tessellation && + adaptive_tessellation = tessellation_mode == TessellationMode::kAdaptive; + if (adaptive_tessellation && (!indexed || index_buffer_info->format != IndexFormat::kInt32)) { return false; } // 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 // an index buffer. // 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. // - Continuous: fractional_even partitioning, factors // 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 // VGT_HOS_MAX_TESS_LEVEL, plus one, inner factor appears to be // the minimum of the two edge factors (but without adding 1) in // each direction. This relies on memexport in games heavily for // generation of the factor buffer, in Halo 3 the buffer is not // 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 // using fractional partitioning: // 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( - "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!", uint32_t(tessellation_mode)); return false; } } else { - per_edge_tessellation = false; + adaptive_tessellation = false; } // 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(); command_list->IASetIndexBuffer(&index_buffer_view); SubmitBarriers(); - if (per_edge_tessellation) { + if (adaptive_tessellation) { // Index buffer used for per-edge factors. command_list->DrawInstanced(index_count, 1, 0, 0); } else { diff --git a/src/xenia/gpu/d3d12/pipeline_cache.cc b/src/xenia/gpu/d3d12/pipeline_cache.cc index e0b203c34..4ee1f1461 100644 --- a/src/xenia/gpu/d3d12/pipeline_cache.cc +++ b/src/xenia/gpu/d3d12/pipeline_cache.cc @@ -423,7 +423,7 @@ PipelineCache::UpdateStatus PipelineCache::UpdateShaderStages( } else { update_desc_.HS.pShaderBytecode = 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; case PrimitiveType::kQuadPatch: @@ -433,7 +433,7 @@ PipelineCache::UpdateStatus PipelineCache::UpdateShaderStages( } else { update_desc_.HS.pShaderBytecode = 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; default: diff --git a/src/xenia/gpu/dxbc_shader_translator.cc b/src/xenia/gpu/dxbc_shader_translator.cc index 81329b047..e6be3c805 100644 --- a/src/xenia/gpu/dxbc_shader_translator.cc +++ b/src/xenia/gpu/dxbc_shader_translator.cc @@ -527,7 +527,7 @@ void DxbcShaderTranslator::StartVertexOrDomainShader() { // When using indexable temps, copy through a r# because x# are apparently // only accessible via mov. // 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). uint32_t primitive_id_gpr_index = vertex_shader_type_ == VertexShaderType::kTriangleDomain ? 1 : 0; diff --git a/src/xenia/gpu/xenos.h b/src/xenia/gpu/xenos.h index 1935a47f3..b661342d6 100644 --- a/src/xenia/gpu/xenos.h +++ b/src/xenia/gpu/xenos.h @@ -36,23 +36,23 @@ enum class PrimitiveType : uint32_t { kQuadList = 0x0D, kQuadStrip = 0x0E, kPolygon = 0x0F, - // These are from Adreno 2xx, and also exist on R600, but on Xenos, these - // don't exist or have different values ( - // k2DCopyRectListV0 = 0x10, - // k2DCopyRectListV1 = 0x11, - // k2DCopyRectListV2 = 0x12, - // k2DCopyRectListV3 = 0x13, - kTrianglePatch = 0x11, - kQuadPatch = 0x12, + k2DCopyRectListV0 = 0x10, + k2DCopyRectListV1 = 0x11, + k2DCopyRectListV2 = 0x12, + k2DCopyRectListV3 = 0x13, k2DFillRectList = 0x14, k2DLineStrip = 0x15, k2DTriStrip = 0x16, + // Tessellation patches (D3DTPT) - reusing 2DCopyRectList types. + kLinePatch = 0x10, + kTrianglePatch = 0x11, + kQuadPatch = 0x12, }; enum class TessellationMode : uint32_t { kDiscrete = 0, kContinuous = 1, - kPerEdge = 2, + kAdaptive = 2, }; enum class Dimension : uint32_t {