[GPU/D3D12] Update tessellation enums
This commit is contained in:
parent
cbba86fcf0
commit
c84511a5f1
|
@ -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 {
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue