diff --git a/src/xenia/gpu/d3d12/d3d12_command_processor.cc b/src/xenia/gpu/d3d12/d3d12_command_processor.cc index 1bdc8257e..e17652797 100644 --- a/src/xenia/gpu/d3d12/d3d12_command_processor.cc +++ b/src/xenia/gpu/d3d12/d3d12_command_processor.cc @@ -55,11 +55,6 @@ DEFINE_bool(d3d12_submit_on_primary_buffer_end, true, "Submit the command list when a PM4 primary buffer ends if it's " "possible to submit immediately to try to reduce frame latency.", "D3D12"); -DEFINE_bool( - d3d12_tessellation_adaptive, true, - "Allow games to use adaptive tessellation - may be disabled if the game " - "has issues with memexport, the maximum factor will be used in this case.", - "D3D12"); namespace xe { namespace gpu { @@ -1351,17 +1346,6 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type, // Set up primitive topology. bool indexed = index_buffer_info != nullptr && index_buffer_info->guest_base; - bool adaptive_tessellation = - host_vertex_shader_type == - Shader::HostVertexShaderType::kLineDomainAdaptive || - host_vertex_shader_type == - Shader::HostVertexShaderType::kTriangleDomainAdaptive || - host_vertex_shader_type == - Shader::HostVertexShaderType::kQuadDomainAdaptive; - // Adaptive tessellation requires an index buffer, but it contains per-edge - // tessellation factors (as floats) instead of control point indices. - assert_true(!adaptive_tessellation || - (indexed && index_buffer_info->format == IndexFormat::kInt32)); PrimitiveType primitive_type_converted; D3D_PRIMITIVE_TOPOLOGY primitive_topology; if (tessellated) { @@ -1461,9 +1445,8 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type, // Update system constants before uploading them. UpdateSystemConstantValues( memexport_used, primitive_two_faced, line_loop_closing_index, - indexed ? index_buffer_info->endianness : Endian::kNone, - adaptive_tessellation, early_z, GetCurrentColorMask(pixel_shader), - pipeline_render_targets); + indexed ? index_buffer_info->endianness : Endian::kNone, early_z, + GetCurrentColorMask(pixel_shader), pipeline_render_targets); // Update constant buffers, descriptors and root parameters. if (!UpdateBindings(vertex_shader, pixel_shader, root_signature)) { @@ -2320,8 +2303,8 @@ void D3D12CommandProcessor::UpdateFixedFunctionState(bool primitive_two_faced) { void D3D12CommandProcessor::UpdateSystemConstantValues( bool shared_memory_is_uav, bool primitive_two_faced, - uint32_t line_loop_closing_index, Endian index_endian, - bool adaptive_tessellation, bool early_z, uint32_t color_mask, + uint32_t line_loop_closing_index, Endian index_endian, bool early_z, + uint32_t color_mask, const RenderTargetCache::PipelineRenderTarget render_targets[4]) { auto& regs = *register_file_; @@ -2345,8 +2328,7 @@ void D3D12CommandProcessor::UpdateSystemConstantValues( auto rb_surface_info = regs.Get(); auto sq_context_misc = regs.Get(); auto sq_program_cntl = regs.Get(); - int32_t vgt_indx_offset = - adaptive_tessellation ? 0 : int32_t(regs[XE_GPU_REG_VGT_INDX_OFFSET].u32); + int32_t vgt_indx_offset = int32_t(regs[XE_GPU_REG_VGT_INDX_OFFSET].u32); // Get the color info register values for each render target, and also put // some safety measures for the ROV path - disable fully aliased render @@ -2500,10 +2482,6 @@ void D3D12CommandProcessor::UpdateSystemConstantValues( regs[XE_GPU_REG_VGT_HOS_MIN_TESS_LEVEL].f32 + 1.0f; float tessellation_factor_max = regs[XE_GPU_REG_VGT_HOS_MAX_TESS_LEVEL].f32 + 1.0f; - if (adaptive_tessellation && !cvars::d3d12_tessellation_adaptive) { - // Make clamping force the factor to a single value the maximum. - tessellation_factor_min = tessellation_factor_max; - } dirty |= system_constants_.tessellation_factor_range_min != tessellation_factor_min; system_constants_.tessellation_factor_range_min = tessellation_factor_min; diff --git a/src/xenia/gpu/d3d12/d3d12_command_processor.h b/src/xenia/gpu/d3d12/d3d12_command_processor.h index d5bd3e3a8..644709949 100644 --- a/src/xenia/gpu/d3d12/d3d12_command_processor.h +++ b/src/xenia/gpu/d3d12/d3d12_command_processor.h @@ -256,8 +256,8 @@ class D3D12CommandProcessor : public CommandProcessor { void UpdateFixedFunctionState(bool primitive_two_faced); void UpdateSystemConstantValues( bool shared_memory_is_uav, bool primitive_two_faced, - uint32_t line_loop_closing_index, Endian index_endian, - bool adaptive_tessellation, bool early_z, uint32_t color_mask, + uint32_t line_loop_closing_index, Endian index_endian, bool early_z, + uint32_t color_mask, const RenderTargetCache::PipelineRenderTarget render_targets[4]); bool UpdateBindings(const D3D12Shader* vertex_shader, const D3D12Shader* pixel_shader, diff --git a/src/xenia/gpu/d3d12/pipeline_cache.cc b/src/xenia/gpu/d3d12/pipeline_cache.cc index 2f62c3656..a13acb61a 100644 --- a/src/xenia/gpu/d3d12/pipeline_cache.cc +++ b/src/xenia/gpu/d3d12/pipeline_cache.cc @@ -50,6 +50,7 @@ namespace gpu { namespace d3d12 { // Generated with `xb buildhlsl`. +#include "xenia/gpu/d3d12/shaders/dxbc/adaptive_quad_hs.h" #include "xenia/gpu/d3d12/shaders/dxbc/adaptive_triangle_hs.h" #include "xenia/gpu/d3d12/shaders/dxbc/continuous_quad_hs.h" #include "xenia/gpu/d3d12/shaders/dxbc/continuous_triangle_hs.h" @@ -761,7 +762,7 @@ Shader::HostVertexShaderType PipelineCache::GetHostVertexShaderTypeIfValid() break; case PrimitiveType::kQuadPatch: if (tessellation_mode == xenos::TessellationMode::kAdaptive) { - // - Viva Pinata - something on the start screen. + // - Viva Pinata - garden ground. return Shader::HostVertexShaderType::kQuadDomainAdaptive; } break; @@ -1493,6 +1494,10 @@ ID3D12PipelineState* PipelineCache::CreateD3D12PipelineState( state_desc.HS.pShaderBytecode = adaptive_triangle_hs; state_desc.HS.BytecodeLength = sizeof(adaptive_triangle_hs); break; + case Shader::HostVertexShaderType::kQuadDomainAdaptive: + state_desc.HS.pShaderBytecode = adaptive_quad_hs; + state_desc.HS.BytecodeLength = sizeof(adaptive_quad_hs); + break; default: assert_unhandled_case(host_vertex_shader_type); return nullptr; diff --git a/src/xenia/gpu/d3d12/shaders/adaptive_quad.hs.hlsl b/src/xenia/gpu/d3d12/shaders/adaptive_quad.hs.hlsl new file mode 100644 index 000000000..16396955a --- /dev/null +++ b/src/xenia/gpu/d3d12/shaders/adaptive_quad.hs.hlsl @@ -0,0 +1,54 @@ +#include "xenos_draw.hlsli" + +struct XeHSConstantDataOutput { + float edges[4] : SV_TessFactor; + float inside[2] : SV_InsideTessFactor; +}; + +XeHSConstantDataOutput XePatchConstant( + InputPatch xe_input_patch) { + XeHSConstantDataOutput output = (XeHSConstantDataOutput)0; + uint i; + + // 1.0 already added to the factor on the CPU, according to the images in + // https://www.slideshare.net/blackdevilvikas/next-generation-graphics-programming-on-xbox-360 + // (fractional_even also requires a factor of at least 2.0). + + // Direct3D 12 (goes in a direction along the perimeter): + // [0] - between U0V1 and U0V0. + // [1] - between U0V0 and U1V0. + // [2] - between U1V0 and U1V1. + // [3] - between U1V1 and U0V1. + // Xbox 360 factors go along the perimeter too according to the example of + // edge factors in Next Generation Graphics Programming on Xbox 360. + // However, if v0->v1... that seems to be working for triangle patches applies + // here too, with the swizzle Xenia uses in domain shaders: + // [0] - between U0V0 and U1V0. + // [1] - between U1V0 and U1V1. + // [2] - between U1V1 and U0V1. + // [3] - between U0V1 and U0V0. + [unroll] for (i = 0u; i < 4u; ++i) { + output.edges[i] = clamp( + asfloat(xe_input_patch[(i + 3u) & 3u].index_or_edge_factor) + 1.0f, + xe_tessellation_factor_range.x, xe_tessellation_factor_range.y); + } + + // Direct3D 12: + // [0] - along U. + // [1] - along V. + output.inside[0u] = min(output.edges[0u], output.edges[2u]); + output.inside[1u] = min(output.edges[1u], output.edges[3u]); + + return output; +} + +[domain("quad")] +[partitioning("fractional_even")] +[outputtopology("triangle_cw")] +[outputcontrolpoints(4)] +[patchconstantfunc("XePatchConstant")] +XeHSAdaptiveControlPointOutput main( + InputPatch xe_input_patch) { + XeHSAdaptiveControlPointOutput output; + return output; +} diff --git a/src/xenia/gpu/d3d12/shaders/adaptive_triangle.hs.hlsl b/src/xenia/gpu/d3d12/shaders/adaptive_triangle.hs.hlsl index 6b5368acc..b71dc55b6 100644 --- a/src/xenia/gpu/d3d12/shaders/adaptive_triangle.hs.hlsl +++ b/src/xenia/gpu/d3d12/shaders/adaptive_triangle.hs.hlsl @@ -5,8 +5,6 @@ struct XeHSConstantDataOutput { float inside : SV_InsideTessFactor; }; -struct XeAdaptiveHSControlPointOutput {}; - XeHSConstantDataOutput XePatchConstant( InputPatch xe_input_patch) { XeHSConstantDataOutput output = (XeHSConstantDataOutput)0; @@ -56,8 +54,8 @@ XeHSConstantDataOutput XePatchConstant( [outputtopology("triangle_cw")] [outputcontrolpoints(3)] [patchconstantfunc("XePatchConstant")] -XeAdaptiveHSControlPointOutput main( +XeHSAdaptiveControlPointOutput main( InputPatch xe_input_patch) { - XeAdaptiveHSControlPointOutput output; + XeHSAdaptiveControlPointOutput output; return output; } diff --git a/src/xenia/gpu/d3d12/shaders/dxbc/adaptive_quad_hs.cso b/src/xenia/gpu/d3d12/shaders/dxbc/adaptive_quad_hs.cso new file mode 100644 index 000000000..fe03d9b14 Binary files /dev/null and b/src/xenia/gpu/d3d12/shaders/dxbc/adaptive_quad_hs.cso differ diff --git a/src/xenia/gpu/d3d12/shaders/dxbc/adaptive_quad_hs.h b/src/xenia/gpu/d3d12/shaders/dxbc/adaptive_quad_hs.h new file mode 100644 index 000000000..4dd6e5f95 --- /dev/null +++ b/src/xenia/gpu/d3d12/shaders/dxbc/adaptive_quad_hs.h @@ -0,0 +1,310 @@ +// generated from `xb buildhlsl` +// source: adaptive_quad.hs.hlsl +const uint8_t adaptive_quad_hs[] = { + 0x44, 0x58, 0x42, 0x43, 0x3D, 0x2B, 0x63, 0xCD, 0x3D, 0x3C, 0x39, 0xC8, + 0xEE, 0xC1, 0xEC, 0x7B, 0xBC, 0x82, 0x12, 0x2A, 0x01, 0x00, 0x00, 0x00, + 0x50, 0x0E, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, + 0x30, 0x0A, 0x00, 0x00, 0x64, 0x0A, 0x00, 0x00, 0x74, 0x0A, 0x00, 0x00, + 0x38, 0x0B, 0x00, 0x00, 0xB4, 0x0D, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, + 0xF0, 0x09, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, 0x05, 0x53, 0x48, + 0x00, 0x05, 0x00, 0x00, 0xC6, 0x09, 0x00, 0x00, 0x13, 0x13, 0x44, 0x25, + 0x3C, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x65, 0x5F, 0x73, + 0x79, 0x73, 0x74, 0x65, 0x6D, 0x5F, 0x63, 0x62, 0x75, 0x66, 0x66, 0x65, + 0x72, 0x00, 0xAB, 0xAB, 0x64, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, + 0x90, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x74, 0x05, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x8F, 0x05, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xA6, 0x05, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x05, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x06, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x5C, 0x06, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x06, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x7B, 0x06, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xC0, 0x06, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x06, 0x00, 0x00, + 0x98, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xD8, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x07, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xD8, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x29, 0x07, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x68, 0x07, 0x00, 0x00, + 0xB0, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x07, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xA1, 0x07, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xB6, 0x07, 0x00, 0x00, + 0xBC, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xD1, 0x07, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xE4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x48, 0x08, 0x00, 0x00, + 0xE0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0xD8, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x65, 0x08, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xD8, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x7A, 0x08, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x95, 0x08, 0x00, 0x00, + 0xF8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xD8, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xAF, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xC0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xE4, 0x08, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, 0x09, 0x00, 0x00, + 0x30, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x1C, 0x09, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x54, 0x09, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, + 0xA0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xAE, 0x09, 0x00, 0x00, 0xB0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xE4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x78, 0x65, 0x5F, 0x66, 0x6C, 0x61, 0x67, 0x73, + 0x00, 0x64, 0x77, 0x6F, 0x72, 0x64, 0x00, 0xAB, 0x00, 0x00, 0x13, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x49, 0x05, 0x00, 0x00, 0x78, 0x65, 0x5F, 0x6C, + 0x69, 0x6E, 0x65, 0x5F, 0x6C, 0x6F, 0x6F, 0x70, 0x5F, 0x63, 0x6C, 0x6F, + 0x73, 0x69, 0x6E, 0x67, 0x5F, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x00, 0x78, + 0x65, 0x5F, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5F, 0x69, 0x6E, 0x64, + 0x65, 0x78, 0x5F, 0x65, 0x6E, 0x64, 0x69, 0x61, 0x6E, 0x00, 0x78, 0x65, + 0x5F, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5F, 0x62, 0x61, 0x73, 0x65, + 0x5F, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x00, 0x69, 0x6E, 0x74, 0x00, 0xAB, + 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBB, 0x05, 0x00, 0x00, + 0x78, 0x65, 0x5F, 0x75, 0x73, 0x65, 0x72, 0x5F, 0x63, 0x6C, 0x69, 0x70, + 0x5F, 0x70, 0x6C, 0x61, 0x6E, 0x65, 0x73, 0x00, 0x66, 0x6C, 0x6F, 0x61, + 0x74, 0x34, 0x00, 0xAB, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF8, 0x05, 0x00, 0x00, 0x78, 0x65, 0x5F, 0x6E, 0x64, 0x63, 0x5F, 0x73, + 0x63, 0x61, 0x6C, 0x65, 0x00, 0x66, 0x6C, 0x6F, 0x61, 0x74, 0x33, 0x00, + 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x06, 0x00, 0x00, + 0x78, 0x65, 0x5F, 0x70, 0x69, 0x78, 0x65, 0x6C, 0x5F, 0x70, 0x6F, 0x73, + 0x5F, 0x72, 0x65, 0x67, 0x00, 0x78, 0x65, 0x5F, 0x6E, 0x64, 0x63, 0x5F, + 0x6F, 0x66, 0x66, 0x73, 0x65, 0x74, 0x00, 0x78, 0x65, 0x5F, 0x70, 0x69, + 0x78, 0x65, 0x6C, 0x5F, 0x68, 0x61, 0x6C, 0x66, 0x5F, 0x70, 0x69, 0x78, + 0x65, 0x6C, 0x5F, 0x6F, 0x66, 0x66, 0x73, 0x65, 0x74, 0x00, 0x66, 0x6C, + 0x6F, 0x61, 0x74, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x96, 0x06, 0x00, 0x00, 0x78, 0x65, 0x5F, 0x70, 0x6F, 0x69, 0x6E, 0x74, + 0x5F, 0x73, 0x69, 0x7A, 0x65, 0x00, 0x66, 0x6C, 0x6F, 0x61, 0x74, 0x32, + 0x00, 0xAB, 0xAB, 0xAB, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xCE, 0x06, 0x00, 0x00, 0x78, 0x65, 0x5F, 0x70, 0x6F, 0x69, 0x6E, 0x74, + 0x5F, 0x73, 0x69, 0x7A, 0x65, 0x5F, 0x6D, 0x69, 0x6E, 0x5F, 0x6D, 0x61, + 0x78, 0x00, 0x78, 0x65, 0x5F, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x5F, 0x73, + 0x63, 0x72, 0x65, 0x65, 0x6E, 0x5F, 0x74, 0x6F, 0x5F, 0x6E, 0x64, 0x63, + 0x00, 0x78, 0x65, 0x5F, 0x73, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x5F, 0x63, + 0x6F, 0x75, 0x6E, 0x74, 0x5F, 0x6C, 0x6F, 0x67, 0x32, 0x00, 0x75, 0x69, + 0x6E, 0x74, 0x32, 0x00, 0x01, 0x00, 0x13, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3E, 0x07, 0x00, 0x00, 0x78, 0x65, 0x5F, 0x61, 0x6C, 0x70, 0x68, 0x61, + 0x5F, 0x74, 0x65, 0x73, 0x74, 0x5F, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6E, 0x63, 0x65, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, + 0x5F, 0x72, 0x65, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x5F, + 0x73, 0x71, 0x75, 0x61, 0x72, 0x65, 0x5F, 0x73, 0x63, 0x61, 0x6C, 0x65, + 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x70, 0x69, + 0x74, 0x63, 0x68, 0x5F, 0x74, 0x69, 0x6C, 0x65, 0x73, 0x00, 0x78, 0x65, + 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x64, 0x65, 0x70, 0x74, 0x68, + 0x5F, 0x62, 0x61, 0x73, 0x65, 0x5F, 0x64, 0x77, 0x6F, 0x72, 0x64, 0x73, + 0x00, 0x78, 0x65, 0x5F, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x5F, 0x65, 0x78, + 0x70, 0x5F, 0x62, 0x69, 0x61, 0x73, 0x00, 0xAB, 0x01, 0x00, 0x03, 0x00, + 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF8, 0x05, 0x00, 0x00, 0x78, 0x65, 0x5F, 0x63, + 0x6F, 0x6C, 0x6F, 0x72, 0x5F, 0x6F, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5F, + 0x6D, 0x61, 0x70, 0x00, 0x75, 0x69, 0x6E, 0x74, 0x34, 0x00, 0xAB, 0xAB, + 0x01, 0x00, 0x13, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x00, 0x00, + 0x78, 0x65, 0x5F, 0x74, 0x65, 0x73, 0x73, 0x65, 0x6C, 0x6C, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x5F, 0x66, 0x61, 0x63, 0x74, 0x6F, 0x72, 0x5F, 0x72, + 0x61, 0x6E, 0x67, 0x65, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, + 0x6D, 0x5F, 0x64, 0x65, 0x70, 0x74, 0x68, 0x5F, 0x72, 0x61, 0x6E, 0x67, + 0x65, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x70, + 0x6F, 0x6C, 0x79, 0x5F, 0x6F, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5F, 0x66, + 0x72, 0x6F, 0x6E, 0x74, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, + 0x6D, 0x5F, 0x70, 0x6F, 0x6C, 0x79, 0x5F, 0x6F, 0x66, 0x66, 0x73, 0x65, + 0x74, 0x5F, 0x62, 0x61, 0x63, 0x6B, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, + 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x00, + 0x01, 0x00, 0x13, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x00, 0x00, + 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x72, 0x74, 0x5F, + 0x62, 0x61, 0x73, 0x65, 0x5F, 0x64, 0x77, 0x6F, 0x72, 0x64, 0x73, 0x5F, + 0x73, 0x63, 0x61, 0x6C, 0x65, 0x64, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, + 0x72, 0x61, 0x6D, 0x5F, 0x72, 0x74, 0x5F, 0x66, 0x6F, 0x72, 0x6D, 0x61, + 0x74, 0x5F, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x00, 0x78, 0x65, 0x5F, 0x65, + 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x72, 0x74, 0x5F, 0x63, 0x6C, 0x61, 0x6D, + 0x70, 0x00, 0xAB, 0xAB, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF8, 0x05, 0x00, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, + 0x5F, 0x72, 0x74, 0x5F, 0x6B, 0x65, 0x65, 0x70, 0x5F, 0x6D, 0x61, 0x73, + 0x6B, 0x00, 0xAB, 0xAB, 0x01, 0x00, 0x13, 0x00, 0x01, 0x00, 0x04, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1C, 0x08, 0x00, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, + 0x5F, 0x72, 0x74, 0x5F, 0x62, 0x6C, 0x65, 0x6E, 0x64, 0x5F, 0x66, 0x61, + 0x63, 0x74, 0x6F, 0x72, 0x73, 0x5F, 0x6F, 0x70, 0x73, 0x00, 0x78, 0x65, + 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x62, 0x6C, 0x65, 0x6E, 0x64, + 0x5F, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74, 0x00, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, + 0x48, 0x4C, 0x53, 0x4C, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, + 0x43, 0x6F, 0x6D, 0x70, 0x69, 0x6C, 0x65, 0x72, 0x20, 0x31, 0x30, 0x2E, + 0x31, 0x00, 0xAB, 0xAB, 0x49, 0x53, 0x47, 0x4E, 0x2C, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x58, 0x45, 0x56, 0x45, + 0x52, 0x54, 0x45, 0x58, 0x49, 0x44, 0x00, 0xAB, 0x4F, 0x53, 0x47, 0x4E, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x50, 0x43, 0x53, 0x47, 0xBC, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0B, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x0E, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0B, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x0E, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0B, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x0E, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x0B, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x0E, 0x00, 0x00, 0xA6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x0E, 0x00, 0x00, 0xA6, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x01, 0x0E, 0x00, 0x00, 0x53, 0x56, 0x5F, 0x54, 0x65, 0x73, 0x73, 0x46, + 0x61, 0x63, 0x74, 0x6F, 0x72, 0x00, 0x53, 0x56, 0x5F, 0x49, 0x6E, 0x73, + 0x69, 0x64, 0x65, 0x54, 0x65, 0x73, 0x73, 0x46, 0x61, 0x63, 0x74, 0x6F, + 0x72, 0x00, 0xAB, 0xAB, 0x53, 0x48, 0x45, 0x58, 0x74, 0x02, 0x00, 0x00, + 0x51, 0x00, 0x03, 0x00, 0x9D, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x01, + 0x93, 0x20, 0x00, 0x01, 0x94, 0x20, 0x00, 0x01, 0x95, 0x18, 0x00, 0x01, + 0x96, 0x20, 0x00, 0x01, 0x97, 0x18, 0x00, 0x01, 0x6A, 0x08, 0x00, 0x01, + 0x59, 0x00, 0x00, 0x07, 0x46, 0x8E, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x01, 0x3E, 0x00, 0x00, 0x01, + 0x73, 0x00, 0x00, 0x01, 0x99, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, + 0x5F, 0x00, 0x00, 0x02, 0x00, 0x70, 0x01, 0x00, 0x5F, 0x00, 0x00, 0x04, + 0x12, 0x90, 0x21, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x67, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0B, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, + 0x12, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, + 0x67, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, + 0x5B, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x06, 0x12, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0A, 0x70, 0x01, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x40, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3F, 0x0A, 0x90, 0xA1, 0x00, 0x0A, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x09, + 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0A, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x09, + 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1A, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x04, + 0x22, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x70, 0x01, 0x00, + 0x36, 0x00, 0x00, 0x06, 0x12, 0x20, 0x90, 0x00, 0x1A, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3E, 0x00, 0x00, 0x01, 0x74, 0x00, 0x00, 0x01, 0x9A, 0x00, 0x00, 0x02, + 0x02, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x03, 0x12, 0xB0, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x03, 0x12, 0xB0, 0x11, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x03, 0x12, 0xB0, 0x11, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x03, 0x12, 0xB0, 0x11, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x02, 0x00, 0x80, 0x01, 0x00, + 0x67, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x0F, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, + 0x01, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x04, + 0x12, 0xB0, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x04, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x80, 0x01, 0x00, 0x33, 0x00, 0x00, 0x0A, 0x22, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0A, 0xB0, 0x91, 0x00, 0x0A, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0A, 0xB0, 0xD1, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x07, + 0x12, 0x20, 0xD0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3E, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x94, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; diff --git a/src/xenia/gpu/d3d12/shaders/dxbc/adaptive_quad_hs.txt b/src/xenia/gpu/d3d12/shaders/dxbc/adaptive_quad_hs.txt new file mode 100644 index 000000000..27aa09942 --- /dev/null +++ b/src/xenia/gpu/d3d12/shaders/dxbc/adaptive_quad_hs.txt @@ -0,0 +1,129 @@ +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer xe_system_cbuffer +// { +// +// uint xe_flags; // Offset: 0 Size: 4 [unused] +// uint xe_line_loop_closing_index; // Offset: 4 Size: 4 [unused] +// uint xe_vertex_index_endian; // Offset: 8 Size: 4 [unused] +// int xe_vertex_base_index; // Offset: 12 Size: 4 [unused] +// float4 xe_user_clip_planes[6]; // Offset: 16 Size: 96 [unused] +// float3 xe_ndc_scale; // Offset: 112 Size: 12 [unused] +// uint xe_pixel_pos_reg; // Offset: 124 Size: 4 [unused] +// float3 xe_ndc_offset; // Offset: 128 Size: 12 [unused] +// float xe_pixel_half_pixel_offset; // Offset: 140 Size: 4 [unused] +// float2 xe_point_size; // Offset: 144 Size: 8 [unused] +// float2 xe_point_size_min_max; // Offset: 152 Size: 8 [unused] +// float2 xe_point_screen_to_ndc; // Offset: 160 Size: 8 [unused] +// uint2 xe_sample_count_log2; // Offset: 168 Size: 8 [unused] +// float xe_alpha_test_reference; // Offset: 176 Size: 4 [unused] +// uint xe_edram_resolution_square_scale;// Offset: 180 Size: 4 [unused] +// uint xe_edram_pitch_tiles; // Offset: 184 Size: 4 [unused] +// uint xe_edram_depth_base_dwords; // Offset: 188 Size: 4 [unused] +// float4 xe_color_exp_bias; // Offset: 192 Size: 16 [unused] +// uint4 xe_color_output_map; // Offset: 208 Size: 16 [unused] +// float2 xe_tessellation_factor_range;// Offset: 224 Size: 8 +// float2 xe_edram_depth_range; // Offset: 232 Size: 8 [unused] +// float2 xe_edram_poly_offset_front; // Offset: 240 Size: 8 [unused] +// float2 xe_edram_poly_offset_back; // Offset: 248 Size: 8 [unused] +// uint4 xe_edram_stencil[2]; // Offset: 256 Size: 32 [unused] +// uint4 xe_edram_rt_base_dwords_scaled;// Offset: 288 Size: 16 [unused] +// uint4 xe_edram_rt_format_flags; // Offset: 304 Size: 16 [unused] +// float4 xe_edram_rt_clamp[4]; // Offset: 320 Size: 64 [unused] +// uint4 xe_edram_rt_keep_mask[2]; // Offset: 384 Size: 32 [unused] +// uint4 xe_edram_rt_blend_factors_ops;// Offset: 416 Size: 16 [unused] +// float4 xe_edram_blend_constant; // Offset: 432 Size: 16 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim ID HLSL Bind Count +// ------------------------------ ---------- ------- ----------- ------- -------------- ------ +// xe_system_cbuffer cbuffer NA NA CB0 cb0 1 +// +// +// +// Patch Constant signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TessFactor 0 x 0 QUADEDGE float x +// SV_TessFactor 1 x 1 QUADEDGE float x +// SV_TessFactor 2 x 2 QUADEDGE float x +// SV_TessFactor 3 x 3 QUADEDGE float x +// SV_InsideTessFactor 0 x 4 QUADINT float x +// SV_InsideTessFactor 1 x 5 QUADINT float x +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// XEVERTEXID 0 x 0 NONE int x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// no Output +// Tessellation Domain # of control points +// -------------------- -------------------- +// Quadrilateral 4 +// +// Tessellation Output Primitive Partitioning Type +// ------------------------------ ------------------ +// Clockwise Triangles Even Fractional +// +hs_5_1 +hs_decls +dcl_input_control_point_count 4 +dcl_output_control_point_count 4 +dcl_tessellator_domain domain_quad +dcl_tessellator_partitioning partitioning_fractional_even +dcl_tessellator_output_primitive output_triangle_cw +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[0:0][15], immediateIndexed, space=0 +hs_control_point_phase +ret +hs_fork_phase +dcl_hs_fork_phase_instance_count 4 +dcl_input vForkInstanceID +dcl_input vicp[4][0].x +dcl_output_siv o0.x, finalQuadUeq0EdgeTessFactor +dcl_output_siv o1.x, finalQuadVeq0EdgeTessFactor +dcl_output_siv o2.x, finalQuadUeq1EdgeTessFactor +dcl_output_siv o3.x, finalQuadVeq1EdgeTessFactor +dcl_temps 1 +dcl_indexrange o0.x 4 +iadd r0.x, vForkInstanceID.x, l(3) +and r0.x, r0.x, l(3) +add r0.x, l(1.000000), vicp[r0.x + 0][0].x +max r0.x, r0.x, CB0[0][14].x +min r0.x, r0.x, CB0[0][14].y +mov r0.y, vForkInstanceID.x +mov o[r0.y + 0].x, r0.x +ret +hs_join_phase +dcl_hs_join_phase_instance_count 2 +dcl_input vpc0.x +dcl_input vpc1.x +dcl_input vpc2.x +dcl_input vpc3.x +dcl_input vJoinInstanceID +dcl_output_siv o4.x, finalQuadUInsideTessFactor +dcl_output_siv o5.x, finalQuadVInsideTessFactor +dcl_temps 1 +dcl_indexrange o4.x 2 +dcl_indexrange vpc0.x 4 +mov r0.x, vJoinInstanceID.x +min r0.y, vpc[r0.x + 0].x, vpc[r0.x + 2].x +mov o[r0.x + 4].x, r0.y +ret +// Approximately 13 instruction slots used diff --git a/src/xenia/gpu/d3d12/shaders/xenos_draw.hlsli b/src/xenia/gpu/d3d12/shaders/xenos_draw.hlsli index 8c887a561..bd462fe9f 100644 --- a/src/xenia/gpu/d3d12/shaders/xenos_draw.hlsli +++ b/src/xenia/gpu/d3d12/shaders/xenos_draw.hlsli @@ -62,6 +62,8 @@ struct XeHSControlPointOutput { float index : XEVERTEXID; }; +struct XeHSAdaptiveControlPointOutput {}; + struct XeVertexPostGS { float4 interpolators[16] : TEXCOORD0; float3 point_params : TEXCOORD16; diff --git a/src/xenia/gpu/dxbc_shader_translator.cc b/src/xenia/gpu/dxbc_shader_translator.cc index a29ca2a12..8d585f299 100644 --- a/src/xenia/gpu/dxbc_shader_translator.cc +++ b/src/xenia/gpu/dxbc_shader_translator.cc @@ -520,8 +520,8 @@ void DxbcShaderTranslator::StartVertexOrDomainShader() { // rotation of the swizzle to the right, and 1 << 2 is set when the // swizzle needs to be flipped before rotating. // - // Direct3D 12 appears to be passing the coordinates in a consistent - // order, so can just use ZYX for triangle patches. + // Direct3D 12 passes the coordinates in a consistent order, so can + // just use the identity swizzle. DxbcOpMov(uses_register_dynamic_addressing() ? DxbcDest::X(0, 1, 0b0010) : DxbcDest::R(1, 0b0010), @@ -534,11 +534,10 @@ void DxbcShaderTranslator::StartVertexOrDomainShader() { assert_true(register_count() >= 2); if (register_count() >= 1) { // Copy the domain location to r0.yz. - // According to the ground shader in Viva Pinata, though it's untested - // as of April 4th, 2020. + // XY swizzle according to the ground shader in Viva Pinata. DxbcOpMov(uses_register_dynamic_addressing() ? DxbcDest::X(0, 0, 0b0110) : DxbcDest::R(0, 0b0110), - DxbcSrc::VDomain(0b000100)); + DxbcSrc::VDomain(0b010000)); // Copy the primitive index to r0.x as a float. uint32_t primitive_id_temp = uses_register_dynamic_addressing() ? PushSystemTemp() : 0; @@ -554,19 +553,16 @@ void DxbcShaderTranslator::StartVertexOrDomainShader() { // the tessellator offloads the reordering of coordinates for edges to // game shaders. // - // In Viva Pinata, if we assume that r0.y is V and r0.z is U, the + // In Viva Pinata, if we assume that r0.y is U and r0.z is V, the // factors each control point value is multiplied by are the // following: - // - (1-v)*(1-u), v*(1-u), (1-v)*u, v*u for 0.0 (base swizzle). - // - v*(1-u), (1-v)*(1-u), v*u, (1-v)*u for 1.0 (YXWZ). - // - v*u, (1-v)*u, v*(1-u), (1-v)*(1-u) for 2.0 (WZYX). - // - (1-v)*u, v*u, (1-v)*(1-u), v*(1-u) for 3.0 (ZWXY). - // According to the control point order at - // https://www.khronos.org/registry/OpenGL/extensions/AMD/AMD_vertex_shader_tessellator.txt - // the first is located at (0,0), the second at (0,1), the third at - // (1,0) and the fourth at (1,1). So, swizzle index 0 appears to be - // the correct one. (This, however, hasn't been tested yet as of April - // 5th, 2020.) + // - (1-u)*(1-v), u*(1-v), (1-u)*v, u*v for 0.0 (identity swizzle). + // - u*(1-v), (1-u)*(1-v), u*v, (1-u)*v for 1.0 (YXWZ). + // - u*v, (1-u)*v, u*(1-v), (1-u)*(1-v) for 2.0 (WZYX). + // - (1-u)*v, u*v, (1-u)*(1-v), u*(1-v) for 3.0 (ZWXY). + // + // Direct3D 12 passes the coordinates in a consistent order, so can + // just use the identity swizzle. DxbcOpMov(uses_register_dynamic_addressing() ? DxbcDest::X(0, 1, 0b0001) : DxbcDest::R(1, 0b0001), @@ -576,7 +572,7 @@ void DxbcShaderTranslator::StartVertexOrDomainShader() { break; default: - // TODO(Triang3l): Support line and non-adaptive patches. + // TODO(Triang3l): Support line and non-adaptive quad patches. assert_unhandled_case(host_vertex_shader_type()); EmitTranslationError( "Unsupported host vertex shader type in StartVertexOrDomainShader");