diff --git a/src/xenia/gpu/d3d12/d3d12_command_processor.cc b/src/xenia/gpu/d3d12/d3d12_command_processor.cc index ca9838696..4f26de650 100644 --- a/src/xenia/gpu/d3d12/d3d12_command_processor.cc +++ b/src/xenia/gpu/d3d12/d3d12_command_processor.cc @@ -689,8 +689,9 @@ bool D3D12CommandProcessor::SetupContext() { return false; } - pipeline_cache_ = std::make_unique(this, register_file_, - IsROVUsedForEDRAM()); + pipeline_cache_ = std::make_unique( + this, register_file_, IsROVUsedForEDRAM(), + texture_cache_->IsResolutionScale2X() ? 2 : 1); if (!pipeline_cache_->Initialize()) { XELOGE("Failed to initialize the graphics pipeline state cache"); return false; @@ -1172,8 +1173,8 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type, return false; } // Translate the shaders now to get memexport configuration and color mask, - // which is needed by the render target cache, and also to get used textures - // and samplers. + // which is needed by the render target cache, to check the possibility of + // doing early depth/stencil, and also to get used textures and samplers. if (!pipeline_cache_->EnsureShadersTranslated(vertex_shader, pixel_shader, primitive_type)) { return false; @@ -1298,12 +1299,27 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type, vertex_shader->GetUsedTextureMask(), pixel_shader != nullptr ? pixel_shader->GetUsedTextureMask() : 0); + // Check if early depth/stencil can be enabled explicitly by RB_DEPTHCONTROL + // or implicitly when alpha test and alpha to coverage are disabled. + uint32_t rb_colorcontrol = regs[XE_GPU_REG_RB_COLORCONTROL].u32; + bool early_z = false; + if (pixel_shader == nullptr) { + early_z = true; + } else if (!pixel_shader->writes_depth()) { + if (rb_depthcontrol & 0x8) { + early_z = true; + } else { + early_z = (!(rb_colorcontrol & 0x8) || (rb_colorcontrol & 0x7) == 0x7) && + !(rb_colorcontrol & 0x10); + } + } + // Create the pipeline if needed and bind it. void* pipeline_handle; ID3D12RootSignature* root_signature; if (!pipeline_cache_->ConfigurePipeline( vertex_shader, pixel_shader, primitive_type_converted, - indexed ? index_buffer_info->format : IndexFormat::kInt16, + indexed ? index_buffer_info->format : IndexFormat::kInt16, early_z, pipeline_render_targets, &pipeline_handle, &root_signature)) { return false; } @@ -1322,7 +1338,7 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type, memexport_used, primitive_type, line_loop_closing_index, indexed ? index_buffer_info->endianness : Endian::kUnspecified, adaptive_tessellation ? (index_buffer_info->guest_base & 0x1FFFFFFC) : 0, - color_mask, pipeline_render_targets); + early_z, color_mask, pipeline_render_targets); // Update constant buffers, descriptors and root parameters. if (!UpdateBindings(vertex_shader, pixel_shader, root_signature)) { @@ -1940,7 +1956,7 @@ void D3D12CommandProcessor::UpdateFixedFunctionState() { void D3D12CommandProcessor::UpdateSystemConstantValues( bool shared_memory_is_uav, PrimitiveType primitive_type, uint32_t line_loop_closing_index, Endian index_endian, - uint32_t edge_factor_base, uint32_t color_mask, + uint32_t edge_factor_base, bool early_z, uint32_t color_mask, const RenderTargetCache::PipelineRenderTarget render_targets[4]) { auto& regs = *register_file_; @@ -1968,7 +1984,10 @@ void D3D12CommandProcessor::UpdateSystemConstantValues( // some safety measures for the ROV path - disable fully aliased render // targets. Also, for ROV, exclude components that don't exist in the format // from the write mask. - uint32_t color_infos[4], rov_color_format_rt_flags[4]; + uint32_t color_infos[4]; + ColorRenderTargetFormat color_formats[4]; + float rt_clamp[4][4]; + uint32_t rt_keep_masks[4][2]; for (uint32_t i = 0; i < 4; ++i) { uint32_t color_info; switch (i) { @@ -1985,29 +2004,27 @@ void D3D12CommandProcessor::UpdateSystemConstantValues( color_info = regs[XE_GPU_REG_RB_COLOR_INFO].u32; } color_infos[i] = color_info; + color_formats[i] = ColorRenderTargetFormat((color_info >> 16) & 0xF); if (IsROVUsedForEDRAM()) { - ColorRenderTargetFormat color_format = - RenderTargetCache::GetBaseColorFormat( - ColorRenderTargetFormat((color_info >> 16) & 0xF)); - uint32_t rt_flags = - DxbcShaderTranslator::GetColorFormatRTFlags(color_format); - rov_color_format_rt_flags[i] = rt_flags; - - // Exclude unused components from the write mask. - color_mask &= - ~(((rt_flags >> DxbcShaderTranslator::kRTFlag_FormatUnusedR_Shift) & - 0xF) - << (i * 4)); + // Get the mask for keeping previous color's components unmodified, + // or two UINT32_MAX if no colors actually existing in the RT are written. + DxbcShaderTranslator::ROV_GetColorFormatSystemConstants( + color_formats[i], (color_mask >> (i * 4)) & 0b1111, rt_clamp[i][0], + rt_clamp[i][1], rt_clamp[i][2], rt_clamp[i][3], rt_keep_masks[i][0], + rt_keep_masks[i][1]); // Disable the render target if it has the same EDRAM base as another one // (with a smaller index - assume it's more important). - if (color_mask & (0xF << (i * 4))) { + if (rt_keep_masks[i][0] == UINT32_MAX && + rt_keep_masks[i][1] == UINT32_MAX) { uint32_t edram_base = color_info & 0xFFF; for (uint32_t j = 0; j < i; ++j) { - if ((color_mask & (0xF << (j * 4))) && - edram_base == (color_infos[j] & 0xFFF)) { - color_mask &= ~(uint32_t(0xF << (i * 4))); + if (edram_base == (color_infos[j] & 0xFFF) && + (rt_keep_masks[j][0] != UINT32_MAX || + rt_keep_masks[j][1] != UINT32_MAX)) { + rt_keep_masks[i][0] = UINT32_MAX; + rt_keep_masks[i][1] = UINT32_MAX; break; } } @@ -2021,8 +2038,9 @@ void D3D12CommandProcessor::UpdateSystemConstantValues( if (IsROVUsedForEDRAM() && (rb_depthcontrol & (0x1 | 0x2))) { uint32_t edram_base_depth = rb_depth_info & 0xFFF; for (uint32_t i = 0; i < 4; ++i) { - if ((color_mask & (0xF << (i * 4))) && - edram_base_depth == (color_infos[i] & 0xFFF)) { + if (edram_base_depth == (color_infos[i] & 0xFFF) && + (rt_keep_masks[i][0] != UINT32_MAX || + rt_keep_masks[i][1] != UINT32_MAX)) { rb_depthcontrol &= ~(uint32_t(0x1 | 0x2)); break; } @@ -2084,47 +2102,35 @@ void D3D12CommandProcessor::UpdateSystemConstantValues( flags |= DxbcShaderTranslator::kSysFlag_AlphaToCoverage; } // Gamma writing. - if (((regs[XE_GPU_REG_RB_COLOR_INFO].u32 >> 16) & 0xF) == - uint32_t(ColorRenderTargetFormat::k_8_8_8_8_GAMMA)) { - flags |= DxbcShaderTranslator::kSysFlag_Color0Gamma; - } - if (((regs[XE_GPU_REG_RB_COLOR1_INFO].u32 >> 16) & 0xF) == - uint32_t(ColorRenderTargetFormat::k_8_8_8_8_GAMMA)) { - flags |= DxbcShaderTranslator::kSysFlag_Color1Gamma; - } - if (((regs[XE_GPU_REG_RB_COLOR2_INFO].u32 >> 16) & 0xF) == - uint32_t(ColorRenderTargetFormat::k_8_8_8_8_GAMMA)) { - flags |= DxbcShaderTranslator::kSysFlag_Color2Gamma; - } - if (((regs[XE_GPU_REG_RB_COLOR3_INFO].u32 >> 16) & 0xF) == - uint32_t(ColorRenderTargetFormat::k_8_8_8_8_GAMMA)) { - flags |= DxbcShaderTranslator::kSysFlag_Color3Gamma; + for (uint32_t i = 0; i < 4; ++i) { + if (color_formats[i] == ColorRenderTargetFormat::k_8_8_8_8_GAMMA) { + flags |= DxbcShaderTranslator::kSysFlag_Color0Gamma << i; + } } if (IsROVUsedForEDRAM() && (rb_depthcontrol & (0x1 | 0x2))) { - flags |= DxbcShaderTranslator::kSysFlag_DepthStencil; + flags |= DxbcShaderTranslator::kSysFlag_ROVDepthStencil; if (DepthRenderTargetFormat((rb_depth_info >> 16) & 0x1) == DepthRenderTargetFormat::kD24FS8) { - flags |= DxbcShaderTranslator::kSysFlag_DepthFloat24; + flags |= DxbcShaderTranslator::kSysFlag_ROVDepthFloat24; } if (rb_depthcontrol & 0x2) { flags |= ((rb_depthcontrol >> 4) & 0x7) - << DxbcShaderTranslator::kSysFlag_DepthPassIfLess_Shift; + << DxbcShaderTranslator::kSysFlag_ROVDepthPassIfLess_Shift; if (rb_depthcontrol & 0x4) { - flags |= DxbcShaderTranslator::kSysFlag_DepthWriteMask | - DxbcShaderTranslator::kSysFlag_DepthStencilWrite; + flags |= DxbcShaderTranslator::kSysFlag_ROVDepthWrite; } } else { // In case stencil is used without depth testing - always pass, and // don't modify the stored depth. - flags |= DxbcShaderTranslator::kSysFlag_DepthPassIfLess | - DxbcShaderTranslator::kSysFlag_DepthPassIfEqual | - DxbcShaderTranslator::kSysFlag_DepthPassIfGreater; + flags |= DxbcShaderTranslator::kSysFlag_ROVDepthPassIfLess | + DxbcShaderTranslator::kSysFlag_ROVDepthPassIfEqual | + DxbcShaderTranslator::kSysFlag_ROVDepthPassIfGreater; } if (rb_depthcontrol & 0x1) { - flags |= DxbcShaderTranslator::kSysFlag_StencilTest; - if (rb_stencilrefmask & (0xFF << 16)) { - flags |= DxbcShaderTranslator::kSysFlag_DepthStencilWrite; - } + flags |= DxbcShaderTranslator::kSysFlag_ROVStencilTest; + } + if (early_z) { + flags |= DxbcShaderTranslator::kSysFlag_ROVDepthStencilEarlyWrite; } } dirty |= system_constants_.flags != flags; @@ -2308,25 +2314,29 @@ void D3D12CommandProcessor::UpdateSystemConstantValues( bool colorcontrol_blend_enable = (rb_colorcontrol & 0x20) == 0; for (uint32_t i = 0; i < 4; ++i) { uint32_t color_info = color_infos[i]; - uint32_t blend_control; - switch (i) { - case 1: - blend_control = regs[XE_GPU_REG_RB_BLENDCONTROL_1].u32; - break; - case 2: - blend_control = regs[XE_GPU_REG_RB_BLENDCONTROL_2].u32; - break; - case 3: - blend_control = regs[XE_GPU_REG_RB_BLENDCONTROL_3].u32; - break; - default: - blend_control = regs[XE_GPU_REG_RB_BLENDCONTROL_0].u32; + uint32_t blend_factors_ops; + if (colorcontrol_blend_enable) { + switch (i) { + case 1: + blend_factors_ops = regs[XE_GPU_REG_RB_BLENDCONTROL_1].u32; + break; + case 2: + blend_factors_ops = regs[XE_GPU_REG_RB_BLENDCONTROL_2].u32; + break; + case 3: + blend_factors_ops = regs[XE_GPU_REG_RB_BLENDCONTROL_3].u32; + break; + default: + blend_factors_ops = regs[XE_GPU_REG_RB_BLENDCONTROL_0].u32; + break; + } + blend_factors_ops &= 0x1FFF1FFF; + } else { + blend_factors_ops = 0x00010001; } // Exponent bias is in bits 20:25 of RB_COLOR_INFO. int32_t color_exp_bias = int32_t(color_info << 6) >> 26; - ColorRenderTargetFormat color_format = - RenderTargetCache::GetBaseColorFormat( - ColorRenderTargetFormat((color_info >> 16) & 0xF)); + ColorRenderTargetFormat color_format = color_formats[i]; if (color_format == ColorRenderTargetFormat::k_16_16 || color_format == ColorRenderTargetFormat::k_16_16_16_16) { // On the Xbox 360, k_16_16_EDRAM and k_16_16_16_16_EDRAM internally have @@ -2346,46 +2356,33 @@ void D3D12CommandProcessor::UpdateSystemConstantValues( dirty |= system_constants_.color_exp_bias[i] != color_exp_bias_scale; system_constants_.color_exp_bias[i] = color_exp_bias_scale; if (IsROVUsedForEDRAM()) { - uint32_t edram_base_dwords = (color_info & 0xFFF) * 1280; - dirty |= system_constants_.edram_base_dwords[i] != edram_base_dwords; - system_constants_.edram_base_dwords[i] = edram_base_dwords; - uint32_t rt_flags = rov_color_format_rt_flags[i]; - // Unused components already excluded from the write mask when color infos - // were obtained, and fully aliased render targets were already skipped. - uint32_t rt_mask = (color_mask >> (i * 4)) & 0xF; - if (rt_mask != 0) { - rt_flags |= rt_mask << DxbcShaderTranslator::kRTFlag_WriteR_Shift; - uint32_t blend_x, blend_y; - if (colorcontrol_blend_enable && - DxbcShaderTranslator::GetBlendConstants(blend_control, blend_x, - blend_y)) { - rt_flags |= DxbcShaderTranslator::kRTFlag_Blend; - uint32_t rt_pair_index = i >> 1; - uint32_t rt_pair_comp = (i & 1) << 1; - if (system_constants_ - .edram_blend_rt01_rt23[rt_pair_index][rt_pair_comp] != - blend_x) { - dirty = true; - system_constants_ - .edram_blend_rt01_rt23[rt_pair_index][rt_pair_comp] = blend_x; - } - if (system_constants_ - .edram_blend_rt01_rt23[rt_pair_index][rt_pair_comp + 1] != - blend_y) { - dirty = true; - system_constants_ - .edram_blend_rt01_rt23[rt_pair_index][rt_pair_comp + 1] = - blend_y; - } + dirty |= + system_constants_.edram_rt_keep_mask[i][0] != rt_keep_masks[i][0]; + system_constants_.edram_rt_keep_mask[i][0] = rt_keep_masks[i][0]; + dirty |= + system_constants_.edram_rt_keep_mask[i][1] != rt_keep_masks[i][1]; + system_constants_.edram_rt_keep_mask[i][1] = rt_keep_masks[i][1]; + if (rt_keep_masks[i][0] != UINT32_MAX || + rt_keep_masks[i][1] != UINT32_MAX) { + uint32_t rt_base_dwords_scaled = (color_info & 0xFFF) * 1280; + if (texture_cache_->IsResolutionScale2X()) { + rt_base_dwords_scaled <<= 2; } - } - dirty |= system_constants_.edram_rt_flags[i] != rt_flags; - system_constants_.edram_rt_flags[i] = rt_flags; - if (system_constants_color_formats_[i] != color_format) { - dirty = true; - DxbcShaderTranslator::SetColorFormatSystemConstants(system_constants_, - i, color_format); - system_constants_color_formats_[i] = color_format; + dirty |= system_constants_.edram_rt_base_dwords_scaled[i] != + rt_base_dwords_scaled; + system_constants_.edram_rt_base_dwords_scaled[i] = + rt_base_dwords_scaled; + uint32_t format_flags = + DxbcShaderTranslator::ROV_AddColorFormatFlags(color_format); + dirty |= system_constants_.edram_rt_format_flags[i] != format_flags; + system_constants_.edram_rt_format_flags[i] = format_flags; + dirty |= std::memcmp(system_constants_.edram_rt_clamp[i], rt_clamp[i], + 4 * sizeof(float)) != 0; + std::memcpy(system_constants_.edram_rt_clamp[i], rt_clamp[i], + 4 * sizeof(float)); + dirty |= system_constants_.edram_rt_blend_factors_ops[i] != + blend_factors_ops; + system_constants_.edram_rt_blend_factors_ops[i] = blend_factors_ops; } } else { dirty |= system_constants_.color_output_map[i] != @@ -2397,11 +2394,11 @@ void D3D12CommandProcessor::UpdateSystemConstantValues( // Resolution scale, depth/stencil testing and blend constant for ROV. if (IsROVUsedForEDRAM()) { - uint32_t resolution_scale_log2 = - texture_cache_->IsResolutionScale2X() ? 1 : 0; - dirty |= - system_constants_.edram_resolution_scale_log2 != resolution_scale_log2; - system_constants_.edram_resolution_scale_log2 = resolution_scale_log2; + uint32_t resolution_square_scale = + texture_cache_->IsResolutionScale2X() ? 4 : 1; + dirty |= system_constants_.edram_resolution_square_scale != + resolution_square_scale; + system_constants_.edram_resolution_square_scale = resolution_square_scale; uint32_t depth_base_dwords = (rb_depth_info & 0xFFF) * 1280; dirty |= system_constants_.edram_depth_base_dwords != depth_base_dwords; @@ -2454,16 +2451,14 @@ void D3D12CommandProcessor::UpdateSystemConstantValues( regs[XE_GPU_REG_PA_SU_POLY_OFFSET_BACK_OFFSET].f32; } } - if (viewport_scale_z < 0.0f) { - // Clip space flipped in the vertex shader, so flip polygon offset too. - poly_offset_front_scale = -poly_offset_front_scale; - poly_offset_front_offset = -poly_offset_front_offset; - poly_offset_back_scale = -poly_offset_back_scale; - poly_offset_back_offset = -poly_offset_back_offset; - } - // See PipelineCache for explanation. + // "slope computed in subpixels (1/12 or 1/16)" - R5xx Acceleration. Also: + // https://github.com/mesa3d/mesa/blob/54ad9b444c8e73da498211870e785239ad3ff1aa/src/gallium/drivers/radeonsi/si_state.c#L943 poly_offset_front_scale *= 1.0f / 16.0f; poly_offset_back_scale *= 1.0f / 16.0f; + if (texture_cache_->IsResolutionScale2X()) { + poly_offset_front_scale *= 2.f; + poly_offset_back_scale *= 2.f; + } dirty |= system_constants_.edram_poly_offset_front_scale != poly_offset_front_scale; system_constants_.edram_poly_offset_front_scale = poly_offset_front_scale; diff --git a/src/xenia/gpu/d3d12/d3d12_command_processor.h b/src/xenia/gpu/d3d12/d3d12_command_processor.h index 3d6fb6c05..c5df90f25 100644 --- a/src/xenia/gpu/d3d12/d3d12_command_processor.h +++ b/src/xenia/gpu/d3d12/d3d12_command_processor.h @@ -212,7 +212,7 @@ class D3D12CommandProcessor : public CommandProcessor { void UpdateSystemConstantValues( bool shared_memory_is_uav, PrimitiveType primitive_type, uint32_t line_loop_closing_index, Endian index_endian, - uint32_t edge_factor_base, uint32_t color_mask, + uint32_t edge_factor_base, 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/deferred_command_list.cc b/src/xenia/gpu/d3d12/deferred_command_list.cc index 1a1a5a7f8..a1a66d8c5 100644 --- a/src/xenia/gpu/d3d12/deferred_command_list.cc +++ b/src/xenia/gpu/d3d12/deferred_command_list.cc @@ -186,12 +186,16 @@ void DeferredCommandList::Execute(ID3D12GraphicsCommandList* command_list, case Command::kD3DSetPipelineState: { current_pipeline_state = *reinterpret_cast(stream); - command_list->SetPipelineState(current_pipeline_state); + if (current_pipeline_state) { + command_list->SetPipelineState(current_pipeline_state); + } } break; case Command::kSetPipelineStateHandle: { current_pipeline_state = command_processor_->GetPipelineStateByHandle( *reinterpret_cast(stream)); - command_list->SetPipelineState(current_pipeline_state); + if (current_pipeline_state) { + command_list->SetPipelineState(current_pipeline_state); + } } break; case Command::kD3DSetSamplePositions: { if (command_list_1 != nullptr) { diff --git a/src/xenia/gpu/d3d12/pipeline_cache.cc b/src/xenia/gpu/d3d12/pipeline_cache.cc index 4eb0df2a0..54817a51b 100644 --- a/src/xenia/gpu/d3d12/pipeline_cache.cc +++ b/src/xenia/gpu/d3d12/pipeline_cache.cc @@ -61,10 +61,12 @@ namespace d3d12 { #include "xenia/gpu/d3d12/shaders/dxbc/tessellation_triangle_vs.h" PipelineCache::PipelineCache(D3D12CommandProcessor* command_processor, - RegisterFile* register_file, bool edram_rov_used) + RegisterFile* register_file, bool edram_rov_used, + uint32_t resolution_scale) : command_processor_(command_processor), register_file_(register_file), - edram_rov_used_(edram_rov_used) { + edram_rov_used_(edram_rov_used), + resolution_scale_(resolution_scale) { auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); shader_translator_ = std::make_unique( @@ -219,7 +221,7 @@ bool PipelineCache::EnsureShadersTranslated(D3D12Shader* vertex_shader, bool PipelineCache::ConfigurePipeline( D3D12Shader* vertex_shader, D3D12Shader* pixel_shader, - PrimitiveType primitive_type, IndexFormat index_format, + PrimitiveType primitive_type, IndexFormat index_format, bool early_z, const RenderTargetCache::PipelineRenderTarget render_targets[5], void** pipeline_handle_out, ID3D12RootSignature** root_signature_out) { #if FINE_GRAINED_DRAW_SCOPES @@ -231,7 +233,8 @@ bool PipelineCache::ConfigurePipeline( PipelineDescription description; if (!GetCurrentStateDescription(vertex_shader, pixel_shader, primitive_type, - index_format, render_targets, description)) { + index_format, early_z, render_targets, + description)) { return false; } @@ -329,10 +332,11 @@ bool PipelineCache::TranslateShader(D3D12Shader* shader, shader->ucode_disassembly().c_str()); } - // If may be useful, create a version of the shader with early depth/stencil - // forced. + // Create a version of the shader with early depth/stencil forced by Xenia + // itself when it's safe to do so or when EARLY_Z_ENABLE is set in + // RB_DEPTHCONTROL. if (shader->type() == ShaderType::kPixel && !edram_rov_used_ && - shader->early_z_allowed()) { + !shader->writes_depth()) { shader->SetForcedEarlyZShaderObject( std::move(DxbcShaderTranslator::ForceEarlyDepthStencil( shader->translated_binary().data()))); @@ -357,7 +361,7 @@ bool PipelineCache::TranslateShader(D3D12Shader* shader, bool PipelineCache::GetCurrentStateDescription( D3D12Shader* vertex_shader, D3D12Shader* pixel_shader, - PrimitiveType primitive_type, IndexFormat index_format, + PrimitiveType primitive_type, IndexFormat index_format, bool early_z, const RenderTargetCache::PipelineRenderTarget render_targets[5], PipelineDescription& description_out) { auto& regs = *register_file_; @@ -537,19 +541,13 @@ bool PipelineCache::GetCurrentStateDescription( } else { poly_offset *= float(1 << 23); } - // Reversed depth is emulated in vertex shaders because MinDepth > MaxDepth - // in viewports doesn't seem to work on Nvidia. - if ((regs[XE_GPU_REG_PA_CL_VTE_CNTL].u32 & (1 << 4)) && - regs[XE_GPU_REG_PA_CL_VPORT_ZSCALE].f32 < 0.0f) { - poly_offset = -poly_offset; - poly_offset_scale = -poly_offset_scale; - } // Using ceil here just in case a game wants the offset but passes a value // that is too small - it's better to apply more offset than to make depth // fighting worse or to disable the offset completely (Direct3D 12 takes an // integer value). description_out.depth_bias = int32_t(std::ceil(std::abs(poly_offset))) * (poly_offset < 0.0f ? -1 : 1); + // "slope computed in subpixels (1/12 or 1/16)" - R5xx Acceleration. description_out.depth_bias_slope_scaled = poly_offset_scale * (1.0f / 16.0f); } @@ -624,16 +622,7 @@ bool PipelineCache::GetCurrentStateDescription( } else { description_out.depth_func = 0b111; } - - // Forced early Z if the shader allows that and alpha testing and alpha to - // coverage are disabled. - // TODO(Triang3l): For memexporting shaders, possibly choose this according - // to the early Z toggle in RB_DEPTHCONTROL (the correct behavior is still - // unknown). - if (pixel_shader != nullptr && - pixel_shader->GetForcedEarlyZShaderObject().size() != 0 && - (!(rb_colorcontrol & 0x8) || (rb_colorcontrol & 0x7) == 0x7) && - !(rb_colorcontrol & 0x10)) { + if (early_z) { description_out.force_early_z = 1; } @@ -932,7 +921,7 @@ ID3D12PipelineState* PipelineCache::CreatePipelineState( state_desc.RasterizerState.DepthBias = description.depth_bias; state_desc.RasterizerState.DepthBiasClamp = 0.0f; state_desc.RasterizerState.SlopeScaledDepthBias = - description.depth_bias_slope_scaled; + description.depth_bias_slope_scaled * float(resolution_scale_); state_desc.RasterizerState.DepthClipEnable = description.depth_clip ? TRUE : FALSE; if (edram_rov_used_) { diff --git a/src/xenia/gpu/d3d12/pipeline_cache.h b/src/xenia/gpu/d3d12/pipeline_cache.h index f09b518d1..daa16caf7 100644 --- a/src/xenia/gpu/d3d12/pipeline_cache.h +++ b/src/xenia/gpu/d3d12/pipeline_cache.h @@ -34,7 +34,8 @@ class D3D12CommandProcessor; class PipelineCache { public: PipelineCache(D3D12CommandProcessor* command_processor, - RegisterFile* register_file, bool edram_rov_used); + RegisterFile* register_file, bool edram_rov_used, + uint32_t resolution_scale); ~PipelineCache(); bool Initialize(); @@ -53,7 +54,7 @@ class PipelineCache { bool ConfigurePipeline( D3D12Shader* vertex_shader, D3D12Shader* pixel_shader, - PrimitiveType primitive_type, IndexFormat index_format, + PrimitiveType primitive_type, IndexFormat index_format, bool early_z, const RenderTargetCache::PipelineRenderTarget render_targets[5], void** pipeline_handle_out, ID3D12RootSignature** root_signature_out); @@ -175,7 +176,7 @@ class PipelineCache { bool GetCurrentStateDescription( D3D12Shader* vertex_shader, D3D12Shader* pixel_shader, - PrimitiveType primitive_type, IndexFormat index_format, + PrimitiveType primitive_type, IndexFormat index_format, bool early_z, const RenderTargetCache::PipelineRenderTarget render_targets[5], PipelineDescription& description_out); @@ -187,6 +188,7 @@ class PipelineCache { // Whether the output merger is emulated in pixel shaders. bool edram_rov_used_; + uint32_t resolution_scale_; // Reusable shader translator. std::unique_ptr shader_translator_ = nullptr; diff --git a/src/xenia/gpu/d3d12/shaders/dxbc/adaptive_triangle_hs.cso b/src/xenia/gpu/d3d12/shaders/dxbc/adaptive_triangle_hs.cso index 6bd21f185..ca223382f 100644 Binary files a/src/xenia/gpu/d3d12/shaders/dxbc/adaptive_triangle_hs.cso and b/src/xenia/gpu/d3d12/shaders/dxbc/adaptive_triangle_hs.cso differ diff --git a/src/xenia/gpu/d3d12/shaders/dxbc/adaptive_triangle_hs.h b/src/xenia/gpu/d3d12/shaders/dxbc/adaptive_triangle_hs.h index 279332439..697fb269e 100644 --- a/src/xenia/gpu/d3d12/shaders/dxbc/adaptive_triangle_hs.h +++ b/src/xenia/gpu/d3d12/shaders/dxbc/adaptive_triangle_hs.h @@ -1,14 +1,14 @@ // generated from `xb buildhlsl` // source: adaptive_triangle.hs.hlsl const uint8_t adaptive_triangle_hs[] = { - 0x44, 0x58, 0x42, 0x43, 0x59, 0x8E, 0x2C, 0x6A, 0x26, 0x4A, 0x07, 0x87, - 0xEA, 0xE3, 0x80, 0x50, 0xA6, 0xCE, 0x8B, 0x03, 0x01, 0x00, 0x00, 0x00, - 0x90, 0x14, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, - 0x98, 0x0E, 0x00, 0x00, 0xA8, 0x0E, 0x00, 0x00, 0xB8, 0x0E, 0x00, 0x00, - 0x4C, 0x0F, 0x00, 0x00, 0xE4, 0x13, 0x00, 0x00, 0xF4, 0x13, 0x00, 0x00, - 0x52, 0x44, 0x45, 0x46, 0x54, 0x0E, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x44, 0x58, 0x42, 0x43, 0xD3, 0x77, 0xE2, 0x68, 0x85, 0x6B, 0x19, 0x33, + 0xF7, 0x3E, 0x88, 0x4D, 0x47, 0xD8, 0xC1, 0xDD, 0x01, 0x00, 0x00, 0x00, + 0xA0, 0x11, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, + 0xA8, 0x0B, 0x00, 0x00, 0xB8, 0x0B, 0x00, 0x00, 0xC8, 0x0B, 0x00, 0x00, + 0x5C, 0x0C, 0x00, 0x00, 0xF4, 0x10, 0x00, 0x00, 0x04, 0x11, 0x00, 0x00, + 0x52, 0x44, 0x45, 0x46, 0x64, 0x0B, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, - 0x01, 0x05, 0x53, 0x48, 0x00, 0x05, 0x00, 0x00, 0x2A, 0x0E, 0x00, 0x00, + 0x01, 0x05, 0x53, 0x48, 0x00, 0x05, 0x00, 0x00, 0x3A, 0x0B, 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, 0xB4, 0x00, 0x00, 0x00, @@ -27,417 +27,354 @@ const uint8_t adaptive_triangle_hs[] = { 0x65, 0x64, 0x5F, 0x6D, 0x65, 0x6D, 0x6F, 0x72, 0x79, 0x5F, 0x75, 0x61, 0x76, 0x00, 0x78, 0x65, 0x5F, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x5F, 0x63, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x00, 0xDE, 0x00, 0x00, 0x00, - 0x2F, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x60, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x08, 0x00, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0xD0, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x70, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x68, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x94, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x70, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8C, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 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, 0x08, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x70, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xA7, 0x06, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x68, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xD7, 0x08, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xCF, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0xF0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE8, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x14, 0x09, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0C, 0x07, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x07, 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, 0x70, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4C, 0x07, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x09, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x84, 0x07, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x70, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x68, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x9D, 0x09, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x68, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x95, 0x07, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xAB, 0x09, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xA3, 0x07, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x09, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x07, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x2C, 0x0A, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x08, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x42, 0x0A, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0A, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3A, 0x08, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x59, 0x0A, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x51, 0x08, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x74, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x6C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x98, 0x0A, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xCC, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x90, 0x08, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xC4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xB0, 0x0A, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xA8, 0x08, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xC5, 0x0A, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xBD, 0x08, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x70, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x68, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xE0, 0x0A, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF4, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xD8, 0x08, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xEC, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x0B, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x0B, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x58, 0x0B, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x50, 0x09, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x75, 0x0B, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6D, 0x09, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x8A, 0x0B, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0A, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x82, 0x09, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xA5, 0x0B, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x9D, 0x09, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xBF, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x70, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xB7, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xDE, 0x0B, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xD8, 0x09, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xF9, 0x0B, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x09, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x70, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x68, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x14, 0x0C, 0x00, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x70, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0E, 0x0A, 0x00, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x0C, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x0B, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2A, 0x0A, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0C, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0A, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x2C, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x5D, 0x0C, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x34, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x57, 0x0A, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2C, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x72, 0x0C, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x0B, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0x0A, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x84, 0x0C, 0x00, 0x00, - 0x50, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x8F, 0x0A, 0x00, 0x00, + 0x50, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xA4, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x9F, 0x0C, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x34, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC8, 0x0A, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xBB, 0x0C, 0x00, 0x00, 0x70, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x0B, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x00, 0xB0, 0x01, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xD7, 0x0C, 0x00, 0x00, - 0x80, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x22, 0x0B, 0x00, 0x00, + 0xC0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xEC, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xF4, 0x0C, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x34, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0D, 0x00, 0x00, 0xA0, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x0B, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x24, 0x0D, 0x00, 0x00, - 0xB0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF4, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x3D, 0x0D, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF4, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x56, 0x0D, 0x00, 0x00, 0xD0, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x0B, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x0D, 0x00, 0x00, - 0xE0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x7E, 0x0D, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF4, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x96, 0x0D, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x0A, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xAE, 0x0D, 0x00, 0x00, - 0x10, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF4, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xC6, 0x0D, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF4, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xDE, 0x0D, 0x00, 0x00, 0x30, 0x02, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x0A, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xF6, 0x0D, 0x00, 0x00, - 0x40, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF4, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x0E, 0x00, 0x00, 0x50, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF4, 0x0A, 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, 0x69, 0x08, 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, 0x5F, 0x61, 0x6E, - 0x64, 0x5F, 0x65, 0x64, 0x67, 0x65, 0x5F, 0x66, 0x61, 0x63, 0x74, 0x6F, - 0x72, 0x73, 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, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 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, - 0xEC, 0x08, 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, + 0x61, 0x06, 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, 0x5F, 0x61, 0x6E, 0x64, 0x5F, 0x65, 0x64, + 0x67, 0x65, 0x5F, 0x66, 0x61, 0x63, 0x74, 0x6F, 0x72, 0x73, 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, + 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, 0x28, 0x09, 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, 0xE4, 0x06, 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, + 0x20, 0x07, 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, 0x59, 0x07, 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, - 0x61, 0x09, 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, 0xC6, 0x09, 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, 0xFE, 0x09, 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, 0x6E, 0x0A, 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, 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, 0xAB, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, + 0xBE, 0x07, 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, - 0x28, 0x09, 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, + 0xF6, 0x07, 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, 0x2C, 0x0B, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x66, 0x08, 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, 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, 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, - 0x72, 0x65, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x5F, 0x73, - 0x63, 0x61, 0x6C, 0x65, 0x5F, 0x6C, 0x6F, 0x67, 0x32, 0x00, 0x78, 0x65, - 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, - 0x69, 0x6C, 0x5F, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6E, 0x63, 0x65, - 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, - 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, 0x6D, - 0x61, 0x73, 0x6B, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, - 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x77, 0x72, 0x69, - 0x74, 0x65, 0x5F, 0x6D, 0x61, 0x73, 0x6B, 0x00, 0x78, 0x65, 0x5F, 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, 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, 0x20, 0x07, 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, + 0x24, 0x09, 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, 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, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, - 0x5F, 0x66, 0x72, 0x6F, 0x6E, 0x74, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, - 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, - 0x62, 0x61, 0x63, 0x6B, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, - 0x6D, 0x5F, 0x62, 0x61, 0x73, 0x65, 0x5F, 0x64, 0x77, 0x6F, 0x72, 0x64, - 0x73, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x72, - 0x74, 0x5F, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x00, 0x78, 0x65, 0x5F, 0x65, - 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x72, 0x74, 0x5F, 0x70, 0x61, 0x63, 0x6B, - 0x5F, 0x77, 0x69, 0x64, 0x74, 0x68, 0x5F, 0x6C, 0x6F, 0x77, 0x00, 0x78, - 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x72, 0x74, 0x5F, 0x70, - 0x61, 0x63, 0x6B, 0x5F, 0x6F, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5F, 0x6C, - 0x6F, 0x77, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, - 0x72, 0x74, 0x5F, 0x70, 0x61, 0x63, 0x6B, 0x5F, 0x77, 0x69, 0x64, 0x74, - 0x68, 0x5F, 0x68, 0x69, 0x67, 0x68, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, - 0x72, 0x61, 0x6D, 0x5F, 0x72, 0x74, 0x5F, 0x70, 0x61, 0x63, 0x6B, 0x5F, - 0x6F, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5F, 0x68, 0x69, 0x67, 0x68, 0x00, - 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x6C, 0x6F, 0x61, - 0x64, 0x5F, 0x6D, 0x61, 0x73, 0x6B, 0x5F, 0x72, 0x74, 0x30, 0x31, 0x00, - 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x6C, 0x6F, 0x61, - 0x64, 0x5F, 0x6D, 0x61, 0x73, 0x6B, 0x5F, 0x72, 0x74, 0x32, 0x33, 0x00, - 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x6C, 0x6F, 0x61, - 0x64, 0x5F, 0x73, 0x63, 0x61, 0x6C, 0x65, 0x5F, 0x72, 0x74, 0x30, 0x31, - 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x6C, 0x6F, - 0x61, 0x64, 0x5F, 0x73, 0x63, 0x61, 0x6C, 0x65, 0x5F, 0x72, 0x74, 0x32, - 0x33, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x62, - 0x6C, 0x65, 0x6E, 0x64, 0x5F, 0x72, 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, - 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x62, 0x6C, 0x65, 0x6E, 0x64, - 0x5F, 0x72, 0x74, 0x32, 0x33, 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, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, - 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x6D, 0x69, 0x6E, - 0x5F, 0x72, 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, - 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x6D, 0x69, 0x6E, - 0x5F, 0x72, 0x74, 0x32, 0x33, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, - 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x6D, 0x61, 0x78, - 0x5F, 0x72, 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, - 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x6D, 0x61, 0x78, - 0x5F, 0x72, 0x74, 0x32, 0x33, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, - 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x73, 0x63, 0x61, - 0x6C, 0x65, 0x5F, 0x72, 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, - 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x73, - 0x63, 0x61, 0x6C, 0x65, 0x5F, 0x72, 0x74, 0x32, 0x33, 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, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4F, 0x53, 0x47, 0x4E, + 0x5F, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6E, 0x63, 0x65, 0x00, 0x78, + 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, + 0x63, 0x69, 0x6C, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, 0x6D, 0x61, 0x73, + 0x6B, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, + 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, + 0x5F, 0x6D, 0x61, 0x73, 0x6B, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, + 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x66, + 0x72, 0x6F, 0x6E, 0x74, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, + 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x62, 0x61, + 0x63, 0x6B, 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, 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, 0x20, 0x07, 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, 0x24, 0x09, 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, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x50, 0x43, 0x53, 0x47, 0x8C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x0E, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x01, 0x0E, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x01, 0x0E, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 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, 0x90, 0x04, 0x00, 0x00, - 0x51, 0x00, 0x03, 0x00, 0x24, 0x01, 0x00, 0x00, 0x71, 0x00, 0x00, 0x01, - 0x93, 0x18, 0x00, 0x01, 0x94, 0x18, 0x00, 0x01, 0x95, 0x10, 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, 0xA1, 0x00, 0x00, 0x06, 0x46, 0x7E, 0x30, 0x00, + 0x4F, 0x53, 0x47, 0x4E, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x50, 0x43, 0x53, 0x47, 0x8C, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x03, 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, + 0x90, 0x04, 0x00, 0x00, 0x51, 0x00, 0x03, 0x00, 0x24, 0x01, 0x00, 0x00, + 0x71, 0x00, 0x00, 0x01, 0x93, 0x18, 0x00, 0x01, 0x94, 0x18, 0x00, 0x01, + 0x95, 0x10, 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, - 0x00, 0x00, 0x00, 0x00, 0x9D, 0x00, 0x00, 0x06, 0x46, 0xEE, 0x31, 0x00, + 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x06, + 0x46, 0x7E, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9D, 0x00, 0x00, 0x06, + 0x46, 0xEE, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x01, + 0x5F, 0x00, 0x00, 0x02, 0x00, 0xB0, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, + 0x12, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x67, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, + 0x03, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x0A, 0x00, 0xD0, 0x00, 0x00, + 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x01, 0x5F, 0x00, 0x00, 0x02, - 0x00, 0xB0, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, - 0x12, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x67, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, - 0x26, 0x00, 0x00, 0x0A, 0x00, 0xD0, 0x00, 0x00, 0x12, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3A, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x08, 0x12, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0xB0, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x0C, 0xE2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xA6, 0x88, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFC, 0xFF, 0xFF, 0x1F, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x29, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, + 0x01, 0x40, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x08, + 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB0, 0x00, 0x00, + 0x01, 0x40, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0C, 0xE2, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xA6, 0x88, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x1F, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x04, 0x03, - 0x2A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA5, 0x00, 0x00, 0x08, - 0x72, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x46, 0xE2, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x01, 0xA5, 0x00, 0x00, 0x08, - 0x72, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x46, 0x72, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x01, 0x55, 0x00, 0x00, 0x09, - 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x80, 0x30, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x09, - 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x2A, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07, + 0x01, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1F, 0x00, 0x04, 0x03, 0x2A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xA5, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0xE2, 0x21, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x01, + 0xA5, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x72, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x01, + 0x55, 0x00, 0x00, 0x09, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2A, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x04, 0x03, 0x0A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x29, 0x00, 0x00, 0x0A, 0x72, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x57, 0x00, 0x00, 0x09, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x80, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, + 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x04, 0x03, 0x0A, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x0A, 0x72, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x40, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0A, + 0x72, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, + 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x55, 0x00, 0x00, 0x0A, 0x72, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0A, 0x72, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x40, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, - 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x0A, - 0x72, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x0A, 0x72, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x07, 0x72, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x01, - 0x1F, 0x00, 0x04, 0x03, 0x3A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x55, 0x00, 0x00, 0x0A, 0x72, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x11, 0x72, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x40, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x15, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0A, 0x72, 0x00, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x02, 0x40, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x07, + 0x72, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x00, 0x01, 0x1F, 0x00, 0x04, 0x03, 0x3A, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x0A, 0x72, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, - 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x09, + 0x02, 0x40, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x11, + 0x72, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x02, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0A, 0x72, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x09, - 0x72, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x56, 0x85, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, - 0x12, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, + 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, + 0x34, 0x00, 0x00, 0x09, 0x72, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, + 0x33, 0x00, 0x00, 0x09, 0x72, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x85, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x05, 0x12, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, + 0x12, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x12, 0x20, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x05, 0x12, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x01, - 0x74, 0x00, 0x00, 0x01, 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, 0x67, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, - 0x01, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0A, 0xB0, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0A, 0xB0, 0x11, 0x00, 0x01, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x07, - 0x12, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0A, 0xB0, 0x11, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x3E, 0x00, 0x00, 0x01, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x54, 0x41, 0x54, - 0x94, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3E, 0x00, 0x00, 0x01, 0x74, 0x00, 0x00, 0x01, 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, 0x67, 0x00, 0x00, 0x04, + 0x12, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x68, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x07, + 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xB0, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0A, 0xB0, 0x11, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x33, 0x00, 0x00, 0x07, 0x12, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xB0, 0x11, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x01, 0x53, 0x46, 0x49, 0x30, + 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x54, 0x41, 0x54, 0x94, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x03, 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, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0A, 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, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x02, 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_triangle_hs.txt b/src/xenia/gpu/d3d12/shaders/dxbc/adaptive_triangle_hs.txt index 6c5b4c1c2..65b8a92ca 100644 --- a/src/xenia/gpu/d3d12/shaders/dxbc/adaptive_triangle_hs.txt +++ b/src/xenia/gpu/d3d12/shaders/dxbc/adaptive_triangle_hs.txt @@ -33,31 +33,18 @@ // 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] -// uint xe_edram_resolution_scale_log2;// Offset: 256 Size: 4 [unused] +// uint xe_edram_resolution_square_scale;// Offset: 256 Size: 4 [unused] // uint xe_edram_stencil_reference; // Offset: 260 Size: 4 [unused] // uint xe_edram_stencil_read_mask; // Offset: 264 Size: 4 [unused] // uint xe_edram_stencil_write_mask; // Offset: 268 Size: 4 [unused] // uint4 xe_edram_stencil_front; // Offset: 272 Size: 16 [unused] // uint4 xe_edram_stencil_back; // Offset: 288 Size: 16 [unused] -// uint4 xe_edram_base_dwords; // Offset: 304 Size: 16 [unused] -// uint4 xe_edram_rt_flags; // Offset: 320 Size: 16 [unused] -// uint4 xe_edram_rt_pack_width_low; // Offset: 336 Size: 16 [unused] -// uint4 xe_edram_rt_pack_offset_low; // Offset: 352 Size: 16 [unused] -// uint4 xe_edram_rt_pack_width_high; // Offset: 368 Size: 16 [unused] -// uint4 xe_edram_rt_pack_offset_high;// Offset: 384 Size: 16 [unused] -// uint4 xe_edram_load_mask_rt01; // Offset: 400 Size: 16 [unused] -// uint4 xe_edram_load_mask_rt23; // Offset: 416 Size: 16 [unused] -// float4 xe_edram_load_scale_rt01; // Offset: 432 Size: 16 [unused] -// float4 xe_edram_load_scale_rt23; // Offset: 448 Size: 16 [unused] -// uint4 xe_edram_blend_rt01; // Offset: 464 Size: 16 [unused] -// uint4 xe_edram_blend_rt23; // Offset: 480 Size: 16 [unused] -// float4 xe_edram_blend_constant; // Offset: 496 Size: 16 [unused] -// float4 xe_edram_store_min_rt01; // Offset: 512 Size: 16 [unused] -// float4 xe_edram_store_min_rt23; // Offset: 528 Size: 16 [unused] -// float4 xe_edram_store_max_rt01; // Offset: 544 Size: 16 [unused] -// float4 xe_edram_store_max_rt23; // Offset: 560 Size: 16 [unused] -// float4 xe_edram_store_scale_rt01; // Offset: 576 Size: 16 [unused] -// float4 xe_edram_store_scale_rt23; // Offset: 592 Size: 16 [unused] +// uint4 xe_edram_rt_base_dwords_scaled;// Offset: 304 Size: 16 [unused] +// uint4 xe_edram_rt_format_flags; // Offset: 320 Size: 16 [unused] +// float4 xe_edram_rt_clamp[4]; // Offset: 336 Size: 64 [unused] +// uint4 xe_edram_rt_keep_mask[2]; // Offset: 400 Size: 32 [unused] +// uint4 xe_edram_rt_blend_factors_ops;// Offset: 432 Size: 16 [unused] +// float4 xe_edram_blend_constant; // Offset: 448 Size: 16 [unused] // // } // diff --git a/src/xenia/gpu/d3d12/shaders/dxbc/continuous_quad_hs.cso b/src/xenia/gpu/d3d12/shaders/dxbc/continuous_quad_hs.cso index 291853241..2423effc2 100644 Binary files a/src/xenia/gpu/d3d12/shaders/dxbc/continuous_quad_hs.cso and b/src/xenia/gpu/d3d12/shaders/dxbc/continuous_quad_hs.cso differ diff --git a/src/xenia/gpu/d3d12/shaders/dxbc/continuous_quad_hs.h b/src/xenia/gpu/d3d12/shaders/dxbc/continuous_quad_hs.h index aa7c43fb4..844683671 100644 --- a/src/xenia/gpu/d3d12/shaders/dxbc/continuous_quad_hs.h +++ b/src/xenia/gpu/d3d12/shaders/dxbc/continuous_quad_hs.h @@ -1,14 +1,14 @@ // generated from `xb buildhlsl` // source: continuous_quad.hs.hlsl const uint8_t continuous_quad_hs[] = { - 0x44, 0x58, 0x42, 0x43, 0x0A, 0x36, 0x34, 0x68, 0x8B, 0xCB, 0x9A, 0x2E, - 0xE5, 0x83, 0x98, 0x9C, 0xAB, 0x32, 0x61, 0x41, 0x01, 0x00, 0x00, 0x00, - 0x08, 0x11, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, - 0x1C, 0x0E, 0x00, 0x00, 0x2C, 0x0E, 0x00, 0x00, 0x3C, 0x0E, 0x00, 0x00, - 0x00, 0x0F, 0x00, 0x00, 0x6C, 0x10, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, - 0xDC, 0x0D, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, + 0x44, 0x58, 0x42, 0x43, 0x32, 0x07, 0xAF, 0x2F, 0x45, 0xAD, 0x31, 0xC4, + 0x2E, 0x33, 0xBF, 0xC5, 0x4C, 0xF1, 0x72, 0x96, 0x01, 0x00, 0x00, 0x00, + 0x18, 0x0E, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, + 0x2C, 0x0B, 0x00, 0x00, 0x3C, 0x0B, 0x00, 0x00, 0x4C, 0x0B, 0x00, 0x00, + 0x10, 0x0C, 0x00, 0x00, 0x7C, 0x0D, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, + 0xEC, 0x0A, 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, 0xB2, 0x0D, 0x00, 0x00, 0x13, 0x13, 0x44, 0x25, + 0x00, 0x05, 0x00, 0x00, 0xC2, 0x0A, 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, @@ -16,353 +16,290 @@ const uint8_t continuous_quad_hs[] = { 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, 0x2F, 0x00, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x60, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xE8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, + 0x72, 0x00, 0xAB, 0xAB, 0x64, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x90, 0x00, 0x00, 0x00, 0xD0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xE0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x14, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x37, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2F, 0x06, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x5F, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x57, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x08, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x94, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xB8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xB0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xDC, 0x08, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xD4, 0x06, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xE8, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0C, 0x07, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x25, 0x09, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x07, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE8, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x09, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x54, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2B, 0x07, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4C, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x09, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xAC, 0x07, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xCA, 0x09, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC2, 0x07, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xE1, 0x09, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xD9, 0x07, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0A, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x18, 0x08, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x54, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x4C, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x38, 0x0A, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x08, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x4D, 0x0A, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x45, 0x08, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x68, 0x0A, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x60, 0x08, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x74, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xA0, 0x0A, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x98, 0x08, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xE0, 0x0A, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xD8, 0x08, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0A, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xF5, 0x08, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x12, 0x0B, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x09, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x2D, 0x0B, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x25, 0x09, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0B, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x66, 0x0B, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x09, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x81, 0x0B, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7B, 0x09, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x0B, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x96, 0x09, 0x00, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xB8, 0x0B, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xB2, 0x09, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xCF, 0x0B, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xC9, 0x09, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xE5, 0x0B, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xDF, 0x09, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFA, 0x0B, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFE, 0x09, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x0A, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x27, 0x0C, 0x00, 0x00, - 0x60, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0A, 0x00, 0x00, + 0x90, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x43, 0x0C, 0x00, 0x00, 0x70, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8C, 0x0A, 0x00, 0x00, 0xB0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0C, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xAA, 0x0A, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0C, 0x00, 0x00, - 0x90, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x94, 0x0C, 0x00, 0x00, 0xA0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xAC, 0x0C, 0x00, 0x00, 0xB0, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xC5, 0x0C, 0x00, 0x00, - 0xC0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xDE, 0x0C, 0x00, 0x00, 0xD0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xF2, 0x0C, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0D, 0x00, 0x00, - 0xF0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x1E, 0x0D, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x0D, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x0D, 0x00, 0x00, - 0x20, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x66, 0x0D, 0x00, 0x00, 0x30, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x7E, 0x0D, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x98, 0x0D, 0x00, 0x00, - 0x50, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x0A, 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, + 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, 0xE9, 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, 0x5F, 0x61, 0x6E, 0x64, 0x5F, 0x65, 0x64, 0x67, 0x65, 0x5F, 0x66, + 0x61, 0x63, 0x74, 0x6F, 0x72, 0x73, 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, 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, - 0xF1, 0x07, 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, 0x5F, 0x61, 0x6E, 0x64, 0x5F, 0x65, 0x64, - 0x67, 0x65, 0x5F, 0x66, 0x61, 0x63, 0x74, 0x6F, 0x72, 0x73, 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, - 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6C, 0x06, 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, 0x74, 0x08, 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, 0xA8, 0x06, 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, - 0xB0, 0x08, 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, 0xE1, 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, 0xE9, 0x08, 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, 0x46, 0x07, 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, 0x7E, 0x07, 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, - 0x4E, 0x09, 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, - 0x86, 0x09, 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, - 0xF6, 0x09, 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, 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, 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, 0xB0, 0x08, 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, - 0xB4, 0x0A, 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, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, 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, 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, - 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, 0x72, 0x65, 0x73, 0x6F, - 0x6C, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x5F, 0x73, 0x63, 0x61, 0x6C, 0x65, - 0x5F, 0x6C, 0x6F, 0x67, 0x32, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, - 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x72, - 0x65, 0x66, 0x65, 0x72, 0x65, 0x6E, 0x63, 0x65, 0x00, 0x78, 0x65, 0x5F, - 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, - 0x6C, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, 0x6D, 0x61, 0x73, 0x6B, 0x00, - 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, - 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x6D, - 0x61, 0x73, 0x6B, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, - 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x66, 0x72, 0x6F, - 0x6E, 0x74, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, - 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x62, 0x61, 0x63, 0x6B, - 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x62, 0x61, - 0x73, 0x65, 0x5F, 0x64, 0x77, 0x6F, 0x72, 0x64, 0x73, 0x00, 0x78, 0x65, - 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x72, 0x74, 0x5F, 0x66, 0x6C, - 0x61, 0x67, 0x73, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, - 0x5F, 0x72, 0x74, 0x5F, 0x70, 0x61, 0x63, 0x6B, 0x5F, 0x77, 0x69, 0x64, - 0x74, 0x68, 0x5F, 0x6C, 0x6F, 0x77, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, - 0x72, 0x61, 0x6D, 0x5F, 0x72, 0x74, 0x5F, 0x70, 0x61, 0x63, 0x6B, 0x5F, - 0x6F, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5F, 0x6C, 0x6F, 0x77, 0x00, 0x78, - 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x72, 0x74, 0x5F, 0x70, - 0x61, 0x63, 0x6B, 0x5F, 0x77, 0x69, 0x64, 0x74, 0x68, 0x5F, 0x68, 0x69, - 0x67, 0x68, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, - 0x72, 0x74, 0x5F, 0x70, 0x61, 0x63, 0x6B, 0x5F, 0x6F, 0x66, 0x66, 0x73, - 0x65, 0x74, 0x5F, 0x68, 0x69, 0x67, 0x68, 0x00, 0x78, 0x65, 0x5F, 0x65, - 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x6C, 0x6F, 0x61, 0x64, 0x5F, 0x6D, 0x61, - 0x73, 0x6B, 0x5F, 0x72, 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, - 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x6C, 0x6F, 0x61, 0x64, 0x5F, 0x6D, 0x61, - 0x73, 0x6B, 0x5F, 0x72, 0x74, 0x32, 0x33, 0x00, 0x78, 0x65, 0x5F, 0x65, - 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x6C, 0x6F, 0x61, 0x64, 0x5F, 0x73, 0x63, - 0x61, 0x6C, 0x65, 0x5F, 0x72, 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, 0x5F, - 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x6C, 0x6F, 0x61, 0x64, 0x5F, 0x73, - 0x63, 0x61, 0x6C, 0x65, 0x5F, 0x72, 0x74, 0x32, 0x33, 0x00, 0x78, 0x65, + 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, 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, 0xA8, 0x06, 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, 0xAC, 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, 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, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6E, 0x63, 0x65, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, + 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, + 0x72, 0x65, 0x61, 0x64, 0x5F, 0x6D, 0x61, 0x73, 0x6B, 0x00, 0x78, 0x65, + 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, + 0x69, 0x6C, 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x6D, 0x61, 0x73, + 0x6B, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, + 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x66, 0x72, 0x6F, 0x6E, 0x74, + 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, + 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x62, 0x61, 0x63, 0x6B, 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, 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, + 0xA8, 0x06, 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, + 0xAC, 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, 0x72, 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, - 0x61, 0x6D, 0x5F, 0x62, 0x6C, 0x65, 0x6E, 0x64, 0x5F, 0x72, 0x74, 0x32, - 0x33, 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, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, - 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x6D, 0x69, 0x6E, 0x5F, 0x72, 0x74, 0x30, - 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, - 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x6D, 0x69, 0x6E, 0x5F, 0x72, 0x74, 0x32, - 0x33, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, - 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x6D, 0x61, 0x78, 0x5F, 0x72, 0x74, 0x30, - 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, - 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x6D, 0x61, 0x78, 0x5F, 0x72, 0x74, 0x32, - 0x33, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, - 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x73, 0x63, 0x61, 0x6C, 0x65, 0x5F, 0x72, - 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, - 0x5F, 0x73, 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x73, 0x63, 0x61, 0x6C, 0x65, - 0x5F, 0x72, 0x74, 0x32, 0x33, 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, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 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, 0x64, 0x01, 0x00, 0x00, 0x51, 0x00, 0x03, 0x00, - 0x59, 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, - 0x73, 0x00, 0x00, 0x01, 0x99, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, - 0x5F, 0x00, 0x00, 0x02, 0x00, 0x70, 0x01, 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, + 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, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 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, 0x64, 0x01, 0x00, 0x00, + 0x51, 0x00, 0x03, 0x00, 0x59, 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, 0x73, 0x00, 0x00, 0x01, 0x99, 0x00, 0x00, 0x02, + 0x04, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x02, 0x00, 0x70, 0x01, 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, 0x36, 0x00, 0x00, 0x04, 0x12, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0A, 0x70, 0x01, 0x00, 0x36, 0x00, 0x00, 0x08, + 0x12, 0x20, 0x90, 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, 0x3E, 0x00, 0x00, 0x01, 0x73, 0x00, 0x00, 0x01, + 0x99, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x02, + 0x00, 0x70, 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, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x12, 0x20, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x04, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0A, 0x70, 0x01, 0x00, 0x36, 0x00, 0x00, 0x08, 0x12, 0x20, 0x90, 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, - 0x3E, 0x00, 0x00, 0x01, 0x73, 0x00, 0x00, 0x01, 0x99, 0x00, 0x00, 0x02, - 0x02, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x02, 0x00, 0x70, 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, 0x36, 0x00, 0x00, 0x04, - 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x70, 0x01, 0x00, - 0x36, 0x00, 0x00, 0x09, 0x12, 0x20, 0xD0, 0x00, 0x04, 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, - 0x3E, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x94, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x70, 0x01, 0x00, 0x36, 0x00, 0x00, 0x09, 0x12, 0x20, 0xD0, 0x00, + 0x04, 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, 0x3E, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, + 0x94, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 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, 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, - 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, + 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/continuous_quad_hs.txt b/src/xenia/gpu/d3d12/shaders/dxbc/continuous_quad_hs.txt index ebb6ecd56..4357f46b6 100644 --- a/src/xenia/gpu/d3d12/shaders/dxbc/continuous_quad_hs.txt +++ b/src/xenia/gpu/d3d12/shaders/dxbc/continuous_quad_hs.txt @@ -29,31 +29,18 @@ // 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] -// uint xe_edram_resolution_scale_log2;// Offset: 256 Size: 4 [unused] +// uint xe_edram_resolution_square_scale;// Offset: 256 Size: 4 [unused] // uint xe_edram_stencil_reference; // Offset: 260 Size: 4 [unused] // uint xe_edram_stencil_read_mask; // Offset: 264 Size: 4 [unused] // uint xe_edram_stencil_write_mask; // Offset: 268 Size: 4 [unused] // uint4 xe_edram_stencil_front; // Offset: 272 Size: 16 [unused] // uint4 xe_edram_stencil_back; // Offset: 288 Size: 16 [unused] -// uint4 xe_edram_base_dwords; // Offset: 304 Size: 16 [unused] -// uint4 xe_edram_rt_flags; // Offset: 320 Size: 16 [unused] -// uint4 xe_edram_rt_pack_width_low; // Offset: 336 Size: 16 [unused] -// uint4 xe_edram_rt_pack_offset_low; // Offset: 352 Size: 16 [unused] -// uint4 xe_edram_rt_pack_width_high; // Offset: 368 Size: 16 [unused] -// uint4 xe_edram_rt_pack_offset_high;// Offset: 384 Size: 16 [unused] -// uint4 xe_edram_load_mask_rt01; // Offset: 400 Size: 16 [unused] -// uint4 xe_edram_load_mask_rt23; // Offset: 416 Size: 16 [unused] -// float4 xe_edram_load_scale_rt01; // Offset: 432 Size: 16 [unused] -// float4 xe_edram_load_scale_rt23; // Offset: 448 Size: 16 [unused] -// uint4 xe_edram_blend_rt01; // Offset: 464 Size: 16 [unused] -// uint4 xe_edram_blend_rt23; // Offset: 480 Size: 16 [unused] -// float4 xe_edram_blend_constant; // Offset: 496 Size: 16 [unused] -// float4 xe_edram_store_min_rt01; // Offset: 512 Size: 16 [unused] -// float4 xe_edram_store_min_rt23; // Offset: 528 Size: 16 [unused] -// float4 xe_edram_store_max_rt01; // Offset: 544 Size: 16 [unused] -// float4 xe_edram_store_max_rt23; // Offset: 560 Size: 16 [unused] -// float4 xe_edram_store_scale_rt01; // Offset: 576 Size: 16 [unused] -// float4 xe_edram_store_scale_rt23; // Offset: 592 Size: 16 [unused] +// uint4 xe_edram_rt_base_dwords_scaled;// Offset: 304 Size: 16 [unused] +// uint4 xe_edram_rt_format_flags; // Offset: 320 Size: 16 [unused] +// float4 xe_edram_rt_clamp[4]; // Offset: 336 Size: 64 [unused] +// uint4 xe_edram_rt_keep_mask[2]; // Offset: 400 Size: 32 [unused] +// uint4 xe_edram_rt_blend_factors_ops;// Offset: 432 Size: 16 [unused] +// float4 xe_edram_blend_constant; // Offset: 448 Size: 16 [unused] // // } // diff --git a/src/xenia/gpu/d3d12/shaders/dxbc/continuous_triangle_hs.cso b/src/xenia/gpu/d3d12/shaders/dxbc/continuous_triangle_hs.cso index 63054b362..56a18142d 100644 Binary files a/src/xenia/gpu/d3d12/shaders/dxbc/continuous_triangle_hs.cso and b/src/xenia/gpu/d3d12/shaders/dxbc/continuous_triangle_hs.cso differ diff --git a/src/xenia/gpu/d3d12/shaders/dxbc/continuous_triangle_hs.h b/src/xenia/gpu/d3d12/shaders/dxbc/continuous_triangle_hs.h index d65deadf5..d8436cf76 100644 --- a/src/xenia/gpu/d3d12/shaders/dxbc/continuous_triangle_hs.h +++ b/src/xenia/gpu/d3d12/shaders/dxbc/continuous_triangle_hs.h @@ -1,14 +1,14 @@ // generated from `xb buildhlsl` // source: continuous_triangle.hs.hlsl const uint8_t continuous_triangle_hs[] = { - 0x44, 0x58, 0x42, 0x43, 0x9F, 0xB1, 0xD4, 0x55, 0xB9, 0xB5, 0x81, 0xA0, - 0xA5, 0xCE, 0xE0, 0x14, 0x7F, 0x20, 0xA7, 0xA7, 0x01, 0x00, 0x00, 0x00, - 0x78, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, - 0x1C, 0x0E, 0x00, 0x00, 0x2C, 0x0E, 0x00, 0x00, 0x3C, 0x0E, 0x00, 0x00, - 0xD0, 0x0E, 0x00, 0x00, 0xDC, 0x0F, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, - 0xDC, 0x0D, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, + 0x44, 0x58, 0x42, 0x43, 0x3D, 0x08, 0x1F, 0xEF, 0xC9, 0x86, 0x78, 0x67, + 0xD6, 0xF4, 0xD0, 0x0C, 0x56, 0x40, 0x1E, 0xB1, 0x01, 0x00, 0x00, 0x00, + 0x88, 0x0D, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, + 0x2C, 0x0B, 0x00, 0x00, 0x3C, 0x0B, 0x00, 0x00, 0x4C, 0x0B, 0x00, 0x00, + 0xE0, 0x0B, 0x00, 0x00, 0xEC, 0x0C, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, + 0xEC, 0x0A, 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, 0xB2, 0x0D, 0x00, 0x00, 0x13, 0x13, 0x44, 0x25, + 0x00, 0x05, 0x00, 0x00, 0xC2, 0x0A, 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, @@ -16,341 +16,278 @@ const uint8_t continuous_triangle_hs[] = { 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, 0x2F, 0x00, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x60, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xE8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, + 0x72, 0x00, 0xAB, 0xAB, 0x64, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x90, 0x00, 0x00, 0x00, 0xD0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xE0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x14, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x37, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2F, 0x06, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x5F, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x57, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x08, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x94, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xB8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xB0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xDC, 0x08, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xD4, 0x06, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xE8, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0C, 0x07, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x25, 0x09, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x07, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE8, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x09, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x54, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2B, 0x07, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4C, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x09, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xAC, 0x07, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xCA, 0x09, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC2, 0x07, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xE1, 0x09, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xD9, 0x07, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0A, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x18, 0x08, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x54, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x4C, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x38, 0x0A, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x08, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x4D, 0x0A, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x45, 0x08, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x68, 0x0A, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x60, 0x08, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x74, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xA0, 0x0A, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x98, 0x08, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xE0, 0x0A, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xD8, 0x08, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0A, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xF5, 0x08, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x12, 0x0B, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x09, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x2D, 0x0B, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x25, 0x09, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0B, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x66, 0x0B, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x09, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x81, 0x0B, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7B, 0x09, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x0B, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x96, 0x09, 0x00, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xB8, 0x0B, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xB2, 0x09, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xCF, 0x0B, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xC9, 0x09, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xE5, 0x0B, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xDF, 0x09, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFA, 0x0B, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFE, 0x09, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x0A, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x27, 0x0C, 0x00, 0x00, - 0x60, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0A, 0x00, 0x00, + 0x90, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x43, 0x0C, 0x00, 0x00, 0x70, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8C, 0x0A, 0x00, 0x00, 0xB0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0C, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xAA, 0x0A, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0C, 0x00, 0x00, - 0x90, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x94, 0x0C, 0x00, 0x00, 0xA0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xAC, 0x0C, 0x00, 0x00, 0xB0, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xC5, 0x0C, 0x00, 0x00, - 0xC0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xDE, 0x0C, 0x00, 0x00, 0xD0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xF2, 0x0C, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0D, 0x00, 0x00, - 0xF0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x1E, 0x0D, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x0D, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x0D, 0x00, 0x00, - 0x20, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x66, 0x0D, 0x00, 0x00, 0x30, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x7E, 0x0D, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x98, 0x0D, 0x00, 0x00, - 0x50, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x0A, 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, + 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, 0xE9, 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, 0x5F, 0x61, 0x6E, 0x64, 0x5F, 0x65, 0x64, 0x67, 0x65, 0x5F, 0x66, + 0x61, 0x63, 0x74, 0x6F, 0x72, 0x73, 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, 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, - 0xF1, 0x07, 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, 0x5F, 0x61, 0x6E, 0x64, 0x5F, 0x65, 0x64, - 0x67, 0x65, 0x5F, 0x66, 0x61, 0x63, 0x74, 0x6F, 0x72, 0x73, 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, - 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6C, 0x06, 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, 0x74, 0x08, 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, 0xA8, 0x06, 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, - 0xB0, 0x08, 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, 0xE1, 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, 0xE9, 0x08, 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, 0x46, 0x07, 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, 0x7E, 0x07, 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, - 0x4E, 0x09, 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, - 0x86, 0x09, 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, - 0xF6, 0x09, 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, 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, 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, 0xB0, 0x08, 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, - 0xB4, 0x0A, 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, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, 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, 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, - 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, 0x72, 0x65, 0x73, 0x6F, - 0x6C, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x5F, 0x73, 0x63, 0x61, 0x6C, 0x65, - 0x5F, 0x6C, 0x6F, 0x67, 0x32, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, - 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x72, - 0x65, 0x66, 0x65, 0x72, 0x65, 0x6E, 0x63, 0x65, 0x00, 0x78, 0x65, 0x5F, - 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, - 0x6C, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, 0x6D, 0x61, 0x73, 0x6B, 0x00, - 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, - 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x6D, - 0x61, 0x73, 0x6B, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, - 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x66, 0x72, 0x6F, - 0x6E, 0x74, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, - 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x62, 0x61, 0x63, 0x6B, - 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x62, 0x61, - 0x73, 0x65, 0x5F, 0x64, 0x77, 0x6F, 0x72, 0x64, 0x73, 0x00, 0x78, 0x65, - 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x72, 0x74, 0x5F, 0x66, 0x6C, - 0x61, 0x67, 0x73, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, - 0x5F, 0x72, 0x74, 0x5F, 0x70, 0x61, 0x63, 0x6B, 0x5F, 0x77, 0x69, 0x64, - 0x74, 0x68, 0x5F, 0x6C, 0x6F, 0x77, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, - 0x72, 0x61, 0x6D, 0x5F, 0x72, 0x74, 0x5F, 0x70, 0x61, 0x63, 0x6B, 0x5F, - 0x6F, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5F, 0x6C, 0x6F, 0x77, 0x00, 0x78, - 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x72, 0x74, 0x5F, 0x70, - 0x61, 0x63, 0x6B, 0x5F, 0x77, 0x69, 0x64, 0x74, 0x68, 0x5F, 0x68, 0x69, - 0x67, 0x68, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, - 0x72, 0x74, 0x5F, 0x70, 0x61, 0x63, 0x6B, 0x5F, 0x6F, 0x66, 0x66, 0x73, - 0x65, 0x74, 0x5F, 0x68, 0x69, 0x67, 0x68, 0x00, 0x78, 0x65, 0x5F, 0x65, - 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x6C, 0x6F, 0x61, 0x64, 0x5F, 0x6D, 0x61, - 0x73, 0x6B, 0x5F, 0x72, 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, - 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x6C, 0x6F, 0x61, 0x64, 0x5F, 0x6D, 0x61, - 0x73, 0x6B, 0x5F, 0x72, 0x74, 0x32, 0x33, 0x00, 0x78, 0x65, 0x5F, 0x65, - 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x6C, 0x6F, 0x61, 0x64, 0x5F, 0x73, 0x63, - 0x61, 0x6C, 0x65, 0x5F, 0x72, 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, 0x5F, - 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x6C, 0x6F, 0x61, 0x64, 0x5F, 0x73, - 0x63, 0x61, 0x6C, 0x65, 0x5F, 0x72, 0x74, 0x32, 0x33, 0x00, 0x78, 0x65, - 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x62, 0x6C, 0x65, 0x6E, 0x64, - 0x5F, 0x72, 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, - 0x61, 0x6D, 0x5F, 0x62, 0x6C, 0x65, 0x6E, 0x64, 0x5F, 0x72, 0x74, 0x32, - 0x33, 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, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, - 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x6D, 0x69, 0x6E, 0x5F, 0x72, 0x74, 0x30, - 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, - 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x6D, 0x69, 0x6E, 0x5F, 0x72, 0x74, 0x32, - 0x33, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, - 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x6D, 0x61, 0x78, 0x5F, 0x72, 0x74, 0x30, - 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, - 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x6D, 0x61, 0x78, 0x5F, 0x72, 0x74, 0x32, - 0x33, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, - 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x73, 0x63, 0x61, 0x6C, 0x65, 0x5F, 0x72, - 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, - 0x5F, 0x73, 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x73, 0x63, 0x61, 0x6C, 0x65, - 0x5F, 0x72, 0x74, 0x32, 0x33, 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, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x4F, 0x53, 0x47, 0x4E, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x43, 0x53, 0x47, - 0x8C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x00, 0x00, - 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 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, 0x04, 0x01, 0x00, 0x00, 0x51, 0x00, 0x03, 0x00, - 0x41, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x01, 0x93, 0x18, 0x00, 0x01, - 0x94, 0x18, 0x00, 0x01, 0x95, 0x10, 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, - 0x73, 0x00, 0x00, 0x01, 0x99, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, - 0x5F, 0x00, 0x00, 0x02, 0x00, 0x70, 0x01, 0x00, 0x67, 0x00, 0x00, 0x04, - 0x12, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x67, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, - 0x01, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x04, - 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x70, 0x01, 0x00, - 0x36, 0x00, 0x00, 0x08, 0x12, 0x20, 0x90, 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, 0x3E, 0x00, 0x00, 0x01, - 0x73, 0x00, 0x00, 0x01, 0x67, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x07, - 0x12, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1A, 0x80, 0x30, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x3E, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x94, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 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, 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, 0xA8, 0x06, 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, 0xAC, 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, 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, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6E, 0x63, 0x65, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, + 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, + 0x72, 0x65, 0x61, 0x64, 0x5F, 0x6D, 0x61, 0x73, 0x6B, 0x00, 0x78, 0x65, + 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, + 0x69, 0x6C, 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x6D, 0x61, 0x73, + 0x6B, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, + 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x66, 0x72, 0x6F, 0x6E, 0x74, + 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, + 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x62, 0x61, 0x63, 0x6B, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 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, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xA8, 0x06, 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, 0x00, 0x00, 0x00, 0x00, + 0xAC, 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, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4F, 0x53, 0x47, 0x4E, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x50, 0x43, 0x53, 0x47, 0x8C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x0E, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x0E, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x0E, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 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, 0x04, 0x01, 0x00, 0x00, + 0x51, 0x00, 0x03, 0x00, 0x41, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x01, + 0x93, 0x18, 0x00, 0x01, 0x94, 0x18, 0x00, 0x01, 0x95, 0x10, 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, 0x73, 0x00, 0x00, 0x01, 0x99, 0x00, 0x00, 0x02, + 0x03, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x02, 0x00, 0x70, 0x01, 0x00, + 0x67, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, + 0x12, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x68, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x04, + 0x12, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x04, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x70, 0x01, 0x00, 0x36, 0x00, 0x00, 0x08, 0x12, 0x20, 0x90, 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, + 0x3E, 0x00, 0x00, 0x01, 0x73, 0x00, 0x00, 0x01, 0x67, 0x00, 0x00, 0x04, + 0x12, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x07, 0x12, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x1A, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, + 0x94, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 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, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; diff --git a/src/xenia/gpu/d3d12/shaders/dxbc/continuous_triangle_hs.txt b/src/xenia/gpu/d3d12/shaders/dxbc/continuous_triangle_hs.txt index ba20f83cd..90ae50955 100644 --- a/src/xenia/gpu/d3d12/shaders/dxbc/continuous_triangle_hs.txt +++ b/src/xenia/gpu/d3d12/shaders/dxbc/continuous_triangle_hs.txt @@ -29,31 +29,18 @@ // 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] -// uint xe_edram_resolution_scale_log2;// Offset: 256 Size: 4 [unused] +// uint xe_edram_resolution_square_scale;// Offset: 256 Size: 4 [unused] // uint xe_edram_stencil_reference; // Offset: 260 Size: 4 [unused] // uint xe_edram_stencil_read_mask; // Offset: 264 Size: 4 [unused] // uint xe_edram_stencil_write_mask; // Offset: 268 Size: 4 [unused] // uint4 xe_edram_stencil_front; // Offset: 272 Size: 16 [unused] // uint4 xe_edram_stencil_back; // Offset: 288 Size: 16 [unused] -// uint4 xe_edram_base_dwords; // Offset: 304 Size: 16 [unused] -// uint4 xe_edram_rt_flags; // Offset: 320 Size: 16 [unused] -// uint4 xe_edram_rt_pack_width_low; // Offset: 336 Size: 16 [unused] -// uint4 xe_edram_rt_pack_offset_low; // Offset: 352 Size: 16 [unused] -// uint4 xe_edram_rt_pack_width_high; // Offset: 368 Size: 16 [unused] -// uint4 xe_edram_rt_pack_offset_high;// Offset: 384 Size: 16 [unused] -// uint4 xe_edram_load_mask_rt01; // Offset: 400 Size: 16 [unused] -// uint4 xe_edram_load_mask_rt23; // Offset: 416 Size: 16 [unused] -// float4 xe_edram_load_scale_rt01; // Offset: 432 Size: 16 [unused] -// float4 xe_edram_load_scale_rt23; // Offset: 448 Size: 16 [unused] -// uint4 xe_edram_blend_rt01; // Offset: 464 Size: 16 [unused] -// uint4 xe_edram_blend_rt23; // Offset: 480 Size: 16 [unused] -// float4 xe_edram_blend_constant; // Offset: 496 Size: 16 [unused] -// float4 xe_edram_store_min_rt01; // Offset: 512 Size: 16 [unused] -// float4 xe_edram_store_min_rt23; // Offset: 528 Size: 16 [unused] -// float4 xe_edram_store_max_rt01; // Offset: 544 Size: 16 [unused] -// float4 xe_edram_store_max_rt23; // Offset: 560 Size: 16 [unused] -// float4 xe_edram_store_scale_rt01; // Offset: 576 Size: 16 [unused] -// float4 xe_edram_store_scale_rt23; // Offset: 592 Size: 16 [unused] +// uint4 xe_edram_rt_base_dwords_scaled;// Offset: 304 Size: 16 [unused] +// uint4 xe_edram_rt_format_flags; // Offset: 320 Size: 16 [unused] +// float4 xe_edram_rt_clamp[4]; // Offset: 336 Size: 64 [unused] +// uint4 xe_edram_rt_keep_mask[2]; // Offset: 400 Size: 32 [unused] +// uint4 xe_edram_rt_blend_factors_ops;// Offset: 432 Size: 16 [unused] +// float4 xe_edram_blend_constant; // Offset: 448 Size: 16 [unused] // // } // diff --git a/src/xenia/gpu/d3d12/shaders/dxbc/discrete_quad_hs.cso b/src/xenia/gpu/d3d12/shaders/dxbc/discrete_quad_hs.cso index 7afacb448..6f1007a15 100644 Binary files a/src/xenia/gpu/d3d12/shaders/dxbc/discrete_quad_hs.cso and b/src/xenia/gpu/d3d12/shaders/dxbc/discrete_quad_hs.cso differ diff --git a/src/xenia/gpu/d3d12/shaders/dxbc/discrete_quad_hs.h b/src/xenia/gpu/d3d12/shaders/dxbc/discrete_quad_hs.h index c4f4c0e8f..ee46142d2 100644 --- a/src/xenia/gpu/d3d12/shaders/dxbc/discrete_quad_hs.h +++ b/src/xenia/gpu/d3d12/shaders/dxbc/discrete_quad_hs.h @@ -1,14 +1,14 @@ // generated from `xb buildhlsl` // source: discrete_quad.hs.hlsl const uint8_t discrete_quad_hs[] = { - 0x44, 0x58, 0x42, 0x43, 0x4E, 0x07, 0xE6, 0x4D, 0x50, 0xA2, 0xCB, 0x4B, - 0x5E, 0xED, 0x6F, 0xC1, 0x07, 0xBD, 0x5B, 0x6E, 0x01, 0x00, 0x00, 0x00, - 0x08, 0x11, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, - 0x1C, 0x0E, 0x00, 0x00, 0x2C, 0x0E, 0x00, 0x00, 0x3C, 0x0E, 0x00, 0x00, - 0x00, 0x0F, 0x00, 0x00, 0x6C, 0x10, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, - 0xDC, 0x0D, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, + 0x44, 0x58, 0x42, 0x43, 0x83, 0xC2, 0x65, 0xA7, 0xBF, 0x6B, 0xFA, 0xDA, + 0x98, 0x5E, 0xE0, 0xC6, 0x23, 0x47, 0x51, 0xD8, 0x01, 0x00, 0x00, 0x00, + 0x18, 0x0E, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, + 0x2C, 0x0B, 0x00, 0x00, 0x3C, 0x0B, 0x00, 0x00, 0x4C, 0x0B, 0x00, 0x00, + 0x10, 0x0C, 0x00, 0x00, 0x7C, 0x0D, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, + 0xEC, 0x0A, 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, 0xB2, 0x0D, 0x00, 0x00, 0x13, 0x13, 0x44, 0x25, + 0x00, 0x05, 0x00, 0x00, 0xC2, 0x0A, 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, @@ -16,353 +16,290 @@ const uint8_t discrete_quad_hs[] = { 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, 0x2F, 0x00, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x60, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xE8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, + 0x72, 0x00, 0xAB, 0xAB, 0x64, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x90, 0x00, 0x00, 0x00, 0xD0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xE0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x14, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x37, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2F, 0x06, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x5F, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x57, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x08, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x94, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xB8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xB0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xDC, 0x08, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xD4, 0x06, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xE8, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0C, 0x07, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x25, 0x09, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x07, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE8, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x09, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x54, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2B, 0x07, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4C, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x09, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xAC, 0x07, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xCA, 0x09, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC2, 0x07, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xE1, 0x09, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xD9, 0x07, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0A, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x18, 0x08, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x54, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x4C, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x38, 0x0A, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x08, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x4D, 0x0A, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x45, 0x08, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x68, 0x0A, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x60, 0x08, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x74, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xA0, 0x0A, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x98, 0x08, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xE0, 0x0A, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xD8, 0x08, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0A, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xF5, 0x08, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x12, 0x0B, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x09, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x2D, 0x0B, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x25, 0x09, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0B, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x66, 0x0B, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x09, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x81, 0x0B, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7B, 0x09, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x0B, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x96, 0x09, 0x00, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xB8, 0x0B, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xB2, 0x09, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xCF, 0x0B, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xC9, 0x09, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xE5, 0x0B, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xDF, 0x09, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFA, 0x0B, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFE, 0x09, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x0A, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x27, 0x0C, 0x00, 0x00, - 0x60, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0A, 0x00, 0x00, + 0x90, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x43, 0x0C, 0x00, 0x00, 0x70, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8C, 0x0A, 0x00, 0x00, 0xB0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0C, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xAA, 0x0A, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0C, 0x00, 0x00, - 0x90, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x94, 0x0C, 0x00, 0x00, 0xA0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xAC, 0x0C, 0x00, 0x00, 0xB0, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xC5, 0x0C, 0x00, 0x00, - 0xC0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xDE, 0x0C, 0x00, 0x00, 0xD0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xF2, 0x0C, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0D, 0x00, 0x00, - 0xF0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x1E, 0x0D, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x0D, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x0D, 0x00, 0x00, - 0x20, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x66, 0x0D, 0x00, 0x00, 0x30, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x7E, 0x0D, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x98, 0x0D, 0x00, 0x00, - 0x50, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x0A, 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, + 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, 0xE9, 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, 0x5F, 0x61, 0x6E, 0x64, 0x5F, 0x65, 0x64, 0x67, 0x65, 0x5F, 0x66, + 0x61, 0x63, 0x74, 0x6F, 0x72, 0x73, 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, 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, - 0xF1, 0x07, 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, 0x5F, 0x61, 0x6E, 0x64, 0x5F, 0x65, 0x64, - 0x67, 0x65, 0x5F, 0x66, 0x61, 0x63, 0x74, 0x6F, 0x72, 0x73, 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, - 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6C, 0x06, 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, 0x74, 0x08, 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, 0xA8, 0x06, 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, - 0xB0, 0x08, 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, 0xE1, 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, 0xE9, 0x08, 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, 0x46, 0x07, 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, 0x7E, 0x07, 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, - 0x4E, 0x09, 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, - 0x86, 0x09, 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, - 0xF6, 0x09, 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, 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, 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, 0xB0, 0x08, 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, - 0xB4, 0x0A, 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, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, 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, 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, - 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, 0x72, 0x65, 0x73, 0x6F, - 0x6C, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x5F, 0x73, 0x63, 0x61, 0x6C, 0x65, - 0x5F, 0x6C, 0x6F, 0x67, 0x32, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, - 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x72, - 0x65, 0x66, 0x65, 0x72, 0x65, 0x6E, 0x63, 0x65, 0x00, 0x78, 0x65, 0x5F, - 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, - 0x6C, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, 0x6D, 0x61, 0x73, 0x6B, 0x00, - 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, - 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x6D, - 0x61, 0x73, 0x6B, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, - 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x66, 0x72, 0x6F, - 0x6E, 0x74, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, - 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x62, 0x61, 0x63, 0x6B, - 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x62, 0x61, - 0x73, 0x65, 0x5F, 0x64, 0x77, 0x6F, 0x72, 0x64, 0x73, 0x00, 0x78, 0x65, - 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x72, 0x74, 0x5F, 0x66, 0x6C, - 0x61, 0x67, 0x73, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, - 0x5F, 0x72, 0x74, 0x5F, 0x70, 0x61, 0x63, 0x6B, 0x5F, 0x77, 0x69, 0x64, - 0x74, 0x68, 0x5F, 0x6C, 0x6F, 0x77, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, - 0x72, 0x61, 0x6D, 0x5F, 0x72, 0x74, 0x5F, 0x70, 0x61, 0x63, 0x6B, 0x5F, - 0x6F, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5F, 0x6C, 0x6F, 0x77, 0x00, 0x78, - 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x72, 0x74, 0x5F, 0x70, - 0x61, 0x63, 0x6B, 0x5F, 0x77, 0x69, 0x64, 0x74, 0x68, 0x5F, 0x68, 0x69, - 0x67, 0x68, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, - 0x72, 0x74, 0x5F, 0x70, 0x61, 0x63, 0x6B, 0x5F, 0x6F, 0x66, 0x66, 0x73, - 0x65, 0x74, 0x5F, 0x68, 0x69, 0x67, 0x68, 0x00, 0x78, 0x65, 0x5F, 0x65, - 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x6C, 0x6F, 0x61, 0x64, 0x5F, 0x6D, 0x61, - 0x73, 0x6B, 0x5F, 0x72, 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, - 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x6C, 0x6F, 0x61, 0x64, 0x5F, 0x6D, 0x61, - 0x73, 0x6B, 0x5F, 0x72, 0x74, 0x32, 0x33, 0x00, 0x78, 0x65, 0x5F, 0x65, - 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x6C, 0x6F, 0x61, 0x64, 0x5F, 0x73, 0x63, - 0x61, 0x6C, 0x65, 0x5F, 0x72, 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, 0x5F, - 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x6C, 0x6F, 0x61, 0x64, 0x5F, 0x73, - 0x63, 0x61, 0x6C, 0x65, 0x5F, 0x72, 0x74, 0x32, 0x33, 0x00, 0x78, 0x65, + 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, 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, 0xA8, 0x06, 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, 0xAC, 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, 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, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6E, 0x63, 0x65, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, + 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, + 0x72, 0x65, 0x61, 0x64, 0x5F, 0x6D, 0x61, 0x73, 0x6B, 0x00, 0x78, 0x65, + 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, + 0x69, 0x6C, 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x6D, 0x61, 0x73, + 0x6B, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, + 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x66, 0x72, 0x6F, 0x6E, 0x74, + 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, + 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x62, 0x61, 0x63, 0x6B, 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, 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, + 0xA8, 0x06, 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, + 0xAC, 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, 0x72, 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, - 0x61, 0x6D, 0x5F, 0x62, 0x6C, 0x65, 0x6E, 0x64, 0x5F, 0x72, 0x74, 0x32, - 0x33, 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, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, - 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x6D, 0x69, 0x6E, 0x5F, 0x72, 0x74, 0x30, - 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, - 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x6D, 0x69, 0x6E, 0x5F, 0x72, 0x74, 0x32, - 0x33, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, - 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x6D, 0x61, 0x78, 0x5F, 0x72, 0x74, 0x30, - 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, - 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x6D, 0x61, 0x78, 0x5F, 0x72, 0x74, 0x32, - 0x33, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, - 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x73, 0x63, 0x61, 0x6C, 0x65, 0x5F, 0x72, - 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, - 0x5F, 0x73, 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x73, 0x63, 0x61, 0x6C, 0x65, - 0x5F, 0x72, 0x74, 0x32, 0x33, 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, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 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, 0x64, 0x01, 0x00, 0x00, 0x51, 0x00, 0x03, 0x00, - 0x59, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x01, 0x93, 0x20, 0x00, 0x01, - 0x94, 0x20, 0x00, 0x01, 0x95, 0x18, 0x00, 0x01, 0x96, 0x08, 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, - 0x73, 0x00, 0x00, 0x01, 0x99, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, - 0x5F, 0x00, 0x00, 0x02, 0x00, 0x70, 0x01, 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, + 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, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 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, 0x64, 0x01, 0x00, 0x00, + 0x51, 0x00, 0x03, 0x00, 0x59, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x01, + 0x93, 0x20, 0x00, 0x01, 0x94, 0x20, 0x00, 0x01, 0x95, 0x18, 0x00, 0x01, + 0x96, 0x08, 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, 0x73, 0x00, 0x00, 0x01, 0x99, 0x00, 0x00, 0x02, + 0x04, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x02, 0x00, 0x70, 0x01, 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, 0x36, 0x00, 0x00, 0x04, 0x12, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0A, 0x70, 0x01, 0x00, 0x36, 0x00, 0x00, 0x08, + 0x12, 0x20, 0x90, 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, 0x3E, 0x00, 0x00, 0x01, 0x73, 0x00, 0x00, 0x01, + 0x99, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x02, + 0x00, 0x70, 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, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x12, 0x20, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x04, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0A, 0x70, 0x01, 0x00, 0x36, 0x00, 0x00, 0x08, 0x12, 0x20, 0x90, 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, - 0x3E, 0x00, 0x00, 0x01, 0x73, 0x00, 0x00, 0x01, 0x99, 0x00, 0x00, 0x02, - 0x02, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x02, 0x00, 0x70, 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, 0x36, 0x00, 0x00, 0x04, - 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x70, 0x01, 0x00, - 0x36, 0x00, 0x00, 0x09, 0x12, 0x20, 0xD0, 0x00, 0x04, 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, - 0x3E, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x94, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x70, 0x01, 0x00, 0x36, 0x00, 0x00, 0x09, 0x12, 0x20, 0xD0, 0x00, + 0x04, 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, 0x3E, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, + 0x94, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 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, 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, - 0x04, 0x00, 0x00, 0x00, 0x03, 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, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 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/discrete_quad_hs.txt b/src/xenia/gpu/d3d12/shaders/dxbc/discrete_quad_hs.txt index 54d599142..bdc83502e 100644 --- a/src/xenia/gpu/d3d12/shaders/dxbc/discrete_quad_hs.txt +++ b/src/xenia/gpu/d3d12/shaders/dxbc/discrete_quad_hs.txt @@ -29,31 +29,18 @@ // 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] -// uint xe_edram_resolution_scale_log2;// Offset: 256 Size: 4 [unused] +// uint xe_edram_resolution_square_scale;// Offset: 256 Size: 4 [unused] // uint xe_edram_stencil_reference; // Offset: 260 Size: 4 [unused] // uint xe_edram_stencil_read_mask; // Offset: 264 Size: 4 [unused] // uint xe_edram_stencil_write_mask; // Offset: 268 Size: 4 [unused] // uint4 xe_edram_stencil_front; // Offset: 272 Size: 16 [unused] // uint4 xe_edram_stencil_back; // Offset: 288 Size: 16 [unused] -// uint4 xe_edram_base_dwords; // Offset: 304 Size: 16 [unused] -// uint4 xe_edram_rt_flags; // Offset: 320 Size: 16 [unused] -// uint4 xe_edram_rt_pack_width_low; // Offset: 336 Size: 16 [unused] -// uint4 xe_edram_rt_pack_offset_low; // Offset: 352 Size: 16 [unused] -// uint4 xe_edram_rt_pack_width_high; // Offset: 368 Size: 16 [unused] -// uint4 xe_edram_rt_pack_offset_high;// Offset: 384 Size: 16 [unused] -// uint4 xe_edram_load_mask_rt01; // Offset: 400 Size: 16 [unused] -// uint4 xe_edram_load_mask_rt23; // Offset: 416 Size: 16 [unused] -// float4 xe_edram_load_scale_rt01; // Offset: 432 Size: 16 [unused] -// float4 xe_edram_load_scale_rt23; // Offset: 448 Size: 16 [unused] -// uint4 xe_edram_blend_rt01; // Offset: 464 Size: 16 [unused] -// uint4 xe_edram_blend_rt23; // Offset: 480 Size: 16 [unused] -// float4 xe_edram_blend_constant; // Offset: 496 Size: 16 [unused] -// float4 xe_edram_store_min_rt01; // Offset: 512 Size: 16 [unused] -// float4 xe_edram_store_min_rt23; // Offset: 528 Size: 16 [unused] -// float4 xe_edram_store_max_rt01; // Offset: 544 Size: 16 [unused] -// float4 xe_edram_store_max_rt23; // Offset: 560 Size: 16 [unused] -// float4 xe_edram_store_scale_rt01; // Offset: 576 Size: 16 [unused] -// float4 xe_edram_store_scale_rt23; // Offset: 592 Size: 16 [unused] +// uint4 xe_edram_rt_base_dwords_scaled;// Offset: 304 Size: 16 [unused] +// uint4 xe_edram_rt_format_flags; // Offset: 320 Size: 16 [unused] +// float4 xe_edram_rt_clamp[4]; // Offset: 336 Size: 64 [unused] +// uint4 xe_edram_rt_keep_mask[2]; // Offset: 400 Size: 32 [unused] +// uint4 xe_edram_rt_blend_factors_ops;// Offset: 432 Size: 16 [unused] +// float4 xe_edram_blend_constant; // Offset: 448 Size: 16 [unused] // // } // diff --git a/src/xenia/gpu/d3d12/shaders/dxbc/discrete_triangle_hs.cso b/src/xenia/gpu/d3d12/shaders/dxbc/discrete_triangle_hs.cso index 945db63cd..961bd6464 100644 Binary files a/src/xenia/gpu/d3d12/shaders/dxbc/discrete_triangle_hs.cso and b/src/xenia/gpu/d3d12/shaders/dxbc/discrete_triangle_hs.cso differ diff --git a/src/xenia/gpu/d3d12/shaders/dxbc/discrete_triangle_hs.h b/src/xenia/gpu/d3d12/shaders/dxbc/discrete_triangle_hs.h index 79bf2997f..ba757fd00 100644 --- a/src/xenia/gpu/d3d12/shaders/dxbc/discrete_triangle_hs.h +++ b/src/xenia/gpu/d3d12/shaders/dxbc/discrete_triangle_hs.h @@ -1,14 +1,14 @@ // generated from `xb buildhlsl` // source: discrete_triangle.hs.hlsl const uint8_t discrete_triangle_hs[] = { - 0x44, 0x58, 0x42, 0x43, 0xEF, 0x69, 0x83, 0xBF, 0x3B, 0x56, 0x40, 0x44, - 0x22, 0x99, 0x4A, 0x72, 0x43, 0xD5, 0x49, 0x09, 0x01, 0x00, 0x00, 0x00, - 0x78, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, - 0x1C, 0x0E, 0x00, 0x00, 0x2C, 0x0E, 0x00, 0x00, 0x3C, 0x0E, 0x00, 0x00, - 0xD0, 0x0E, 0x00, 0x00, 0xDC, 0x0F, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, - 0xDC, 0x0D, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, + 0x44, 0x58, 0x42, 0x43, 0x2F, 0x97, 0x96, 0x5C, 0x36, 0xC0, 0xB5, 0xDF, + 0x60, 0x56, 0x5E, 0x21, 0x4C, 0xA2, 0xF2, 0xFA, 0x01, 0x00, 0x00, 0x00, + 0x88, 0x0D, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, + 0x2C, 0x0B, 0x00, 0x00, 0x3C, 0x0B, 0x00, 0x00, 0x4C, 0x0B, 0x00, 0x00, + 0xE0, 0x0B, 0x00, 0x00, 0xEC, 0x0C, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, + 0xEC, 0x0A, 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, 0xB2, 0x0D, 0x00, 0x00, 0x13, 0x13, 0x44, 0x25, + 0x00, 0x05, 0x00, 0x00, 0xC2, 0x0A, 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, @@ -16,341 +16,278 @@ const uint8_t discrete_triangle_hs[] = { 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, 0x2F, 0x00, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x60, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xE8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, + 0x72, 0x00, 0xAB, 0xAB, 0x64, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x90, 0x00, 0x00, 0x00, 0xD0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xE0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x14, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x37, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2F, 0x06, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x5F, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x57, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x08, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x94, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xB8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xB0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xDC, 0x08, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xD4, 0x06, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xE8, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0C, 0x07, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x25, 0x09, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x07, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE8, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x09, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x54, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2B, 0x07, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4C, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x09, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xAC, 0x07, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xCA, 0x09, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC2, 0x07, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xE1, 0x09, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xD9, 0x07, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0A, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x18, 0x08, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x54, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x4C, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x38, 0x0A, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x08, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x4D, 0x0A, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x45, 0x08, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x68, 0x0A, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x60, 0x08, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x74, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xA0, 0x0A, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x98, 0x08, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xE0, 0x0A, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xD8, 0x08, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0A, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xF5, 0x08, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x12, 0x0B, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x09, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x2D, 0x0B, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x25, 0x09, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0B, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x66, 0x0B, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x09, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x81, 0x0B, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7B, 0x09, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x0B, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x96, 0x09, 0x00, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xB8, 0x0B, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xB2, 0x09, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xCF, 0x0B, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xC9, 0x09, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xE5, 0x0B, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xDF, 0x09, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFA, 0x0B, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFE, 0x09, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x0A, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x27, 0x0C, 0x00, 0x00, - 0x60, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0A, 0x00, 0x00, + 0x90, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x43, 0x0C, 0x00, 0x00, 0x70, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8C, 0x0A, 0x00, 0x00, 0xB0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0C, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xAA, 0x0A, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0C, 0x00, 0x00, - 0x90, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x94, 0x0C, 0x00, 0x00, 0xA0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xAC, 0x0C, 0x00, 0x00, 0xB0, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xC5, 0x0C, 0x00, 0x00, - 0xC0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xDE, 0x0C, 0x00, 0x00, 0xD0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xF2, 0x0C, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0D, 0x00, 0x00, - 0xF0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x1E, 0x0D, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x0D, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x0D, 0x00, 0x00, - 0x20, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x66, 0x0D, 0x00, 0x00, 0x30, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x7E, 0x0D, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x98, 0x0D, 0x00, 0x00, - 0x50, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x0A, 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, + 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, 0xE9, 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, 0x5F, 0x61, 0x6E, 0x64, 0x5F, 0x65, 0x64, 0x67, 0x65, 0x5F, 0x66, + 0x61, 0x63, 0x74, 0x6F, 0x72, 0x73, 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, 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, - 0xF1, 0x07, 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, 0x5F, 0x61, 0x6E, 0x64, 0x5F, 0x65, 0x64, - 0x67, 0x65, 0x5F, 0x66, 0x61, 0x63, 0x74, 0x6F, 0x72, 0x73, 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, - 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6C, 0x06, 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, 0x74, 0x08, 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, 0xA8, 0x06, 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, - 0xB0, 0x08, 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, 0xE1, 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, 0xE9, 0x08, 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, 0x46, 0x07, 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, 0x7E, 0x07, 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, - 0x4E, 0x09, 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, - 0x86, 0x09, 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, - 0xF6, 0x09, 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, 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, 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, 0xB0, 0x08, 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, - 0xB4, 0x0A, 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, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, 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, 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, - 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, 0x72, 0x65, 0x73, 0x6F, - 0x6C, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x5F, 0x73, 0x63, 0x61, 0x6C, 0x65, - 0x5F, 0x6C, 0x6F, 0x67, 0x32, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, - 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x72, - 0x65, 0x66, 0x65, 0x72, 0x65, 0x6E, 0x63, 0x65, 0x00, 0x78, 0x65, 0x5F, - 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, - 0x6C, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, 0x6D, 0x61, 0x73, 0x6B, 0x00, - 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, - 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x6D, - 0x61, 0x73, 0x6B, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, - 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x66, 0x72, 0x6F, - 0x6E, 0x74, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, - 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x62, 0x61, 0x63, 0x6B, - 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x62, 0x61, - 0x73, 0x65, 0x5F, 0x64, 0x77, 0x6F, 0x72, 0x64, 0x73, 0x00, 0x78, 0x65, - 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x72, 0x74, 0x5F, 0x66, 0x6C, - 0x61, 0x67, 0x73, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, - 0x5F, 0x72, 0x74, 0x5F, 0x70, 0x61, 0x63, 0x6B, 0x5F, 0x77, 0x69, 0x64, - 0x74, 0x68, 0x5F, 0x6C, 0x6F, 0x77, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, - 0x72, 0x61, 0x6D, 0x5F, 0x72, 0x74, 0x5F, 0x70, 0x61, 0x63, 0x6B, 0x5F, - 0x6F, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5F, 0x6C, 0x6F, 0x77, 0x00, 0x78, - 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x72, 0x74, 0x5F, 0x70, - 0x61, 0x63, 0x6B, 0x5F, 0x77, 0x69, 0x64, 0x74, 0x68, 0x5F, 0x68, 0x69, - 0x67, 0x68, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, - 0x72, 0x74, 0x5F, 0x70, 0x61, 0x63, 0x6B, 0x5F, 0x6F, 0x66, 0x66, 0x73, - 0x65, 0x74, 0x5F, 0x68, 0x69, 0x67, 0x68, 0x00, 0x78, 0x65, 0x5F, 0x65, - 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x6C, 0x6F, 0x61, 0x64, 0x5F, 0x6D, 0x61, - 0x73, 0x6B, 0x5F, 0x72, 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, - 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x6C, 0x6F, 0x61, 0x64, 0x5F, 0x6D, 0x61, - 0x73, 0x6B, 0x5F, 0x72, 0x74, 0x32, 0x33, 0x00, 0x78, 0x65, 0x5F, 0x65, - 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x6C, 0x6F, 0x61, 0x64, 0x5F, 0x73, 0x63, - 0x61, 0x6C, 0x65, 0x5F, 0x72, 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, 0x5F, - 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x6C, 0x6F, 0x61, 0x64, 0x5F, 0x73, - 0x63, 0x61, 0x6C, 0x65, 0x5F, 0x72, 0x74, 0x32, 0x33, 0x00, 0x78, 0x65, - 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x62, 0x6C, 0x65, 0x6E, 0x64, - 0x5F, 0x72, 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, - 0x61, 0x6D, 0x5F, 0x62, 0x6C, 0x65, 0x6E, 0x64, 0x5F, 0x72, 0x74, 0x32, - 0x33, 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, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, - 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x6D, 0x69, 0x6E, 0x5F, 0x72, 0x74, 0x30, - 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, - 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x6D, 0x69, 0x6E, 0x5F, 0x72, 0x74, 0x32, - 0x33, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, - 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x6D, 0x61, 0x78, 0x5F, 0x72, 0x74, 0x30, - 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, - 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x6D, 0x61, 0x78, 0x5F, 0x72, 0x74, 0x32, - 0x33, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, - 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x73, 0x63, 0x61, 0x6C, 0x65, 0x5F, 0x72, - 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, - 0x5F, 0x73, 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x73, 0x63, 0x61, 0x6C, 0x65, - 0x5F, 0x72, 0x74, 0x32, 0x33, 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, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x4F, 0x53, 0x47, 0x4E, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x43, 0x53, 0x47, - 0x8C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x00, 0x00, - 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 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, 0x04, 0x01, 0x00, 0x00, 0x51, 0x00, 0x03, 0x00, - 0x41, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x01, 0x93, 0x18, 0x00, 0x01, - 0x94, 0x18, 0x00, 0x01, 0x95, 0x10, 0x00, 0x01, 0x96, 0x08, 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, - 0x73, 0x00, 0x00, 0x01, 0x99, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, - 0x5F, 0x00, 0x00, 0x02, 0x00, 0x70, 0x01, 0x00, 0x67, 0x00, 0x00, 0x04, - 0x12, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x67, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, - 0x01, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x04, - 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x70, 0x01, 0x00, - 0x36, 0x00, 0x00, 0x08, 0x12, 0x20, 0x90, 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, 0x3E, 0x00, 0x00, 0x01, - 0x73, 0x00, 0x00, 0x01, 0x67, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x07, - 0x12, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1A, 0x80, 0x30, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x3E, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x94, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 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, 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, 0xA8, 0x06, 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, 0xAC, 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, 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, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6E, 0x63, 0x65, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, + 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, + 0x72, 0x65, 0x61, 0x64, 0x5F, 0x6D, 0x61, 0x73, 0x6B, 0x00, 0x78, 0x65, + 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, + 0x69, 0x6C, 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x6D, 0x61, 0x73, + 0x6B, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, + 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x66, 0x72, 0x6F, 0x6E, 0x74, + 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, + 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x62, 0x61, 0x63, 0x6B, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 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, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xA8, 0x06, 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, 0x00, 0x00, 0x00, 0x00, + 0xAC, 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, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4F, 0x53, 0x47, 0x4E, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x50, 0x43, 0x53, 0x47, 0x8C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x0E, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x0E, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x0E, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 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, 0x04, 0x01, 0x00, 0x00, + 0x51, 0x00, 0x03, 0x00, 0x41, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x01, + 0x93, 0x18, 0x00, 0x01, 0x94, 0x18, 0x00, 0x01, 0x95, 0x10, 0x00, 0x01, + 0x96, 0x08, 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, 0x73, 0x00, 0x00, 0x01, 0x99, 0x00, 0x00, 0x02, + 0x03, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x02, 0x00, 0x70, 0x01, 0x00, + 0x67, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, 0x12, 0x20, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, + 0x12, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x68, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x04, + 0x12, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x04, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x70, 0x01, 0x00, 0x36, 0x00, 0x00, 0x08, 0x12, 0x20, 0x90, 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, + 0x3E, 0x00, 0x00, 0x01, 0x73, 0x00, 0x00, 0x01, 0x67, 0x00, 0x00, 0x04, + 0x12, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x07, 0x12, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x1A, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, + 0x94, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 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, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; diff --git a/src/xenia/gpu/d3d12/shaders/dxbc/discrete_triangle_hs.txt b/src/xenia/gpu/d3d12/shaders/dxbc/discrete_triangle_hs.txt index fcc177d40..a69e4ba2f 100644 --- a/src/xenia/gpu/d3d12/shaders/dxbc/discrete_triangle_hs.txt +++ b/src/xenia/gpu/d3d12/shaders/dxbc/discrete_triangle_hs.txt @@ -29,31 +29,18 @@ // 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] -// uint xe_edram_resolution_scale_log2;// Offset: 256 Size: 4 [unused] +// uint xe_edram_resolution_square_scale;// Offset: 256 Size: 4 [unused] // uint xe_edram_stencil_reference; // Offset: 260 Size: 4 [unused] // uint xe_edram_stencil_read_mask; // Offset: 264 Size: 4 [unused] // uint xe_edram_stencil_write_mask; // Offset: 268 Size: 4 [unused] // uint4 xe_edram_stencil_front; // Offset: 272 Size: 16 [unused] // uint4 xe_edram_stencil_back; // Offset: 288 Size: 16 [unused] -// uint4 xe_edram_base_dwords; // Offset: 304 Size: 16 [unused] -// uint4 xe_edram_rt_flags; // Offset: 320 Size: 16 [unused] -// uint4 xe_edram_rt_pack_width_low; // Offset: 336 Size: 16 [unused] -// uint4 xe_edram_rt_pack_offset_low; // Offset: 352 Size: 16 [unused] -// uint4 xe_edram_rt_pack_width_high; // Offset: 368 Size: 16 [unused] -// uint4 xe_edram_rt_pack_offset_high;// Offset: 384 Size: 16 [unused] -// uint4 xe_edram_load_mask_rt01; // Offset: 400 Size: 16 [unused] -// uint4 xe_edram_load_mask_rt23; // Offset: 416 Size: 16 [unused] -// float4 xe_edram_load_scale_rt01; // Offset: 432 Size: 16 [unused] -// float4 xe_edram_load_scale_rt23; // Offset: 448 Size: 16 [unused] -// uint4 xe_edram_blend_rt01; // Offset: 464 Size: 16 [unused] -// uint4 xe_edram_blend_rt23; // Offset: 480 Size: 16 [unused] -// float4 xe_edram_blend_constant; // Offset: 496 Size: 16 [unused] -// float4 xe_edram_store_min_rt01; // Offset: 512 Size: 16 [unused] -// float4 xe_edram_store_min_rt23; // Offset: 528 Size: 16 [unused] -// float4 xe_edram_store_max_rt01; // Offset: 544 Size: 16 [unused] -// float4 xe_edram_store_max_rt23; // Offset: 560 Size: 16 [unused] -// float4 xe_edram_store_scale_rt01; // Offset: 576 Size: 16 [unused] -// float4 xe_edram_store_scale_rt23; // Offset: 592 Size: 16 [unused] +// uint4 xe_edram_rt_base_dwords_scaled;// Offset: 304 Size: 16 [unused] +// uint4 xe_edram_rt_format_flags; // Offset: 320 Size: 16 [unused] +// float4 xe_edram_rt_clamp[4]; // Offset: 336 Size: 64 [unused] +// uint4 xe_edram_rt_keep_mask[2]; // Offset: 400 Size: 32 [unused] +// uint4 xe_edram_rt_blend_factors_ops;// Offset: 432 Size: 16 [unused] +// float4 xe_edram_blend_constant; // Offset: 448 Size: 16 [unused] // // } // diff --git a/src/xenia/gpu/d3d12/shaders/dxbc/primitive_point_list_gs.cso b/src/xenia/gpu/d3d12/shaders/dxbc/primitive_point_list_gs.cso index c34951aad..92a01a669 100644 Binary files a/src/xenia/gpu/d3d12/shaders/dxbc/primitive_point_list_gs.cso and b/src/xenia/gpu/d3d12/shaders/dxbc/primitive_point_list_gs.cso differ diff --git a/src/xenia/gpu/d3d12/shaders/dxbc/primitive_point_list_gs.h b/src/xenia/gpu/d3d12/shaders/dxbc/primitive_point_list_gs.h index 98a40246b..06f1fb297 100644 --- a/src/xenia/gpu/d3d12/shaders/dxbc/primitive_point_list_gs.h +++ b/src/xenia/gpu/d3d12/shaders/dxbc/primitive_point_list_gs.h @@ -1,14 +1,14 @@ // generated from `xb buildhlsl` // source: primitive_point_list.gs.hlsl const uint8_t primitive_point_list_gs[] = { - 0x44, 0x58, 0x42, 0x43, 0xDF, 0x09, 0x7D, 0xF7, 0xDE, 0x2E, 0x9F, 0x4F, - 0x1A, 0xC3, 0xA6, 0x4C, 0x38, 0xB4, 0xC9, 0x80, 0x01, 0x00, 0x00, 0x00, - 0x74, 0x20, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x18, 0x0E, 0x00, 0x00, 0x48, 0x10, 0x00, 0x00, 0xCC, 0x12, 0x00, 0x00, - 0xD8, 0x1F, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xDC, 0x0D, 0x00, 0x00, + 0x44, 0x58, 0x42, 0x43, 0x80, 0xFA, 0x69, 0x4E, 0x87, 0x86, 0x83, 0x83, + 0xF1, 0x80, 0x20, 0x6B, 0xF0, 0x91, 0x4E, 0xD1, 0x01, 0x00, 0x00, 0x00, + 0x84, 0x1D, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x28, 0x0B, 0x00, 0x00, 0x58, 0x0D, 0x00, 0x00, 0xDC, 0x0F, 0x00, 0x00, + 0xE8, 0x1C, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xEC, 0x0A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, 0x05, 0x53, 0x47, 0x00, 0x05, 0x00, 0x00, - 0xB2, 0x0D, 0x00, 0x00, 0x13, 0x13, 0x44, 0x25, 0x3C, 0x00, 0x00, 0x00, + 0xC2, 0x0A, 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, @@ -16,574 +16,409 @@ const uint8_t primitive_point_list_gs[] = { 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, 0x2F, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, - 0x60, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xE8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, + 0xD0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xE0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x37, 0x08, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x06, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x5F, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x78, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x57, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x9C, 0x08, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x94, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x08, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xD4, 0x06, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE8, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x14, 0x09, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0C, 0x07, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x25, 0x09, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1D, 0x07, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x33, 0x09, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x07, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x54, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x4C, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x78, 0x09, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x07, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xB4, 0x09, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xAC, 0x07, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xCA, 0x09, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xC2, 0x07, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xE1, 0x09, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFC, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xD9, 0x07, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x20, 0x0A, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x08, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x38, 0x0A, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x30, 0x08, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x4D, 0x0A, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x08, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x68, 0x0A, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0x08, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x0A, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x98, 0x08, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xE0, 0x0A, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xD8, 0x08, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0A, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF5, 0x08, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x12, 0x0B, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x09, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x2D, 0x0B, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x25, 0x09, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x47, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x66, 0x0B, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x60, 0x09, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x81, 0x0B, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7B, 0x09, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x9C, 0x0B, 0x00, 0x00, 0x0C, 0x01, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x96, 0x09, 0x00, 0x00, 0x0C, 0x01, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x0B, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xB2, 0x09, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xCF, 0x0B, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC9, 0x09, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xE5, 0x0B, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xDF, 0x09, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x0B, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x09, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x0C, 0x0C, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x17, 0x0A, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x27, 0x0C, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x0A, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x43, 0x0C, 0x00, 0x00, - 0x70, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x0A, 0x00, 0x00, + 0xB0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xB4, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x5F, 0x0C, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xAA, 0x0A, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x74, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0C, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x94, 0x0C, 0x00, 0x00, - 0xA0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xAC, 0x0C, 0x00, 0x00, 0xB0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xC5, 0x0C, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xDE, 0x0C, 0x00, 0x00, - 0xD0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xF2, 0x0C, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xBC, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x0D, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x0D, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x0D, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x4E, 0x0D, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x66, 0x0D, 0x00, 0x00, - 0x30, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x7E, 0x0D, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x98, 0x0D, 0x00, 0x00, 0x50, 0x02, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x0A, 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, 0xF1, 0x07, 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, 0x5F, 0x61, 0x6E, 0x64, 0x5F, 0x65, 0x64, 0x67, 0x65, 0x5F, 0x66, - 0x61, 0x63, 0x74, 0x6F, 0x72, 0x73, 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, 0x00, 0x00, 0x02, 0x00, + 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, 0x74, 0x08, 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, 0xE9, 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, 0x5F, 0x61, 0x6E, + 0x64, 0x5F, 0x65, 0x64, 0x67, 0x65, 0x5F, 0x66, 0x61, 0x63, 0x74, 0x6F, + 0x72, 0x73, 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, 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, 0xB0, 0x08, 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, 0xE9, 0x08, 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, + 0x6C, 0x06, 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, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x09, 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, 0xA8, 0x06, 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, 0x86, 0x09, 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, 0xF6, 0x09, 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, 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, 0xAB, 0x01, 0x00, 0x03, 0x00, + 0xE1, 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, 0x46, 0x07, 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, 0x7E, 0x07, 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, 0xEE, 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, 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, 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, + 0xA8, 0x06, 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, 0xB0, 0x08, 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, 0xB4, 0x0A, 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, 0x72, 0x65, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x69, - 0x6F, 0x6E, 0x5F, 0x73, 0x63, 0x61, 0x6C, 0x65, 0x5F, 0x6C, 0x6F, 0x67, - 0x32, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, - 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x72, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6E, 0x63, 0x65, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, - 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x72, 0x65, - 0x61, 0x64, 0x5F, 0x6D, 0x61, 0x73, 0x6B, 0x00, 0x78, 0x65, 0x5F, 0x65, - 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, - 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x6D, 0x61, 0x73, 0x6B, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xAC, 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, + 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, 0x73, 0x74, 0x65, - 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x66, 0x72, 0x6F, 0x6E, 0x74, 0x00, 0x78, - 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, - 0x63, 0x69, 0x6C, 0x5F, 0x62, 0x61, 0x63, 0x6B, 0x00, 0x78, 0x65, 0x5F, - 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x62, 0x61, 0x73, 0x65, 0x5F, 0x64, - 0x77, 0x6F, 0x72, 0x64, 0x73, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, - 0x61, 0x6D, 0x5F, 0x72, 0x74, 0x5F, 0x66, 0x6C, 0x61, 0x67, 0x73, 0x00, + 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6E, + 0x63, 0x65, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, + 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x72, 0x65, 0x61, 0x64, + 0x5F, 0x6D, 0x61, 0x73, 0x6B, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, + 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, 0x6C, 0x5F, 0x77, + 0x72, 0x69, 0x74, 0x65, 0x5F, 0x6D, 0x61, 0x73, 0x6B, 0x00, 0x78, 0x65, + 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, + 0x69, 0x6C, 0x5F, 0x66, 0x72, 0x6F, 0x6E, 0x74, 0x00, 0x78, 0x65, 0x5F, + 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x65, 0x6E, 0x63, 0x69, + 0x6C, 0x5F, 0x62, 0x61, 0x63, 0x6B, 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, 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, 0xA8, 0x06, 0x00, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x72, 0x74, 0x5F, - 0x70, 0x61, 0x63, 0x6B, 0x5F, 0x77, 0x69, 0x64, 0x74, 0x68, 0x5F, 0x6C, - 0x6F, 0x77, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, - 0x72, 0x74, 0x5F, 0x70, 0x61, 0x63, 0x6B, 0x5F, 0x6F, 0x66, 0x66, 0x73, - 0x65, 0x74, 0x5F, 0x6C, 0x6F, 0x77, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, - 0x72, 0x61, 0x6D, 0x5F, 0x72, 0x74, 0x5F, 0x70, 0x61, 0x63, 0x6B, 0x5F, - 0x77, 0x69, 0x64, 0x74, 0x68, 0x5F, 0x68, 0x69, 0x67, 0x68, 0x00, 0x78, - 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x72, 0x74, 0x5F, 0x70, - 0x61, 0x63, 0x6B, 0x5F, 0x6F, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5F, 0x68, - 0x69, 0x67, 0x68, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, - 0x5F, 0x6C, 0x6F, 0x61, 0x64, 0x5F, 0x6D, 0x61, 0x73, 0x6B, 0x5F, 0x72, - 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, - 0x5F, 0x6C, 0x6F, 0x61, 0x64, 0x5F, 0x6D, 0x61, 0x73, 0x6B, 0x5F, 0x72, - 0x74, 0x32, 0x33, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, - 0x5F, 0x6C, 0x6F, 0x61, 0x64, 0x5F, 0x73, 0x63, 0x61, 0x6C, 0x65, 0x5F, - 0x72, 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, - 0x6D, 0x5F, 0x6C, 0x6F, 0x61, 0x64, 0x5F, 0x73, 0x63, 0x61, 0x6C, 0x65, - 0x5F, 0x72, 0x74, 0x32, 0x33, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, - 0x61, 0x6D, 0x5F, 0x62, 0x6C, 0x65, 0x6E, 0x64, 0x5F, 0x72, 0x74, 0x30, - 0x31, 0x00, 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x62, - 0x6C, 0x65, 0x6E, 0x64, 0x5F, 0x72, 0x74, 0x32, 0x33, 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, 0x78, 0x65, - 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x6F, 0x72, 0x65, - 0x5F, 0x6D, 0x69, 0x6E, 0x5F, 0x72, 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, - 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x6F, 0x72, 0x65, - 0x5F, 0x6D, 0x69, 0x6E, 0x5F, 0x72, 0x74, 0x32, 0x33, 0x00, 0x78, 0x65, - 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x6F, 0x72, 0x65, - 0x5F, 0x6D, 0x61, 0x78, 0x5F, 0x72, 0x74, 0x30, 0x31, 0x00, 0x78, 0x65, - 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x6F, 0x72, 0x65, - 0x5F, 0x6D, 0x61, 0x78, 0x5F, 0x72, 0x74, 0x32, 0x33, 0x00, 0x78, 0x65, - 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x6F, 0x72, 0x65, - 0x5F, 0x73, 0x63, 0x61, 0x6C, 0x65, 0x5F, 0x72, 0x74, 0x30, 0x31, 0x00, - 0x78, 0x65, 0x5F, 0x65, 0x64, 0x72, 0x61, 0x6D, 0x5F, 0x73, 0x74, 0x6F, - 0x72, 0x65, 0x5F, 0x73, 0x63, 0x61, 0x6C, 0x65, 0x5F, 0x72, 0x74, 0x32, - 0x33, 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, - 0x28, 0x02, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x07, 0x04, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, - 0x09, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, - 0x15, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, - 0x15, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, + 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, 0xAC, 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, 0x28, 0x02, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, + 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, + 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, + 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, + 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, + 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x07, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x03, 0x03, 0x00, 0x00, 0x09, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x0F, 0x0F, 0x00, 0x00, 0x15, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x0F, 0x0F, 0x00, 0x00, 0x15, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x03, 0x03, 0x00, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4F, 0x4F, 0x52, 0x44, + 0x00, 0x53, 0x56, 0x5F, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, + 0x00, 0x53, 0x56, 0x5F, 0x43, 0x6C, 0x69, 0x70, 0x44, 0x69, 0x73, 0x74, + 0x61, 0x6E, 0x63, 0x65, 0x00, 0xAB, 0xAB, 0xAB, 0x4F, 0x53, 0x47, 0x35, + 0x7C, 0x02, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x54, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x54, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x54, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x54, 0x02, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x54, 0x02, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, + 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x54, 0x02, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x03, 0x0C, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5D, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x69, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x03, 0x0C, 0x00, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4F, 0x4F, 0x52, 0x44, 0x00, 0x53, 0x56, 0x5F, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x53, 0x56, 0x5F, 0x43, 0x6C, 0x69, 0x70, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, - 0x00, 0xAB, 0xAB, 0xAB, 0x4F, 0x53, 0x47, 0x35, 0x7C, 0x02, 0x00, 0x00, - 0x15, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x54, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x54, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x54, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x54, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x0B, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x54, 0x02, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x54, 0x02, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x03, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x5D, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x69, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x02, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x03, 0x0C, 0x00, 0x00, 0x54, 0x45, 0x58, 0x43, - 0x4F, 0x4F, 0x52, 0x44, 0x00, 0x53, 0x56, 0x5F, 0x50, 0x6F, 0x73, 0x69, - 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x53, 0x56, 0x5F, 0x43, 0x6C, 0x69, 0x70, - 0x44, 0x69, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x00, 0xAB, 0xAB, 0xAB, - 0x53, 0x48, 0x45, 0x58, 0x04, 0x0D, 0x00, 0x00, 0x51, 0x00, 0x02, 0x00, - 0x41, 0x03, 0x00, 0x00, 0x6A, 0x08, 0x00, 0x01, 0x59, 0x00, 0x00, 0x07, - 0x46, 0x8E, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x5F, 0x00, 0x00, 0x04, 0xF2, 0x10, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0xAB, 0xAB, 0xAB, 0x53, 0x48, 0x45, 0x58, 0x04, 0x0D, 0x00, 0x00, + 0x51, 0x00, 0x02, 0x00, 0x41, 0x03, 0x00, 0x00, 0x6A, 0x08, 0x00, 0x01, + 0x59, 0x00, 0x00, 0x07, 0x46, 0x8E, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, 0xF2, 0x10, 0x20, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, - 0xF2, 0x10, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, + 0xF2, 0x10, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, 0xF2, 0x10, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, 0xF2, 0x10, 0x20, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, - 0xF2, 0x10, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, 0xF2, 0x10, 0x20, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, + 0xF2, 0x10, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, 0xF2, 0x10, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, 0xF2, 0x10, 0x20, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, - 0xF2, 0x10, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, 0xF2, 0x10, 0x20, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, + 0xF2, 0x10, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, 0xF2, 0x10, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, 0xF2, 0x10, 0x20, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, - 0xF2, 0x10, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, 0xF2, 0x10, 0x20, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, + 0xF2, 0x10, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, 0xF2, 0x10, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, 0xF2, 0x10, 0x20, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, - 0xF2, 0x10, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, + 0x0B, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, 0xF2, 0x10, 0x20, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, + 0xF2, 0x10, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, 0xF2, 0x10, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, 0x72, 0x10, 0x20, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, - 0x32, 0x10, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x61, 0x00, 0x00, 0x05, 0xF2, 0x10, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, - 0xF2, 0x10, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, 0xF2, 0x10, 0x20, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, + 0x72, 0x10, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, 0x32, 0x10, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, - 0x5D, 0x08, 0x00, 0x01, 0x8F, 0x00, 0x00, 0x03, 0x00, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x5C, 0x28, 0x00, 0x01, 0x65, 0x00, 0x00, 0x03, - 0xF2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, - 0xF2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, - 0xF2, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, - 0xF2, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, - 0xF2, 0x20, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, - 0xF2, 0x20, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, - 0xF2, 0x20, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, - 0xF2, 0x20, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, - 0xF2, 0x20, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, - 0xF2, 0x20, 0x10, 0x00, 0x09, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, - 0xF2, 0x20, 0x10, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, - 0xF2, 0x20, 0x10, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, - 0xF2, 0x20, 0x10, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, - 0xF2, 0x20, 0x10, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, - 0xF2, 0x20, 0x10, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, - 0xF2, 0x20, 0x10, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, - 0x72, 0x20, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, - 0x32, 0x20, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, - 0xF2, 0x20, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x67, 0x00, 0x00, 0x04, 0xF2, 0x20, 0x10, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, 0x32, 0x20, 0x10, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5E, 0x00, 0x00, 0x02, - 0x04, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x08, 0x12, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x2A, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x37, 0x00, 0x00, 0x0C, 0x32, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x1A, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x46, 0x80, 0x30, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x34, 0x00, 0x00, 0x09, 0x32, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x46, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x8A, 0x30, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x33, 0x00, 0x00, 0x09, 0x32, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x46, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF6, 0x8F, 0x30, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x09, 0x32, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x46, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x80, 0x30, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x08, 0xC2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF6, 0x1F, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0D, - 0xF2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE6, 0x0E, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0xBF, - 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0xBF, - 0x46, 0x14, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x0B, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x08, 0x32, 0x20, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, - 0x42, 0x20, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x2A, 0x10, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, - 0x32, 0x20, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, 0x46, 0x10, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, - 0x32, 0x20, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xC2, 0x20, 0x10, 0x00, - 0x12, 0x00, 0x00, 0x00, 0xA6, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0x32, 0x20, 0x10, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x46, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x03, 0x00, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0B, 0xC2, 0x00, 0x10, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x05, 0xF2, 0x10, 0x20, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x5F, 0x00, 0x00, 0x04, 0xF2, 0x10, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x04, 0x32, 0x10, 0x20, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, + 0x02, 0x00, 0x00, 0x00, 0x5D, 0x08, 0x00, 0x01, 0x8F, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x28, 0x00, 0x01, + 0x65, 0x00, 0x00, 0x03, 0xF2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0xF2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0xF2, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0xF2, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0xF2, 0x20, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0xF2, 0x20, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0xF2, 0x20, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0xF2, 0x20, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0xF2, 0x20, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0xF2, 0x20, 0x10, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0xF2, 0x20, 0x10, 0x00, 0x0A, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0xF2, 0x20, 0x10, 0x00, 0x0B, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0xF2, 0x20, 0x10, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0xF2, 0x20, 0x10, 0x00, 0x0D, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0xF2, 0x20, 0x10, 0x00, 0x0E, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0xF2, 0x20, 0x10, 0x00, 0x0F, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0x72, 0x20, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0x32, 0x20, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x67, 0x00, 0x00, 0x04, 0xF2, 0x20, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, 0xF2, 0x20, 0x10, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, + 0x32, 0x20, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x5E, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x08, + 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2A, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x0C, 0x32, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xA6, 0x1A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x46, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x09, 0x32, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xA6, 0x8A, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x09, 0x32, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF6, 0x8F, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x09, 0x32, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, 0xC2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF6, 0x1F, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x06, 0x14, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x0B, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x08, 0x32, 0x20, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, - 0x42, 0x20, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x2A, 0x10, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, - 0x32, 0x20, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, 0x46, 0x10, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, - 0x32, 0x20, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, 0xE6, 0x0A, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xC2, 0x20, 0x10, 0x00, - 0x12, 0x00, 0x00, 0x00, 0xA6, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0x32, 0x20, 0x10, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x46, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x03, 0x00, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0C, 0x32, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF6, 0x1F, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x46, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x0D, 0xF2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xE6, 0x0E, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xBF, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, + 0x00, 0x00, 0x80, 0xBF, 0x46, 0x14, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, @@ -618,20 +453,75 @@ const uint8_t primitive_point_list_gs[] = { 0x0F, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, 0x32, 0x20, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0x42, 0x20, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x2A, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0x32, 0x20, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, 0x46, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x32, 0x20, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x46, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, + 0x46, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xC2, 0x20, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, 0xA6, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x13, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0x32, 0x20, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x46, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0B, + 0xC2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x04, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF6, 0x1F, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x06, 0x14, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, + 0x0B, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0B, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, + 0x0E, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, + 0x0F, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, 0x32, 0x20, 0x10, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, + 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0x42, 0x20, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x2A, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0x32, 0x20, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x46, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x05, 0x32, 0x20, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, + 0xE6, 0x0A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, + 0xC2, 0x20, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, 0xA6, 0x1E, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, + 0xF2, 0x20, 0x10, 0x00, 0x13, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, + 0x32, 0x20, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x46, 0x10, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0C, + 0x32, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x80, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF6, 0x1F, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x46, 0x10, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, @@ -665,13 +555,13 @@ const uint8_t primitive_point_list_gs[] = { 0xF2, 0x20, 0x10, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, 0x32, 0x20, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0x42, 0x20, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x2A, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0x32, 0x20, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, 0x46, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x32, 0x20, 0x10, 0x00, - 0x12, 0x00, 0x00, 0x00, 0xE6, 0x0A, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xC2, 0x20, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, 0xA6, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x13, 0x00, 0x00, 0x00, @@ -679,19 +569,66 @@ const uint8_t primitive_point_list_gs[] = { 0x36, 0x00, 0x00, 0x06, 0x32, 0x20, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x46, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x03, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x76, 0x00, 0x00, 0x03, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3E, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x94, 0x00, 0x00, 0x00, - 0x6B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x2A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x0A, 0x00, 0x00, 0x00, + 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x0B, 0x00, 0x00, 0x00, + 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x0D, 0x00, 0x00, 0x00, + 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x0E, 0x00, 0x00, 0x00, + 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, 0x0F, 0x00, 0x00, 0x00, + 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x08, 0x32, 0x20, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, + 0x42, 0x20, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x2A, 0x10, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, + 0x32, 0x20, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, 0x46, 0x10, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, + 0x32, 0x20, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, 0xE6, 0x0A, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xC2, 0x20, 0x10, 0x00, + 0x12, 0x00, 0x00, 0x00, 0xA6, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0xF2, 0x20, 0x10, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x46, 0x1E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, 0x32, 0x20, 0x10, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x46, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x03, 0x00, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x03, 0x00, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, + 0x94, 0x00, 0x00, 0x00, 0x6B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 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, 0x01, 0x00, 0x00, 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, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 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, 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, }; diff --git a/src/xenia/gpu/d3d12/shaders/dxbc/primitive_point_list_gs.txt b/src/xenia/gpu/d3d12/shaders/dxbc/primitive_point_list_gs.txt index 00ef94bba..a0e3bc69d 100644 --- a/src/xenia/gpu/d3d12/shaders/dxbc/primitive_point_list_gs.txt +++ b/src/xenia/gpu/d3d12/shaders/dxbc/primitive_point_list_gs.txt @@ -29,31 +29,18 @@ // 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] -// uint xe_edram_resolution_scale_log2;// Offset: 256 Size: 4 [unused] +// uint xe_edram_resolution_square_scale;// Offset: 256 Size: 4 [unused] // uint xe_edram_stencil_reference; // Offset: 260 Size: 4 [unused] // uint xe_edram_stencil_read_mask; // Offset: 264 Size: 4 [unused] // uint xe_edram_stencil_write_mask; // Offset: 268 Size: 4 [unused] // uint4 xe_edram_stencil_front; // Offset: 272 Size: 16 [unused] // uint4 xe_edram_stencil_back; // Offset: 288 Size: 16 [unused] -// uint4 xe_edram_base_dwords; // Offset: 304 Size: 16 [unused] -// uint4 xe_edram_rt_flags; // Offset: 320 Size: 16 [unused] -// uint4 xe_edram_rt_pack_width_low; // Offset: 336 Size: 16 [unused] -// uint4 xe_edram_rt_pack_offset_low; // Offset: 352 Size: 16 [unused] -// uint4 xe_edram_rt_pack_width_high; // Offset: 368 Size: 16 [unused] -// uint4 xe_edram_rt_pack_offset_high;// Offset: 384 Size: 16 [unused] -// uint4 xe_edram_load_mask_rt01; // Offset: 400 Size: 16 [unused] -// uint4 xe_edram_load_mask_rt23; // Offset: 416 Size: 16 [unused] -// float4 xe_edram_load_scale_rt01; // Offset: 432 Size: 16 [unused] -// float4 xe_edram_load_scale_rt23; // Offset: 448 Size: 16 [unused] -// uint4 xe_edram_blend_rt01; // Offset: 464 Size: 16 [unused] -// uint4 xe_edram_blend_rt23; // Offset: 480 Size: 16 [unused] -// float4 xe_edram_blend_constant; // Offset: 496 Size: 16 [unused] -// float4 xe_edram_store_min_rt01; // Offset: 512 Size: 16 [unused] -// float4 xe_edram_store_min_rt23; // Offset: 528 Size: 16 [unused] -// float4 xe_edram_store_max_rt01; // Offset: 544 Size: 16 [unused] -// float4 xe_edram_store_max_rt23; // Offset: 560 Size: 16 [unused] -// float4 xe_edram_store_scale_rt01; // Offset: 576 Size: 16 [unused] -// float4 xe_edram_store_scale_rt23; // Offset: 592 Size: 16 [unused] +// uint4 xe_edram_rt_base_dwords_scaled;// Offset: 304 Size: 16 [unused] +// uint4 xe_edram_rt_format_flags; // Offset: 320 Size: 16 [unused] +// float4 xe_edram_rt_clamp[4]; // Offset: 336 Size: 64 [unused] +// uint4 xe_edram_rt_keep_mask[2]; // Offset: 400 Size: 32 [unused] +// uint4 xe_edram_rt_blend_factors_ops;// Offset: 432 Size: 16 [unused] +// float4 xe_edram_blend_constant; // Offset: 448 Size: 16 [unused] // // } // diff --git a/src/xenia/gpu/d3d12/shaders/xenos_draw.hlsli b/src/xenia/gpu/d3d12/shaders/xenos_draw.hlsli index 37c3ba18e..4b7ddd733 100644 --- a/src/xenia/gpu/d3d12/shaders/xenos_draw.hlsli +++ b/src/xenia/gpu/d3d12/shaders/xenos_draw.hlsli @@ -35,7 +35,7 @@ cbuffer xe_system_cbuffer : register(b0) { float2 xe_edram_poly_offset_front; float2 xe_edram_poly_offset_back; - uint xe_edram_resolution_scale_log2; + uint xe_edram_resolution_square_scale; uint xe_edram_stencil_reference; uint xe_edram_stencil_read_mask; uint xe_edram_stencil_write_mask; @@ -44,43 +44,17 @@ cbuffer xe_system_cbuffer : register(b0) { uint4 xe_edram_stencil_back; - uint4 xe_edram_base_dwords; + uint4 xe_edram_rt_base_dwords_scaled; - uint4 xe_edram_rt_flags; + uint4 xe_edram_rt_format_flags; - uint4 xe_edram_rt_pack_width_low; + float4 xe_edram_rt_clamp[4]; - uint4 xe_edram_rt_pack_offset_low; + uint4 xe_edram_rt_keep_mask[2]; - uint4 xe_edram_rt_pack_width_high; - - uint4 xe_edram_rt_pack_offset_high; - - uint4 xe_edram_load_mask_rt01; - - uint4 xe_edram_load_mask_rt23; - - float4 xe_edram_load_scale_rt01; - - float4 xe_edram_load_scale_rt23; - - uint4 xe_edram_blend_rt01; - - uint4 xe_edram_blend_rt23; + uint4 xe_edram_rt_blend_factors_ops; float4 xe_edram_blend_constant; - - float4 xe_edram_store_min_rt01; - - float4 xe_edram_store_min_rt23; - - float4 xe_edram_store_max_rt01; - - float4 xe_edram_store_max_rt23; - - float4 xe_edram_store_scale_rt01; - - float4 xe_edram_store_scale_rt23; }; struct XeVertex { diff --git a/src/xenia/gpu/dxbc_shader_translator.cc b/src/xenia/gpu/dxbc_shader_translator.cc index 4208d5d26..84effdaae 100644 --- a/src/xenia/gpu/dxbc_shader_translator.cc +++ b/src/xenia/gpu/dxbc_shader_translator.cc @@ -185,7 +185,8 @@ bool DxbcShaderTranslator::UseSwitchForControlFlow() const { return FLAGS_dxbc_switch && vendor_id_ != 0x8086; } -uint32_t DxbcShaderTranslator::PushSystemTemp(bool zero, uint32_t count) { +uint32_t DxbcShaderTranslator::PushSystemTemp(uint32_t zero_mask, + uint32_t count) { uint32_t register_index = system_temp_count_current_; if (!uses_register_dynamic_addressing() && !is_depth_only_pixel_shader_) { // Guest shader registers first if they're not in x0. Depth-only pixel @@ -198,19 +199,28 @@ uint32_t DxbcShaderTranslator::PushSystemTemp(bool zero, uint32_t count) { system_temp_count_max_ = std::max(system_temp_count_max_, system_temp_count_current_); - if (zero) { + if (zero_mask) { + uint32_t zero_operand, zero_count; + if (zero_mask == 0b0001 || zero_mask == 0b0010 || zero_mask == 0b0100 || + zero_mask == 0b1000) { + zero_operand = EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0); + zero_count = 1; + } else { + zero_operand = EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0); + zero_count = 4; + } for (uint32_t i = 0; i < count; ++i) { - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(4 + zero_count)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, zero_mask, 1)); shader_code_.push_back(register_index + i); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); + shader_code_.push_back(zero_operand); + for (uint32_t j = 0; j < zero_count; ++j) { + shader_code_.push_back(0); + } ++stat_.instruction_count; ++stat_.mov_instruction_count; } @@ -224,6 +234,186 @@ void DxbcShaderTranslator::PopSystemTemp(uint32_t count) { system_temp_count_current_ -= std::min(count, system_temp_count_current_); } +void DxbcShaderTranslator::ConvertPWLGamma( + bool to_gamma, int32_t source_temp, uint32_t source_temp_component, + uint32_t target_temp, uint32_t target_temp_component, uint32_t piece_temp, + uint32_t piece_temp_component, uint32_t accumulator_temp, + uint32_t accumulator_temp_component) { + assert_true(source_temp != target_temp || + source_temp_component != target_temp_component || + ((target_temp != accumulator_temp || + target_temp_component != accumulator_temp_component) && + (target_temp != piece_temp || + target_temp_component != piece_temp_component))); + assert_true(piece_temp != source_temp || + piece_temp_component != source_temp_component); + assert_true(accumulator_temp != source_temp || + accumulator_temp_component != source_temp_component); + assert_true(piece_temp != accumulator_temp || + piece_temp_component != accumulator_temp_component); + uint32_t piece_temp_mask = 1 << piece_temp_component; + uint32_t accumulator_temp_mask = 1 << accumulator_temp_component; + + // For each piece: + // 1) Calculate how far we are on it. Multiply by 1/width, subtract + // start/width and saturate. + // 2) Add the contribution of the piece - multiply the position on the piece + // by its slope*width and accumulate. + + // Piece 1. + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | + ENCODE_D3D10_SB_INSTRUCTION_SATURATE(1) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back(EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, + piece_temp_mask, 1)); + shader_code_.push_back(piece_temp); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + source_temp_component, 1)); + shader_code_.push_back(source_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + // 1.0 / 0.0625 to, 1.0 / 0.25 from. + shader_code_.push_back(to_gamma ? 0x41800000u : 0x40800000u); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back(EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, + accumulator_temp_mask, 1)); + shader_code_.push_back(accumulator_temp); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + piece_temp_component, 1)); + shader_code_.push_back(piece_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + // 4.0 * 0.0625 to, 0.25 * 0.25 from. + shader_code_.push_back(to_gamma ? 0x3E800000u : 0x3D800000u); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Piece 2. + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | + ENCODE_D3D10_SB_INSTRUCTION_SATURATE(1) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back(EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, + piece_temp_mask, 1)); + shader_code_.push_back(piece_temp); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + source_temp_component, 1)); + shader_code_.push_back(source_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + // 1.0 / 0.0625 to, 1.0 / 0.125 from. + shader_code_.push_back(to_gamma ? 0x41800000u : 0x41000000u); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + // -0.0625 / 0.0625 to, -0.25 / 0.125 from. + shader_code_.push_back(to_gamma ? 0xBF800000u : 0xC0000000u); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back(EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, + accumulator_temp_mask, 1)); + shader_code_.push_back(accumulator_temp); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + piece_temp_component, 1)); + shader_code_.push_back(piece_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + // 2.0 * 0.0625 to, 0.5 * 0.125 from. + shader_code_.push_back(to_gamma ? 0x3E000000u : 0x3D800000u); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_TEMP, accumulator_temp_component, 1)); + shader_code_.push_back(accumulator_temp); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Piece 3. + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | + ENCODE_D3D10_SB_INSTRUCTION_SATURATE(1) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back(EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, + piece_temp_mask, 1)); + shader_code_.push_back(piece_temp); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + source_temp_component, 1)); + shader_code_.push_back(source_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + // 1.0 / 0.375 to, 1.0 / 0.375 from. + shader_code_.push_back(0x402AAAABu); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + // -0.125 / 0.375 to, -0.375 / 0.375 from. + shader_code_.push_back(to_gamma ? 0xBEAAAAABu : 0xBF800000u); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back(EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, + accumulator_temp_mask, 1)); + shader_code_.push_back(accumulator_temp); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + piece_temp_component, 1)); + shader_code_.push_back(piece_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + // 1.0 * 0.375 to, 1.0 * 0.375 from. + shader_code_.push_back(0x3EC00000u); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_TEMP, accumulator_temp_component, 1)); + shader_code_.push_back(accumulator_temp); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Piece 4. + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | + ENCODE_D3D10_SB_INSTRUCTION_SATURATE(1) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back(EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, + piece_temp_mask, 1)); + shader_code_.push_back(piece_temp); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + source_temp_component, 1)); + shader_code_.push_back(source_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + // 1.0 / 0.5 to, 1.0 / 0.25 from. + shader_code_.push_back(to_gamma ? 0x40000000u : 0x40800000u); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + // -0.5 / 0.5 to, -0.75 / 0.25 from. + shader_code_.push_back(to_gamma ? 0xBF800000u : 0xC0400000u); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D10_SB_OPERAND_TYPE_TEMP, 1 << target_temp_component, 1)); + shader_code_.push_back(target_temp); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + piece_temp_component, 1)); + shader_code_.push_back(piece_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + // 0.5 * 0.5 to, 2.0 * 0.25 from. + shader_code_.push_back(to_gamma ? 0x3E800000u : 0x3F000000u); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_TEMP, accumulator_temp_component, 1)); + shader_code_.push_back(accumulator_temp); + ++stat_.instruction_count; + ++stat_.float_instruction_count; +} + void DxbcShaderTranslator::StartVertexShader_LoadVertexIndex() { // Vertex index is in an input bound to SV_VertexID, byte swapped according to // xe_vertex_index_endian_and_edge_factors system constant and written to GPR @@ -717,38 +907,13 @@ void DxbcShaderTranslator::StartVertexOrDomainShader() { } void DxbcShaderTranslator::StartPixelShader() { - if (edram_rov_used_ && !writes_depth()) { - // Load depth at the center to system_temp_depth_.x. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_DIV) | - ENCODE_D3D10_SB_INSTRUCTION_SATURATE(1) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(system_temp_depth_); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_INPUT, 0, 1)); - shader_code_.push_back(uint32_t(InOutRegister::kPSInClipSpaceZW)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_INPUT, 1, 1)); - shader_code_.push_back(uint32_t(InOutRegister::kPSInClipSpaceZW)); - ++stat_.instruction_count; - ++stat_.float_instruction_count; + if (edram_rov_used_) { + // Load the EDRAM addresses and the coverage. + StartPixelShader_LoadROVParameters(); - // Unconditionally calculate depth derivatives to system_temp_depth.yz for - // applying the polygon offset. - for (uint32_t i = 0; i < 2; ++i) { - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(i ? D3D11_SB_OPCODE_DERIV_RTY_COARSE - : D3D11_SB_OPCODE_DERIV_RTX_COARSE) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back(EncodeVectorMaskedOperand( - D3D10_SB_OPERAND_TYPE_TEMP, 0b0010 << i, 1)); - shader_code_.push_back(system_temp_depth_); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(system_temp_depth_); - ++stat_.instruction_count; - ++stat_.float_instruction_count; + // Do early 2x2 quad rejection if it makes sense. + if (ROV_IsDepthStencilEarly()) { + ROV_DepthStencilTest(); } } @@ -901,24 +1066,41 @@ void DxbcShaderTranslator::StartPixelShader() { ++stat_.float_instruction_count; // Undo 2x resolution scale in VPOS. if (edram_rov_used_) { + // Check if resolution scale is 4. + system_constants_used_ |= 1ull + << kSysConst_EDRAMResolutionSquareScale_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IEQ) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0100, 1)); + shader_code_.push_back(param_gen_value_temp); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMResolutionSquareScale_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMResolutionSquareScale_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(4); + ++stat_.instruction_count; + ++stat_.int_instruction_count; // Get inverse of the width/height scale. - system_constants_used_ |= 1ull << kSysConst_EDRAMResolutionScaleLog2_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IMAD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); shader_code_.push_back( EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0100, 1)); shader_code_.push_back(param_gen_value_temp); shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_EDRAMResolutionScaleLog2_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMResolutionScaleLog2_Vec); + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(param_gen_value_temp); shader_code_.push_back( EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); - shader_code_.push_back(uint32_t(-(1 << 23))); + // 0.5 + shader_code_.push_back(0x3F000000); shader_code_.push_back( EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + // 1.0 shader_code_.push_back(0x3F800000); ++stat_.instruction_count; ++stat_.int_instruction_count; @@ -1030,25 +1212,48 @@ void DxbcShaderTranslator::StartPixelShader() { } void DxbcShaderTranslator::StartTranslation() { + // Allocate labels and registers for subroutines. + label_rov_depth_to_24bit_ = UINT32_MAX; + label_rov_depth_stencil_sample_ = UINT32_MAX; + std::memset(label_rov_color_sample_, 0xFF, sizeof(label_rov_color_sample_)); + uint32_t label_index = 0; + system_temps_subroutine_count_ = 0; + if (IsDxbcPixelShader() && edram_rov_used_) { + label_rov_depth_to_24bit_ = label_index++; + system_temps_subroutine_count_ = + std::max((uint32_t)1, system_temps_subroutine_count_); + label_rov_depth_stencil_sample_ = label_index++; + system_temps_subroutine_count_ = + std::max((uint32_t)2, system_temps_subroutine_count_); + for (uint32_t i = 0; i < xe::countof(label_rov_color_sample_); ++i) { + if (writes_color_target(i)) { + label_rov_color_sample_[i] = label_index++; + system_temps_subroutine_count_ = + std::max((uint32_t)4, system_temps_subroutine_count_); + } + } + } + system_temps_subroutine_ = PushSystemTemp(0, system_temps_subroutine_count_); + // Allocate global system temporary registers that may also be used in the // epilogue. if (IsDxbcVertexOrDomainShader()) { - system_temp_position_ = PushSystemTemp(true); + system_temp_position_ = PushSystemTemp(0b1111); } else if (IsDxbcPixelShader()) { - if (!is_depth_only_pixel_shader_) { - // In the ROV path, no need to initialize the colors because original - // values will be kept for the unwritten components. - system_temps_color_ = PushSystemTemp(!edram_rov_used_, 4); - } if (edram_rov_used_) { - if (!is_depth_only_pixel_shader_) { - system_temp_color_written_ = PushSystemTemp(true); - } + system_temp_rov_params_ = PushSystemTemp(); // If the shader doesn't write to depth, StartPixelShader will load the - // depth and its derivatives, so no need to initialize. If it does, - // initialize it to something consistent - depth must be written in every - // shader execution path (at least in PC ps_3_0 and later shader models). - system_temp_depth_ = PushSystemTemp(writes_depth()); + // depth/stencil for early test, so no need to initialize. If it does, + // initialize it to something consistent - depth must be written on every + // shader execution path (at least in PC ps_3_0 and later shader models) + // and to make compilation easier. + system_temp_rov_depth_stencil_ = + PushSystemTemp(writes_depth() ? 0b0001 : 0); + } + for (uint32_t i = 0; i < 4; ++i) { + if (writes_color_target(i)) { + system_temps_color_[i] = PushSystemTemp(0b1111); + } } } @@ -1068,9 +1273,9 @@ void DxbcShaderTranslator::StartTranslation() { // If memexport is used at all, allocate a register containing whether eM# // have actually been written to. if (system_temp_memexport_written_ == UINT32_MAX) { - system_temp_memexport_written_ = PushSystemTemp(true); + system_temp_memexport_written_ = PushSystemTemp(0b1111); } - system_temps_memexport_address_[i] = PushSystemTemp(true); + system_temps_memexport_address_[i] = PushSystemTemp(0b1111); uint32_t memexport_data_index; while (xe::bit_scan_forward(memexport_alloc_written, &memexport_data_index)) { @@ -1081,12 +1286,12 @@ void DxbcShaderTranslator::StartTranslation() { } // Allocate system temporary variables for the translated code. - system_temp_pv_ = PushSystemTemp(true); - system_temp_ps_pc_p0_a0_ = PushSystemTemp(true); - system_temp_aL_ = PushSystemTemp(true); - system_temp_loop_count_ = PushSystemTemp(true); - system_temp_grad_h_lod_ = PushSystemTemp(true); - system_temp_grad_v_ = PushSystemTemp(true); + system_temp_pv_ = PushSystemTemp(); + system_temp_ps_pc_p0_a0_ = PushSystemTemp(0b1111); + system_temp_aL_ = PushSystemTemp(0b1111); + system_temp_loop_count_ = PushSystemTemp(0b1111); + system_temp_grad_h_lod_ = PushSystemTemp(0b1111); + system_temp_grad_v_ = PushSystemTemp(0b0111); } // Write stage-specific prologue. @@ -1482,30 +1687,47 @@ void DxbcShaderTranslator::CompleteShaderCode() { CompletePixelShader(); } - if (IsDxbcVertexOrDomainShader()) { - // Release system_temp_position_. - PopSystemTemp(); - } else if (IsDxbcPixelShader()) { - if (edram_rov_used_) { - // Release system_temp_depth_. - PopSystemTemp(); - if (!is_depth_only_pixel_shader_) { - // Release system_temp_color_written_. - PopSystemTemp(); - } - } - if (!is_depth_only_pixel_shader_) { - // Release system_temps_color_. - PopSystemTemp(4); - } - } - // Return from `main`. shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_RET) | ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); ++stat_.instruction_count; ++stat_.static_flow_control_count; + // Write subroutines - can only do this immediately after `ret`. They still + // need the global system temps, and can't allocate their own temps (since + // they may be called from anywhere and don't know anything about the caller's + // register allocation). + if (label_rov_depth_to_24bit_ != UINT32_MAX) { + CompleteShaderCode_ROV_DepthTo24BitSubroutine(); + } + if (label_rov_depth_stencil_sample_ != UINT32_MAX) { + CompleteShaderCode_ROV_DepthStencilSampleSubroutine(); + } + for (uint32_t i = 0; i < 4; ++i) { + if (label_rov_color_sample_[i] != UINT32_MAX) { + CompleteShaderCode_ROV_ColorSampleSubroutine(i); + } + } + + if (IsDxbcVertexOrDomainShader()) { + // Release system_temp_position_. + PopSystemTemp(); + } else if (IsDxbcPixelShader()) { + // Release system_temps_color_. + for (int32_t i = 3; i >= 0; --i) { + if (writes_color_target(i)) { + PopSystemTemp(); + } + } + if (edram_rov_used_) { + // Release system_temp_rov_params_ and system_temp_rov_depth_stencil_. + PopSystemTemp(2); + } + } + + // Release system_temps_subroutine_. + PopSystemTemp(system_temps_subroutine_count_); + // Remap float constant indices if not indexed dynamically. if (!float_constants_dynamic_indexed_ && !float_constant_index_offsets_.empty()) { @@ -2279,7 +2501,7 @@ void DxbcShaderTranslator::StoreResult(const InstructionResult& result, ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); shader_code_.push_back(EncodeVectorMaskedOperand( D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(system_temp_depth_); + shader_code_.push_back(system_temp_rov_depth_stencil_); } else { shader_code_.push_back( ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | @@ -2455,8 +2677,8 @@ void DxbcShaderTranslator::StoreResult(const InstructionResult& result, saturate_bit); shader_code_.push_back( EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, mask, 1)); - shader_code_.push_back(system_temps_color_ + - uint32_t(result.storage_index)); + shader_code_.push_back( + system_temps_color_[uint32_t(result.storage_index)]); break; default: @@ -2504,19 +2726,20 @@ void DxbcShaderTranslator::StoreResult(const InstructionResult& result, // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/dx9-graphics-reference-asm-ps-registers-output-color // if a color target has been written to - including due to flow control - // the render target must not be modified (the unwritten components of a - // written target are undefined, but let's keep the original value in this - // case). + // written target are undefined, not sure if this behavior is respected on + // the real GPU, but the ROV code currently uses pre-packed masks to keep + // the old values, so preservation of components is not done). shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_OR) | ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back(EncodeVectorMaskedOperand( - D3D10_SB_OPERAND_TYPE_TEMP, 1 << uint32_t(result.storage_index), 1)); - shader_code_.push_back(system_temp_color_written_); - shader_code_.push_back(EncodeVectorSelectOperand( - D3D10_SB_OPERAND_TYPE_TEMP, uint32_t(result.storage_index), 1)); - shader_code_.push_back(system_temp_color_written_); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temp_rov_params_); shader_code_.push_back( EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); - shader_code_.push_back(swizzle_mask | constant_mask); + shader_code_.push_back(1 << (8 + uint32_t(result.storage_index))); ++stat_.instruction_count; ++stat_.uint_instruction_count; } @@ -3169,19 +3392,35 @@ uint32_t DxbcShaderTranslator::AppendString(std::vector& dest, const DxbcShaderTranslator::RdefType DxbcShaderTranslator::rdef_types_[size_t( DxbcShaderTranslator::RdefTypeIndex::kCount)] = { + // kFloat {"float", 0, 3, 1, 1, 0, 0, RdefTypeIndex::kUnknown, nullptr}, + // kFloat2 {"float2", 1, 3, 1, 2, 0, 0, RdefTypeIndex::kUnknown, nullptr}, + // kFloat3 {"float3", 1, 3, 1, 3, 0, 0, RdefTypeIndex::kUnknown, nullptr}, + // kFloat4 {"float4", 1, 3, 1, 4, 0, 0, RdefTypeIndex::kUnknown, nullptr}, + // kInt {"int", 0, 2, 1, 1, 0, 0, RdefTypeIndex::kUnknown, nullptr}, + // kUint {"uint", 0, 19, 1, 1, 0, 0, RdefTypeIndex::kUnknown, nullptr}, + // kUint2 {"uint2", 1, 19, 1, 2, 0, 0, RdefTypeIndex::kUnknown, nullptr}, + // kUint4 {"uint4", 1, 19, 1, 4, 0, 0, RdefTypeIndex::kUnknown, nullptr}, + // kFloat4Array4 + {nullptr, 1, 3, 1, 4, 4, 0, RdefTypeIndex::kFloat4, nullptr}, + // kFloat4Array6 {nullptr, 1, 3, 1, 4, 6, 0, RdefTypeIndex::kFloat4, nullptr}, - // Float constants - size written dynamically. + // kFloat4ConstantArray - float constants - size written dynamically. {nullptr, 1, 3, 1, 4, 0, 0, RdefTypeIndex::kFloat4, nullptr}, + // kUint4Array2 + {nullptr, 1, 19, 1, 4, 2, 0, RdefTypeIndex::kUint4, nullptr}, + // kUint4Array8 {nullptr, 1, 19, 1, 4, 8, 0, RdefTypeIndex::kUint4, nullptr}, + // kUint4Array32 {nullptr, 1, 19, 1, 4, 32, 0, RdefTypeIndex::kUint4, nullptr}, + // kUint4Array48 {nullptr, 1, 19, 1, 4, 48, 0, RdefTypeIndex::kUint4, nullptr}, }; @@ -3220,7 +3459,7 @@ const DxbcShaderTranslator::SystemConstantRdef DxbcShaderTranslator:: {"xe_edram_poly_offset_front", RdefTypeIndex::kFloat2, 8}, {"xe_edram_poly_offset_back", RdefTypeIndex::kFloat2, 8}, - {"xe_edram_resolution_scale_log2", RdefTypeIndex::kUint, 4}, + {"xe_edram_resolution_square_scale", RdefTypeIndex::kUint, 4}, {"xe_edram_stencil_reference", RdefTypeIndex::kUint, 4}, {"xe_edram_stencil_read_mask", RdefTypeIndex::kUint, 4}, {"xe_edram_stencil_write_mask", RdefTypeIndex::kUint, 4}, @@ -3229,43 +3468,17 @@ const DxbcShaderTranslator::SystemConstantRdef DxbcShaderTranslator:: {"xe_edram_stencil_back", RdefTypeIndex::kUint4, 16}, - {"xe_edram_base_dwords", RdefTypeIndex::kUint4, 16}, + {"xe_edram_rt_base_dwords_scaled", RdefTypeIndex::kUint4, 16}, - {"xe_edram_rt_flags", RdefTypeIndex::kUint4, 16}, + {"xe_edram_rt_format_flags", RdefTypeIndex::kUint4, 16}, - {"xe_edram_rt_pack_width_low", RdefTypeIndex::kUint4, 16}, + {"xe_edram_rt_clamp", RdefTypeIndex::kFloat4Array4, 64}, - {"xe_edram_rt_pack_offset_low", RdefTypeIndex::kUint4, 16}, + {"xe_edram_rt_keep_mask", RdefTypeIndex::kUint4Array2, 32}, - {"xe_edram_rt_pack_width_high", RdefTypeIndex::kUint4, 16}, - - {"xe_edram_rt_pack_offset_high", RdefTypeIndex::kUint4, 16}, - - {"xe_edram_load_mask_low_rt01", RdefTypeIndex::kUint4, 16}, - - {"xe_edram_load_mask_low_rt23", RdefTypeIndex::kUint4, 16}, - - {"xe_edram_load_scale_rt01", RdefTypeIndex::kFloat4, 16}, - - {"xe_edram_load_scale_rt23", RdefTypeIndex::kFloat4, 16}, - - {"xe_edram_blend_rt01", RdefTypeIndex::kUint4, 16}, - - {"xe_edram_blend_rt23", RdefTypeIndex::kUint4, 16}, + {"xe_edram_rt_blend_factors_ops", RdefTypeIndex::kUint4, 16}, {"xe_edram_blend_constant", RdefTypeIndex::kFloat4, 16}, - - {"xe_edram_store_min_rt01", RdefTypeIndex::kFloat4, 16}, - - {"xe_edram_store_min_rt23", RdefTypeIndex::kFloat4, 16}, - - {"xe_edram_store_max_rt01", RdefTypeIndex::kFloat4, 16}, - - {"xe_edram_store_max_rt23", RdefTypeIndex::kFloat4, 16}, - - {"xe_edram_store_scale_rt01", RdefTypeIndex::kFloat4, 16}, - - {"xe_edram_store_scale_rt23", RdefTypeIndex::kFloat4, 16}, }; void DxbcShaderTranslator::WriteResourceDefinitions() { @@ -3763,7 +3976,7 @@ void DxbcShaderTranslator::WriteResourceDefinitions() { // Register space 0. shader_object_.push_back(0); // UAV ID U1 or U0 depending on whether there's U0. - shader_object_.push_back(GetEDRAMUAVIndex()); + shader_object_.push_back(ROV_GetEDRAMUAVIndex()); } // Constant buffers. @@ -4098,14 +4311,15 @@ void DxbcShaderTranslator::WriteOutputSignature() { // Unknown. shader_object_.push_back(8); } else { + bool writes_color = writes_any_color_target(); // Color render targets, optionally depth. - shader_object_.push_back((is_depth_only_pixel_shader_ ? 0 : 4) + + shader_object_.push_back((writes_color ? 4 : 0) + (writes_depth() ? 1 : 0)); // Unknown. shader_object_.push_back(8); // Color render targets. - if (!is_depth_only_pixel_shader_) { + if (writes_color) { for (uint32_t i = 0; i < 4; ++i) { // Reserve space for the semantic name (SV_Target). shader_object_.push_back(0); @@ -4137,7 +4351,7 @@ void DxbcShaderTranslator::WriteOutputSignature() { sizeof(uint32_t); uint32_t name_position_dwords = chunk_position_dwords + signature_position_dwords; - if (!is_depth_only_pixel_shader_) { + if (writes_color) { for (uint32_t i = 0; i < 4; ++i) { shader_object_[name_position_dwords] = new_offset; name_position_dwords += signature_size_dwords; @@ -4367,7 +4581,7 @@ void DxbcShaderTranslator::WriteShaderCode() { ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); shader_object_.push_back(EncodeVectorSwizzledOperand( D3D11_SB_OPERAND_TYPE_UNORDERED_ACCESS_VIEW, kSwizzleXYZW, 3)); - shader_object_.push_back(GetEDRAMUAVIndex()); + shader_object_.push_back(ROV_GetEDRAMUAVIndex()); shader_object_.push_back(uint32_t(UAVRegister::kEDRAM)); shader_object_.push_back(uint32_t(UAVRegister::kEDRAM)); shader_object_.push_back( @@ -4540,7 +4754,7 @@ void DxbcShaderTranslator::WriteShaderCode() { EncodeScalarOperand(D3D11_SB_OPERAND_TYPE_INPUT_COVERAGE_MASK, 0)); ++stat_.dcl_count; } else { - if (!is_depth_only_pixel_shader_) { + if (writes_any_color_target()) { // Color output. for (uint32_t i = 0; i < 4; ++i) { shader_object_.push_back( diff --git a/src/xenia/gpu/dxbc_shader_translator.h b/src/xenia/gpu/dxbc_shader_translator.h index 7830174db..0639ca19e 100644 --- a/src/xenia/gpu/dxbc_shader_translator.h +++ b/src/xenia/gpu/dxbc_shader_translator.h @@ -63,25 +63,32 @@ class DxbcShaderTranslator : public ShaderTranslator { kSysFlag_AlphaPassIfEqual_Shift, kSysFlag_AlphaPassIfGreater_Shift, kSysFlag_AlphaToCoverage_Shift, - kSysFlag_DepthStencil_Shift, - kSysFlag_DepthFloat24_Shift, - // Depth/stencil testing not done if DepthStencilRead is disabled, but - // writing may still be done. - kSysFlag_DepthPassIfLess_Shift, - kSysFlag_DepthPassIfEqual_Shift, - kSysFlag_DepthPassIfGreater_Shift, - // 1 to write new depth to the depth buffer, 0 to keep the old one if the - // depth test passes. - kSysFlag_DepthWriteMask_Shift, - kSysFlag_StencilTest_Shift, - // This doesn't include depth/stencil masks - only reflects the fact that - // the new value must be written. - kSysFlag_DepthStencilWrite_Shift, kSysFlag_Color0Gamma_Shift, kSysFlag_Color1Gamma_Shift, kSysFlag_Color2Gamma_Shift, kSysFlag_Color3Gamma_Shift, + kSysFlag_ROVDepthStencil_Shift, + kSysFlag_ROVDepthFloat24_Shift, + kSysFlag_ROVDepthPassIfLess_Shift, + kSysFlag_ROVDepthPassIfEqual_Shift, + kSysFlag_ROVDepthPassIfGreater_Shift, + // 1 to write new depth to the depth buffer, 0 to keep the old one if the + // depth test passes. + kSysFlag_ROVDepthWrite_Shift, + kSysFlag_ROVStencilTest_Shift, + // If the depth/stencil test has failed, but resulted in a stencil value + // that is different than the one currently in the depth buffer, write it + // anyway and don't run the shader (to check if the sample may be discarded + // some way). This, however, also results in depth/stencil testing done + // entirely early even when it passes to prevent writing in divergent places + // in the shader. When the shader can kill, this must be set only for + // RB_DEPTHCONTROL EARLY_Z_ENABLE, not for alpha test/alpha to coverage + // disabled. + kSysFlag_ROVDepthStencilEarlyWrite_Shift, + + kSysFlag_Count, + kSysFlag_SharedMemoryIsUAV = 1u << kSysFlag_SharedMemoryIsUAV_Shift, kSysFlag_XYDividedByW = 1u << kSysFlag_XYDividedByW_Shift, kSysFlag_ZDividedByW = 1u << kSysFlag_ZDividedByW_Shift, @@ -97,19 +104,21 @@ class DxbcShaderTranslator : public ShaderTranslator { kSysFlag_AlphaPassIfEqual = 1u << kSysFlag_AlphaPassIfEqual_Shift, kSysFlag_AlphaPassIfGreater = 1u << kSysFlag_AlphaPassIfGreater_Shift, kSysFlag_AlphaToCoverage = 1u << kSysFlag_AlphaToCoverage_Shift, - kSysFlag_DepthStencil = 1u << kSysFlag_DepthStencil_Shift, - kSysFlag_DepthFloat24 = 1u << kSysFlag_DepthFloat24_Shift, - kSysFlag_DepthPassIfLess = 1u << kSysFlag_DepthPassIfLess_Shift, - kSysFlag_DepthPassIfEqual = 1u << kSysFlag_DepthPassIfEqual_Shift, - kSysFlag_DepthPassIfGreater = 1u << kSysFlag_DepthPassIfGreater_Shift, - kSysFlag_DepthWriteMask = 1u << kSysFlag_DepthWriteMask_Shift, - kSysFlag_StencilTest = 1u << kSysFlag_StencilTest_Shift, - kSysFlag_DepthStencilWrite = 1u << kSysFlag_DepthStencilWrite_Shift, kSysFlag_Color0Gamma = 1u << kSysFlag_Color0Gamma_Shift, kSysFlag_Color1Gamma = 1u << kSysFlag_Color1Gamma_Shift, kSysFlag_Color2Gamma = 1u << kSysFlag_Color2Gamma_Shift, kSysFlag_Color3Gamma = 1u << kSysFlag_Color3Gamma_Shift, + kSysFlag_ROVDepthStencil = 1u << kSysFlag_ROVDepthStencil_Shift, + kSysFlag_ROVDepthFloat24 = 1u << kSysFlag_ROVDepthFloat24_Shift, + kSysFlag_ROVDepthPassIfLess = 1u << kSysFlag_ROVDepthPassIfLess_Shift, + kSysFlag_ROVDepthPassIfEqual = 1u << kSysFlag_ROVDepthPassIfEqual_Shift, + kSysFlag_ROVDepthPassIfGreater = 1u << kSysFlag_ROVDepthPassIfGreater_Shift, + kSysFlag_ROVDepthWrite = 1u << kSysFlag_ROVDepthWrite_Shift, + kSysFlag_ROVStencilTest = 1u << kSysFlag_ROVStencilTest_Shift, + kSysFlag_ROVDepthStencilEarlyWrite = + 1u << kSysFlag_ROVDepthStencilEarlyWrite_Shift, }; + static_assert(kSysFlag_Count <= 32, "Too many flags in the system constants"); enum : uint32_t { kStencilOp_Flag_CurrentMask_Shift, @@ -142,151 +151,17 @@ class DxbcShaderTranslator : public ShaderTranslator { kStencilOp_Flag_CurrentMask | kStencilOp_Flag_Decrement, }; + // Appended to the format in the format constant. enum : uint32_t { - // Whether the render target needs to be merged with another (if the write - // mask is not 1111, or 11 for 16_16, or 1 for 32_FLOAT, or blending is - // enabled and it's not no-op). - kRTFlag_WriteR_Shift, - kRTFlag_WriteG_Shift, - kRTFlag_WriteB_Shift, - kRTFlag_WriteA_Shift, - kRTFlag_Blend_Shift, - // Whether the component does not exist in the render target format. - kRTFlag_FormatUnusedR_Shift, - kRTFlag_FormatUnusedG_Shift, - kRTFlag_FormatUnusedB_Shift, - kRTFlag_FormatUnusedA_Shift, - // Whether the format is fixed-point and needs to be converted to integer - // (k_8_8_8_8, k_2_10_10_10, k_16_16, k_16_16_16_16). - kRTFlag_FormatFixed_Shift, - // Whether the format is k_2_10_10_10_FLOAT and 7e3 conversion is needed. - kRTFlag_FormatFloat10_Shift, - // Whether the format is k_16_16_FLOAT or k_16_16_16_16_FLOAT and - // f16tof32/f32tof16 is needed. - kRTFlag_FormatFloat16_Shift, + // Starting from bit 4 because the format itself needs 4 bits. + kRTFormatFlag_64bpp_Shift = 4, + // Requires clamping of blending sources and factors. + kRTFormatFlag_FixedPointColor_Shift, + kRTFormatFlag_FixedPointAlpha_Shift, - kRTFlag_WriteR = 1u << kRTFlag_WriteR_Shift, - kRTFlag_WriteG = 1u << kRTFlag_WriteG_Shift, - kRTFlag_WriteB = 1u << kRTFlag_WriteB_Shift, - kRTFlag_WriteA = 1u << kRTFlag_WriteA_Shift, - kRTFlag_Blend = 1u << kRTFlag_Blend_Shift, - kRTFlag_FormatUnusedR = 1u << kRTFlag_FormatUnusedR_Shift, - kRTFlag_FormatUnusedG = 1u << kRTFlag_FormatUnusedG_Shift, - kRTFlag_FormatUnusedB = 1u << kRTFlag_FormatUnusedB_Shift, - kRTFlag_FormatUnusedA = 1u << kRTFlag_FormatUnusedA_Shift, - kRTFlag_FormatFixed = 1u << kRTFlag_FormatFixed_Shift, - kRTFlag_FormatFloat10 = 1u << kRTFlag_FormatFloat10_Shift, - kRTFlag_FormatFloat16 = 1u << kRTFlag_FormatFloat16_Shift, - }; - - enum : uint32_t { - // X/Z of the blend constant for the render target. - - // For ONE_MINUS modes, enable both One and the needed factor with _Neg. - kBlendX_Src_One_Shift = 0, - kBlendX_Src_One = 1u << kBlendX_Src_One_Shift, - kBlendX_Src_SrcColor_Shift = 1, - kBlendX_Src_SrcColor_Pos = 1u << kBlendX_Src_SrcColor_Shift, - kBlendX_Src_SrcColor_Neg = 3u << kBlendX_Src_SrcColor_Shift, - kBlendX_Src_SrcAlpha_Shift = 3, - kBlendX_Src_SrcAlpha_Pos = 1u << kBlendX_Src_SrcAlpha_Shift, - kBlendX_Src_SrcAlpha_Neg = 3u << kBlendX_Src_SrcAlpha_Shift, - kBlendX_Src_DestColor_Shift = 5, - kBlendX_Src_DestColor_Pos = 1u << kBlendX_Src_DestColor_Shift, - kBlendX_Src_DestColor_Neg = 3u << kBlendX_Src_DestColor_Shift, - kBlendX_Src_DestAlpha_Shift = 7, - kBlendX_Src_DestAlpha_Pos = 1u << kBlendX_Src_DestAlpha_Shift, - kBlendX_Src_DestAlpha_Neg = 3u << kBlendX_Src_DestAlpha_Shift, - kBlendX_Src_SrcAlphaSaturate_Shift = 9, - kBlendX_Src_SrcAlphaSaturate = 1u << kBlendX_Src_SrcAlphaSaturate_Shift, - - kBlendX_SrcAlpha_One_Shift = 10, - kBlendX_SrcAlpha_One = 1u << kBlendX_SrcAlpha_One_Shift, - kBlendX_SrcAlpha_SrcAlpha_Shift = 11, - kBlendX_SrcAlpha_SrcAlpha_Pos = 1u << kBlendX_SrcAlpha_SrcAlpha_Shift, - kBlendX_SrcAlpha_SrcAlpha_Neg = 3u << kBlendX_SrcAlpha_SrcAlpha_Shift, - kBlendX_SrcAlpha_DestAlpha_Shift = 13, - kBlendX_SrcAlpha_DestAlpha_Pos = 1u << kBlendX_SrcAlpha_DestAlpha_Shift, - kBlendX_SrcAlpha_DestAlpha_Neg = 3u << kBlendX_SrcAlpha_DestAlpha_Shift, - - // For ONE_MINUS modes, enable both One and the needed factor with _Neg. - kBlendX_Dest_One_Shift = 15, - kBlendX_Dest_One = 1u << kBlendX_Dest_One_Shift, - kBlendX_Dest_SrcColor_Shift = 16, - kBlendX_Dest_SrcColor_Pos = 1u << kBlendX_Dest_SrcColor_Shift, - kBlendX_Dest_SrcColor_Neg = 3u << kBlendX_Dest_SrcColor_Shift, - kBlendX_Dest_SrcAlpha_Shift = 18, - kBlendX_Dest_SrcAlpha_Pos = 1u << kBlendX_Dest_SrcAlpha_Shift, - kBlendX_Dest_SrcAlpha_Neg = 3u << kBlendX_Dest_SrcAlpha_Shift, - kBlendX_Dest_DestColor_Shift = 20, - kBlendX_Dest_DestColor_Pos = 1u << kBlendX_Dest_DestColor_Shift, - kBlendX_Dest_DestColor_Neg = 3u << kBlendX_Dest_DestColor_Shift, - kBlendX_Dest_DestAlpha_Shift = 22, - kBlendX_Dest_DestAlpha_Pos = 1u << kBlendX_Dest_DestAlpha_Shift, - kBlendX_Dest_DestAlpha_Neg = 3u << kBlendX_Dest_DestAlpha_Shift, - kBlendX_Dest_SrcAlphaSaturate_Shift = 24, - kBlendX_Dest_SrcAlphaSaturate = 1u << kBlendX_Dest_SrcAlphaSaturate_Shift, - - kBlendX_DestAlpha_One_Shift = 25, - kBlendX_DestAlpha_One = 1u << kBlendX_DestAlpha_One_Shift, - kBlendX_DestAlpha_SrcAlpha_Shift = 26, - kBlendX_DestAlpha_SrcAlpha_Pos = 1u << kBlendX_DestAlpha_SrcAlpha_Shift, - kBlendX_DestAlpha_SrcAlpha_Neg = 3u << kBlendX_DestAlpha_SrcAlpha_Shift, - kBlendX_DestAlpha_DestAlpha_Shift = 28, - kBlendX_DestAlpha_DestAlpha_Pos = 1u << kBlendX_DestAlpha_DestAlpha_Shift, - kBlendX_DestAlpha_DestAlpha_Neg = 3u << kBlendX_DestAlpha_DestAlpha_Shift, - - // Y/W of the blend constant for the render target. - - kBlendY_Src_ConstantColor_Shift = 0, - kBlendY_Src_ConstantColor_Pos = 1u << kBlendY_Src_ConstantColor_Shift, - kBlendY_Src_ConstantColor_Neg = 3u << kBlendY_Src_ConstantColor_Shift, - kBlendY_Src_ConstantAlpha_Shift = 2, - kBlendY_Src_ConstantAlpha_Pos = 1u << kBlendY_Src_ConstantAlpha_Shift, - kBlendY_Src_ConstantAlpha_Neg = 3u << kBlendY_Src_ConstantAlpha_Shift, - - kBlendY_SrcAlpha_ConstantAlpha_Shift = 4, - kBlendY_SrcAlpha_ConstantAlpha_Pos = - 1u << kBlendY_SrcAlpha_ConstantAlpha_Shift, - kBlendY_SrcAlpha_ConstantAlpha_Neg = - 3u << kBlendY_SrcAlpha_ConstantAlpha_Shift, - - kBlendY_Dest_ConstantColor_Shift = 6, - kBlendY_Dest_ConstantColor_Pos = 1u << kBlendY_Dest_ConstantColor_Shift, - kBlendY_Dest_ConstantColor_Neg = 3u << kBlendY_Dest_ConstantColor_Shift, - kBlendY_Dest_ConstantAlpha_Shift = 8, - kBlendY_Dest_ConstantAlpha_Pos = 1u << kBlendY_Dest_ConstantAlpha_Shift, - kBlendY_Dest_ConstantAlpha_Neg = 3u << kBlendY_Dest_ConstantAlpha_Shift, - - kBlendY_DestAlpha_ConstantAlpha_Shift = 10, - kBlendY_DestAlpha_ConstantAlpha_Pos = - 1u << kBlendY_DestAlpha_ConstantAlpha_Shift, - kBlendY_DestAlpha_ConstantAlpha_Neg = - 3u << kBlendY_DestAlpha_ConstantAlpha_Shift, - - // For addition/subtraction/inverse subtraction, but must be positive for - // min/max. - kBlendY_Src_OpSign_Shift = 12, - kBlendY_Src_OpSign_Pos = 1u << kBlendY_Src_OpSign_Shift, - kBlendY_Src_OpSign_Neg = 3u << kBlendY_Src_OpSign_Shift, - kBlendY_SrcAlpha_OpSign_Shift = 14, - kBlendY_SrcAlpha_OpSign_Pos = 1u << kBlendY_SrcAlpha_OpSign_Shift, - kBlendY_SrcAlpha_OpSign_Neg = 3u << kBlendY_SrcAlpha_OpSign_Shift, - kBlendY_Dest_OpSign_Shift = 16, - kBlendY_Dest_OpSign_Pos = 1u << kBlendY_Dest_OpSign_Shift, - kBlendY_Dest_OpSign_Neg = 3u << kBlendY_Dest_OpSign_Shift, - kBlendY_DestAlpha_OpSign_Shift = 18, - kBlendY_DestAlpha_OpSign_Pos = 1u << kBlendY_DestAlpha_OpSign_Shift, - kBlendY_DestAlpha_OpSign_Neg = 3u << kBlendY_DestAlpha_OpSign_Shift, - - kBlendY_Color_OpMin_Shift = 20, - kBlendY_Color_OpMin = 1u << kBlendY_Color_OpMin_Shift, - kBlendY_Color_OpMax_Shift = 21, - kBlendY_Color_OpMax = 1u << kBlendY_Color_OpMax_Shift, - kBlendY_Alpha_OpMin_Shift = 22, - kBlendY_Alpha_OpMin = 1u << kBlendY_Alpha_OpMin_Shift, - kBlendY_Alpha_OpMax_Shift = 23, - kBlendY_Alpha_OpMax = 1u << kBlendY_Alpha_OpMax_Shift, + kRTFormatFlag_64bpp = 1u << kRTFormatFlag_64bpp_Shift, + kRTFormatFlag_FixedPointColor = 1u << kRTFormatFlag_FixedPointColor_Shift, + kRTFormatFlag_FixedPointAlpha = 1u << kRTFormatFlag_FixedPointAlpha_Shift, }; // IF SYSTEM CONSTANTS ARE CHANGED OR ADDED, THE FOLLOWING MUST BE UPDATED: @@ -357,7 +232,7 @@ class DxbcShaderTranslator : public ShaderTranslator { float edram_poly_offset_back[2]; }; - uint32_t edram_resolution_scale_log2; + uint32_t edram_resolution_square_scale; uint32_t edram_stencil_reference; uint32_t edram_stencil_read_mask; uint32_t edram_stencil_write_mask; @@ -384,56 +259,29 @@ class DxbcShaderTranslator : public ShaderTranslator { uint32_t edram_stencil_back[4]; }; - uint32_t edram_base_dwords[4]; + uint32_t edram_rt_base_dwords_scaled[4]; - // Binding and format info flags. - uint32_t edram_rt_flags[4]; + // RT format combined with kRTFormatFlags. + uint32_t edram_rt_format_flags[4]; - // Format info - widths of components in the lower 32 bits (for ibfe/bfi), - // packed as 8:8:8:8 for each render target. - uint32_t edram_rt_pack_width_low[4]; + // Format info - values to clamp the color to before blending or storing. + // Low color, low alpha, high color, high alpha. + float edram_rt_clamp[4][4]; - // Format info - offsets of components in the lower 32 bits (for ibfe/bfi), - // packed as 8:8:8:8 for each render target. - uint32_t edram_rt_pack_offset_low[4]; + // Format info - mask to apply to the old packed RT data, and to apply as + // inverted to the new packed data, before storing (more or less the inverse + // of the write mask packed like render target channels). This can be used + // to bypass unpacking if blending is not used. If 0 and not blending, + // reading the old data from the EDRAM buffer is not required. + uint32_t edram_rt_keep_mask[4][2]; - // Format info - widths of components in the upper 32 bits (for ibfe/bfi), - // packed as 8:8:8:8 for each render target. - uint32_t edram_rt_pack_width_high[4]; - - // Format info - offsets of components in the upper 32 bits (for ibfe/bfi), - // packed as 8:8:8:8 for each render target. - uint32_t edram_rt_pack_offset_high[4]; - - // Format info - mask of color and alpha after unpacking, but before float - // conversion. Primarily to differentiate between signed and unsigned - // formats because ibfe is used for both since k_16_16 and k_16_16_16_16 are - // signed. - uint32_t edram_load_mask_rt01_rt23[2][4]; - - // Format info - scale to apply to the color and the alpha of each render - // target after unpacking and converting. - float edram_load_scale_rt01_rt23[2][4]; - - // Render target blending options. - uint32_t edram_blend_rt01_rt23[2][4]; + // Render target blending options - RB_BLENDCONTROL, with only the relevant + // options (factors and operations - AND 0x1FFF1FFF). If 0x00010001 + // (1 * src + 0 * dst), blending is disabled for the render target. + uint32_t edram_rt_blend_factors_ops[4]; // The constant blend factor for the respective modes. float edram_blend_constant[4]; - - // Format info - minimum color and alpha values (as float, before - // conversion) writable to the each render target. Integer so it's easier to - // write infinity. - uint32_t edram_store_min_rt01_rt23[2][4]; - - // Format info - maximum color and alpha values (as float, before - // conversion) writable to the each render target. Integer so it's easier to - // write infinity. - uint32_t edram_store_max_rt01_rt23[2][4]; - - // Format info - scale to apply to the color and the alpha of each render - // target before converting and packing. - float edram_store_scale_rt01_rt23[2][4]; }; // 192 textures at most because there are 32 fetch constants, and textures can @@ -490,16 +338,38 @@ class DxbcShaderTranslator : public ShaderTranslator { // overriding that alpha testing is used in the shader. static std::vector ForceEarlyDepthStencil(const uint8_t* shader); + // Returns the format with internal flags for passing via the + // edram_rt_format_flags system constant. + static constexpr uint32_t ROV_AddColorFormatFlags( + ColorRenderTargetFormat format) { + uint32_t format_flags = uint32_t(format); + if (format == ColorRenderTargetFormat::k_16_16_16_16 || + format == ColorRenderTargetFormat::k_16_16_16_16_FLOAT || + format == ColorRenderTargetFormat::k_32_32_FLOAT) { + format_flags |= kRTFormatFlag_64bpp; + } + if (format == ColorRenderTargetFormat::k_8_8_8_8 || + format == ColorRenderTargetFormat::k_8_8_8_8_GAMMA || + format == ColorRenderTargetFormat::k_2_10_10_10 || + format == ColorRenderTargetFormat::k_16_16 || + format == ColorRenderTargetFormat::k_16_16_16_16 || + format == ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10) { + format_flags |= + kRTFormatFlag_FixedPointColor | kRTFormatFlag_FixedPointAlpha; + } else if (format == ColorRenderTargetFormat::k_2_10_10_10_FLOAT || + format == + ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16) { + format_flags |= kRTFormatFlag_FixedPointAlpha; + } + return format_flags; + } // Returns the bits that need to be added to the RT flags constant - needs to // be done externally, not in SetColorFormatConstants, because the flags // contain other state. - static uint32_t GetColorFormatRTFlags(ColorRenderTargetFormat format); - static void SetColorFormatSystemConstants(SystemConstants& constants, - uint32_t rt_index, - ColorRenderTargetFormat format); - // Returns whether blending should be done at all (not 1 * src + 0 * dest). - static bool GetBlendConstants(uint32_t blend_control, uint32_t& blend_x_out, - uint32_t& blend_y_out); + static void ROV_GetColorFormatSystemConstants( + ColorRenderTargetFormat format, uint32_t write_mask, float& clamp_rgb_low, + float& clamp_alpha_low, float& clamp_rgb_high, float& clamp_alpha_high, + uint32_t& keep_mask_low, uint32_t& keep_mask_high); // Creates a special pixel shader without color outputs - this resets the // state of the translator. @@ -547,6 +417,7 @@ class DxbcShaderTranslator : public ShaderTranslator { kSysConst_VertexBaseIndex_Comp = 3, kSysConst_UserClipPlanes_Index = kSysConst_VertexBaseIndex_Index + 1, + // 6 vectors. kSysConst_UserClipPlanes_Vec = kSysConst_VertexBaseIndex_Vec + 1, kSysConst_NDCScale_Index = kSysConst_UserClipPlanes_Index + 1, @@ -613,24 +484,25 @@ class DxbcShaderTranslator : public ShaderTranslator { kSysConst_EDRAMPolyOffsetBackScale_Comp = 2, kSysConst_EDRAMPolyOffsetBackOffset_Comp = 3, - kSysConst_EDRAMResolutionScaleLog2_Index = + kSysConst_EDRAMResolutionSquareScale_Index = kSysConst_EDRAMPolyOffsetBack_Index + 1, - kSysConst_EDRAMResolutionScaleLog2_Vec = + kSysConst_EDRAMResolutionSquareScale_Vec = kSysConst_EDRAMPolyOffsetBack_Vec + 1, - kSysConst_EDRAMResolutionScaleLog2_Comp = 0, + kSysConst_EDRAMResolutionSquareScale_Comp = 0, kSysConst_EDRAMStencilReference_Index = - kSysConst_EDRAMResolutionScaleLog2_Index + 1, + kSysConst_EDRAMResolutionSquareScale_Index + 1, kSysConst_EDRAMStencilReference_Vec = - kSysConst_EDRAMResolutionScaleLog2_Vec, + kSysConst_EDRAMResolutionSquareScale_Vec, kSysConst_EDRAMStencilReference_Comp = 1, kSysConst_EDRAMStencilReadMask_Index = kSysConst_EDRAMStencilReference_Index + 1, - kSysConst_EDRAMStencilReadMask_Vec = kSysConst_EDRAMResolutionScaleLog2_Vec, + kSysConst_EDRAMStencilReadMask_Vec = + kSysConst_EDRAMResolutionSquareScale_Vec, kSysConst_EDRAMStencilReadMask_Comp = 2, kSysConst_EDRAMStencilWriteMask_Index = kSysConst_EDRAMStencilReadMask_Index + 1, kSysConst_EDRAMStencilWriteMask_Vec = - kSysConst_EDRAMResolutionScaleLog2_Vec, + kSysConst_EDRAMResolutionSquareScale_Vec, kSysConst_EDRAMStencilWriteMask_Comp = 3, kSysConst_EDRAMStencilFront_Index = @@ -646,70 +518,32 @@ class DxbcShaderTranslator : public ShaderTranslator { kSysConst_EDRAMStencilSide_Pass_Comp = 2, kSysConst_EDRAMStencilSide_Comparison_Comp = 3, - kSysConst_EDRAMBaseDwords_Index = kSysConst_EDRAMStencilBack_Index + 1, - kSysConst_EDRAMBaseDwords_Vec = kSysConst_EDRAMStencilBack_Vec + 1, + kSysConst_EDRAMRTBaseDwordsScaled_Index = + kSysConst_EDRAMStencilBack_Index + 1, + kSysConst_EDRAMRTBaseDwordsScaled_Vec = kSysConst_EDRAMStencilBack_Vec + 1, - kSysConst_EDRAMRTFlags_Index = kSysConst_EDRAMBaseDwords_Index + 1, - kSysConst_EDRAMRTFlags_Vec = kSysConst_EDRAMBaseDwords_Vec + 1, + kSysConst_EDRAMRTFormatFlags_Index = + kSysConst_EDRAMRTBaseDwordsScaled_Index + 1, + kSysConst_EDRAMRTFormatFlags_Vec = + kSysConst_EDRAMRTBaseDwordsScaled_Vec + 1, - kSysConst_EDRAMRTPackWidthLow_Index = kSysConst_EDRAMRTFlags_Index + 1, - kSysConst_EDRAMRTPackWidthLow_Vec = kSysConst_EDRAMRTFlags_Vec + 1, + kSysConst_EDRAMRTClamp_Index = kSysConst_EDRAMRTFormatFlags_Index + 1, + // 4 vectors. + kSysConst_EDRAMRTClamp_Vec = kSysConst_EDRAMRTFormatFlags_Vec + 1, - kSysConst_EDRAMRTPackOffsetLow_Index = - kSysConst_EDRAMRTPackWidthLow_Index + 1, - kSysConst_EDRAMRTPackOffsetLow_Vec = kSysConst_EDRAMRTPackWidthLow_Vec + 1, + kSysConst_EDRAMRTKeepMask_Index = kSysConst_EDRAMRTClamp_Index + 1, + // 2 vectors (render targets 01 and 23). + kSysConst_EDRAMRTKeepMask_Vec = kSysConst_EDRAMRTClamp_Vec + 4, - kSysConst_EDRAMRTPackWidthHigh_Index = - kSysConst_EDRAMRTPackOffsetLow_Index + 1, - kSysConst_EDRAMRTPackWidthHigh_Vec = kSysConst_EDRAMRTPackOffsetLow_Vec + 1, + kSysConst_EDRAMRTBlendFactorsOps_Index = + kSysConst_EDRAMRTKeepMask_Index + 1, + kSysConst_EDRAMRTBlendFactorsOps_Vec = kSysConst_EDRAMRTKeepMask_Vec + 2, - kSysConst_EDRAMRTPackOffsetHigh_Index = - kSysConst_EDRAMRTPackWidthHigh_Index + 1, - kSysConst_EDRAMRTPackOffsetHigh_Vec = - kSysConst_EDRAMRTPackWidthHigh_Vec + 1, + kSysConst_EDRAMBlendConstant_Index = + kSysConst_EDRAMRTBlendFactorsOps_Index + 1, + kSysConst_EDRAMBlendConstant_Vec = kSysConst_EDRAMRTBlendFactorsOps_Vec + 1, - kSysConst_EDRAMLoadMaskRT01_Index = - kSysConst_EDRAMRTPackOffsetHigh_Index + 1, - kSysConst_EDRAMLoadMaskRT01_Vec = kSysConst_EDRAMRTPackOffsetHigh_Vec + 1, - - kSysConst_EDRAMLoadMaskRT23_Index = kSysConst_EDRAMLoadMaskRT01_Index + 1, - kSysConst_EDRAMLoadMaskRT23_Vec = kSysConst_EDRAMLoadMaskRT01_Vec + 1, - - kSysConst_EDRAMLoadScaleRT01_Index = kSysConst_EDRAMLoadMaskRT23_Index + 1, - kSysConst_EDRAMLoadScaleRT01_Vec = kSysConst_EDRAMLoadMaskRT23_Vec + 1, - - kSysConst_EDRAMLoadScaleRT23_Index = kSysConst_EDRAMLoadScaleRT01_Index + 1, - kSysConst_EDRAMLoadScaleRT23_Vec = kSysConst_EDRAMLoadScaleRT01_Vec + 1, - - kSysConst_EDRAMBlendRT01_Index = kSysConst_EDRAMLoadScaleRT23_Index + 1, - kSysConst_EDRAMBlendRT01_Vec = kSysConst_EDRAMLoadScaleRT23_Vec + 1, - - kSysConst_EDRAMBlendRT23_Index = kSysConst_EDRAMBlendRT01_Index + 1, - kSysConst_EDRAMBlendRT23_Vec = kSysConst_EDRAMBlendRT01_Vec + 1, - - kSysConst_EDRAMBlendConstant_Index = kSysConst_EDRAMBlendRT23_Index + 1, - kSysConst_EDRAMBlendConstant_Vec = kSysConst_EDRAMBlendRT23_Vec + 1, - - kSysConst_EDRAMStoreMinRT01_Index = kSysConst_EDRAMBlendConstant_Index + 1, - kSysConst_EDRAMStoreMinRT01_Vec = kSysConst_EDRAMBlendConstant_Vec + 1, - - kSysConst_EDRAMStoreMinRT23_Index = kSysConst_EDRAMStoreMinRT01_Index + 1, - kSysConst_EDRAMStoreMinRT23_Vec = kSysConst_EDRAMStoreMinRT01_Vec + 1, - - kSysConst_EDRAMStoreMaxRT01_Index = kSysConst_EDRAMStoreMinRT23_Index + 1, - kSysConst_EDRAMStoreMaxRT01_Vec = kSysConst_EDRAMStoreMinRT23_Vec + 1, - - kSysConst_EDRAMStoreMaxRT23_Index = kSysConst_EDRAMStoreMaxRT01_Index + 1, - kSysConst_EDRAMStoreMaxRT23_Vec = kSysConst_EDRAMStoreMaxRT01_Vec + 1, - - kSysConst_EDRAMStoreScaleRT01_Index = kSysConst_EDRAMStoreMaxRT23_Index + 1, - kSysConst_EDRAMStoreScaleRT01_Vec = kSysConst_EDRAMStoreMaxRT23_Vec + 1, - - kSysConst_EDRAMStoreScaleRT23_Index = - kSysConst_EDRAMStoreScaleRT01_Index + 1, - kSysConst_EDRAMStoreScaleRT23_Vec = kSysConst_EDRAMStoreScaleRT01_Vec + 1, - - kSysConst_Count = kSysConst_EDRAMStoreScaleRT23_Index + 1 + kSysConst_Count = kSysConst_EDRAMBlendConstant_Index + 1 }; static_assert(kSysConst_Count <= 64, "Too many system constants, can't use uint64_t for usage bits"); @@ -828,14 +662,69 @@ class DxbcShaderTranslator : public ShaderTranslator { // Allocates new consecutive r# registers for internal use and returns the // index of the first. - uint32_t PushSystemTemp(bool zero = false, uint32_t count = 1); + uint32_t PushSystemTemp(uint32_t zero_mask = 0, uint32_t count = 1); // Frees the last allocated internal r# registers for later reuse. void PopSystemTemp(uint32_t count = 1); + // Converts one scalar to or from PWL gamma, using 1 temporary scalar. + // The target may be the same as any of the source, the piece temporary or the + // accumulator, but not two or three of these. + // The piece and the accumulator can't be the same as source or as each other. + void ConvertPWLGamma(bool to_gamma, int32_t source_temp, + uint32_t source_temp_component, uint32_t target_temp, + uint32_t target_temp_component, uint32_t piece_temp, + uint32_t piece_temp_component, uint32_t accumulator_temp, + uint32_t accumulator_temp_component); + + inline uint32_t ROV_GetEDRAMUAVIndex() const { + // xe_edram is U1 when there's xe_shared_memory_uav which is U0, but when + // there's no xe_shared_memory_uav, it's U0. + return is_depth_only_pixel_shader_ ? 0 : 1; + } + // Whether it's possible and worth skipping running the translated shader for + // 2x2 quads. + bool ROV_IsDepthStencilEarly() const { + return !is_depth_only_pixel_shader_ && !writes_depth(); + } + // Does all the depth/stencil-related things, including or not including + // writing based on whether it's late, or on whether it's safe to do it early. + // Updates system_temp_rov_params_ result and coverage if allowed and safe, + // updates system_temp_rov_depth_stencil_, and if early and the coverage is + // empty for all pixels in the 2x2 quad and safe to return early (stencil is + // unchanged or known that it's safe not to await kills/alphatest/AtoC), + // returns from the shader. + void ROV_DepthStencilTest(); + // Unpacks a 32bpp or a 64bpp color in packed_temp.packed_temp_components to + // color_temp, using 2 temporary VGPRs. + void ROV_UnpackColor(uint32_t rt_index, uint32_t packed_temp, + uint32_t packed_temp_components, uint32_t color_temp, + uint32_t temp1, uint32_t temp1_component, uint32_t temp2, + uint32_t temp2_component); + // Packs a float32x4 color value to 32bpp or a 64bpp in color_temp to + // packed_temp.packed_temp_components, using 2 temporary VGPR. color_temp and + // packed_temp may be the same if packed_temp_components is 0. + void ROV_PackPreClampedColor(uint32_t rt_index, uint32_t color_temp, + uint32_t packed_temp, + uint32_t packed_temp_components, uint32_t temp1, + uint32_t temp1_component, uint32_t temp2, + uint32_t temp2_component); + // Emits a sequence of `case` labels for color blend factors, generating the + // factor from src_temp.rgb and dst_temp.rgb to factor_temp.rgb. factor_temp + // can be the same as src_temp or dst_temp. + void ROV_HandleColorBlendFactorCases(uint32_t src_temp, uint32_t dst_temp, + uint32_t factor_temp); + // Emits a sequence of `case` labels for alpha blend factors, generating the + // factor from src_temp.a and dst_temp.a to factor_temp.factor_component. + // factor_temp can be the same as src_temp or dst_temp. + void ROV_HandleAlphaBlendFactorCases(uint32_t src_temp, uint32_t dst_temp, + uint32_t factor_temp, + uint32_t factor_component); + // Writing the prologue. void StartVertexShader_LoadVertexIndex(); void StartVertexOrDomainShader(); void StartDomainShader(); + void StartPixelShader_LoadROVParameters(); void StartPixelShader(); // Writing the epilogue. @@ -843,93 +732,69 @@ class DxbcShaderTranslator : public ShaderTranslator { // multiple times. void ExportToMemory(); void CompleteVertexOrDomainShader(); - // Converts four depth values to 24-bit unorm or float, depending on the flag - // value. - void CompletePixelShader_DepthTo24Bit(uint32_t depths_temp); - // Applies the exponent bias from the constant to colors. - void CompletePixelShader_ApplyColorExpBias(); - // This just converts the color output value from/to gamma space, not checking - // any conditions. - void CompletePixelShader_GammaCorrect(uint32_t color_temp, bool to_gamma); + // Applies the exponent bias from the constant to one color output. + void CompletePixelShader_ApplyColorExpBias(uint32_t rt_index); // Discards the SSAA sample if it fails alpha to coverage. void CompletePixelShader_WriteToRTVs_AlphaToCoverage(); void CompletePixelShader_WriteToRTVs(); - inline uint32_t GetEDRAMUAVIndex() const { - // xe_edram is U1 when there's xe_shared_memory_uav which is U0, but when - // there's no xe_shared_memory_uav, it's U0. - return is_depth_only_pixel_shader_ ? 0 : 1; - } - // Extracts the coverage from SV_Coverage and performs alpha to coverage if - // necessary. Does not perform any depth/stencil testing. For covered samples, - // writes a non-zero component, for non-covered, writes 0. Discards the pixel - // if no coverage. - void CompletePixelShader_WriteToROV_GetCoverage(uint32_t coverage_out_temp); - // Performs depth/stencil testing. coverage_in_out_temp should contain the - // coverage mask obtained from CompletePixelShader_WriteToROV_GetCoverage to - // indicate which samples need to be depth/stencil-tested, and after the - // execution contains which covered samples have passed the depth/stencil test - // (non-zero components where covered, zero where not covered or failed the - // test). - // - // edram_dword_offset_temp.x must contain the address of the first - // depth/stencil sample - .yzw will be overwritten by this function with the - // addresses for the other samples if depth/stencil is enabled. - void CompletePixelShader_WriteToROV_DepthStencil( - uint32_t edram_dword_offset_temp, uint32_t coverage_in_out_temp); - // Extracts widths and offsets of the components in the lower or the upper - // dword of a pixel from the format constants, for use as ibfe and bfi - // operands later. - void CompletePixelShader_WriteToROV_ExtractPackLayout(uint32_t rt_index, - bool high, - uint32_t width_temp, - uint32_t offset_temp); - // Components of rt_format_flags_temp. - enum : uint32_t { - kROVRTFormatFlagTemp_ColorFixed, - kROVRTFormatFlagTemp_AlphaFixed, - kROVRTFormatFlagTemp_Float10, - kROVRTFormatFlagTemp_Float16, - - kROVRTFormatFlagTemp_Fixed_Swizzle = - kROVRTFormatFlagTemp_ColorFixed * 0b00010101 + - kROVRTFormatFlagTemp_AlphaFixed * 0b01000000, - }; - void CompletePixelShader_WriteToROV_UnpackColor( - uint32_t data_low_temp, uint32_t data_high_temp, uint32_t data_component, - uint32_t rt_index, uint32_t rt_format_flags_temp, uint32_t target_temp); - // Clamps the color to the range representable by the render target's format. - // Will also remove NaN since min and max return the non-NaN value. - // color_in_temp and color_out_temp may be the same. - void CompletePixelShader_WriteToROV_ClampColor(uint32_t rt_index, - uint32_t color_in_temp, - uint32_t color_out_temp); - // Extracts 0.0 or plus/minus 1.0 from a blend constant. For example, it can - // be used to extract one scale for color and alpha into XY, and another scale - // for color and alpha into ZW. constant_swizzle is a bit mask indicating - // which part of the blend constant for the render target to extract the scale - // from, 0b00000000 for X/Z only, 0b01010101 for Y/W only, 0b00000001 for X/Z - // in the first component, Y/W in the rest (XY changed to ZW automatically - // according to the render target index - don't set the higher bit). - void CompletePixelShader_WriteToROV_ExtractBlendScales( - uint32_t rt_index, uint32_t constant_swizzle, bool is_signed, - uint32_t shift_x, uint32_t shift_y, uint32_t shift_z, uint32_t shift_w, - uint32_t target_temp, uint32_t write_mask = 0b1111); - void CompletePixelShader_WriteToROV_ApplyZeroBlendScale( - uint32_t scale_temp, uint32_t scale_swizzle, uint32_t factor_in_temp, - uint32_t factor_swizzle, uint32_t factor_out_temp, - uint32_t write_mask = 0b1111); - void CompletePixelShader_WriteToROV_Blend(uint32_t rt_index, - uint32_t rt_format_flags_temp, - uint32_t src_color_and_output_temp, - uint32_t dest_color_temp); - // Assumes the incoming color is already clamped to the range representable by - // the RT format. - void CompletePixelShader_WriteToROV_PackColor( - uint32_t data_low_temp, uint32_t data_high_temp, uint32_t data_component, - uint32_t rt_index, uint32_t rt_format_flags_temp, - uint32_t source_and_scratch_temp); + // Returns if coverage in system_temp_rov_params_.x is empty. + void CompletePixelShader_ROV_CheckAnyCovered( + bool check_deferred_stencil_write, uint32_t temp, + uint32_t temp_component); + // Masks the sample away from system_temp_rov_params_.x if it's not covered. + void CompletePixelShader_ROV_AlphaToCoverageSample(uint32_t sample_index, + float threshold, + uint32_t temp, + uint32_t temp_component); + // Performs alpha to coverage if necessary, updating the low (coverage) bits + // of system_temp_. + void CompletePixelShader_ROV_AlphaToCoverage(); void CompletePixelShader_WriteToROV(); void CompletePixelShader(); + + // Writes a function that converts depth to 24 bits, putting it in 0:23, not + // creating space for stencil (ROV only). + // Input: + // - system_temps_subroutine_[0].x - Z/W + polygon offset at sample. + // Output: + // - system_temps_subroutine_[0].x - 24-bit depth. + // Local temps: + // - system_temps_subroutine_[0].y. + void CompleteShaderCode_ROV_DepthTo24BitSubroutine(); + // Writes a function that does early (or both early and late, when not + // separating) depth/stencil testing for one sample (ROV only). + // Input: + // - system_temps_subroutine_[0].x - depth converted to 24 bits in bits 0:23. + // - system_temp_rov_params_.y - depth sample EDRAM address. + // Output: + // - system_temps_subroutine_[0].x - resulting packed depth/stencil. + // - system_temps_subroutine_[0].y - test result, bit 0 if test FAILED (so + // coverage can be updated with XOR), and if depth/stencil is early, also + // bit 4 if the pixel shader still needs to be done to check for + // kills/alphatest/AtoC before writing the new stencil. + // Local temps: + // - system_temps_subroutine_[0].zw. + // - system_temps_subroutine_[1].xy. + void CompleteShaderCode_ROV_DepthStencilSampleSubroutine(); + // Writes a function that does loading, blending, write masking and storing + // for one color sample of the specified render target. + // Input: + // - system_temps_subroutine_[0].xy: + // - If not blending, packed source color (will be masked by the function). + // - If blending, used as a temporary. + // - system_temp_rov_params_.zw - color sample 32bpp and 64bpp EDRAM + // addresses. + // - system_temps_color_[rt_index]: + // - If blending (blend control is 0x00010001), source color clamped to the + // render target's representable range if it's fixed-point, unclamped + // source color if it's floating-point, not modified. + // - If not blending, ignored. + // Local temps: + // - system_temps_subroutine_[0].zw. + // - system_temps_subroutine_[1].xyzw. + // - system_temps_subroutine_[2].xyz. + // - system_temps_subroutine_[3].xyz. + void CompleteShaderCode_ROV_ColorSampleSubroutine(uint32_t rt_index); void CompleteShaderCode(); // Writes the original instruction disassembly in the output DXBC if enabled, @@ -1107,10 +972,14 @@ class DxbcShaderTranslator : public ShaderTranslator { kUint, kUint2, kUint4, + // Render target clamping ranges. + kFloat4Array4, // User clip planes. kFloat4Array6, // Float constants - size written dynamically. kFloat4ConstantArray, + // Render target keep masks. + kUint4Array2, // Bool constants. kUint4Array8, // Loop constants. @@ -1175,30 +1044,59 @@ class DxbcShaderTranslator : public ShaderTranslator { // indices are written). std::vector float_constant_index_offsets_; + // Subroutine labels. D3D10_SB_OPCODE_LABEL is not counted as an instruction + // in STAT. + uint32_t label_rov_depth_to_24bit_; + uint32_t label_rov_depth_stencil_sample_; + uint32_t label_rov_color_sample_[4]; + // Number of currently allocated Xenia internal r# registers. uint32_t system_temp_count_current_; // Total maximum number of temporary registers ever used during this // translation (for the declaration). uint32_t system_temp_count_max_; + // Registers for the needed count of non-main-subroutine-local variables. + // This includes arguments. + uint32_t system_temps_subroutine_; + // Number of registers allocated for subroutines other than main. + uint32_t system_temps_subroutine_count_; + // Position in vertex shaders (because viewport and W transformations can be // applied in the end of the shader). uint32_t system_temp_position_; - - // 4 color outputs in pixel shaders (because of exponent bias, alpha test and - // remapping, and also for ROV writing). - uint32_t system_temps_color_; - // Whether the color output has been written in the execution path (ROV only). - uint32_t system_temp_color_written_; - // Depth value (ROV only). The meaning depends on whether the shader writes to - // depth. - // If depth is written to: - // - X - the value that was written to oDepth. - // If not: - // - X - clip space Z / clip space W from the respective pixel shader input. - // - Y - depth X derivative (for polygon offset). - // - Z - depth Y derivative. - uint32_t system_temp_depth_; + // ROV only - 4 persistent VGPRs when writing to color targets, 2 VGPRs when + // not: + // X - Bit masks: + // 0:3 - Per-sample coverage at the current stage of the shader's execution. + // Affected by things like SV_Coverage, early or late depth/stencil + // (always resets bits for failing, no matter if need to defer writing), + // alpha to coverage. + // 4:7 - Depth write deferred mask - when early depth/stencil resulted in a + // different value for the sample (like different stencil if the test + // failed), but can't write it before running the shader because it's + // not known if the sample will be discarded by the shader, alphatest or + // AtoC. + // Early depth/stencil rejection of the pixel is possible when both 0:3 and + // 4:7 are zero. + // 8:11 - Whether color buffers have been written to, if not written on the + // taken execution path, don't export according to Direct3D 9 register + // documentation (some games rely on this behavior). + // Y - Absolute resolution-scaled EDRAM offset for depth/stencil, in dwords. + // Z - Base-relative resolution-scaled EDRAM offset for 32bpp color data, in + // dwords. + // W - Base-relative resolution-scaled EDRAM offset for 64bpp color data, in + // dwords. + uint32_t system_temp_rov_params_; + // ROV only - new depth/stencil data. 4 VGPRs. + // When not writing to oDepth: New per-sample depth/stencil values, generated + // during early depth/stencil test (actual writing checks coverage bits). + // When writing to oDepth: X also used to hold the depth written by the + // shader, later used as a temporary during depth/stencil testing. + uint32_t system_temp_rov_depth_stencil_; + // Up to 4 color outputs in pixel shaders (because of exponent bias, alpha + // test and remapping, and also for ROV writing). + uint32_t system_temps_color_[4]; // Bits containing whether each eM# has been written, for up to 16 streams, or // UINT32_MAX if memexport is not used. 8 bits (5 used) for each stream, with diff --git a/src/xenia/gpu/dxbc_shader_translator_alu.cc b/src/xenia/gpu/dxbc_shader_translator_alu.cc index bba16c647..ba49b51f2 100644 --- a/src/xenia/gpu/dxbc_shader_translator_alu.cc +++ b/src/xenia/gpu/dxbc_shader_translator_alu.cc @@ -1052,15 +1052,19 @@ bool DxbcShaderTranslator::ProcessVectorAluOperation( ++stat_.instruction_count; ++stat_.uint_instruction_count; // Discard. - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_DISCARD) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE( + edram_rov_used_ ? D3D10_SB_OPCODE_RETC + : D3D10_SB_OPCODE_DISCARD) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); shader_code_.push_back( EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); shader_code_.push_back(system_temp_pv_); ++stat_.instruction_count; + if (edram_rov_used_) { + ++stat_.dynamic_flow_control_count; + } break; case AluVectorOpcode::kDst: { @@ -2272,15 +2276,19 @@ bool DxbcShaderTranslator::ProcessScalarAluOperation( ++stat_.instruction_count; ++stat_.uint_instruction_count; // Discard. - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_DISCARD) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE( + edram_rov_used_ ? D3D10_SB_OPCODE_RETC + : D3D10_SB_OPCODE_DISCARD) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); shader_code_.push_back( EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); shader_code_.push_back(system_temp_ps_pc_p0_a0_); ++stat_.instruction_count; + if (edram_rov_used_) { + ++stat_.dynamic_flow_control_count; + } break; case AluScalarOpcode::kMulsc0: diff --git a/src/xenia/gpu/dxbc_shader_translator_fetch.cc b/src/xenia/gpu/dxbc_shader_translator_fetch.cc index 8f78e55c5..703c9277e 100644 --- a/src/xenia/gpu/dxbc_shader_translator_fetch.cc +++ b/src/xenia/gpu/dxbc_shader_translator_fetch.cc @@ -1843,11 +1843,10 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction( ++stat_.float_instruction_count; } - // Allocate the register for the value from the signed texture, and later - // for biasing and gamma correction. - uint32_t signs_value_temp = instr.opcode == FetchOpcode::kTextureFetch - ? PushSystemTemp() - : UINT32_MAX; + // Allocate the register for the value from the signed texture. + uint32_t signed_value_temp = instr.opcode == FetchOpcode::kTextureFetch + ? PushSystemTemp() + : UINT32_MAX; // tfetch1D/2D/Cube just fetch directly. tfetch3D needs to fetch either // the 3D texture or the 2D stacked texture, so two sample instructions @@ -1867,7 +1866,7 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction( // Sample both 3D and 2D array bindings for tfetch3D. for (uint32_t i = 0; i < (instr.dimension == TextureDimension::k3D ? 2u : 1u); ++i) { - if (i != 0) { + if (i) { shader_code_.push_back( ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); @@ -1876,9 +1875,9 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction( // Sample both unsigned and signed. for (uint32_t j = 0; j < 2; ++j) { uint32_t srv_register_current = - i != 0 ? srv_registers_stacked[j] : srv_registers[j]; + i ? srv_registers_stacked[j] : srv_registers[j]; uint32_t target_temp_current = - j != 0 ? signs_value_temp : system_temp_pv_; + j ? signed_value_temp : system_temp_pv_; if (instr.opcode == FetchOpcode::kGetTextureComputedLod) { // The non-pixel-shader case should be handled before because it // just returns a constant in this case. @@ -2043,242 +2042,170 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction( cbuffer_index_fetch_constants_ = cbuffer_count_++; } - assert_true(signs_value_temp != UINT32_MAX); - uint32_t signs_temp = PushSystemTemp(); - uint32_t signs_select_temp = PushSystemTemp(); + assert_true(signed_value_temp != UINT32_MAX); + uint32_t sign_temp = PushSystemTemp(); - // Multiplex unsigned and signed SRVs, apply sign bias (2 * color - 1) - // and linearize gamma textures. This is done before applying the - // exponent bias because biasing and linearization must be done on color - // values in 0...1 range, and this is closer to the storage format, - // while exponent bias is closer to the actual usage in shaders. - // Extract the sign values from dword 0 ([0].x or [1].z) of the fetch - // constant, in bits 2:3, 4:5, 6:7 and 8:9. - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_UBFE) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(17)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(signs_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(2); - shader_code_.push_back(2); - shader_code_.push_back(2); - shader_code_.push_back(2); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(2); - shader_code_.push_back(4); - shader_code_.push_back(6); - shader_code_.push_back(8); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, (tfetch_index & 1) * 2, 3)); - shader_code_.push_back(cbuffer_index_fetch_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kFetchConstants)); - shader_code_.push_back(tfetch_pair_offset + (tfetch_index & 1)); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Replace the components fetched from the unsigned texture from those - // fetched from the signed where needed (the signed values are already - // loaded to signs_value_temp). - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IEQ) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(signs_select_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(signs_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(uint32_t(TextureSign::kSigned)); - shader_code_.push_back(uint32_t(TextureSign::kSigned)); - shader_code_.push_back(uint32_t(TextureSign::kSigned)); - shader_code_.push_back(uint32_t(TextureSign::kSigned)); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(system_temp_pv_); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(signs_select_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(signs_value_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(system_temp_pv_); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - // Reusing signs_value_temp from now because the value from the signed - // texture has already been copied. - - // Expand 0...1 to -1...1 (for normal and DuDv maps, for instance). - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(15)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(signs_value_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(system_temp_pv_); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0x40000000u); - shader_code_.push_back(0x40000000u); - shader_code_.push_back(0x40000000u); - shader_code_.push_back(0x40000000u); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0xBF800000u); - shader_code_.push_back(0xBF800000u); - shader_code_.push_back(0xBF800000u); - shader_code_.push_back(0xBF800000u); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - // Change the color to the biased one where needed. - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IEQ) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(signs_select_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(signs_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(uint32_t(TextureSign::kUnsignedBiased)); - shader_code_.push_back(uint32_t(TextureSign::kUnsignedBiased)); - shader_code_.push_back(uint32_t(TextureSign::kUnsignedBiased)); - shader_code_.push_back(uint32_t(TextureSign::kUnsignedBiased)); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(system_temp_pv_); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(signs_select_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(signs_value_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(system_temp_pv_); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - // Linearize the texture if it's stored in a gamma format. + // Choose between channels from the unsigned SRV and the signed one, + // apply sign bias (2 * color - 1) and linearize gamma textures. + // This is done before applying the exponent bias because biasing and + // linearization must be done on color values in 0...1 range, and this + // is closer to the storage format, while exponent bias is closer to the + // actual usage in shaders. for (uint32_t i = 0; i < 4; ++i) { - // Calculate how far we are on each piece of the curve. Multiply by - // 1/width of each piece, subtract start/width of it and saturate. + // Extract the sign values from dword 0 ([0].x or [1].z) of the fetch + // constant (in bits 2:9, 2 bits per component) to sign_temp.x. shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | - ENCODE_D3D10_SB_INSTRUCTION_SATURATE(1) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(15)); + ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_UBFE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(signs_select_temp); + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(sign_temp); shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(system_temp_pv_); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - // 1.0 / 0.25 - shader_code_.push_back(0x40800000u); - // 1.0 / 0.125 - shader_code_.push_back(0x41000000u); - // 1.0 / 0.375 - shader_code_.push_back(0x402AAAABu); - // 1.0 / 0.25 - shader_code_.push_back(0x40800000u); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - // -0.0 / 0.25 - shader_code_.push_back(0); - // -0.25 / 0.125 - shader_code_.push_back(0xC0000000u); - // -0.375 / 0.375 - shader_code_.push_back(0xBF800000u); - // -0.75 / 0.25 - shader_code_.push_back(0xC0400000u); + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(2); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(2 + i * 2); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + (tfetch_index & 1) * 2, 3)); + shader_code_.push_back(cbuffer_index_fetch_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kFetchConstants)); + shader_code_.push_back(tfetch_pair_offset + (tfetch_index & 1)); ++stat_.instruction_count; - ++stat_.float_instruction_count; - // Combine the contribution of all pieces to the resulting linearized - // value - multiply each piece by slope*width and sum them. + ++stat_.uint_instruction_count; + + // Get if the channel is signed to sign_temp.y. shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_DP4) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IEQ) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(sign_temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(sign_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(TextureSign::kSigned)); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Choose between the unsigned and the signed channel. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); shader_code_.push_back( EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1 << i, 1)); - shader_code_.push_back(signs_value_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(signs_select_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - // 0.25 * 0.25 - shader_code_.push_back(0x3D800000u); - // 0.5 * 0.125 - shader_code_.push_back(0x3D800000u); - // 1.0 * 0.375 - shader_code_.push_back(0x3EC00000u); - // 2.0 * 0.25 - shader_code_.push_back(0x3F000000u); + shader_code_.push_back(system_temp_pv_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(sign_temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); + shader_code_.push_back(signed_value_temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); + shader_code_.push_back(system_temp_pv_); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + + // Get if the channel is biased to sign_temp.y. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IEQ) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(sign_temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(sign_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(TextureSign::kUnsignedBiased)); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Expand 0...1 to -1...1 (for normal and DuDv maps, for instance) to + // sign_temp.z. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0100, 1)); + shader_code_.push_back(sign_temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); + shader_code_.push_back(system_temp_pv_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0x40000000u); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0xBF800000u); ++stat_.instruction_count; ++stat_.float_instruction_count; - } - // Change the color to the linearized one where needed. - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IEQ) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(signs_select_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(signs_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(uint32_t(TextureSign::kGamma)); - shader_code_.push_back(uint32_t(TextureSign::kGamma)); - shader_code_.push_back(uint32_t(TextureSign::kGamma)); - shader_code_.push_back(uint32_t(TextureSign::kGamma)); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(system_temp_pv_); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(signs_select_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(signs_value_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(system_temp_pv_); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - // Release signs_temp and signs_select_temp. - PopSystemTemp(2); + // Choose between the unbiased and the biased channel. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1 << i, 1)); + shader_code_.push_back(system_temp_pv_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(sign_temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(sign_temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); + shader_code_.push_back(system_temp_pv_); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + + // Get if the channel is in PWL gamma to sign_temp.x. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IEQ) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(sign_temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(sign_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(TextureSign::kGamma)); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Check if need to degamma. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(sign_temp); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Degamma the channel. + ConvertPWLGamma(false, system_temp_pv_, i, system_temp_pv_, i, + sign_temp, 0, sign_temp, 1); + + // Close the gamma conditional. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + } + + // Release sign_temp. + PopSystemTemp(); // Apply exponent bias. uint32_t exp_adjust_temp = PushSystemTemp(); @@ -2352,7 +2279,7 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction( PopSystemTemp(); } - if (signs_value_temp != UINT32_MAX) { + if (signed_value_temp != UINT32_MAX) { PopSystemTemp(); } if (lod_temp != system_temp_grad_h_lod_) { diff --git a/src/xenia/gpu/dxbc_shader_translator_memexport.cc b/src/xenia/gpu/dxbc_shader_translator_memexport.cc index 07fba60c3..fa40441dc 100644 --- a/src/xenia/gpu/dxbc_shader_translator_memexport.cc +++ b/src/xenia/gpu/dxbc_shader_translator_memexport.cc @@ -78,22 +78,46 @@ void DxbcShaderTranslator::ExportToMemory() { if (IsDxbcPixelShader()) { // Disable memexport in pixel shaders with supersampling since VPOS is // ambiguous. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(control_temp); if (edram_rov_used_) { system_constants_used_ |= 1ull - << kSysConst_EDRAMResolutionScaleLog2_Index; + << kSysConst_EDRAMResolutionSquareScale_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_UGE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(control_temp); shader_code_.push_back(EncodeVectorSelectOperand( D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_EDRAMResolutionScaleLog2_Comp, 3)); + kSysConst_EDRAMResolutionSquareScale_Comp, 3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1); shader_code_.push_back(cbuffer_index_system_constants_); shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMResolutionScaleLog2_Vec); + shader_code_.push_back(kSysConst_EDRAMResolutionSquareScale_Vec); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(control_temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(control_temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(control_temp); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; } else { system_constants_used_ |= 1ull << kSysConst_SampleCountLog2_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(control_temp); // Enough to check just Y because it's scaled for both 2x and 4x. shader_code_.push_back( EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, @@ -101,15 +125,15 @@ void DxbcShaderTranslator::ExportToMemory() { shader_code_.push_back(cbuffer_index_system_constants_); shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); shader_code_.push_back(kSysConst_SampleCountLog2_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(control_temp); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; } - shader_code_.push_back( - EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); - shader_code_.push_back(0); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(control_temp); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; } // Check if memexport can be done. @@ -1238,7 +1262,7 @@ void DxbcShaderTranslator::ExportToMemory() { // Extract the mask of eM register actually written to on the execution // path. - uint32_t eM_written_temps = PushSystemTemp(false, eM_count > 4 ? 2 : 1); + uint32_t eM_written_temps = PushSystemTemp(0, eM_count > 4 ? 2 : 1); shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); shader_code_.push_back(EncodeVectorMaskedOperand( diff --git a/src/xenia/gpu/dxbc_shader_translator_om.cc b/src/xenia/gpu/dxbc_shader_translator_om.cc index aca6f3402..482dabf35 100644 --- a/src/xenia/gpu/dxbc_shader_translator_om.cc +++ b/src/xenia/gpu/dxbc_shader_translator_om.cc @@ -17,397 +17,697 @@ namespace xe { namespace gpu { using namespace ucode; -uint32_t DxbcShaderTranslator::GetColorFormatRTFlags( - ColorRenderTargetFormat format) { - static const uint32_t kRTFormatFlags[16] = { - // k_8_8_8_8 - kRTFlag_FormatFixed, - // k_8_8_8_8_GAMMA - kRTFlag_FormatFixed, - // k_2_10_10_10 - kRTFlag_FormatFixed, - // k_2_10_10_10_FLOAT - kRTFlag_FormatFloat10, - // k_16_16 - kRTFlag_FormatFixed | kRTFlag_FormatUnusedB | kRTFlag_FormatUnusedA, - // k_16_16_16_16 - kRTFlag_FormatFixed, - // k_16_16_FLOAT - kRTFlag_FormatFloat16 | kRTFlag_FormatUnusedB | kRTFlag_FormatUnusedA, - // k_16_16_16_16_FLOAT - kRTFlag_FormatFloat16, - // Unused - kRTFlag_FormatUnusedR | kRTFlag_FormatUnusedG | kRTFlag_FormatUnusedB | - kRTFlag_FormatUnusedA, - // Unused - kRTFlag_FormatUnusedR | kRTFlag_FormatUnusedG | kRTFlag_FormatUnusedB | - kRTFlag_FormatUnusedA, - // k_2_10_10_10_AS_10_10_10_10 - kRTFlag_FormatFixed, - // Unused. - kRTFlag_FormatUnusedR | kRTFlag_FormatUnusedG | kRTFlag_FormatUnusedB | - kRTFlag_FormatUnusedA, - // k_2_10_10_10_FLOAT_AS_16_16_16_16 - kRTFlag_FormatFloat10, - // Unused. - kRTFlag_FormatUnusedR | kRTFlag_FormatUnusedG | kRTFlag_FormatUnusedB | - kRTFlag_FormatUnusedA, - // k_32_FLOAT - kRTFlag_FormatUnusedG | kRTFlag_FormatUnusedB | kRTFlag_FormatUnusedA, - // k_32_32_FLOAT - kRTFlag_FormatUnusedB | kRTFlag_FormatUnusedA, - }; - return kRTFormatFlags[uint32_t(format)]; -} - -void DxbcShaderTranslator::SetColorFormatSystemConstants( - SystemConstants& constants, uint32_t rt_index, - ColorRenderTargetFormat format) { - constants.edram_rt_pack_width_high[rt_index] = 0; - constants.edram_rt_pack_offset_high[rt_index] = 0; - uint32_t color_mask = UINT32_MAX, alpha_mask = UINT32_MAX; - uint32_t color_min = 0, alpha_min = 0; - uint32_t color_max = 0x3F800000, alpha_max = 0x3F800000; - float color_load_scale = 1.0f, alpha_load_scale = 1.0f; - float color_store_scale = 1.0f, alpha_store_scale = 1.0f; +void DxbcShaderTranslator::ROV_GetColorFormatSystemConstants( + ColorRenderTargetFormat format, uint32_t write_mask, float& clamp_rgb_low, + float& clamp_alpha_low, float& clamp_rgb_high, float& clamp_alpha_high, + uint32_t& keep_mask_low, uint32_t& keep_mask_high) { + keep_mask_low = keep_mask_high = 0; switch (format) { case ColorRenderTargetFormat::k_8_8_8_8: - case ColorRenderTargetFormat::k_8_8_8_8_GAMMA: - constants.edram_rt_pack_width_low[rt_index] = - 8 | (8 << 8) | (8 << 16) | (8 << 24); - constants.edram_rt_pack_offset_low[rt_index] = - (8 << 8) | (16 << 16) | (24 << 24); - color_mask = alpha_mask = 255; - color_load_scale = alpha_load_scale = 1.0f / 255.0f; - color_store_scale = alpha_store_scale = 255.0f; - break; + case ColorRenderTargetFormat::k_8_8_8_8_GAMMA: { + clamp_rgb_low = clamp_alpha_low = 0.0f; + clamp_rgb_high = clamp_alpha_high = 1.0f; + for (uint32_t i = 0; i < 4; ++i) { + if (!(write_mask & (1 << i))) { + keep_mask_low |= uint32_t(0xFF) << (i * 8); + } + } + } break; case ColorRenderTargetFormat::k_2_10_10_10: - case ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10: - constants.edram_rt_pack_width_low[rt_index] = - 10 | (10 << 8) | (10 << 16) | (2 << 24); - constants.edram_rt_pack_offset_low[rt_index] = - (10 << 8) | (20 << 16) | (30 << 24); - color_mask = 1023; - alpha_mask = 3; - color_load_scale = 1.0f / 1023.0f; - alpha_load_scale = 1.0f / 3.0f; - color_store_scale = 1023.0f; - alpha_store_scale = 3.0f; - break; + case ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10: { + clamp_rgb_low = clamp_alpha_low = 0.0f; + clamp_rgb_high = clamp_alpha_high = 1.0f; + for (uint32_t i = 0; i < 3; ++i) { + if (!(write_mask & (1 << i))) { + keep_mask_low |= uint32_t(0x3FF) << (i * 10); + } + } + if (!(write_mask & 0b1000)) { + keep_mask_low |= uint32_t(3) << 30; + } + } break; case ColorRenderTargetFormat::k_2_10_10_10_FLOAT: - case ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16: - constants.edram_rt_pack_width_low[rt_index] = - 10 | (10 << 8) | (10 << 16) | (2 << 24); - constants.edram_rt_pack_offset_low[rt_index] = - (10 << 8) | (20 << 16) | (30 << 24); - color_mask = 1023; - alpha_mask = 3; - // 31.875. - color_max = 0x41FF0000; - alpha_load_scale = 1.0f / 3.0f; - alpha_store_scale = 3.0f; - break; + case ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16: { + clamp_rgb_low = clamp_alpha_low = 0.0f; + clamp_rgb_high = 31.875f; + clamp_alpha_high = 1.0f; + for (uint32_t i = 0; i < 3; ++i) { + if (!(write_mask & (1 << i))) { + keep_mask_low |= uint32_t(0x3FF) << (i * 10); + } + } + if (!(write_mask & 0b1000)) { + keep_mask_low |= uint32_t(3) << 30; + } + } break; case ColorRenderTargetFormat::k_16_16: case ColorRenderTargetFormat::k_16_16_16_16: - constants.edram_rt_pack_width_low[rt_index] = 16 | (16 << 8); - constants.edram_rt_pack_offset_low[rt_index] = 16 << 8; - if (format == ColorRenderTargetFormat::k_16_16_16_16) { - constants.edram_rt_pack_width_high[rt_index] = (16 << 16) | (16 << 24); - constants.edram_rt_pack_offset_high[rt_index] = 16 << 24; + // Alpha clamping affects blending source, so it's non-zero for alpha for + // k_16_16 (the render target is fixed-point). + clamp_rgb_low = clamp_alpha_low = -32.0f; + clamp_rgb_high = clamp_alpha_high = 32.0f; + if (!(write_mask & 0b0001)) { + keep_mask_low |= 0xFFFFu; + } + if (!(write_mask & 0b0010)) { + keep_mask_low |= 0xFFFF0000u; + } + if (format == ColorRenderTargetFormat::k_16_16_16_16) { + if (!(write_mask & 0b0100)) { + keep_mask_high |= 0xFFFFu; + } + if (!(write_mask & 0b1000)) { + keep_mask_high |= 0xFFFF0000u; + } + } else { + write_mask &= 0b0011; } - // -32.0. - color_min = alpha_min = 0xC2000000u; - // 32.0. - color_max = alpha_max = 0x42000000u; - color_load_scale = alpha_load_scale = 32.0f / 32767.0f; - color_store_scale = alpha_store_scale = 32767.0f / 32.0f; break; case ColorRenderTargetFormat::k_16_16_FLOAT: case ColorRenderTargetFormat::k_16_16_16_16_FLOAT: - constants.edram_rt_pack_width_low[rt_index] = 16 | (16 << 8); - constants.edram_rt_pack_offset_low[rt_index] = 16 << 8; - if (format == ColorRenderTargetFormat::k_16_16_16_16_FLOAT) { - constants.edram_rt_pack_width_high[rt_index] = (16 << 16) | (16 << 24); - constants.edram_rt_pack_offset_high[rt_index] = 16 << 24; + // No NaNs on the Xbox 360 GPU, though can't use the extended range with + // f32tof16. + clamp_rgb_low = clamp_alpha_low = -65504.0f; + clamp_rgb_high = clamp_alpha_high = 65504.0f; + if (!(write_mask & 0b0001)) { + keep_mask_low |= 0xFFFFu; + } + if (!(write_mask & 0b0010)) { + keep_mask_low |= 0xFFFF0000u; + } + if (format == ColorRenderTargetFormat::k_16_16_16_16_FLOAT) { + if (!(write_mask & 0b0100)) { + keep_mask_high |= 0xFFFFu; + } + if (!(write_mask & 0b1000)) { + keep_mask_high |= 0xFFFF0000u; + } + } else { + write_mask &= 0b0011; } - color_mask = alpha_mask = 0xFFFF; - // -65504.0 to 65504.0 - the Xbox 360 doesn't have Infinity or NaN in - // float16, instead it has the range expanded to 131008.0, however, - // supporting it correctly would require making changes to texture - // formats (float32 would be required for emulating textures, which is - // pretty big, resolves also will require conversion; vertex fetch, vpkd3d - // CPU instruction). The precision in the 65504-131008 range is very low - // anyway, let's hope games don't really rely on it. So let's only clamp - // to a finite value to remove specials from blending. - // https://blogs.msdn.microsoft.com/chuckw/2013/03/05/known-issues-directxmath-3-03/ - // TODO(Triang3l): Maybe handle float16 correctly everywhere. - color_min = alpha_min = 0xC77FE000u; - color_max = alpha_max = 0x477FE000u; break; case ColorRenderTargetFormat::k_32_FLOAT: - case ColorRenderTargetFormat::k_32_32_FLOAT: - constants.edram_rt_pack_width_low[rt_index] = 32; - constants.edram_rt_pack_offset_low[rt_index] = 0; - if (format == ColorRenderTargetFormat::k_32_32_FLOAT) { - constants.edram_rt_pack_width_high[rt_index] = 32; + // No clamping - let min/max always pick the original value. + clamp_rgb_low = clamp_alpha_low = clamp_rgb_high = clamp_alpha_high = + std::nanf(""); + write_mask &= 0b0001; + if (!(write_mask & 0b0001)) { + keep_mask_low = ~uint32_t(0); + } + break; + case ColorRenderTargetFormat::k_32_32_FLOAT: + // No clamping - let min/max always pick the original value. + clamp_rgb_low = clamp_alpha_low = clamp_rgb_high = clamp_alpha_high = + std::nanf(""); + write_mask &= 0b0011; + if (!(write_mask & 0b0001)) { + keep_mask_low = ~uint32_t(0); + } + if (!(write_mask & 0b0010)) { + keep_mask_high = ~uint32_t(0); } - // -Infinity. - color_min = alpha_min = 0xFF800000u; - // Infinity. - color_max = alpha_max = 0x7F800000u; break; default: - assert_always(); + assert_unhandled_case(format); + // Disable invalid render targets. + write_mask = 0; break; } - uint32_t rt_pair_index = rt_index >> 1; - uint32_t rt_pair_comp = (rt_index & 1) << 1; - constants.edram_load_mask_rt01_rt23[rt_pair_index][rt_pair_comp] = color_mask; - constants.edram_load_mask_rt01_rt23[rt_pair_index][rt_pair_comp + 1] = - alpha_mask; - constants.edram_load_scale_rt01_rt23[rt_pair_index][rt_pair_comp] = - color_load_scale; - constants.edram_load_scale_rt01_rt23[rt_pair_index][rt_pair_comp + 1] = - alpha_load_scale; - constants.edram_store_min_rt01_rt23[rt_pair_index][rt_pair_comp] = color_min; - constants.edram_store_min_rt01_rt23[rt_pair_index][rt_pair_comp + 1] = - alpha_min; - constants.edram_store_max_rt01_rt23[rt_pair_index][rt_pair_comp] = color_max; - constants.edram_store_max_rt01_rt23[rt_pair_index][rt_pair_comp + 1] = - alpha_max; - constants.edram_store_scale_rt01_rt23[rt_pair_index][rt_pair_comp] = - color_store_scale; - constants.edram_store_scale_rt01_rt23[rt_pair_index][rt_pair_comp + 1] = - alpha_store_scale; + // Special case handled in the shaders for empty write mask to completely skip + // a disabled render target: all keep bits are set. + if (!write_mask) { + keep_mask_low = keep_mask_high = ~uint32_t(0); + } } -bool DxbcShaderTranslator::GetBlendConstants(uint32_t blend_control, - uint32_t& blend_x_out, - uint32_t& blend_y_out) { - static const uint32_t kBlendXSrcFactorMap[32] = { - 0, - kBlendX_Src_One, - 0, - 0, - kBlendX_Src_SrcColor_Pos, - kBlendX_Src_One | kBlendX_Src_SrcColor_Neg, - kBlendX_Src_SrcAlpha_Pos, - kBlendX_Src_One | kBlendX_Src_SrcAlpha_Neg, - kBlendX_Src_DestColor_Pos, - kBlendX_Src_One | kBlendX_Src_DestColor_Neg, - kBlendX_Src_DestAlpha_Pos, - kBlendX_Src_One | kBlendX_Src_DestAlpha_Neg, - 0, - kBlendX_Src_One, - 0, - kBlendX_Src_One, - kBlendX_Src_SrcAlphaSaturate, - }; - static const uint32_t kBlendYSrcFactorMap[32] = { - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - kBlendY_Src_ConstantColor_Pos, - kBlendY_Src_ConstantColor_Neg, - kBlendY_Src_ConstantAlpha_Pos, - kBlendY_Src_ConstantAlpha_Neg, - 0, - }; - static const uint32_t kBlendXSrcAlphaFactorMap[32] = { - 0, - kBlendX_SrcAlpha_One, - 0, - 0, - kBlendX_SrcAlpha_SrcAlpha_Pos, - kBlendX_SrcAlpha_One | kBlendX_SrcAlpha_SrcAlpha_Neg, - kBlendX_SrcAlpha_SrcAlpha_Pos, - kBlendX_SrcAlpha_One | kBlendX_SrcAlpha_SrcAlpha_Neg, - kBlendX_SrcAlpha_DestAlpha_Pos, - kBlendX_SrcAlpha_One | kBlendX_SrcAlpha_DestAlpha_Neg, - kBlendX_SrcAlpha_DestAlpha_Pos, - kBlendX_SrcAlpha_One | kBlendX_SrcAlpha_DestAlpha_Neg, - 0, - kBlendX_SrcAlpha_One, - 0, - kBlendX_SrcAlpha_One, - kBlendX_SrcAlpha_One, - }; - static const uint32_t kBlendYSrcAlphaFactorMap[32] = { - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - kBlendY_SrcAlpha_ConstantAlpha_Pos, - kBlendY_SrcAlpha_ConstantAlpha_Neg, - kBlendY_SrcAlpha_ConstantAlpha_Pos, - kBlendY_SrcAlpha_ConstantAlpha_Neg, - 0, - }; - static const uint32_t kBlendXDestFactorMap[32] = { - 0, - kBlendX_Dest_One, - 0, - 0, - kBlendX_Dest_SrcColor_Pos, - kBlendX_Dest_One | kBlendX_Dest_SrcColor_Neg, - kBlendX_Dest_SrcAlpha_Pos, - kBlendX_Dest_One | kBlendX_Dest_SrcAlpha_Neg, - kBlendX_Dest_DestColor_Pos, - kBlendX_Dest_One | kBlendX_Dest_DestColor_Neg, - kBlendX_Dest_DestAlpha_Pos, - kBlendX_Dest_One | kBlendX_Dest_DestAlpha_Neg, - 0, - kBlendX_Dest_One, - 0, - kBlendX_Dest_One, - kBlendX_Dest_SrcAlphaSaturate, - }; - static const uint32_t kBlendYDestFactorMap[32] = { - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - kBlendY_Dest_ConstantColor_Pos, - kBlendY_Dest_ConstantColor_Neg, - kBlendY_Dest_ConstantAlpha_Pos, - kBlendY_Dest_ConstantAlpha_Neg, - 0, - }; - static const uint32_t kBlendXDestAlphaFactorMap[32] = { - 0, - kBlendX_DestAlpha_One, - 0, - 0, - kBlendX_DestAlpha_SrcAlpha_Pos, - kBlendX_DestAlpha_One | kBlendX_DestAlpha_SrcAlpha_Neg, - kBlendX_DestAlpha_SrcAlpha_Pos, - kBlendX_DestAlpha_One | kBlendX_DestAlpha_SrcAlpha_Neg, - kBlendX_DestAlpha_DestAlpha_Pos, - kBlendX_DestAlpha_One | kBlendX_DestAlpha_DestAlpha_Neg, - kBlendX_DestAlpha_DestAlpha_Pos, - kBlendX_DestAlpha_One | kBlendX_DestAlpha_DestAlpha_Neg, - 0, - kBlendX_DestAlpha_One, - 0, - kBlendX_DestAlpha_One, - kBlendX_DestAlpha_One, - }; - static const uint32_t kBlendYDestAlphaFactorMap[32] = { - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - kBlendY_DestAlpha_ConstantAlpha_Pos, - kBlendY_DestAlpha_ConstantAlpha_Neg, - kBlendY_DestAlpha_ConstantAlpha_Pos, - kBlendY_DestAlpha_ConstantAlpha_Neg, - 0, - }; +void DxbcShaderTranslator::StartPixelShader_LoadROVParameters() { + bool color_targets_written = writes_any_color_target(); - uint32_t blend_x = 0, blend_y = 0; + // *************************************************************************** + // Get EDRAM offsets for the pixel: + // system_temp_rov_params_.y - for depth (absolute). + // system_temp_rov_params_.z - for 32bpp color (base-relative). + // system_temp_rov_params_.w - for 64bpp color (base-relative). + // *************************************************************************** - // Min and max don't use the factors. + // Extract the resolution scale as log2(scale)/2 specific for 1 (-> 0) and + // 4 (-> 1) to a temp SGPR. + uint32_t resolution_scale_log2_temp = PushSystemTemp(); + system_constants_used_ |= 1ull << kSysConst_EDRAMResolutionSquareScale_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(resolution_scale_log2_temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMResolutionSquareScale_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMResolutionSquareScale_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(2); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; - BlendOp op_color = BlendOp((blend_control >> 5) & 0x7); - if (op_color == BlendOp::kMin) { - blend_y |= kBlendY_Color_OpMin; - } else if (op_color == BlendOp::kMax) { - blend_y |= kBlendY_Color_OpMax; - } else { - uint32_t src_factor = blend_control & 0x1F; - uint32_t dest_factor = (blend_control >> 8) & 0x1F; - blend_x |= - kBlendXSrcFactorMap[src_factor] | kBlendXDestFactorMap[dest_factor]; - blend_y |= - kBlendYSrcFactorMap[src_factor] | kBlendYDestFactorMap[dest_factor]; - switch (op_color) { - case BlendOp::kAdd: - blend_y |= kBlendY_Src_OpSign_Pos | kBlendY_Dest_OpSign_Pos; - break; - case BlendOp::kSubtract: - blend_y |= kBlendY_Src_OpSign_Pos | kBlendY_Dest_OpSign_Neg; - break; - case BlendOp::kRevSubtract: - blend_y |= kBlendY_Src_OpSign_Neg | kBlendY_Dest_OpSign_Pos; - break; - default: - assert_always(); - } + // Convert the pixel position (if resolution scale is 4, this will be 2x2 + // bigger) to integer to system_temp_rov_params_.zw. + // system_temp_rov_params_.z = X host pixel position as uint + // system_temp_rov_params_.w = Y host pixel position as uint + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_FTOU) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1100, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_INPUT, 0b01000000, 1)); + shader_code_.push_back(uint32_t(InOutRegister::kPSInPosition)); + ++stat_.instruction_count; + ++stat_.conversion_instruction_count; + + // Revert the resolution scale to convert the position to guest pixels. + // system_temp_rov_params_.z = X guest pixel position / sample width + // system_temp_rov_params_.w = Y guest pixel position / sample height + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1100, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(resolution_scale_log2_temp); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Convert the position from pixels to samples. + // system_temp_rov_params_.z = X guest sample 0 position + // system_temp_rov_params_.w = Y guest sample 0 position + system_constants_used_ |= 1ull << kSysConst_SampleCountLog2_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ISHL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1100, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + (kSysConst_SampleCountLog2_Comp << 4) | + ((kSysConst_SampleCountLog2_Comp + 1) << 6), + 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_SampleCountLog2_Vec); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Get 80x16 samples tile index - start dividing X by 80 by getting the high + // part of the result of multiplication of X by 0xCCCCCCCD into X. + // system_temp_rov_params_.x = (X * 0xCCCCCCCD) >> 32, or X / 80 * 64 + // system_temp_rov_params_.z = X guest sample 0 position + // system_temp_rov_params_.w = Y guest sample 0 position + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_UMUL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeZeroComponentOperand(D3D10_SB_OPERAND_TYPE_NULL, 0)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0xCCCCCCCDu); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Get 80x16 samples tile index - finish dividing X by 80 and divide Y by 16 + // into system_temp_rov_params_.xy. + // system_temp_rov_params_.x = X tile position + // system_temp_rov_params_.y = Y tile position + // system_temp_rov_params_.z = X guest sample 0 position + // system_temp_rov_params_.w = Y guest sample 0 position + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b00001100, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); + shader_code_.push_back(6); + shader_code_.push_back(4); + shader_code_.push_back(0); + shader_code_.push_back(0); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Get the tile index to system_temp_rov_params_.y. + // system_temp_rov_params_.x = X tile position + // system_temp_rov_params_.y = tile index + // system_temp_rov_params_.z = X guest sample 0 position + // system_temp_rov_params_.w = Y guest sample 0 position + system_constants_used_ |= 1ull << kSysConst_EDRAMPitchTiles_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_UMAD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMPitchTiles_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMPitchTiles_Vec); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temp_rov_params_); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Convert the tile index into a tile offset. + // system_temp_rov_params_.x = X tile position + // system_temp_rov_params_.y = tile offset + // system_temp_rov_params_.z = X guest sample 0 position + // system_temp_rov_params_.w = Y guest sample 0 position + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_UMUL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back( + EncodeZeroComponentOperand(D3D10_SB_OPERAND_TYPE_NULL, 0)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1280); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Get tile-local X sample index into system_temp_rov_params_.z. + // system_temp_rov_params_.y = tile offset + // system_temp_rov_params_.z = X sample 0 position within the tile + // system_temp_rov_params_.w = Y guest sample 0 position + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IMAD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0100, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(-80)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(system_temp_rov_params_); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Get tile-local Y sample index into system_temp_rov_params_.w. + // system_temp_rov_params_.y = tile offset + // system_temp_rov_params_.z = X sample 0 position within the tile + // system_temp_rov_params_.w = Y sample 0 position within the tile + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(15); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Go to the target row within the tile in system_temp_rov_params_.y. + // system_temp_rov_params_.y = row offset + // system_temp_rov_params_.z = X sample 0 position within the tile + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IMAD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(80); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temp_rov_params_); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Choose in which 40-sample half of the tile the pixel is, for swapping + // 40-sample columns when accessing the depth buffer - games expect this + // behavior when writing depth back to the EDRAM via color writing (GTA IV, + // Halo 3). + // system_temp_rov_params_.x = tile-local sample 0 X >= 40 + // system_temp_rov_params_.y = row offset + // system_temp_rov_params_.z = X sample 0 position within the tile + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_UGE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(40); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Choose what to add to the depth/stencil X position. + // system_temp_rov_params_.x = 40 or -40 offset for the depth buffer + // system_temp_rov_params_.y = row offset + // system_temp_rov_params_.z = X sample 0 position within the tile + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(-40)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(40); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + + // Flip tile halves for the depth/stencil buffer. + // system_temp_rov_params_.x = X sample 0 position within the depth tile + // system_temp_rov_params_.y = row offset + // system_temp_rov_params_.z = X sample 0 position within the tile + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temp_rov_params_); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + if (color_targets_written) { + // Write 32bpp color offset to system_temp_rov_params_.z. + // system_temp_rov_params_.x = X sample 0 position within the depth tile + // system_temp_rov_params_.y = row offset + // system_temp_rov_params_.z = unscaled 32bpp color offset + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0100, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(system_temp_rov_params_); + ++stat_.instruction_count; + ++stat_.int_instruction_count; } - BlendOp op_alpha = BlendOp((blend_control >> 21) & 0x7); - if (op_alpha == BlendOp::kMin) { - blend_y |= kBlendY_Alpha_OpMin; - } else if (op_alpha == BlendOp::kMax) { - blend_y |= kBlendY_Alpha_OpMax; + // Write depth/stencil offset to system_temp_rov_params_.y. + // system_temp_rov_params_.y = unscaled 32bpp depth/stencil offset + // system_temp_rov_params_.z = unscaled 32bpp color offset if needed + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temp_rov_params_); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Add the EDRAM base for depth/stencil. + // system_temp_rov_params_.y = unscaled 32bpp depth/stencil address + // system_temp_rov_params_.z = unscaled 32bpp color offset if needed + system_constants_used_ |= 1ull << kSysConst_EDRAMDepthBaseDwords_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMDepthBaseDwords_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMDepthBaseDwords_Vec); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Apply the resolution scale. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(resolution_scale_log2_temp); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Release resolution_scale_log2_temp. + PopSystemTemp(); + + uint32_t offsets_masked, offsets_select; + uint32_t offsets_immediate, offsets_components; + if (color_targets_written) { + offsets_masked = + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0110, 1); + offsets_select = EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, + kSwizzleXYZW, 1); + offsets_immediate = EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0); + offsets_components = 4; } else { - uint32_t src_alpha_factor = (blend_control >> 16) & 0x1F; - uint32_t dest_alpha_factor = (blend_control >> 24) & 0x1F; - blend_x |= kBlendXSrcAlphaFactorMap[src_alpha_factor] | - kBlendXDestAlphaFactorMap[dest_alpha_factor]; - blend_y |= kBlendYSrcAlphaFactorMap[src_alpha_factor] | - kBlendYDestAlphaFactorMap[dest_alpha_factor]; - switch (op_alpha) { - case BlendOp::kAdd: - blend_y |= kBlendY_SrcAlpha_OpSign_Pos | kBlendY_DestAlpha_OpSign_Pos; - break; - case BlendOp::kSubtract: - blend_y |= kBlendY_SrcAlpha_OpSign_Pos | kBlendY_DestAlpha_OpSign_Neg; - break; - case BlendOp::kRevSubtract: - blend_y |= kBlendY_SrcAlpha_OpSign_Neg | kBlendY_DestAlpha_OpSign_Pos; - break; - default: - assert_always(); - } + offsets_masked = + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1); + offsets_select = + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1); + offsets_immediate = + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0); + offsets_components = 1; } - blend_x_out = blend_x; - blend_y_out = blend_y; + // Scale the offsets by the resolution scale. + // system_temp_rov_params_.y = scaled 32bpp depth/stencil first host pixel + // address + // system_temp_rov_params_.z = scaled 32bpp color first host pixel offset if + // needed + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ISHL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(6 + offsets_components)); + shader_code_.push_back(offsets_masked); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back(offsets_select); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back(offsets_immediate); + for (uint32_t i = 0; i < offsets_components; ++i) { + shader_code_.push_back(2); + } + ++stat_.instruction_count; + ++stat_.int_instruction_count; - // 1 * src + 0 * dest is nop, don't waste GPU time. - return (blend_control & 0x1FFF1FFF) != 0x00010001; + // Add host pixel offsets. + // system_temp_rov_params_.y = scaled 32bpp depth/stencil address + // system_temp_rov_params_.z = scaled 32bpp color offset if needed + for (uint32_t i = 0; i < 2; ++i) { + // Convert a position component to integer. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_FTOU) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_INPUT, i, 1)); + shader_code_.push_back(uint32_t(InOutRegister::kPSInPosition)); + ++stat_.instruction_count; + ++stat_.conversion_instruction_count; + + // Insert the host pixel offset on each axis. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_BFI) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH( + 9 + offsets_components * 2)); + shader_code_.push_back(offsets_masked); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back(offsets_immediate); + for (uint32_t j = 0; j < offsets_components; ++j) { + shader_code_.push_back(1); + } + shader_code_.push_back(offsets_immediate); + for (uint32_t j = 0; j < offsets_components; ++j) { + shader_code_.push_back(i); + } + if (color_targets_written) { + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + } else { + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + } + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back(offsets_select); + shader_code_.push_back(system_temp_rov_params_); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + } + + // Close the resolution scale conditional. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + if (color_targets_written) { + // Get the 64bpp color offset to system_temp_rov_params_.w. + // TODO(Triang3l): Find some game that aliases 64bpp with 32bpp to emulate + // the real layout. + // system_temp_rov_params_.y = scaled 32bpp depth/stencil address + // system_temp_rov_params_.z = scaled 32bpp color offset + // system_temp_rov_params_.w = scaled 64bpp color offset + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ISHL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + } + + // *************************************************************************** + // Sample coverage to system_temp_rov_params_.x. + // *************************************************************************** + + // Using ForcedSampleCount of 4 (2 is not supported on Nvidia), so for 2x + // MSAA, handling samples 0 and 3 (upper-left and lower-right) as 0 and 1. + + // Check if 4x MSAA is enabled. + system_constants_used_ |= 1ull << kSysConst_SampleCountLog2_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_SampleCountLog2_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_SampleCountLog2_Vec); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Copy the 4x AA coverage to system_temp_rov_params_.x. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(6)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D11_SB_OPERAND_TYPE_INPUT_COVERAGE_MASK, 0, 0)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back((1 << 4) - 1); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Handle 1 or 2 samples. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Extract sample 3 coverage, which will be used as sample 1. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_UBFE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(3); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D11_SB_OPERAND_TYPE_INPUT_COVERAGE_MASK, 0, 0)); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Combine coverage of samples 0 (in bit 0 of vCoverage) and 3 (in bit 0 of + // system_temp_rov_params_.x). + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_BFI) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(31); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D11_SB_OPERAND_TYPE_INPUT_COVERAGE_MASK, 0, 0)); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Close the 4x MSAA conditional. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; } -void DxbcShaderTranslator::CompletePixelShader_DepthTo24Bit( - uint32_t depths_temp) { - // Allocate temporary registers for conversion. - uint32_t temp1 = PushSystemTemp(), temp2 = PushSystemTemp(); +void DxbcShaderTranslator::ROV_DepthStencilTest() { + uint32_t temp1 = PushSystemTemp(); - // Unpack the depth format. + // Check whether depth/stencil is enabled. 1 SGPR taken. + // temp1.x = kSysFlag_ROVDepthStencil system_constants_used_ |= 1ull << kSysConst_Flags_Index; shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); @@ -421,11 +721,12 @@ void DxbcShaderTranslator::CompletePixelShader_DepthTo24Bit( shader_code_.push_back(kSysConst_Flags_Vec); shader_code_.push_back( EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); - shader_code_.push_back(kSysFlag_DepthFloat24); + shader_code_.push_back(kSysFlag_ROVDepthStencil); ++stat_.instruction_count; ++stat_.uint_instruction_count; - // Convert according to the format. + // Open the depth/stencil enabled conditional. 1 SGPR released. + // temp1.x = free shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( D3D10_SB_INSTRUCTION_TEST_NONZERO) | @@ -436,490 +737,2834 @@ void DxbcShaderTranslator::CompletePixelShader_DepthTo24Bit( ++stat_.instruction_count; ++stat_.dynamic_flow_control_count; + if (writes_depth()) { + // Convert the shader-generated depth to 24-bit - move the 32-bit depth to + // the conversion subroutine's argument. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temp_rov_depth_stencil_); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + + // Convert the shader-generated depth to 24-bit. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CALL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back(EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_LABEL, 1)); + shader_code_.push_back(label_rov_depth_to_24bit_); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + // Store a copy of the depth in temp1.x to reload later. + // temp1.x = 24-bit oDepth + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + } else { + // Load the first sample's Z and W to system_temps_subroutine_[0] - need + // this regardless of coverage for polygon offset. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_EVAL_SAMPLE_INDEX) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_INPUT, kSwizzleXYZW, 1)); + shader_code_.push_back(uint32_t(InOutRegister::kPSInClipSpaceZW)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0); + ++stat_.instruction_count; + + // Calculate the first sample's Z/W to system_temps_subroutine_[0].x for + // conversion to 24-bit and depth test. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_DIV) | + ENCODE_D3D10_SB_INSTRUCTION_SATURATE(1) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Apply viewport Z range to the first sample because this would affect the + // slope-scaled depth bias (tested on PC on Direct3D 12, by comparing the + // fraction of the polygon's area with depth clamped - affected by the + // constant bias, but not affected by the slope-scaled bias, also depth + // range clamping should be done after applying the offset as well). + system_constants_used_ |= 1ull << kSysConst_EDRAMDepthRange_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | + ENCODE_D3D10_SB_INSTRUCTION_SATURATE(1) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(13)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMDepthRangeScale_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMDepthRange_Vec); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMDepthRangeOffset_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMDepthRange_Vec); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Get the derivatives of a sample's depth, for the slope-scaled polygon + // offset. Probably not very significant that it's for the sample 0 rather + // than for the center, likely neither is accurate because Xenos probably + // calculates the slope between 16ths of a pixel according to the meaning of + // the slope-scaled polygon offset in R5xx Acceleration. Take 2 VGPRs. + // temp1.x = ddx(z) + // temp1.y = ddy(z) + for (uint32_t i = 0; i < 2; ++i) { + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(i ? D3D11_SB_OPCODE_DERIV_RTY_COARSE + : D3D11_SB_OPCODE_DERIV_RTX_COARSE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D10_SB_OPERAND_TYPE_TEMP, 0b0001 << i, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + } + + // Get the maximum depth slope for polygon offset to temp1.y. + // Release 1 VGPR (Y derivative). + // temp1.x = max(|ddx(z)|, |ddy(z)|) + // temp1.y = free + // https://docs.microsoft.com/en-us/windows/desktop/direct3d9/depth-bias + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAX) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1) | + ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); + shader_code_.push_back(ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER( + D3D10_SB_OPERAND_MODIFIER_ABS)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1) | + ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); + shader_code_.push_back(ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER( + D3D10_SB_OPERAND_MODIFIER_ABS)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Copy the needed polygon offset values to temp1.yz. Take 2 VGPRs. + // temp1.x = max(|ddx(z)|, |ddy(z)|) + // temp1.y = polygon offset scale + // temp1.z = polygon offset bias + system_constants_used_ |= (1ull << kSysConst_EDRAMPolyOffsetFront_Index) | + (1ull << kSysConst_EDRAMPolyOffsetBack_Index); + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(13)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0110, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_INPUT, 0, 1)); + shader_code_.push_back(uint32_t(InOutRegister::kPSInFrontFace)); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + (kSysConst_EDRAMPolyOffsetFrontScale_Comp << 2) | + (kSysConst_EDRAMPolyOffsetFrontOffset_Comp << 4), + 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMPolyOffsetFront_Vec); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + (kSysConst_EDRAMPolyOffsetBackScale_Comp << 2) | + (kSysConst_EDRAMPolyOffsetBackOffset_Comp << 4), + 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMPolyOffsetBack_Vec); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + + // Apply the slope scale and the constant bias to the offset, and release 2 + // VGPRs. + // temp1.x = polygon offset + // temp1.y = free + // temp1.z = free + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Calculate the upper Z range bound to temp1.y for clamping after biasing, + // taking 1 SGPR. + // temp1.x = polygon offset + // temp1.y = viewport maximum depth + system_constants_used_ |= 1ull << kSysConst_EDRAMDepthRange_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMDepthRangeOffset_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMDepthRange_Vec); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMDepthRangeScale_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMDepthRange_Vec); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + } + + for (uint32_t i = 0; i < 4; ++i) { + // Get if the current sample is covered to temp1.y. Take 1 VGPR. + // temp1.x = polygon offset or 24-bit oDepth + // temp1.y = viewport maximum depth if not writing to oDepth + // temp1.z = coverage of the current sample + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0100, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1 << i); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Check if the current sample is covered. Release 1 VGPR. + // temp1.x = polygon offset or 24-bit oDepth + // temp1.y = viewport maximum depth if not writing to oDepth + // temp1.z = free + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + if (writes_depth()) { + // Same depth for all samples, already converted to 24-bit - only move it + // to the depth/stencil sample subroutine argument from temp1.x if it's + // not already there (it's there for the first sample - returned from the + // conversion to 24-bit). + if (i) { + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + } + } else { + if (i) { + // Sample's depth precalculated for sample 0 (for slope-scaled depth + // bias calculation), but need to calculate it for other samples. + + // Using system_temps_subroutine_[0].xy as temps for Z/W since Y will + // contain the result anyway after the call, and temp1.x contains the + // polygon offset. + + if (i == 1) { + // Using ForcedSampleCount of 4 (2 is not supported on Nvidia), so for + // 2x MSAA, handling samples 0 and 3 (upper-left and lower-right) as 0 + // and 1. Thus, evaluate Z/W at sample 3 when 4x is not enabled. + system_constants_used_ |= 1ull << kSysConst_SampleCountLog2_Index; + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_SampleCountLog2_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_SampleCountLog2_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(3); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_EVAL_SAMPLE_INDEX) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_INPUT, kSwizzleXYZW, 1)); + shader_code_.push_back(uint32_t(InOutRegister::kPSInClipSpaceZW)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + } else { + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_EVAL_SAMPLE_INDEX) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_INPUT, kSwizzleXYZW, 1)); + shader_code_.push_back(uint32_t(InOutRegister::kPSInClipSpaceZW)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1 << i); + ++stat_.instruction_count; + } + + // Calculate Z/W for the current sample from the evaluated Z and W. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_DIV) | + ENCODE_D3D10_SB_INSTRUCTION_SATURATE(1) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Apply viewport Z range the same way as it was applied to sample 0. + system_constants_used_ |= 1ull << kSysConst_EDRAMDepthRange_Index; + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | + ENCODE_D3D10_SB_INSTRUCTION_SATURATE(1) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(13)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMDepthRangeScale_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMDepthRange_Vec); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMDepthRangeOffset_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMDepthRange_Vec); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + } + + // Add the bias to the depth of the sample. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Clamp the biased depth to the lower viewport depth bound. + system_constants_used_ |= 1ull << kSysConst_EDRAMDepthRange_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAX) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMDepthRangeOffset_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMDepthRange_Vec); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Clamp the biased depth to the upper viewport depth bound. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MIN) | + ENCODE_D3D10_SB_INSTRUCTION_SATURATE(1) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Convert the depth to 24-bit - takes system_temps_subroutine_[0].x, + // returns also in system_temps_subroutine_[0].x. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CALL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_LABEL, 1)); + shader_code_.push_back(label_rov_depth_to_24bit_); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + } + + // Perform depth/stencil test for the sample, get the result in bits 4 + // (passed) and 8 (new depth/stencil buffer value is different). + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CALL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back(EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_LABEL, 1)); + shader_code_.push_back(label_rov_depth_stencil_sample_); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + // Write the resulting depth/stencil value in system_temps_subroutine_[0].x + // to the sample's depth in system_temp_rov_depth_stencil_. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1 << i, 1)); + shader_code_.push_back(system_temp_rov_depth_stencil_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + + if (i) { + // Shift the result bits to the correct position. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ISHL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(i); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + } + + // Add the result in system_temps_subroutine_[0].y to + // system_temp_rov_params_.x. Bits 0:3 will be cleared in case of test + // failure (only doing this for covered samples), bits 4:7 will be added if + // need to defer writing. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_XOR) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Close the sample conditional. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Go to the next sample (samples are at +0, +80, +1, +81, so need to do + // +80, -79, +80 and -81 after each sample). + system_constants_used_ |= 1ull + << kSysConst_EDRAMResolutionSquareScale_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IMAD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back((i & 1) ? -78 - i : 80); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMResolutionSquareScale_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMResolutionSquareScale_Vec); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temp_rov_params_); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + } + + if (ROV_IsDepthStencilEarly()) { + // Check if safe to discard the whole 2x2 quad early, without running the + // translated pixel shader, by checking if coverage is 0 in all pixels in + // the quad and if there are no samples which failed the depth test, but + // where stencil was modified and needs to be written in the end. Must + // reject at 2x2 quad granularity because texture fetches need derivatives. + + // temp1.x = coverage | deferred depth/stencil write + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0b11111111); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // temp1.x = 1.0 if any sample is covered or potentially needs stencil write + // in the end of the shader in the current pixel + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0x3F800000); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + + for (uint32_t i = 0; i < 2; ++i) { + // temp1.x = 1.0 if anything is covered in the current pixel (i = 0) / + // the current half of the quad (i = 1) + // temp1.y = non-zero if anything is covered in the pixel across X + // (i = 0) / the two pixels across Y (i = 1) + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(i ? D3D11_SB_OPCODE_DERIV_RTY_COARSE + : D3D11_SB_OPCODE_DERIV_RTX_FINE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // temp1.x = 1.0 if anything is covered in the current half of the quad + // (i = 0) / the whole quad (i = 1) + // temp1.y = free + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0x3F800000); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + } + + // End the shader if nothing is covered in the 2x2 quad after early + // depth/stencil. + // temp1.x = free + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_RETC) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_ZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + } + + // Close the large depth/stencil conditional. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Release temp1. + PopSystemTemp(); +} + +void DxbcShaderTranslator::ROV_UnpackColor( + uint32_t rt_index, uint32_t packed_temp, uint32_t packed_temp_components, + uint32_t color_temp, uint32_t temp1, uint32_t temp1_component, + uint32_t temp2, uint32_t temp2_component) { + assert_true(color_temp != packed_temp || packed_temp_components == 0); + + uint32_t temp1_mask = 1 << temp1_component; + uint32_t temp2_mask = 1 << temp2_component; + + // Break register dependencies and initialize if there are not enough + // components. The rest of the function will write at least RG (k_32_FLOAT and + // k_32_32_FLOAT handled with the same default label), and if packed_temp is + // the same as color_temp, the packed color won't be touched. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1100, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); + shader_code_.push_back(0); + shader_code_.push_back(0); + shader_code_.push_back(0); + shader_code_.push_back(0x3F800000); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + + // Choose the packing based on the render target's format. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTFormatFlags_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_SWITCH) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTFormatFlags_Vec); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + // *************************************************************************** - // 20e4 conversion begins here. - // CFloat24 from d3dref9.dll. + // k_8_8_8_8 + // k_8_8_8_8_GAMMA // *************************************************************************** + for (uint32_t i = 0; i < 2; ++i) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back( + ROV_AddColorFormatFlags(i ? ColorRenderTargetFormat::k_8_8_8_8_GAMMA + : ColorRenderTargetFormat::k_8_8_8_8)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; - // Assuming the depth is already clamped to [0, 2) (in all places, the depth - // is written with the saturate flag set). + // Unpack the components. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_UBFE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(15)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); + shader_code_.push_back(8); + shader_code_.push_back(8); + shader_code_.push_back(8); + shader_code_.push_back(8); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); + shader_code_.push_back(0); + shader_code_.push_back(8); + shader_code_.push_back(16); + shader_code_.push_back(24); + shader_code_.push_back(EncodeVectorReplicatedOperand( + D3D10_SB_OPERAND_TYPE_TEMP, packed_temp_components, 1)); + shader_code_.push_back(packed_temp); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; - // Calculate the denormalized value if the number is too small to be - // represented as normalized 20e4 into Y. + // Convert from fixed-point. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_UTOF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(color_temp); + ++stat_.instruction_count; + ++stat_.conversion_instruction_count; - // t1 = f32 & 0x7FFFFF - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); + // Normalize. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); + // 1.0 / 255.0 + shader_code_.push_back(0x3B808081); + shader_code_.push_back(0x3B808081); + shader_code_.push_back(0x3B808081); + shader_code_.push_back(0x3B808081); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + if (i) { + for (uint32_t j = 0; j < 3; ++j) { + ConvertPWLGamma(false, color_temp, j, color_temp, j, temp1, + temp1_component, temp2, temp2_component); + } + } + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + } + + // *************************************************************************** + // k_2_10_10_10 + // k_2_10_10_10_AS_10_10_10_10 + // *************************************************************************** + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back( + ROV_AddColorFormatFlags(ColorRenderTargetFormat::k_2_10_10_10)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(ROV_AddColorFormatFlags( + ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + // Unpack the components. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_UBFE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(15)); shader_code_.push_back( EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(temp1); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depths_temp); + shader_code_.push_back(color_temp); shader_code_.push_back(EncodeVectorSwizzledOperand( D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0x7FFFFF); - shader_code_.push_back(0x7FFFFF); - shader_code_.push_back(0x7FFFFF); - shader_code_.push_back(0x7FFFFF); + shader_code_.push_back(10); + shader_code_.push_back(10); + shader_code_.push_back(10); + shader_code_.push_back(2); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); + shader_code_.push_back(0); + shader_code_.push_back(10); + shader_code_.push_back(20); + shader_code_.push_back(30); + shader_code_.push_back(EncodeVectorReplicatedOperand( + D3D10_SB_OPERAND_TYPE_TEMP, packed_temp_components, 1)); + shader_code_.push_back(packed_temp); ++stat_.instruction_count; ++stat_.uint_instruction_count; - // t1 = (f32 & 0x7FFFFF) | 0x800000 - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_OR) | + // Convert from fixed-point. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_UTOF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(color_temp); + ++stat_.instruction_count; + ++stat_.conversion_instruction_count; + + // Normalize. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); shader_code_.push_back( EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(temp1); + shader_code_.push_back(color_temp); shader_code_.push_back( EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(temp1); + shader_code_.push_back(color_temp); shader_code_.push_back(EncodeVectorSwizzledOperand( D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0x800000); - shader_code_.push_back(0x800000); - shader_code_.push_back(0x800000); - shader_code_.push_back(0x800000); + // 1.0 / 1023.0 + shader_code_.push_back(0x3A802008); + shader_code_.push_back(0x3A802008); + shader_code_.push_back(0x3A802008); + // 1.0 / 3.0 + shader_code_.push_back(0x3EAAAAAB); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // *************************************************************************** + // k_2_10_10_10_FLOAT + // k_2_10_10_10_FLOAT_AS_16_16_16_16 + // https://github.com/Microsoft/DirectXTex/blob/master/DirectXTex/DirectXTexConvert.cpp + // *************************************************************************** + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back( + ROV_AddColorFormatFlags(ColorRenderTargetFormat::k_2_10_10_10_FLOAT)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(ROV_AddColorFormatFlags( + ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + // Unpack the alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_UBFE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(2); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(30); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + packed_temp_components, 1)); + shader_code_.push_back(packed_temp); ++stat_.instruction_count; ++stat_.uint_instruction_count; - // t2 = f32 >> 23 - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); + // Convert the alpha from fixed-point. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_UTOF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(temp2); + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(color_temp); shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depths_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(23); - shader_code_.push_back(23); - shader_code_.push_back(23); - shader_code_.push_back(23); + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(color_temp); + ++stat_.instruction_count; + ++stat_.conversion_instruction_count; + + // Normalize the alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + // 1.0 / 3.0 + shader_code_.push_back(0x3EAAAAAB); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Process the components in reverse order because color_temp.r stores the + // packed color which shouldn't be touched until G and B are converted if + // packed_temp and color_temp are the same. + for (int32_t i = 2; i >= 0; --i) { + // Unpack the exponent to the temp. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_UBFE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(3); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(i * 10 + 7); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_TEMP, packed_temp_components, 1)); + shader_code_.push_back(packed_temp); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Unpack the mantissa to the result. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_UBFE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1 << i, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(7); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(i * 10); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_TEMP, packed_temp_components, 1)); + shader_code_.push_back(packed_temp); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Check if the number is denormalized. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_ZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + temp1_component, 1)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Check if the number is non-zero (if the mantissa isn't zero - the + // exponent is known to be zero at this point). + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); + shader_code_.push_back(color_temp); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Normalize the mantissa. + // Note that HLSL firstbithigh(x) is compiled to DXBC like: + // `x ? 31 - firstbit_hi(x) : -1` + // (it returns the index from the LSB, not the MSB, but -1 for zero too). + // temp = firstbit_hi(mantissa) + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_FIRSTBIT_HI) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); + shader_code_.push_back(color_temp); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // temp = 7 - (31 - firstbit_hi(mantissa)) + // Or, if expanded: + // temp = firstbit_hi(mantissa) - 24 + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + temp1_component, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(-24)); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // mantissa = mantissa << (7 - firstbithigh(mantissa)) + // AND 0x7F not needed after this - BFI will do it. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ISHL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1 << i, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + temp1_component, 1)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Get the normalized exponent. + // exponent = 1 - (7 - firstbithigh(mantissa)) + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + temp1_component, 1) | + ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); + shader_code_.push_back(ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER( + D3D10_SB_OPERAND_MODIFIER_NEG)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // The number is zero. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Set the unbiased exponent to -124 for zero - 124 will be added later, + // resulting in zero float32. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(-124)); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + + // Close the non-zero check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Close the denormal check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Bias the exponent and move it to the correct location in f32. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IMAD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + temp1_component, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1 << 23); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(124 << 23); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Combine the mantissa and the exponent. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_BFI) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1 << i, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(7); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(16); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + temp1_component, 1)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + } + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // *************************************************************************** + // k_16_16 + // k_16_16_16_16 (64bpp) + // *************************************************************************** + for (uint32_t i = 0; i < 2; ++i) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back( + ROV_AddColorFormatFlags(i ? ColorRenderTargetFormat::k_16_16_16_16 + : ColorRenderTargetFormat::k_16_16)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + uint32_t color_mask = i ? 0b1111 : 0b0011; + + // Unpack the components. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_IBFE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(15)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, color_mask, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); + shader_code_.push_back(16); + shader_code_.push_back(16); + shader_code_.push_back(16); + shader_code_.push_back(16); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); + shader_code_.push_back(0); + shader_code_.push_back(16); + shader_code_.push_back(0); + shader_code_.push_back(16); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, + 0b01010000 + packed_temp_components * 0b01010101, 1)); + shader_code_.push_back(packed_temp); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Convert from fixed-point. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ITOF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, color_mask, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(color_temp); + ++stat_.instruction_count; + ++stat_.conversion_instruction_count; + + // Normalize. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, color_mask, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); + // 32.0 / 32767.0 + shader_code_.push_back(0x3A800100); + shader_code_.push_back(0x3A800100); + shader_code_.push_back(0x3A800100); + shader_code_.push_back(0x3A800100); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + } + + // *************************************************************************** + // k_16_16_FLOAT + // k_16_16_16_16_FLOAT (64bpp) + // *************************************************************************** + for (uint32_t i = 0; i < 2; ++i) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back( + ROV_AddColorFormatFlags(i ? ColorRenderTargetFormat::k_16_16_16_16_FLOAT + : ColorRenderTargetFormat::k_16_16_FLOAT)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + uint32_t color_mask = i ? 0b1111 : 0b0011; + + // Unpack the components. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_UBFE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(15)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, color_mask, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); + shader_code_.push_back(16); + shader_code_.push_back(16); + shader_code_.push_back(16); + shader_code_.push_back(16); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); + shader_code_.push_back(0); + shader_code_.push_back(16); + shader_code_.push_back(0); + shader_code_.push_back(16); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, + 0b01010000 + packed_temp_components * 0b01010101, 1)); + shader_code_.push_back(packed_temp); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Convert from 16-bit float. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_F16TOF32) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, color_mask, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(color_temp); + ++stat_.instruction_count; + ++stat_.conversion_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + } + + if (packed_temp != color_temp) { + // Assume k_32_FLOAT or k_32_32_FLOAT for the rest. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_DEFAULT) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, 0b0100 + packed_temp_components * 0b0101, + 1)); + shader_code_.push_back(packed_temp); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + } + + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDSWITCH) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; +} + +void DxbcShaderTranslator::ROV_PackPreClampedColor( + uint32_t rt_index, uint32_t color_temp, uint32_t packed_temp, + uint32_t packed_temp_components, uint32_t temp1, uint32_t temp1_component, + uint32_t temp2, uint32_t temp2_component) { + assert_true(color_temp != packed_temp || packed_temp_components == 0); + + uint32_t temp1_mask = 1 << temp1_component; + uint32_t temp2_mask = 1 << temp2_component; + + // Choose the packing based on the render target's format. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTFormatFlags_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_SWITCH) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTFormatFlags_Vec); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // *************************************************************************** + // k_8_8_8_8 + // k_8_8_8_8_GAMMA + // *************************************************************************** + for (uint32_t i = 0; i < 2; ++i) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back( + ROV_AddColorFormatFlags(i ? ColorRenderTargetFormat::k_8_8_8_8_GAMMA + : ColorRenderTargetFormat::k_8_8_8_8)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + for (uint32_t j = 0; j < 4; ++j) { + if (i && j < 3) { + ConvertPWLGamma(true, color_temp, j, temp1, temp1_component, temp1, + temp1_component, temp2, temp2_component); + + // Denormalize. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_TEMP, temp1_component, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + // 255.0 + shader_code_.push_back(0x437F0000); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + } else { + // Denormalize. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, j, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + // 255.0 + shader_code_.push_back(0x437F0000); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + } + + // Round towards the nearest even integer. Rounding towards the nearest + // (adding +-0.5 before truncating) is giving incorrect results for depth, + // so better to use round_ne here too. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ROUND_NE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_TEMP, temp1_component, 1)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Convert to fixed-point. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_FTOU) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + if (j) { + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + } else { + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D10_SB_OPERAND_TYPE_TEMP, 1 << packed_temp_components, 1)); + shader_code_.push_back(packed_temp); + } + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_TEMP, temp1_component, 1)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.conversion_instruction_count; + + // Pack the upper components. + if (j) { + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_BFI) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D10_SB_OPERAND_TYPE_TEMP, 1 << packed_temp_components, 1)); + shader_code_.push_back(packed_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(8); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(j * 8); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_TEMP, temp1_component, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_TEMP, packed_temp_components, 1)); + shader_code_.push_back(packed_temp); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + } + } + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + } + + // *************************************************************************** + // k_2_10_10_10 + // k_2_10_10_10_AS_10_10_10_10 + // *************************************************************************** + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back( + ROV_AddColorFormatFlags(ColorRenderTargetFormat::k_2_10_10_10)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(ROV_AddColorFormatFlags( + ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + for (uint32_t i = 0; i < 4; ++i) { + // Denormalize. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + // 1023.0 or 3.0 + shader_code_.push_back(i < 3 ? 0x447FC000 : 0x40400000); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Round towards the nearest even integer. Rounding towards the nearest + // (adding +-0.5 before truncating) is giving incorrect results for depth, + // so better to use round_ne here too. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ROUND_NE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + temp1_component, 1)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Convert to fixed-point. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_FTOU) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + if (i) { + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + } else { + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D10_SB_OPERAND_TYPE_TEMP, 1 << packed_temp_components, 1)); + shader_code_.push_back(packed_temp); + } + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + temp1_component, 1)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.conversion_instruction_count; + + // Pack the upper components. + if (i) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_BFI) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D10_SB_OPERAND_TYPE_TEMP, 1 << packed_temp_components, 1)); + shader_code_.push_back(packed_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(i < 3 ? 10 : 2); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(i * 10); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_TEMP, temp1_component, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_TEMP, packed_temp_components, 1)); + shader_code_.push_back(packed_temp); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + } + } + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // *************************************************************************** + // k_2_10_10_10_FLOAT + // k_2_10_10_10_FLOAT_AS_16_16_16_16 + // https://github.com/Microsoft/DirectXTex/blob/master/DirectXTex/DirectXTexConvert.cpp + // *************************************************************************** + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back( + ROV_AddColorFormatFlags(ColorRenderTargetFormat::k_2_10_10_10_FLOAT)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(ROV_AddColorFormatFlags( + ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + for (uint32_t i = 0; i < 3; ++i) { + // Check if the number is too small to be represented as normalized 7e3. + // temp2 = f32 < 0x3E800000 + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ULT) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp2_mask, 1)); + shader_code_.push_back(temp2); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0x3E800000); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Handle denormalized numbers separately. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + temp2_component, 1)); + shader_code_.push_back(temp2); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // temp2 = f32 >> 23 + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp2_mask, 1)); + shader_code_.push_back(temp2); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(23); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // temp2 = 125 - (f32 >> 23) + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp2_mask, 1)); + shader_code_.push_back(temp2); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(125); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + temp2_component, 1) | + ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); + shader_code_.push_back(ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER( + D3D10_SB_OPERAND_MODIFIER_NEG)); + shader_code_.push_back(temp2); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Don't allow the shift to overflow, since in DXBC the lower 5 bits of the + // shift amount are used. + // temp2 = min(125 - (f32 >> 23), 24) + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_UMIN) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp2_mask, 1)); + shader_code_.push_back(temp2); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + temp2_component, 1)); + shader_code_.push_back(temp2); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(24); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // biased_f32 = (f32 & 0x7FFFFF) | 0x800000 + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_BFI) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(9); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(23); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); + shader_code_.push_back(color_temp); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // biased_f32 = ((f32 & 0x7FFFFF) | 0x800000) >> min(125 - (f32 >> 23), 24) + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + temp1_component, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + temp2_component, 1)); + shader_code_.push_back(temp2); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Not denormalized? + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Bias the exponent. + // biased_f32 = f32 + 0xC2000000 + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0xC2000000u); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Close the denormal check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Build the 7e3 number. + // temp2 = (biased_f32 >> 16) & 1 + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_UBFE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp2_mask, 1)); + shader_code_.push_back(temp2); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(16); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + temp1_component, 1)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // f10 = biased_f32 + 0x7FFF + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + temp1_component, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0x7FFF); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // f10 = biased_f32 + 0x7FFF + ((biased_f32 >> 16) & 1) + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + temp1_component, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + temp2_component, 1)); + shader_code_.push_back(temp2); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // f10 = ((biased_f32 + 0x7FFF + ((biased_f32 >> 16) & 1)) >> 16) & 0x3FF + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_UBFE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + if (i) { + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + } else { + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D10_SB_OPERAND_TYPE_TEMP, 1 << packed_temp_components, 1)); + shader_code_.push_back(packed_temp); + } + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(10); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(16); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + temp1_component, 1)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Pack the upper components. + if (i) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_BFI) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D10_SB_OPERAND_TYPE_TEMP, 1 << packed_temp_components, 1)); + shader_code_.push_back(packed_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(10); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(i * 10); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_TEMP, temp1_component, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_TEMP, packed_temp_components, 1)); + shader_code_.push_back(packed_temp); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + } + } + + // Denormalize the alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + // 3.0 + shader_code_.push_back(0x40400000); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Round the alpha towards the nearest even integer. Rounding towards the + // nearest (adding +-0.5 before truncating) is giving incorrect results for + // depth, so better to use round_ne here too. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ROUND_NE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + temp1_component, 1)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Convert the alpha to fixed-point. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_FTOU) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + temp1_component, 1)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.conversion_instruction_count; + + // Pack the alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_BFI) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D10_SB_OPERAND_TYPE_TEMP, 1 << packed_temp_components, 1)); + shader_code_.push_back(packed_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(2); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(30); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + temp1_component, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back(EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, + packed_temp_components, 1)); + shader_code_.push_back(packed_temp); ++stat_.instruction_count; ++stat_.uint_instruction_count; - // t2 = 113 - (f32 >> 23) - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // *************************************************************************** + // k_16_16 + // k_16_16_16_16 (64bpp) + // *************************************************************************** + for (uint32_t i = 0; i < 2; ++i) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back( + ROV_AddColorFormatFlags(i ? ColorRenderTargetFormat::k_16_16_16_16 + : ColorRenderTargetFormat::k_16_16)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + for (uint32_t j = 0; j < (uint32_t(2) << i); ++j) { + // Denormalize. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, j, 1)); + shader_code_.push_back(color_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + // 32767.0 / 32.0 + shader_code_.push_back(0x447FFE00); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Round towards the nearest even integer. Rounding towards the nearest + // (adding +-0.5 before truncating) is giving incorrect results for depth, + // so better to use round_ne here too. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ROUND_NE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_TEMP, temp1_component, 1)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Convert to fixed-point. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_FTOI) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + if (j & 1) { + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + } else { + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D10_SB_OPERAND_TYPE_TEMP, + 1 << (packed_temp_components + (j >> 1)), 1)); + shader_code_.push_back(packed_temp); + } + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_TEMP, temp1_component, 1)); + shader_code_.push_back(temp1); + ++stat_.instruction_count; + ++stat_.conversion_instruction_count; + + // Pack green or alpha. + if (j & 1) { + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_BFI) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D10_SB_OPERAND_TYPE_TEMP, + 1 << (packed_temp_components + (j >> 1)), 1)); + shader_code_.push_back(packed_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(16); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(16); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_TEMP, temp1_component, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_TEMP, packed_temp_components + (j >> 1), 1)); + shader_code_.push_back(packed_temp); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + } + } + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + } + + // *************************************************************************** + // k_16_16_FLOAT + // k_16_16_16_16_FLOAT (64bpp) + // *************************************************************************** + for (uint32_t i = 0; i < 2; ++i) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back( + ROV_AddColorFormatFlags(i ? ColorRenderTargetFormat::k_16_16_16_16_FLOAT + : ColorRenderTargetFormat::k_16_16_FLOAT)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + for (uint32_t j = 0; j < (uint32_t(2) << i); ++j) { + // Convert to 16-bit float. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_F32TOF16) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + if (j & 1) { + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D10_SB_OPERAND_TYPE_TEMP, temp1_mask, 1)); + shader_code_.push_back(temp1); + } else { + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D10_SB_OPERAND_TYPE_TEMP, + 1 << (packed_temp_components + (j >> 1)), 1)); + shader_code_.push_back(packed_temp); + } + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, j, 1)); + shader_code_.push_back(color_temp); + ++stat_.instruction_count; + ++stat_.conversion_instruction_count; + + // Pack green or alpha. + if (j & 1) { + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_BFI) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D10_SB_OPERAND_TYPE_TEMP, + 1 << (packed_temp_components + (j >> 1)), 1)); + shader_code_.push_back(packed_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(16); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(16); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_TEMP, temp1_component, 1)); + shader_code_.push_back(temp1); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_TEMP, packed_temp_components + (j >> 1), 1)); + shader_code_.push_back(packed_temp); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + } + } + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + } + + if (packed_temp != color_temp) { + // Assume k_32_FLOAT or k_32_32_FLOAT for the rest. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_DEFAULT) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D10_SB_OPERAND_TYPE_TEMP, 0b11 << packed_temp_components, 1)); + shader_code_.push_back(packed_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, 0b0100 << (packed_temp_components * 2), 1)); + shader_code_.push_back(color_temp); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + } + + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDSWITCH) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; +} + +void DxbcShaderTranslator::ROV_HandleColorBlendFactorCases( + uint32_t src_temp, uint32_t dst_temp, uint32_t factor_temp) { + // kOne. + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kOne)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); + shader_code_.push_back(0x3F800000); + shader_code_.push_back(0x3F800000); + shader_code_.push_back(0x3F800000); + shader_code_.push_back(0); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // kSrcColor + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kSrcColor)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + if (factor_temp != src_temp) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(src_temp); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + } + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // kOneMinusSrcColor + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kOneMinusSrcColor)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ADD) | ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(temp2); + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(factor_temp); shader_code_.push_back(EncodeVectorSwizzledOperand( D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(113); - shader_code_.push_back(113); - shader_code_.push_back(113); - shader_code_.push_back(113); + shader_code_.push_back(0x3F800000); + shader_code_.push_back(0x3F800000); + shader_code_.push_back(0x3F800000); + shader_code_.push_back(0); shader_code_.push_back( EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1) | ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); shader_code_.push_back( ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER(D3D10_SB_OPERAND_MODIFIER_NEG)); - shader_code_.push_back(temp2); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // Don't allow the shift to overflow, since in DXBC the lower 5 bits of the - // shift amount are used (otherwise 0 becomes 8). - // t2 = min(113 - (f32 >> 23), 24) - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_UMIN) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(temp2); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(temp2); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(24); - shader_code_.push_back(24); - shader_code_.push_back(24); - shader_code_.push_back(24); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // t1 = ((f32 & 0x7FFFFF) | 0x800000) >> min(113 - (f32 >> 23), 24) - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(temp1); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(temp1); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(temp2); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Check if the number is too small to be represented as normalized 20e4. - // t2 = f32 < 0x38800000 - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ULT) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(temp2); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depths_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0x38800000); - shader_code_.push_back(0x38800000); - shader_code_.push_back(0x38800000); - shader_code_.push_back(0x38800000); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Bias the exponent. - // f32 += 0xC8000000 - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(depths_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depths_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0xC8000000u); - shader_code_.push_back(0xC8000000u); - shader_code_.push_back(0xC8000000u); - shader_code_.push_back(0xC8000000u); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // Replace the number in f32 with a denormalized one if needed. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(depths_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(temp2); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(temp1); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depths_temp); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - // Build the 20e4 number. - // t1 = f32 >> 3 - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(temp1); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depths_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(3); - shader_code_.push_back(3); - shader_code_.push_back(3); - shader_code_.push_back(3); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // t1 = (f32 >> 3) & 1 - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(temp1); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(temp1); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(1); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // f24 = f32 + 3 - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(depths_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depths_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(3); - shader_code_.push_back(3); - shader_code_.push_back(3); - shader_code_.push_back(3); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // f24 = f32 + 3 + ((f32 >> 3) & 1) - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(depths_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depths_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(temp1); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // f24 = (f32 + 3 + ((f32 >> 3) & 1)) >> 3 - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(depths_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depths_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(3); - shader_code_.push_back(3); - shader_code_.push_back(3); - shader_code_.push_back(3); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // f24 = ((f32 + 3 + ((f32 >> 3) & 1)) >> 3) & 0xFFFFFF - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(depths_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depths_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0xFFFFFF); - shader_code_.push_back(0xFFFFFF); - shader_code_.push_back(0xFFFFFF); - shader_code_.push_back(0xFFFFFF); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // *************************************************************************** - // 20e4 conversion ends here. - // *************************************************************************** - - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - - // *************************************************************************** - // Unorm24 conversion begins here. - // *************************************************************************** - - // Multiply by float(0xFFFFFF). - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(depths_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depths_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0x4B7FFFFF); - shader_code_.push_back(0x4B7FFFFF); - shader_code_.push_back(0x4B7FFFFF); - shader_code_.push_back(0x4B7FFFFF); + shader_code_.push_back(src_temp); ++stat_.instruction_count; ++stat_.float_instruction_count; - // Round to the nearest even integer. This seems to be the correct way: - // rounding towards zero gives 0xFF instead of 0x100 in clear shaders in, for - // instance, Halo 3, but other clear shaders in it are also broken if 0.5 is - // added before ftou instead of round_ne. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ROUND_NE) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(depths_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depths_temp); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - - // Convert to fixed-point. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_FTOU) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(depths_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depths_temp); - ++stat_.instruction_count; - ++stat_.conversion_instruction_count; - - // *************************************************************************** - // Unorm24 conversion ends here. - // *************************************************************************** - - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); ++stat_.instruction_count; - // Release temp1 and temp2. - PopSystemTemp(2); + // kSrcAlpha + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kSrcAlpha)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(src_temp); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // kOneMinusSrcAlpha + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kOneMinusSrcAlpha)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); + shader_code_.push_back(0x3F800000); + shader_code_.push_back(0x3F800000); + shader_code_.push_back(0x3F800000); + shader_code_.push_back(0); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1) | + ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); + shader_code_.push_back( + ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER(D3D10_SB_OPERAND_MODIFIER_NEG)); + shader_code_.push_back(src_temp); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // kDstColor + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kDstColor)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + if (factor_temp != dst_temp) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(dst_temp); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + } + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // kOneMinusDstColor + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kOneMinusDstColor)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); + shader_code_.push_back(0x3F800000); + shader_code_.push_back(0x3F800000); + shader_code_.push_back(0x3F800000); + shader_code_.push_back(0); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1) | + ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); + shader_code_.push_back( + ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER(D3D10_SB_OPERAND_MODIFIER_NEG)); + shader_code_.push_back(dst_temp); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // kDstAlpha + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kDstAlpha)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(dst_temp); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // kOneMinusDstAlpha + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kOneMinusDstAlpha)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); + shader_code_.push_back(0x3F800000); + shader_code_.push_back(0x3F800000); + shader_code_.push_back(0x3F800000); + shader_code_.push_back(0); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1) | + ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); + shader_code_.push_back( + ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER(D3D10_SB_OPERAND_MODIFIER_NEG)); + shader_code_.push_back(dst_temp); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Factors involving the constant. + system_constants_used_ |= 1ull << kSysConst_EDRAMBlendConstant_Index; + + // kConstantColor + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kConstantColor)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, kSwizzleXYZW, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMBlendConstant_Vec); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // kOneMinusConstantColor + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kOneMinusConstantColor)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(13)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); + shader_code_.push_back(0x3F800000); + shader_code_.push_back(0x3F800000); + shader_code_.push_back(0x3F800000); + shader_code_.push_back(0); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSwizzleXYZW, 3) | + ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); + shader_code_.push_back( + ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER(D3D10_SB_OPERAND_MODIFIER_NEG)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMBlendConstant_Vec); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // kConstantAlpha + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kConstantAlpha)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back(EncodeVectorReplicatedOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, 3, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMBlendConstant_Vec); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // kOneMinusConstantAlpha + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kOneMinusConstantAlpha)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(13)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); + shader_code_.push_back(0x3F800000); + shader_code_.push_back(0x3F800000); + shader_code_.push_back(0x3F800000); + shader_code_.push_back(0); + shader_code_.push_back(EncodeVectorReplicatedOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, 3, 3) | + ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); + shader_code_.push_back( + ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER(D3D10_SB_OPERAND_MODIFIER_NEG)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMBlendConstant_Vec); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // kSrcAlphaSaturate + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kSrcAlphaSaturate)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0x3F800000); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1) | + ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); + shader_code_.push_back( + ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER(D3D10_SB_OPERAND_MODIFIER_NEG)); + shader_code_.push_back(dst_temp); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MIN) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(src_temp); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(factor_temp); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // kZero default. + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_DEFAULT) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); + shader_code_.push_back(0); + shader_code_.push_back(0); + shader_code_.push_back(0); + shader_code_.push_back(0); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; } -void DxbcShaderTranslator::CompletePixelShader_ApplyColorExpBias() { - if (is_depth_only_pixel_shader_) { +void DxbcShaderTranslator::ROV_HandleAlphaBlendFactorCases( + uint32_t src_temp, uint32_t dst_temp, uint32_t factor_temp, + uint32_t factor_component) { + uint32_t factor_mask = 1 << factor_component; + + // kOne, kSrcAlphaSaturate. + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kOne)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kSrcAlphaSaturate)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, factor_mask, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0x3F800000); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // kSrcColor, kSrcAlpha. + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kSrcColor)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kSrcAlpha)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + if (factor_temp != src_temp || factor_component != 3) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, factor_mask, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(src_temp); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + } + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // kOneMinusSrcColor, kOneMinusSrcAlpha. + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kOneMinusSrcColor)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kOneMinusSrcAlpha)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, factor_mask, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0x3F800000); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1) | + ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); + shader_code_.push_back( + ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER(D3D10_SB_OPERAND_MODIFIER_NEG)); + shader_code_.push_back(src_temp); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // kDstColor, kDstAlpha. + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kDstColor)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kDstAlpha)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + if (factor_temp != dst_temp || factor_component != 3) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, factor_mask, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(dst_temp); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + } + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // kOneMinusDstColor, kOneMinusDstAlpha. + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kOneMinusDstColor)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kOneMinusDstAlpha)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, factor_mask, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0x3F800000); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1) | + ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); + shader_code_.push_back( + ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER(D3D10_SB_OPERAND_MODIFIER_NEG)); + shader_code_.push_back(dst_temp); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Factors involving the constant. + system_constants_used_ |= 1ull << kSysConst_EDRAMBlendConstant_Index; + + // kConstantColor, kConstantAlpha. + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kConstantColor)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kConstantAlpha)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, factor_mask, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, 3, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMBlendConstant_Vec); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // kOneMinusConstantColor, kOneMinusConstantAlpha. + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kOneMinusConstantColor)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CASE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(uint32_t(BlendFactor::kOneMinusConstantAlpha)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, factor_mask, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0x3F800000); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, 3, 3) | + ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); + shader_code_.push_back( + ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER(D3D10_SB_OPERAND_MODIFIER_NEG)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMBlendConstant_Vec); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // kZero default. + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_DEFAULT) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, factor_mask, 1)); + shader_code_.push_back(factor_temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAK) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; +} + +void DxbcShaderTranslator::CompletePixelShader_ApplyColorExpBias( + uint32_t rt_index) { + if (!writes_color_target(rt_index)) { return; } // The constant contains 2.0^bias. - for (uint32_t i = 0; i < 4; ++i) { - if (!writes_color_target(i)) { - continue; - } - system_constants_used_ |= 1ull << kSysConst_ColorExpBias_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(system_temps_color_ + i); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(system_temps_color_ + i); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, i, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_ColorExpBias_Vec); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - } -} - -void DxbcShaderTranslator::CompletePixelShader_GammaCorrect(uint32_t color_temp, - bool to_gamma) { - uint32_t pieces_temp = PushSystemTemp(); - for (uint32_t j = 0; j < 3; ++j) { - // Calculate how far we are on each piece of the curve. Multiply by 1/width - // of each piece, subtract start/width of it and saturate. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | - ENCODE_D3D10_SB_INSTRUCTION_SATURATE(1) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(15)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(pieces_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, j, 1)); - shader_code_.push_back(color_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - if (to_gamma) { - // 1.0 / 0.0625 - shader_code_.push_back(0x41800000u); - // 1.0 / 0.0625 - shader_code_.push_back(0x41800000u); - // 1.0 / 0.375 - shader_code_.push_back(0x402AAAABu); - // 1.0 / 0.5 - shader_code_.push_back(0x40000000u); - } else { - // 1.0 / 0.25 - shader_code_.push_back(0x40800000u); - // 1.0 / 0.125 - shader_code_.push_back(0x41000000u); - // 1.0 / 0.375 - shader_code_.push_back(0x402AAAABu); - // 1.0 / 0.25 - shader_code_.push_back(0x40800000u); - } - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - if (to_gamma) { - // -0.0 / 0.0625 - shader_code_.push_back(0); - // -0.0625 / 0.0625 - shader_code_.push_back(0xBF800000u); - // -0.125 / 0.375 - shader_code_.push_back(0xBEAAAAABu); - // -0.5 / 0.5 - shader_code_.push_back(0xBF800000u); - } else { - // -0.0 / 0.25 - shader_code_.push_back(0); - // -0.25 / 0.125 - shader_code_.push_back(0xC0000000u); - // -0.375 / 0.375 - shader_code_.push_back(0xBF800000u); - // -0.75 / 0.25 - shader_code_.push_back(0xC0400000u); - } - ++stat_.instruction_count; - ++stat_.float_instruction_count; - // Combine the contribution of all pieces to the resulting value - multiply - // each piece by slope*width and sum them. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_DP4) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1 << j, 1)); - shader_code_.push_back(color_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(pieces_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - if (to_gamma) { - // 4.0 * 0.0625 - shader_code_.push_back(0x3E800000u); - // 2.0 * 0.0625 - shader_code_.push_back(0x3E000000u); - // 1.0 * 0.375 - shader_code_.push_back(0x3EC00000u); - // 0.5 * 0.5 - shader_code_.push_back(0x3E800000u); - } else { - // 0.25 * 0.25 - shader_code_.push_back(0x3D800000u); - // 0.5 * 0.125 - shader_code_.push_back(0x3D800000u); - // 1.0 * 0.375 - shader_code_.push_back(0x3EC00000u); - // 2.0 * 0.25 - shader_code_.push_back(0x3F000000u); - } - ++stat_.instruction_count; - ++stat_.float_instruction_count; - } - // Release pieces_temp. - PopSystemTemp(); + system_constants_used_ |= 1ull << kSysConst_ColorExpBias_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); + shader_code_.push_back(system_temps_color_[rt_index]); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temps_color_[rt_index]); + shader_code_.push_back(EncodeVectorReplicatedOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_ColorExpBias_Vec); + ++stat_.instruction_count; + ++stat_.float_instruction_count; } void DxbcShaderTranslator::CompletePixelShader_WriteToRTVs_AlphaToCoverage() { - if (is_depth_only_pixel_shader_ || !writes_color_target(0)) { + if (!writes_color_target(0)) { return; } - // Refer to CompletePixelShader_WriteToROV_GetCoverage for the description of - // the alpha to coverage pattern used. + // Refer to CompletePixelShader_ROV_AlphaToCoverage for the description of the + // alpha to coverage pattern used. uint32_t atoc_temp = PushSystemTemp(); @@ -1144,7 +3789,7 @@ void DxbcShaderTranslator::CompletePixelShader_WriteToRTVs_AlphaToCoverage() { shader_code_.push_back(atoc_temp); shader_code_.push_back( EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); - shader_code_.push_back(system_temps_color_); + shader_code_.push_back(system_temps_color_[0]); shader_code_.push_back( EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); shader_code_.push_back(atoc_temp); @@ -1171,47 +3816,65 @@ void DxbcShaderTranslator::CompletePixelShader_WriteToRTVs_AlphaToCoverage() { } void DxbcShaderTranslator::CompletePixelShader_WriteToRTVs() { + if (!writes_any_color_target()) { + return; + } + // Check if this sample needs to be discarded by alpha to coverage. CompletePixelShader_WriteToRTVs_AlphaToCoverage(); - // Apply the exponent bias after alpha to coverage because it needs the - // unbiased alpha from the shader. - CompletePixelShader_ApplyColorExpBias(); + // Get the write mask as components, and also apply the exponent bias after + // alpha to coverage because it needs the unbiased alpha from the shader. + uint32_t guest_rt_mask = 0; + for (uint32_t i = 0; i < 4; ++i) { + if (!writes_color_target(i)) { + continue; + } + guest_rt_mask |= 1 << i; + CompletePixelShader_ApplyColorExpBias(i); + } // Convert to gamma space - this is incorrect, since it must be done after // blending on the Xbox 360, but this is just one of many blending issues in // the RTV path. uint32_t gamma_temp = PushSystemTemp(); - system_constants_used_ |= 1ull << kSysConst_Flags_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(12)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(gamma_temp); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, kSysConst_Flags_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_Flags_Vec); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(kSysFlag_Color0Gamma); - shader_code_.push_back(kSysFlag_Color1Gamma); - shader_code_.push_back(kSysFlag_Color2Gamma); - shader_code_.push_back(kSysFlag_Color3Gamma); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; for (uint32_t i = 0; i < 4; ++i) { + if (!(guest_rt_mask & (1 << i))) { + continue; + } + + system_constants_used_ |= 1ull << kSysConst_Flags_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(gamma_temp); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, kSysConst_Flags_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_Flags_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(kSysFlag_Color0Gamma << i); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( D3D10_SB_INSTRUCTION_TEST_NONZERO) | ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); shader_code_.push_back(gamma_temp); ++stat_.instruction_count; ++stat_.dynamic_flow_control_count; - CompletePixelShader_GammaCorrect(system_temps_color_ + i, true); + + for (uint32_t j = 0; j < 3; ++j) { + ConvertPWLGamma(true, system_temps_color_[i], j, system_temps_color_[i], + j, gamma_temp, 0, gamma_temp, 1); + } + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); ++stat_.instruction_count; @@ -1232,8 +3895,8 @@ void DxbcShaderTranslator::CompletePixelShader_WriteToRTVs() { // mask = map.iiii == (0, 1, 2, 3) shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IEQ) | ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(12)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); + shader_code_.push_back(EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, + guest_rt_mask, 1)); shader_code_.push_back(remap_movc_mask_temp); shader_code_.push_back(EncodeVectorReplicatedOperand( D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, i, 3)); @@ -1248,10 +3911,15 @@ void DxbcShaderTranslator::CompletePixelShader_WriteToRTVs() { shader_code_.push_back(3); ++stat_.instruction_count; ++stat_.int_instruction_count; + bool guest_rt_first = true; for (uint32_t j = 0; j < 4; ++j) { // If map.i == j, move guest color j to the temporary host color. + if (!(guest_rt_mask & (1 << j))) { + continue; + } shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH( + guest_rt_first ? 12 : 9)); shader_code_.push_back( EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); shader_code_.push_back(remap_movc_target_temp); @@ -1260,10 +3928,20 @@ void DxbcShaderTranslator::CompletePixelShader_WriteToRTVs() { shader_code_.push_back(remap_movc_mask_temp); shader_code_.push_back(EncodeVectorSwizzledOperand( D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(system_temps_color_ + j); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(remap_movc_target_temp); + shader_code_.push_back(system_temps_color_[j]); + if (guest_rt_first) { + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); + shader_code_.push_back(0); + shader_code_.push_back(0); + shader_code_.push_back(0); + shader_code_.push_back(0); + guest_rt_first = false; + } else { + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(remap_movc_target_temp); + } ++stat_.instruction_count; ++stat_.movc_instruction_count; } @@ -1283,64 +3961,100 @@ void DxbcShaderTranslator::CompletePixelShader_WriteToRTVs() { PopSystemTemp(2); } -void DxbcShaderTranslator::CompletePixelShader_WriteToROV_GetCoverage( - uint32_t coverage_out_temp) { - // Load the coverage from the rasterizer. For 2x AA, use samples 0 and 3 - // (top-left and bottom-right), for 4x, use all, because ForcedSampleCount - // can't be 2. - system_constants_used_ |= 1ull << kSysConst_SampleCountLog2_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(17)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(coverage_out_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_SampleCountLog2_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_SampleCountLog2_Vec); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(1 << 0); - shader_code_.push_back(1 << 1); - shader_code_.push_back(1 << 2); - shader_code_.push_back(1 << 3); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(1 << 0); - shader_code_.push_back(1 << 3); - shader_code_.push_back(0); - shader_code_.push_back(0); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; +void DxbcShaderTranslator::CompletePixelShader_ROV_CheckAnyCovered( + bool check_deferred_stencil_write, uint32_t temp, uint32_t temp_component) { shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(6)); + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back(EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, + 1 << temp_component, 1)); + shader_code_.push_back(temp); shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(coverage_out_temp); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D11_SB_OPERAND_TYPE_INPUT_COVERAGE_MASK, 0, 0)); + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temp_rov_params_); shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(coverage_out_temp); + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(check_deferred_stencil_write ? 0b11111111 : 0b1111); ++stat_.instruction_count; ++stat_.uint_instruction_count; + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_RETC) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN(D3D10_SB_INSTRUCTION_TEST_ZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp_component, 1)); + shader_code_.push_back(temp); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; +} + +void DxbcShaderTranslator::CompletePixelShader_ROV_AlphaToCoverageSample( + uint32_t sample_index, float threshold, uint32_t temp, + uint32_t temp_component) { + // Check if alpha of oC0 is at or greater than the threshold. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_GE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back(EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, + 1 << temp_component, 1)); + shader_code_.push_back(temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_color_[0]); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(*reinterpret_cast(&threshold)); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Keep all bits in system_temp_rov_params_.x but the ones that need to be + // removed in case of failure (coverage and deferred depth/stencil write are + // removed). + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_OR) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back(EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, + 1 << temp_component, 1)); + shader_code_.push_back(temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp_component, 1)); + shader_code_.push_back(temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(~(uint32_t(0b00010001) << sample_index)); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Clear the coverage for samples that have failed the test. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, temp_component, 1)); + shader_code_.push_back(temp); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; +} + +void DxbcShaderTranslator::CompletePixelShader_ROV_AlphaToCoverage() { // Check if alpha to coverage can be done at all in this shader. - if (is_depth_only_pixel_shader_ || !writes_color_target(0)) { + if (!writes_color_target(0)) { return; } - uint32_t atoc_temp = PushSystemTemp(); + // 1 VGPR or 1 SGPR. + uint32_t temp = PushSystemTemp(); - // Extract the flag to check if alpha to coverage is enabled. + // Extract the flag to check if alpha to coverage is enabled (1 SGPR). system_constants_used_ |= 1ull << kSysConst_Flags_Index; shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); shader_code_.push_back( EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(atoc_temp); + shader_code_.push_back(temp); shader_code_.push_back(EncodeVectorSelectOperand( D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, kSysConst_Flags_Comp, 3)); shader_code_.push_back(cbuffer_index_system_constants_); @@ -1359,7 +4073,7 @@ void DxbcShaderTranslator::CompletePixelShader_WriteToROV_GetCoverage( ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); shader_code_.push_back( EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(atoc_temp); + shader_code_.push_back(temp); ++stat_.instruction_count; ++stat_.dynamic_flow_control_count; @@ -1382,4620 +4096,578 @@ void DxbcShaderTranslator::CompletePixelShader_WriteToROV_GetCoverage( // TODO(Triang3l): Find an Adreno device with dithering enabled, and where the // numbers 3, 1, 0, 2 look meaningful for pixels in quads, and implement // offsets. - // Choose the thresholds based on the sample count - first between 2 and 1 - // samples. - system_constants_used_ |= 1ull << kSysConst_SampleCountLog2_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(17)); + + // The test must effect not only the coverage bits, but also the deferred + // depth/stencil write bits since the coverage is zeroed for samples that have + // failed the depth/stencil test, but stencil may still require writing - but + // if the sample is discarded by alpha to coverage, it must not be written at + // all. + + // Check if any MSAA is enabled. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(atoc_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_SampleCountLog2_Comp + 1, 3)); + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_SampleCountLog2_Comp + 1, 3)); shader_code_.push_back(cbuffer_index_system_constants_); shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); shader_code_.push_back(kSysConst_SampleCountLog2_Vec); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - // 0.25 - shader_code_.push_back(0x3E800000); - // 0.75 - shader_code_.push_back(0x3F400000); - // NaN - comparison always fails - shader_code_.push_back(0x7FC00000); - shader_code_.push_back(0x7FC00000); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - // 0.5 - shader_code_.push_back(0x3F000000); - shader_code_.push_back(0x7FC00000); - shader_code_.push_back(0x7FC00000); - shader_code_.push_back(0x7FC00000); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - // Choose the thresholds based on the sample count - between 4 or 1/2 samples. - system_constants_used_ |= 1ull << kSysConst_SampleCountLog2_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(14)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(atoc_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_SampleCountLog2_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_SampleCountLog2_Vec); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - // 0.625 - shader_code_.push_back(0x3F200000); - // 0.375 - shader_code_.push_back(0x3EC00000); - // 0.125 - shader_code_.push_back(0x3E000000); - // 0.875 - shader_code_.push_back(0x3F600000); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(atoc_temp); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - // Check if alpha of oC0 is greater than the threshold for each sample or - // equal to it. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_GE) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(atoc_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); - shader_code_.push_back(system_temps_color_); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(atoc_temp); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - - // Mask the sample coverage. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(coverage_out_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(coverage_out_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(atoc_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Check if the pixel can be discarded totally - merge masked coverage of - // samples 01 and 23. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_OR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1)); - shader_code_.push_back(atoc_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(coverage_out_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b01001110, 1)); - shader_code_.push_back(coverage_out_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Check if the pixel can be discarded totally - merge masked coverage of - // samples 0|2 and 1|3. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_OR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(atoc_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(atoc_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); - shader_code_.push_back(atoc_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Don't even do depth/stencil for pixels fully discarded by alpha to - // coverage. - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_RETC) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN(D3D10_SB_INSTRUCTION_TEST_ZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(atoc_temp); ++stat_.instruction_count; ++stat_.dynamic_flow_control_count; + // Check if MSAA is 4x or 2x. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_SampleCountLog2_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_SampleCountLog2_Vec); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + CompletePixelShader_ROV_AlphaToCoverageSample(0, 0.625f, temp, 0); + CompletePixelShader_ROV_AlphaToCoverageSample(1, 0.375f, temp, 0); + CompletePixelShader_ROV_AlphaToCoverageSample(2, 0.125f, temp, 0); + CompletePixelShader_ROV_AlphaToCoverageSample(3, 0.875f, temp, 0); + + // 2x MSAA is used. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + CompletePixelShader_ROV_AlphaToCoverageSample(0, 0.25f, temp, 0); + CompletePixelShader_ROV_AlphaToCoverageSample(1, 0.75f, temp, 0); + + // Close the 4x check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // MSAA is disabled. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + CompletePixelShader_ROV_AlphaToCoverageSample(0, 0.5f, temp, 0); + + // Close the 2x/4x check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Check if any sample is still covered. + CompletePixelShader_ROV_CheckAnyCovered(true, temp, 0); + + // Release temp. + PopSystemTemp(); + // Close the alpha to coverage check. shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); ++stat_.instruction_count; - - // Release atoc_temp. - PopSystemTemp(); -} - -void DxbcShaderTranslator::CompletePixelShader_WriteToROV_DepthStencil( - uint32_t edram_dword_offset_temp, uint32_t coverage_in_out_temp) { - uint32_t flags_temp = PushSystemTemp(); - - // Check if anything related to depth/stencil needs to be done at all, and get - // the conditions of passing the depth test - as 0 or 0xFFFFFFFF - into - // flags_temp. - system_constants_used_ |= 1ull << kSysConst_Flags_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_IBFE) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(17)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(flags_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(kSysFlag_DepthStencil_Shift); - shader_code_.push_back(kSysFlag_DepthPassIfLess_Shift); - shader_code_.push_back(kSysFlag_DepthPassIfEqual_Shift); - shader_code_.push_back(kSysFlag_DepthPassIfGreater_Shift); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, kSysConst_Flags_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_Flags_Vec); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // Prevent going out of EDRAM bounds - disable depth/stencil testing if - // outside of the EDRAM. - uint32_t edram_bound_check_temp = PushSystemTemp(); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ULT) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(edram_bound_check_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(edram_dword_offset_temp); - shader_code_.push_back( - EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); - shader_code_.push_back(1280 * 2048); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(flags_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(flags_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(edram_bound_check_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - // Release edram_bound_check_temp. - PopSystemTemp(); - - // Enter the depth/stencil test if needed. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(flags_temp); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - - // Allocate a temporary register for new depth values (but if the shader - // writes depth, reuse system_temp_depth_, which already contains the pixel - // depth for all samples in X) and calculate the depth values for all samples - // into it. - uint32_t depth_new_values_temp; - if (writes_depth()) { - depth_new_values_temp = system_temp_depth_; - - // Replicate pixel depth into all samples. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1110, 1)); - shader_code_.push_back(depth_new_values_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(depth_new_values_temp); - ++stat_.instruction_count; - ++stat_.mov_instruction_count; - } else { - depth_new_values_temp = PushSystemTemp(); - - // Replicate pixel depth into all samples if using only a single sample. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(depth_new_values_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(system_temp_depth_); - ++stat_.instruction_count; - ++stat_.mov_instruction_count; - - // If multisampling, calculate depth at every sample. Check if using 2x MSAA - // at least. - system_constants_used_ |= 1ull << kSysConst_SampleCountLog2_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_SampleCountLog2_Comp + 1, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_SampleCountLog2_Vec); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - - // Load Z and W at sample 0 to depth_new_values_temp.xy and at sample 3 to - // depth_new_values_temp.zw for 2x MSAA. - for (uint32_t i = 0; i < 2; ++i) { - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_EVAL_SAMPLE_INDEX) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back(EncodeVectorMaskedOperand( - D3D10_SB_OPERAND_TYPE_TEMP, i ? 0b1100 : 0b0011, 1)); - shader_code_.push_back(depth_new_values_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_INPUT, i ? 0b01000000 : 0b00000100, 1)); - shader_code_.push_back(uint32_t(InOutRegister::kPSInClipSpaceZW)); - shader_code_.push_back( - EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); - shader_code_.push_back(i ? 3 : 0); - ++stat_.instruction_count; - } - - // Calculate Z/W at samples 0 and 3 to depth_new_values_temp.xy for 2x MSAA. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_DIV) | - ENCODE_D3D10_SB_INSTRUCTION_SATURATE(1) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1)); - shader_code_.push_back(depth_new_values_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b00001000, 1)); - shader_code_.push_back(depth_new_values_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b00001101, 1)); - shader_code_.push_back(depth_new_values_temp); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - - // Check if using 4x MSAA. - system_constants_used_ |= 1ull << kSysConst_SampleCountLog2_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_SampleCountLog2_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_SampleCountLog2_Vec); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - - // Sample 3 is used as 3 with 4x MSAA, not as 1. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); - shader_code_.push_back(depth_new_values_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); - shader_code_.push_back(depth_new_values_temp); - ++stat_.instruction_count; - ++stat_.mov_instruction_count; - - // Load Z and W at sample 1 to clip_space_zw_01_temp.xy and at sample 2 to - // clip_space_zw_01_temp.zw for 4x MSAA. - uint32_t clip_space_zw_01_temp = PushSystemTemp(); - for (uint32_t i = 0; i < 2; ++i) { - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_EVAL_SAMPLE_INDEX) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back(EncodeVectorMaskedOperand( - D3D10_SB_OPERAND_TYPE_TEMP, i ? 0b1100 : 0b0011, 1)); - shader_code_.push_back(clip_space_zw_01_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_INPUT, i ? 0b01000000 : 0b00000100, 1)); - shader_code_.push_back(uint32_t(InOutRegister::kPSInClipSpaceZW)); - shader_code_.push_back( - EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); - shader_code_.push_back(i ? 2 : 1); - ++stat_.instruction_count; - } - - // Calculate Z/W at samples 1 and 2 to depth_new_values_temp.yz for 4x MSAA. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_DIV) | - ENCODE_D3D10_SB_INSTRUCTION_SATURATE(1) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0110, 1)); - shader_code_.push_back(depth_new_values_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b00100000, 1)); - shader_code_.push_back(clip_space_zw_01_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b00110100, 1)); - shader_code_.push_back(clip_space_zw_01_temp); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - - // Release clip_space_zw_01_temp. - PopSystemTemp(); - - // 4x MSAA sample loading done. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - - // 2x MSAA sample loading done. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - - // Get the maximum depth slope for polygon offset to system_temp_depth_.y. - // https://docs.microsoft.com/en-us/windows/desktop/direct3d9/depth-bias - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAX) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); - shader_code_.push_back(system_temp_depth_); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1) | - ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); - shader_code_.push_back(ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER( - D3D10_SB_OPERAND_MODIFIER_ABS)); - shader_code_.push_back(system_temp_depth_); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1) | - ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); - shader_code_.push_back(ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER( - D3D10_SB_OPERAND_MODIFIER_ABS)); - shader_code_.push_back(system_temp_depth_); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - - // Copy the needed polygon offset values to system_temp_depth_.zw. - system_constants_used_ |= (1ull << kSysConst_EDRAMPolyOffsetFront_Index) | - (1ull << kSysConst_EDRAMPolyOffsetBack_Index); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(13)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1100, 1)); - shader_code_.push_back(system_temp_depth_); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_INPUT, 0, 1)); - shader_code_.push_back(uint32_t(InOutRegister::kPSInFrontFace)); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - (kSysConst_EDRAMPolyOffsetFrontScale_Comp << 4) | - (kSysConst_EDRAMPolyOffsetFrontOffset_Comp << 6), - 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMPolyOffsetFront_Vec); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - (kSysConst_EDRAMPolyOffsetBackScale_Comp << 4) | - (kSysConst_EDRAMPolyOffsetBackOffset_Comp << 6), - 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMPolyOffsetBack_Vec); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - // Calculate total polygon offset to system_temp_depth_.z. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0100, 1)); - shader_code_.push_back(system_temp_depth_); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); - shader_code_.push_back(system_temp_depth_); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); - shader_code_.push_back(system_temp_depth_); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); - shader_code_.push_back(system_temp_depth_); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - - // Apply polygon offset. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ADD) | - ENCODE_D3D10_SB_INSTRUCTION_SATURATE(1) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(depth_new_values_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depth_new_values_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); - shader_code_.push_back(system_temp_depth_); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - - // Apply viewport Z range. - system_constants_used_ |= 1ull << kSysConst_EDRAMDepthRange_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | - ENCODE_D3D10_SB_INSTRUCTION_SATURATE(1) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(13)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(depth_new_values_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depth_new_values_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_EDRAMDepthRangeScale_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMDepthRange_Vec); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_EDRAMDepthRangeOffset_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMDepthRange_Vec); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - } - - // Convert the depth to the target format. - CompletePixelShader_DepthTo24Bit(depth_new_values_temp); - - // Get EDRAM offsets for each sample. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1110, 1)); - shader_code_.push_back(edram_dword_offset_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(edram_dword_offset_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0); - shader_code_.push_back(80); - shader_code_.push_back(1); - shader_code_.push_back(81); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // Apply pixel width and height scale. - system_constants_used_ |= 1ull << kSysConst_EDRAMResolutionScaleLog2_Index; - for (uint32_t i = 0; i < 2; ++i) { - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ISHL) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(edram_dword_offset_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(edram_dword_offset_temp); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_EDRAMResolutionScaleLog2_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMResolutionScaleLog2_Vec); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - } - - // Choose the pixel for 2x scaling. - uint32_t resolution_scale_pixel_temp = PushSystemTemp(); - - // 1) Convert pixel position to integer. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_FTOU) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1)); - shader_code_.push_back(resolution_scale_pixel_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_INPUT, kSwizzleXYZW, 1)); - shader_code_.push_back(uint32_t(InOutRegister::kPSInPosition)); - ++stat_.instruction_count; - ++stat_.conversion_instruction_count; - - // 2) For 2x, get the current pixel in the quad. For 1x, write 0 for it. - system_constants_used_ |= 1ull << kSysConst_EDRAMResolutionScaleLog2_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1)); - shader_code_.push_back(resolution_scale_pixel_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(resolution_scale_pixel_temp); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_EDRAMResolutionScaleLog2_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMResolutionScaleLog2_Vec); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // 3) Calculate dword offset of the pixel in the quad. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_UMAD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(resolution_scale_pixel_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); - shader_code_.push_back(resolution_scale_pixel_temp); - shader_code_.push_back( - EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); - shader_code_.push_back(2); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(resolution_scale_pixel_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // 4) Add the quad pixel offset. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(edram_dword_offset_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(edram_dword_offset_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(resolution_scale_pixel_temp); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // Release resolution_scale_pixel_temp. - PopSystemTemp(); - - // Load the previous depth/stencil values. - // The `if`s are REQUIRED - interlocking is done per-sample, not per-pixel! - uint32_t depth_values_temp = PushSystemTemp(); - for (uint32_t i = 0; i < 4; ++i) { - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(coverage_in_out_temp); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_LD_UAV_TYPED) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1 << i, 1)); - shader_code_.push_back(depth_values_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(edram_dword_offset_temp); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D11_SB_OPERAND_TYPE_UNORDERED_ACCESS_VIEW, 0, 2)); - shader_code_.push_back(GetEDRAMUAVIndex()); - shader_code_.push_back(uint32_t(UAVRegister::kEDRAM)); - ++stat_.instruction_count; - ++stat_.texture_load_instructions; - - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - } - - // Take the stencil part of the original values. - uint32_t stencil_values_temp = PushSystemTemp(); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(stencil_values_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depth_values_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0xFF); - shader_code_.push_back(0xFF); - shader_code_.push_back(0xFF); - shader_code_.push_back(0xFF); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Take the depth part of the original values. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(depth_values_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depth_values_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(8); - shader_code_.push_back(8); - shader_code_.push_back(8); - shader_code_.push_back(8); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Do the depth test. - uint32_t depth_test_results_temp = PushSystemTemp(true); - uint32_t depth_test_op_results_temp = PushSystemTemp(); - for (uint32_t i = 0; i < 3; ++i) { - // Check if this operation giving true should result in passing. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1 + i, 1)); - shader_code_.push_back(flags_temp); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - - // Get the result of the operation: less, equal or greater. - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(i == 1 ? D3D10_SB_OPCODE_IEQ - : D3D10_SB_OPCODE_ULT) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(depth_test_op_results_temp); - if (i != 0) { - // For 1, old == new. For 2, new > old, but with ult, old < new. - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depth_values_temp); - } - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depth_new_values_temp); - if (i == 0) { - // New < old. - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depth_values_temp); - } - ++stat_.instruction_count; - if (i == 1) { - ++stat_.int_instruction_count; - } else { - ++stat_.uint_instruction_count; - } - - // Merge the result. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_OR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(depth_test_results_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depth_test_results_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depth_test_op_results_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - } - // Release depth_test_op_results_temp. - PopSystemTemp(); - - // Get bits containing whether stencil testing needs to be done, depth/stencil - // needs to be written, and the depth write mask. - system_constants_used_ |= 1ull << kSysConst_Flags_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(12)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(flags_temp); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, kSysConst_Flags_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_Flags_Vec); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(kSysFlag_StencilTest); - shader_code_.push_back(kSysFlag_DepthStencilWrite); - shader_code_.push_back(kSysFlag_DepthWriteMask); - shader_code_.push_back(0); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Check if stencil test needs to be done. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(flags_temp); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - - // *************************************************************************** - // Stencil test begins here. Will replace the values in stencil_values_temp. - // *************************************************************************** - - uint32_t stencil_control_temp = PushSystemTemp(); - // Stencil temps: stencil_control_temp - - // Load the comparison bits to stencil_control_temp.x. - system_constants_used_ |= (1ull << kSysConst_EDRAMStencilFront_Index) | - (1ull << kSysConst_EDRAMStencilBack_Index); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(13)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(stencil_control_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_INPUT, 0, 1)); - shader_code_.push_back(uint32_t(InOutRegister::kPSInFrontFace)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_EDRAMStencilSide_Comparison_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMStencilFront_Vec); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_EDRAMStencilSide_Comparison_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMStencilBack_Vec); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - // Load the masked reference value to stencil_control_temp.w. - system_constants_used_ |= (1ull << kSysConst_EDRAMStencilReference_Index) | - (1ull << kSysConst_EDRAMStencilReadMask_Vec); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); - shader_code_.push_back(stencil_control_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_EDRAMStencilReference_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMStencilReference_Vec); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_EDRAMStencilReadMask_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMStencilReadMask_Vec); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Expand the comparison bits - less, equal, greater - into - // stencil_control_temp.xyz. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(stencil_control_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(stencil_control_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(1 << 0); - shader_code_.push_back(1 << 1); - shader_code_.push_back(1 << 2); - shader_code_.push_back(0); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Allocate the stencil test results register. - uint32_t stencil_test_results_temp = PushSystemTemp(true); - // Stencil temps: stencil_control_temp | stencil_test_results_temp - - // Mask the current stencil values into stencil_values_read_masked_temp. - uint32_t stencil_values_read_masked_temp = PushSystemTemp(); - // Stencil temps: stencil_control_temp | stencil_test_results_temp | - // stencil_values_read_masked_temp - system_constants_used_ |= 1ull << kSysConst_EDRAMStencilReadMask_Vec; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(stencil_values_read_masked_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_values_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_EDRAMStencilReadMask_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMStencilReadMask_Vec); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Do the stencil test. - uint32_t stencil_test_op_results_temp = PushSystemTemp(); - // Stencil temps: stencil_control_temp | stencil_test_results_temp | - // stencil_values_read_masked_temp | - // stencil_test_op_results_temp - for (uint32_t i = 0; i < 3; ++i) { - // Check if this operation giving true should result in passing. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(stencil_control_temp); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - - // Get the result of the operation: less, equal or greater. - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(i == 1 ? D3D10_SB_OPCODE_IEQ - : D3D10_SB_OPCODE_ULT) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(stencil_test_op_results_temp); - if (i != 0) { - // For 1, old == new. For 2, new > old, but with ult, old < new. - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_values_read_masked_temp); - } - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); - shader_code_.push_back(stencil_control_temp); - if (i == 0) { - // New < old. - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_values_read_masked_temp); - } - ++stat_.instruction_count; - if (i == 1) { - ++stat_.int_instruction_count; - } else { - ++stat_.uint_instruction_count; - } - - // Merge the result. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_OR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(stencil_test_results_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_test_results_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_test_op_results_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - } - - // Release stencil_values_read_masked_temp and stencil_test_op_results_temp. - PopSystemTemp(2); - // Stencil temps: stencil_control_temp | stencil_test_results_temp - - // Get the operations for the current face into stencil_control_temp.xyz. - system_constants_used_ |= (1ull << kSysConst_EDRAMStencilFront_Index) | - (1ull << kSysConst_EDRAMStencilBack_Index); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(13)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(stencil_control_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_INPUT, 0, 1)); - shader_code_.push_back(uint32_t(InOutRegister::kPSInFrontFace)); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, kSwizzleXYZW, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMStencilFront_Vec); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, kSwizzleXYZW, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMStencilBack_Vec); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - // Select the operations for each sample, part 1 for stencil pass case - both - // depth/stencil passed or depth failed into stencil_pass_op_temp. - uint32_t stencil_pass_op_temp = PushSystemTemp(); - // Stencil temps: stencil_control_temp | stencil_test_results_temp | - // stencil_pass_op_temp - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(stencil_pass_op_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depth_test_results_temp); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSysConst_EDRAMStencilSide_Pass_Comp, 1)); - shader_code_.push_back(stencil_control_temp); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSysConst_EDRAMStencilSide_DepthFail_Comp, - 1)); - shader_code_.push_back(stencil_control_temp); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - // Select the operations for each sample, part 2 for stencil fail case, into - // stencil_control_temp, so stencil_pass_op_temp can be released. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(stencil_control_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_test_results_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_pass_op_temp); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSysConst_EDRAMStencilSide_Fail_Comp, 1)); - shader_code_.push_back(stencil_control_temp); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - // Release stencil_pass_op_temp. - PopSystemTemp(); - // Stencil temps: stencil_control_temp | stencil_test_results_temp - - // We don't need separate depth and stencil test results anymore, so now we - // can mark the samples to be discarded if the stencil test has failed - by - // setting that whole depth/stencil test has failed. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(depth_test_results_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depth_test_results_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_test_results_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Release stencil_test_results_temp. - PopSystemTemp(); - // Stencil temps: stencil_control_temp - - // Allocate the register for combining sub-operation results into the new - // value to write. - uint32_t stencil_new_values_temp = PushSystemTemp(); - // Stencil temps: stencil_control_temp | stencil_new_values_temp - - // Allocate the register for sub-operation factors. - uint32_t stencil_subop_temp = PushSystemTemp(); - // Stencil temps: stencil_control_temp | stencil_new_values_temp | - // stencil_subop_temp - - // 1) Apply the current value mask (keep/increment/decrement/invert vs. - // zero/replace) - expand to 0xFFFFFFFF or 0, then AND. - - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_IBFE) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(15)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(stencil_subop_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(kStencilOp_Flag_CurrentMask_Shift); - shader_code_.push_back(kStencilOp_Flag_CurrentMask_Shift); - shader_code_.push_back(kStencilOp_Flag_CurrentMask_Shift); - shader_code_.push_back(kStencilOp_Flag_CurrentMask_Shift); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_control_temp); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(stencil_new_values_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_values_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_subop_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // 2) Increment/decrement stencil - expand 2 bits to 0, 1 or 0xFFFFFFFF (-1) - // and add. - // Not caring about & 0xFF now - applying the write mask will drop the unused - // bits. - - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_IBFE) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(15)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(stencil_subop_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(2); - shader_code_.push_back(2); - shader_code_.push_back(2); - shader_code_.push_back(2); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(kStencilOp_Flag_Add_Shift); - shader_code_.push_back(kStencilOp_Flag_Add_Shift); - shader_code_.push_back(kStencilOp_Flag_Add_Shift); - shader_code_.push_back(kStencilOp_Flag_Add_Shift); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_control_temp); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(stencil_new_values_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_new_values_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_subop_temp); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // 3) Saturate to 0-255 after adding (INCRSAT/DECRSAT), then conditionally - // move if needed. - - uint32_t stencil_saturate_temp = PushSystemTemp(); - // Stencil temps: stencil_control_temp | stencil_new_values_temp | - // stencil_subop_temp | stencil_saturate_temp - - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IMAX) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(stencil_saturate_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_new_values_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IMIN) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(stencil_saturate_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_saturate_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(255); - shader_code_.push_back(255); - shader_code_.push_back(255); - shader_code_.push_back(255); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(stencil_subop_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_control_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(kStencilOp_Flag_Saturate); - shader_code_.push_back(kStencilOp_Flag_Saturate); - shader_code_.push_back(kStencilOp_Flag_Saturate); - shader_code_.push_back(kStencilOp_Flag_Saturate); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(stencil_new_values_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_subop_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_saturate_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_new_values_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Release stencil_saturate_temp. - PopSystemTemp(); - // Stencil temps: stencil_control_temp | stencil_new_values_temp | - // stencil_subop_temp - - // 4) Invert - XOR 0xFFFFFFFF or 0. - // Not caring about & 0xFF now - applying the write mask will drop the unused - // bits. - - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_IBFE) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(15)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(stencil_subop_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(kStencilOp_Flag_Invert_Shift); - shader_code_.push_back(kStencilOp_Flag_Invert_Shift); - shader_code_.push_back(kStencilOp_Flag_Invert_Shift); - shader_code_.push_back(kStencilOp_Flag_Invert_Shift); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_control_temp); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_XOR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(stencil_new_values_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_new_values_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_subop_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // 5) Replace with the reference value if needed. - - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(stencil_subop_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_control_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(kStencilOp_Flag_NewMask); - shader_code_.push_back(kStencilOp_Flag_NewMask); - shader_code_.push_back(kStencilOp_Flag_NewMask); - shader_code_.push_back(kStencilOp_Flag_NewMask); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - system_constants_used_ |= 1ull << kSysConst_EDRAMStencilReference_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(stencil_new_values_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_subop_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_EDRAMStencilReference_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMStencilReference_Vec); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_new_values_temp); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - // Release stencil_subop_temp. - PopSystemTemp(); - // Stencil temps: stencil_control_temp | stencil_new_values_temp - - // Apply the write mask to the new value - this will also reduce it to 8 bits. - system_constants_used_ |= 1ull << kSysConst_EDRAMStencilWriteMask_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(stencil_new_values_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_new_values_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_EDRAMStencilWriteMask_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMStencilWriteMask_Vec); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Invert the write mask into stencil_control_temp.x to keep the unmodified - // bits of the old value. - system_constants_used_ |= 1ull << kSysConst_EDRAMStencilWriteMask_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_NOT) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(stencil_control_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_EDRAMStencilWriteMask_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMStencilWriteMask_Vec); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Mask the old value. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(stencil_values_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_values_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(stencil_control_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Combine the old and new stencil values. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_OR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(stencil_values_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_values_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_new_values_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Release stencil_control_temp and stencil_new_values_temp. - PopSystemTemp(); - - // *************************************************************************** - // Stencil test ends here. - // *************************************************************************** - - // If not doing stencil test, it's safe to update the coverage a bit earlier - - // no need to modify the stencil, no need to write the new depth/stencil to - // the ROV. - // Check if stencil test is not done. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - - // Update the coverage according to the depth test result (0 or 0xFFFFFFFF) - // earlier if stencil is disabled. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(coverage_in_out_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(coverage_in_out_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depth_test_results_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Stencil test done. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - - // Check if depth/stencil needs to be written. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); - shader_code_.push_back(flags_temp); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - - // Check the depth write mask. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); - shader_code_.push_back(flags_temp); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - - // If depth must be written, replace the old depth with the new one for the - // samples for which the test has passed. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(depth_values_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depth_test_results_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depth_new_values_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depth_values_temp); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - // Close the depth write mask conditional. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - - // Combine depth and stencil into depth_values_temp. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_UMAD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(12)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(depth_values_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depth_values_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(256); - shader_code_.push_back(256); - shader_code_.push_back(256); - shader_code_.push_back(256); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(stencil_values_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Write new depth/stencil for the covered samples. - // The `if`s are REQUIRED - interlocking is done per-sample, not per-pixel! - for (uint32_t i = 0; i < 4; ++i) { - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(coverage_in_out_temp); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_STORE_UAV_TYPED) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); - shader_code_.push_back(EncodeVectorMaskedOperand( - D3D11_SB_OPERAND_TYPE_UNORDERED_ACCESS_VIEW, 0b1111, 2)); - shader_code_.push_back(GetEDRAMUAVIndex()); - shader_code_.push_back(uint32_t(UAVRegister::kEDRAM)); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(edram_dword_offset_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(depth_values_temp); - ++stat_.instruction_count; - ++stat_.c_texture_store_instructions; - - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - } - - // Close the depth/stencil write conditional. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - - if (!is_depth_only_pixel_shader_) { - // Update the coverage according to the depth/stencil test result (0 or - // 0xFFFFFFFF) after writing the new depth/stencil if stencil is enabled. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(coverage_in_out_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(coverage_in_out_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(depth_test_results_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - } - - // Release depth_new_values_temp (if allocated), depth_values_temp, - // stencil_values_temp and depth_test_results_temp. - PopSystemTemp(writes_depth() ? 3 : 4); - - // Depth/stencil operations done. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - - // Release flags_temp. - PopSystemTemp(); -} - -void DxbcShaderTranslator::CompletePixelShader_WriteToROV_ExtractPackLayout( - uint32_t rt_index, bool high, uint32_t width_temp, uint32_t offset_temp) { - if (high) { - system_constants_used_ |= (1ull << kSysConst_EDRAMRTPackWidthHigh_Index) | - (1ull << kSysConst_EDRAMRTPackOffsetHigh_Index); - } else { - system_constants_used_ |= (1ull << kSysConst_EDRAMRTPackWidthLow_Index) | - (1ull << kSysConst_EDRAMRTPackOffsetLow_Index); - } - for (uint32_t i = 0; i < 2; ++i) { - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_UBFE) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(17)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(i ? offset_temp : width_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(8); - shader_code_.push_back(8); - shader_code_.push_back(8); - shader_code_.push_back(8); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0); - shader_code_.push_back(8); - shader_code_.push_back(16); - shader_code_.push_back(24); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - if (i) { - shader_code_.push_back(high ? kSysConst_EDRAMRTPackOffsetHigh_Vec - : kSysConst_EDRAMRTPackOffsetLow_Vec); - } else { - shader_code_.push_back(high ? kSysConst_EDRAMRTPackWidthHigh_Vec - : kSysConst_EDRAMRTPackWidthLow_Vec); - } - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - } -} - -void DxbcShaderTranslator::CompletePixelShader_WriteToROV_UnpackColor( - uint32_t data_low_temp, uint32_t data_high_temp, uint32_t data_component, - uint32_t rt_index, uint32_t rt_format_flags_temp, uint32_t target_temp) { - // For indexing of the format constants. - uint32_t rt_pair_index = rt_index >> 1; - uint32_t rt_pair_swizzle = rt_index & 1 ? 0b11101010 : 0b01000000; - - // Allocate temporary registers for unpacking pixels. - uint32_t pack_width_temp = PushSystemTemp(); - uint32_t pack_offset_temp = PushSystemTemp(); - - // Unpack the bits from the lower 32 bits, as signed because of k_16_16 and - // k_16_16_16_16 (will be masked later if needed). - CompletePixelShader_WriteToROV_ExtractPackLayout( - rt_index, false, pack_width_temp, pack_offset_temp); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_IBFE) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(target_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(pack_width_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(pack_offset_temp); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_TEMP, data_component, 1)); - shader_code_.push_back(data_low_temp); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // Allocate a register for the components from the upper 32 bits (will be - // combined with the lower using OR). - uint32_t high_temp = PushSystemTemp(); - - // Unpack the bits from the upper 32 bits. - CompletePixelShader_WriteToROV_ExtractPackLayout( - rt_index, true, pack_width_temp, pack_offset_temp); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_IBFE) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(high_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(pack_width_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(pack_offset_temp); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_TEMP, data_component, 1)); - shader_code_.push_back(data_high_temp); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // Combine the components from the lower and the upper 32 bits. In ibfe, if - // width is 0, the result is 0 (not 0xFFFFFFFF), so it's fine to do this - // without pre-masking. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_OR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(target_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(target_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(high_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Release pack_width_temp, pack_offset_temp and high_temp. - PopSystemTemp(3); - - // Mask the components to differentiate between signed and unsigned. - system_constants_used_ |= (1ull << kSysConst_EDRAMLoadMaskRT01_Index) - << rt_pair_index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(target_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(target_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_pair_swizzle, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMLoadMaskRT01_Vec + rt_pair_index); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Convert from fixed-point. - uint32_t fixed_temp = PushSystemTemp(); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ITOF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(fixed_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(target_temp); - ++stat_.instruction_count; - ++stat_.conversion_instruction_count; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(target_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kROVRTFormatFlagTemp_Fixed_Swizzle, 1)); - shader_code_.push_back(rt_format_flags_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(fixed_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(target_temp); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - // Release fixed_temp. - PopSystemTemp(); - - // *************************************************************************** - // 7e3 conversion begins here. - // https://github.com/Microsoft/DirectXTex/blob/master/DirectXTex/DirectXTexConvert.cpp - // *************************************************************************** - - // Check if the target format is 7e3 and the conversion is needed (this is - // pretty long, better to branch here). - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); - shader_code_.push_back(EncodeVectorSelectOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kROVRTFormatFlagTemp_Float10, 1)); - shader_code_.push_back(rt_format_flags_temp); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - - uint32_t f10_mantissa_temp = PushSystemTemp(); - uint32_t f10_exponent_temp = PushSystemTemp(); - uint32_t f10_denormalized_temp = PushSystemTemp(); - - // Extract the mantissa. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_mantissa_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(target_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0x7F); - shader_code_.push_back(0x7F); - shader_code_.push_back(0x7F); - shader_code_.push_back(0x7F); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Extract the exponent. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_exponent_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(target_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(7); - shader_code_.push_back(7); - shader_code_.push_back(7); - shader_code_.push_back(7); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Normalize the mantissa for denormalized numbers (with zero exponent - - // exponent can be used for selection in movc). - // Note that HLSL firstbithigh(x) is compiled to DXBC like: - // `x ? 31 - firstbit_hi(x) : -1` - // (it returns the index from the LSB, not the MSB, but -1 for zero as well). - - // denormalized_temp = firstbit_hi(mantissa) - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_FIRSTBIT_HI) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_denormalized_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_mantissa_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // denormalized_temp = 7 - (31 - firstbit_hi(mantissa)) - // Or, if expanded: - // denormalized_temp = firstbit_hi(mantissa) - 24 - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_denormalized_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_denormalized_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(uint32_t(-24)); - shader_code_.push_back(uint32_t(-24)); - shader_code_.push_back(uint32_t(-24)); - shader_code_.push_back(uint32_t(-24)); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // If mantissa is zero, then: - // denormalized_temp = 7 - (-1) = 8 - // After this, it works like the following HLSL: - // denormalized_temp = 7 - firstbithigh(mantissa) - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(12)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_denormalized_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_mantissa_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_denormalized_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(8); - shader_code_.push_back(8); - shader_code_.push_back(8); - shader_code_.push_back(8); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - // If the number is not denormalized, make - // `(mantissa << (7 - firstbithigh(mantissa))) & 0x7F` - // a no-op - zero 7 - firstbithigh(mantissa). - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(12)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_denormalized_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_exponent_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_denormalized_temp); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - // Normalize the mantissa - step 1. - // mantissa = mantissa << (7 - firstbithigh(mantissa)) - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ISHL) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_mantissa_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_mantissa_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_denormalized_temp); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // Normalize the mantissa - step 2. - // mantissa = (mantissa << (7 - firstbithigh(mantissa))) & 0x7F - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_mantissa_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_mantissa_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0x7F); - shader_code_.push_back(0x7F); - shader_code_.push_back(0x7F); - shader_code_.push_back(0x7F); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Get the normalized exponent. - // denormalized_temp = 1 - (7 - firstbithigh(mantissa)) - // If the number is normal, the result will be ignored anyway, so zeroing - // 7 - firstbithigh(mantissa) will have no effect on this. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_denormalized_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1) | - ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); - shader_code_.push_back( - ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER(D3D10_SB_OPERAND_MODIFIER_NEG)); - shader_code_.push_back(f10_denormalized_temp); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // Overwrite the exponent with the normalized one if needed. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_exponent_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_exponent_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_exponent_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_denormalized_temp); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - // Bias the exponent. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_exponent_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_exponent_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(124); - shader_code_.push_back(124); - shader_code_.push_back(124); - shader_code_.push_back(124); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // If the original number is zero, make the exponent zero (mantissa is already - // zero in this case). - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(12)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_exponent_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(target_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_exponent_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - // Shift the mantissa into its float32 position. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ISHL) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_mantissa_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_mantissa_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(16); - shader_code_.push_back(16); - shader_code_.push_back(16); - shader_code_.push_back(16); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // Shift the exponent into its float32 position. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ISHL) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_exponent_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_exponent_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(23); - shader_code_.push_back(23); - shader_code_.push_back(23); - shader_code_.push_back(23); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // Combine mantissa and exponent into float32 numbers. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_OR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(target_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_mantissa_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_exponent_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Release f10_mantissa_temp, f10_exponent_temp and f10_denormalized_temp. - PopSystemTemp(3); - - // 7e3 conversion done. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - - // *************************************************************************** - // 7e3 conversion ends here. - // *************************************************************************** - - // Convert from 16-bit float. - uint32_t f16_temp = PushSystemTemp(); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_F16TOF32) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(f16_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(target_temp); - ++stat_.instruction_count; - ++stat_.conversion_instruction_count; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(target_temp); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kROVRTFormatFlagTemp_Float16, 1)); - shader_code_.push_back(rt_format_flags_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f16_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(target_temp); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - // Release f16_temp. - PopSystemTemp(); - - // Scale by the fixed-point conversion factor. - system_constants_used_ |= (1ull << kSysConst_EDRAMLoadScaleRT01_Index) - << rt_pair_index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(target_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(target_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_pair_swizzle, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMLoadScaleRT01_Vec + rt_pair_index); - ++stat_.instruction_count; - ++stat_.float_instruction_count; -} - -void DxbcShaderTranslator::CompletePixelShader_WriteToROV_ExtractBlendScales( - uint32_t rt_index, uint32_t constant_swizzle, bool is_signed, - uint32_t shift_x, uint32_t shift_y, uint32_t shift_z, uint32_t shift_w, - uint32_t target_temp, uint32_t write_mask) { - uint32_t rt_pair_index = rt_index >> 1; - if (rt_index & 1) { - constant_swizzle |= 0b10101010; - } - - // Sign-extend 2 bits for signed, extract 1 bit for unsigned. - system_constants_used_ |= (1ull << kSysConst_EDRAMBlendRT01_Index) - << rt_pair_index; - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(is_signed ? D3D11_SB_OPCODE_IBFE - : D3D11_SB_OPCODE_UBFE) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(17)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, write_mask, 1)); - shader_code_.push_back(target_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - uint32_t width = is_signed ? 2 : 1; - shader_code_.push_back(width); - shader_code_.push_back(width); - shader_code_.push_back(width); - shader_code_.push_back(width); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(shift_x); - shader_code_.push_back(shift_y); - shader_code_.push_back(shift_z); - shader_code_.push_back(shift_w); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, constant_swizzle, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMBlendRT01_Vec + rt_pair_index); - ++stat_.instruction_count; - if (is_signed) { - ++stat_.int_instruction_count; - } else { - ++stat_.uint_instruction_count; - } - - // Convert -1, 0 or 1 integer to float. - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(is_signed ? D3D10_SB_OPCODE_ITOF - : D3D10_SB_OPCODE_UTOF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, write_mask, 1)); - shader_code_.push_back(target_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(target_temp); - ++stat_.instruction_count; - ++stat_.conversion_instruction_count; -} - -void DxbcShaderTranslator::CompletePixelShader_WriteToROV_ClampColor( - uint32_t rt_index, uint32_t color_in_temp, uint32_t color_out_temp) { - uint32_t rt_pair_index = rt_index >> 1; - uint32_t rt_pair_swizzle = rt_index & 1 ? 0b11101010 : 0b01000000; - - system_constants_used_ |= (1ull << kSysConst_EDRAMStoreMinRT01_Index) - << rt_pair_index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAX) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(color_out_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(color_in_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_pair_swizzle, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMStoreMinRT01_Vec + rt_pair_index); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - - system_constants_used_ |= (1ull << kSysConst_EDRAMStoreMaxRT01_Index) - << rt_pair_index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MIN) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(color_out_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(color_out_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_pair_swizzle, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMStoreMaxRT01_Vec + rt_pair_index); - ++stat_.instruction_count; - ++stat_.float_instruction_count; -} - -void DxbcShaderTranslator::CompletePixelShader_WriteToROV_ApplyZeroBlendScale( - uint32_t scale_temp, uint32_t scale_swizzle, uint32_t factor_in_temp, - uint32_t factor_swizzle, uint32_t factor_out_temp, uint32_t write_mask) { - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(12)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, write_mask, 1)); - shader_code_.push_back(factor_out_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, - scale_swizzle, 1)); - shader_code_.push_back(scale_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, - factor_swizzle, 1)); - shader_code_.push_back(factor_in_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; -} - -void DxbcShaderTranslator::CompletePixelShader_WriteToROV_Blend( - uint32_t rt_index, uint32_t rt_format_flags_temp, - uint32_t src_color_and_output_temp, uint32_t dest_color_temp) { - // Temporary register for scales of things that contribute to the blending, - // usually -1.0, 0.0 or 1.0. - uint32_t scale_temp = PushSystemTemp(); - // Temporary register for making 0 * Infinity result in 0 rather than NaN, - // for clamping of the source color and the factors, and for applying alpha - // saturate factor. - uint32_t factor_calculation_temp = PushSystemTemp(); - uint32_t src_factor_and_result_temp = PushSystemTemp(); - uint32_t dest_factor_and_minmax_temp = PushSystemTemp(); - - // Clamp the source color if needed. For fixed-point formats, clamping must - // always be done, for floating-point, it must not be, however, - // k_2_10_10_10_FLOAT has fixed-point alpha. - // https://docs.microsoft.com/en-us/windows/desktop/direct3d11/d3d10-graphics-programming-guide-output-merger-stage - CompletePixelShader_WriteToROV_ClampColor(rt_index, src_color_and_output_temp, - factor_calculation_temp); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(src_color_and_output_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kROVRTFormatFlagTemp_Fixed_Swizzle, 1)); - shader_code_.push_back(rt_format_flags_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(factor_calculation_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(src_color_and_output_temp); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - // Interleaving source and destination writes when possible to reduce - // write-read dependencies. - - // Constant one for factors, reusing dest_factor_and_minmax_temp (since it's - // the last to be modified). - CompletePixelShader_WriteToROV_ExtractBlendScales( - rt_index, 0b00000000, false, kBlendX_Src_One_Shift, - kBlendX_SrcAlpha_One_Shift, kBlendX_Dest_One_Shift, - kBlendX_DestAlpha_One_Shift, dest_factor_and_minmax_temp); - - // Source color for color factors, source alpha for alpha factors, plus ones. - // This will initialize src_factor_and_result_temp and - // dest_factor_and_minmax_temp. - CompletePixelShader_WriteToROV_ExtractBlendScales( - rt_index, 0b00000000, true, kBlendX_Src_SrcColor_Shift, - kBlendX_SrcAlpha_SrcAlpha_Shift, kBlendX_Dest_SrcColor_Shift, - kBlendX_DestAlpha_SrcAlpha_Shift, scale_temp); - for (uint32_t i = 0; i < 2; ++i) { - uint32_t swizzle = i ? 0b11101010 : 0b01000000; - CompletePixelShader_WriteToROV_ApplyZeroBlendScale( - scale_temp, swizzle, src_color_and_output_temp, kSwizzleXYZW, - factor_calculation_temp); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(i ? dest_factor_and_minmax_temp - : src_factor_and_result_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(factor_calculation_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, swizzle, 1)); - shader_code_.push_back(scale_temp); - // dest_factor_and_minmax_temp is the last one to be modified, so it stores - // the ones (not to allocate an additional temporary register). - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, swizzle, 1)); - shader_code_.push_back(dest_factor_and_minmax_temp); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - } - - // Destination color for color factors, destination alpha for alpha factors. - CompletePixelShader_WriteToROV_ExtractBlendScales( - rt_index, 0b00000000, true, kBlendX_Src_DestColor_Shift, - kBlendX_SrcAlpha_DestAlpha_Shift, kBlendX_Dest_DestColor_Shift, - kBlendX_DestAlpha_DestAlpha_Shift, scale_temp); - for (uint32_t i = 0; i < 2; ++i) { - uint32_t swizzle = i ? 0b11101010 : 0b01000000; - CompletePixelShader_WriteToROV_ApplyZeroBlendScale( - scale_temp, swizzle, dest_color_temp, kSwizzleXYZW, - factor_calculation_temp); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(i ? dest_factor_and_minmax_temp - : src_factor_and_result_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(factor_calculation_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, swizzle, 1)); - shader_code_.push_back(scale_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(i ? dest_factor_and_minmax_temp - : src_factor_and_result_temp); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - } - - // Source and destination alphas for color factors. - CompletePixelShader_WriteToROV_ExtractBlendScales( - rt_index, 0b00000000, true, kBlendX_Src_SrcAlpha_Shift, - kBlendX_Dest_SrcAlpha_Shift, kBlendX_Src_DestAlpha_Shift, - kBlendX_Dest_DestAlpha_Shift, scale_temp); - CompletePixelShader_WriteToROV_ApplyZeroBlendScale( - scale_temp, kSwizzleXYZW, src_color_and_output_temp, kSwizzleWWWW, - factor_calculation_temp, 0b0011); - CompletePixelShader_WriteToROV_ApplyZeroBlendScale( - scale_temp, kSwizzleXYZW, dest_color_temp, kSwizzleWWWW, - factor_calculation_temp, 0b1100); - for (uint32_t i = 0; i < 4; ++i) { - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(i & 1 ? dest_factor_and_minmax_temp - : src_factor_and_result_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(factor_calculation_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(scale_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(i & 1 ? dest_factor_and_minmax_temp - : src_factor_and_result_temp); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - } - - // Constant color for color factors, constant alpha for alpha factors. - system_constants_used_ |= 1ull << kSysConst_EDRAMBlendConstant_Index; - CompletePixelShader_WriteToROV_ExtractBlendScales( - rt_index, 0b01010101, true, kBlendY_Src_ConstantColor_Shift, - kBlendY_SrcAlpha_ConstantAlpha_Shift, kBlendY_Dest_ConstantColor_Shift, - kBlendY_DestAlpha_ConstantAlpha_Shift, scale_temp); - for (uint32_t i = 0; i < 2; ++i) { - uint32_t swizzle = i ? 0b11101010 : 0b01000000; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(14)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(factor_calculation_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, swizzle, 1)); - shader_code_.push_back(scale_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, kSwizzleXYZW, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMBlendConstant_Vec); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(i ? dest_factor_and_minmax_temp - : src_factor_and_result_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(factor_calculation_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, swizzle, 1)); - shader_code_.push_back(scale_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(i ? dest_factor_and_minmax_temp - : src_factor_and_result_temp); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - } - - // Constant alpha for color factors. - CompletePixelShader_WriteToROV_ExtractBlendScales( - rt_index, 0b01010101, true, kBlendY_Src_ConstantAlpha_Shift, - kBlendY_Dest_ConstantAlpha_Shift, 0, 0, scale_temp, 0b0011); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(14)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1)); - shader_code_.push_back(factor_calculation_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(scale_temp); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, 3, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMBlendConstant_Vec); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - for (uint32_t i = 0; i < 2; ++i) { - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(i ? dest_factor_and_minmax_temp - : src_factor_and_result_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(factor_calculation_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(scale_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(i ? dest_factor_and_minmax_temp - : src_factor_and_result_temp); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - } - - // Alpha saturate mode. - - // 1) Clamp the alphas to 1 or less. - // https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ne-d3d12-d3d12_blend - for (uint32_t i = 0; i < 2; ++i) { - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAX) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1 << i, 1)); - shader_code_.push_back(factor_calculation_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); - shader_code_.push_back(i ? dest_color_temp : src_color_and_output_temp); - shader_code_.push_back( - EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); - shader_code_.push_back(0x3F800000); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - } - - // 2) Subtract the destination alpha from 1. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); - shader_code_.push_back(factor_calculation_temp); - shader_code_.push_back( - EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); - shader_code_.push_back(0x3F800000); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1) | - ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); - shader_code_.push_back( - ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER(D3D10_SB_OPERAND_MODIFIER_NEG)); - shader_code_.push_back(factor_calculation_temp); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - - // 3) Min(source alpha, 1 - destination alpha). - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MIN) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(factor_calculation_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(factor_calculation_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); - shader_code_.push_back(factor_calculation_temp); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - - // 4) Extract whether the source and the destination color factors are - // saturate (for alphas, One should be used in this case). - system_constants_used_ |= (1ull << kSysConst_EDRAMBlendRT01_Index) - << (rt_index >> 1); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(12)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0110, 1)); - shader_code_.push_back(factor_calculation_temp); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, (rt_index & 1) * 2, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMBlendRT01_Vec + (rt_index >> 1)); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0); - shader_code_.push_back(kBlendX_Src_SrcAlphaSaturate); - shader_code_.push_back(kBlendX_Dest_SrcAlphaSaturate); - shader_code_.push_back(0); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // 5) Replace the color factors with the saturated alpha. - for (uint32_t i = 0; i < 2; ++i) { - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(i ? dest_factor_and_minmax_temp - : src_factor_and_result_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1 + i, 1)); - shader_code_.push_back(factor_calculation_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(factor_calculation_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(i ? dest_factor_and_minmax_temp - : src_factor_and_result_temp); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - } - - // Multiply the colors by the factors, with 0 * Infinity = 0 behavior. - for (uint32_t i = 0; i < 2; ++i) { - uint32_t factor_temp = - i ? dest_factor_and_minmax_temp : src_factor_and_result_temp; - uint32_t color_temp = i ? dest_color_temp : src_color_and_output_temp; - - // Get the multiplicand closer to zero to check if any of them is zero. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MIN) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(factor_calculation_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1) | - ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); - shader_code_.push_back(ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER( - D3D10_SB_OPERAND_MODIFIER_ABS)); - shader_code_.push_back(color_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1) | - ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); - shader_code_.push_back(ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER( - D3D10_SB_OPERAND_MODIFIER_ABS)); - shader_code_.push_back(factor_temp); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - - // Multiply. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(factor_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(color_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(factor_temp); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - - // Check if the color or the factor is zero to zero the result (min isn't - // required to flush denormals in the result). - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_EQ) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(factor_calculation_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(factor_calculation_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - - // Zero the result if the color or the factor is zero. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(12)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(factor_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(factor_calculation_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(factor_temp); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - // Clamp the color if the components aren't floating-point. - // https://docs.microsoft.com/en-us/windows/desktop/direct3d11/d3d10-graphics-programming-guide-output-merger-stage - CompletePixelShader_WriteToROV_ClampColor(rt_index, factor_temp, - factor_calculation_temp); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(factor_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kROVRTFormatFlagTemp_Fixed_Swizzle, 1)); - shader_code_.push_back(rt_format_flags_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(factor_calculation_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(factor_temp); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - } - - // Apply the signs for addition/subtraction/inverse subtraction and - // add/subtract/inverse subtract (for min/max, this will be overwritten - // later). - CompletePixelShader_WriteToROV_ExtractBlendScales( - rt_index, 0b01010101, true, kBlendY_Src_OpSign_Shift, - kBlendY_SrcAlpha_OpSign_Shift, kBlendY_Dest_OpSign_Shift, - kBlendY_DestAlpha_OpSign_Shift, scale_temp); - - // 1) Apply the source signs (zero is not used, so no need to check). - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(src_factor_and_result_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(src_factor_and_result_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b01000000, 1)); - shader_code_.push_back(scale_temp); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - - // 2) Apply the destination signs and combine. dest_factor_and_minmax_temp - // may be reused for min/max from now on. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(src_factor_and_result_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(dest_factor_and_minmax_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b11101010, 1)); - shader_code_.push_back(scale_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(src_factor_and_result_temp); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - - // Extract whether min/max should be done. - system_constants_used_ |= (1ull << kSysConst_EDRAMBlendRT01_Index) - << (rt_index >> 1); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(12)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(scale_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - (rt_index & 1) ? 0b11111111 : 0b01010101, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMBlendRT01_Vec + (rt_index >> 1)); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(kBlendY_Color_OpMin); - shader_code_.push_back(kBlendY_Alpha_OpMin); - shader_code_.push_back(kBlendY_Color_OpMax); - shader_code_.push_back(kBlendY_Alpha_OpMax); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Replace the result with the minimum or the maximum of the source and the - // destination because min/max don't use factors (also not using anything - // involving multiplication for this so 0 * Infinity may not affect this). - // Final output to src_color_and_output_temp happens here. - for (uint32_t i = 0; i < 2; ++i) { - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE( - i ? D3D10_SB_OPCODE_MAX : D3D10_SB_OPCODE_MIN) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(dest_factor_and_minmax_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(src_color_and_output_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(dest_color_temp); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - // In min, writing to the intermediate result register because max still - // needs the original source color. - // In max, doing the final output. - shader_code_.push_back(i ? src_color_and_output_temp - : src_factor_and_result_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, i ? 0b11101010 : 0b01000000, 1)); - shader_code_.push_back(scale_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(dest_factor_and_minmax_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(src_factor_and_result_temp); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - } - - // Release scale_temp, factor_calculation_temp, src_factor_and_result_temp - // and dest_factor_and_minmax_temp. - PopSystemTemp(4); -} - -void DxbcShaderTranslator::CompletePixelShader_WriteToROV_PackColor( - uint32_t data_low_temp, uint32_t data_high_temp, uint32_t data_component, - uint32_t rt_index, uint32_t rt_format_flags_temp, - uint32_t source_and_scratch_temp) { - // For indexing of the format constants. - uint32_t rt_pair_index = rt_index >> 1; - uint32_t rt_pair_swizzle = rt_index & 1 ? 0b11101010 : 0b01000000; - - // Scale by the fixed-point conversion factor. - system_constants_used_ |= (1ull << kSysConst_EDRAMStoreScaleRT01_Index) - << rt_pair_index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(source_and_scratch_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(source_and_scratch_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_pair_swizzle, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMStoreScaleRT01_Vec + rt_pair_index); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - - // Convert to fixed-point, rounding towards the nearest even integer. - // Rounding towards the nearest (adding +-0.5 before truncating) is giving - // incorrect results for depth, so better to use round_ne here too. - uint32_t fixed_temp = PushSystemTemp(); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ROUND_NE) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(fixed_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(source_and_scratch_temp); - ++stat_.instruction_count; - ++stat_.float_instruction_count; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_FTOI) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(fixed_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(fixed_temp); - ++stat_.instruction_count; - ++stat_.conversion_instruction_count; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(source_and_scratch_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kROVRTFormatFlagTemp_Fixed_Swizzle, 1)); - shader_code_.push_back(rt_format_flags_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(fixed_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(source_and_scratch_temp); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - // Release fixed_temp. - PopSystemTemp(); - - // *************************************************************************** - // 7e3 conversion begins here. - // https://github.com/Microsoft/DirectXTex/blob/master/DirectXTex/DirectXTexConvert.cpp - // *************************************************************************** - - // Check if the target format is 7e3 and the conversion is needed (this is - // pretty long, better to branch here). - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); - shader_code_.push_back(EncodeVectorSelectOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kROVRTFormatFlagTemp_Float10, 1)); - shader_code_.push_back(rt_format_flags_temp); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - - uint32_t f10_temp1 = PushSystemTemp(), f10_temp2 = PushSystemTemp(); - - // Assuming RGB is already clamped to [0.0, 31.875], and alpha is a float and - // already clamped and multiplied by 3 to get [0.0, 3.0]. - - // Calculate the denormalized value if the numbers are too small to be - // represented as normalized 7e3 into f10_temp1. - - // t1 = f32 & 0x7FFFFF - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_temp1); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(source_and_scratch_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0x7FFFFF); - shader_code_.push_back(0x7FFFFF); - shader_code_.push_back(0x7FFFFF); - shader_code_.push_back(0x7FFFFF); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // t1 = (f32 & 0x7FFFFF) | 0x800000 - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_OR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_temp1); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_temp1); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0x800000); - shader_code_.push_back(0x800000); - shader_code_.push_back(0x800000); - shader_code_.push_back(0x800000); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // t2 = f32 >> 23 - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_temp2); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(source_and_scratch_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(23); - shader_code_.push_back(23); - shader_code_.push_back(23); - shader_code_.push_back(23); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // t2 = 125 - (f32 >> 23) - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_temp2); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(125); - shader_code_.push_back(125); - shader_code_.push_back(125); - shader_code_.push_back(125); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1) | - ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); - shader_code_.push_back( - ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER(D3D10_SB_OPERAND_MODIFIER_NEG)); - shader_code_.push_back(f10_temp2); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // Don't allow the shift to overflow, since in DXBC the lower 5 bits of the - // shift amount are used. - // t2 = min(125 - (f32 >> 23), 24) - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_UMIN) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_temp2); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_temp2); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(24); - shader_code_.push_back(24); - shader_code_.push_back(24); - shader_code_.push_back(24); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // t1 = ((f32 & 0x7FFFFF) | 0x800000) >> min(125 - (f32 >> 23), 24) - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_temp1); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_temp1); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_temp2); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Check if the numbers are too small to be represented as normalized 7e3. - // t2 = f32 < 0x3E800000 - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ULT) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_temp2); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(source_and_scratch_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0x3E800000); - shader_code_.push_back(0x3E800000); - shader_code_.push_back(0x3E800000); - shader_code_.push_back(0x3E800000); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Bias the exponent. - // f32 += 0xC2000000 - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(source_and_scratch_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(source_and_scratch_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0xC2000000u); - shader_code_.push_back(0xC2000000u); - shader_code_.push_back(0xC2000000u); - shader_code_.push_back(0xC2000000u); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // Replace the number in f32 with a denormalized one if needed. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(source_and_scratch_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_temp2); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_temp1); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(source_and_scratch_temp); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - // Build the 7e3 numbers. - // t1 = f32 >> 16 - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_temp1); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(source_and_scratch_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(16); - shader_code_.push_back(16); - shader_code_.push_back(16); - shader_code_.push_back(16); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // t1 = (f32 >> 16) & 1 - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(f10_temp1); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_temp1); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(1); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // f10 = f32 + 0x7FFF - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(source_and_scratch_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(source_and_scratch_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0x7FFF); - shader_code_.push_back(0x7FFF); - shader_code_.push_back(0x7FFF); - shader_code_.push_back(0x7FFF); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // f10 = f32 + 0x7FFF + ((f32 >> 16) & 1) - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(source_and_scratch_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(source_and_scratch_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f10_temp1); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // f10 = (f32 + 0x7FFF + ((f32 >> 16) & 1)) >> 16 - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(source_and_scratch_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(source_and_scratch_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(16); - shader_code_.push_back(16); - shader_code_.push_back(16); - shader_code_.push_back(16); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // f10 = ((f32 + 0x7FFF + ((f32 >> 16) & 1)) >> 16) & 0x3FF - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); - shader_code_.push_back(source_and_scratch_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(source_and_scratch_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0x3FF); - shader_code_.push_back(0x3FF); - shader_code_.push_back(0x3FF); - shader_code_.push_back(0x3FF); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Release f10_temp1 and f10_temp2. - PopSystemTemp(2); - - // 7e3 conversion done. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - - // *************************************************************************** - // 7e3 conversion ends here. - // *************************************************************************** - - // Convert to 16-bit float. - uint32_t f16_temp = PushSystemTemp(); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_F32TOF16) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(f16_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(source_and_scratch_temp); - ++stat_.instruction_count; - ++stat_.conversion_instruction_count; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(source_and_scratch_temp); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kROVRTFormatFlagTemp_Float16, 1)); - shader_code_.push_back(rt_format_flags_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(f16_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(source_and_scratch_temp); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - // Release f16_temp. - PopSystemTemp(); - - // Pack and store the lower and the upper 32 bits. - uint32_t pack_temp = PushSystemTemp(); - uint32_t pack_width_temp = PushSystemTemp(); - uint32_t pack_offset_temp = PushSystemTemp(); - - for (uint32_t i = 0; i < 2; ++i) { - if (i != 0) { - // Check if need to store the upper 32 bits. - system_constants_used_ |= 1ull << kSysConst_EDRAMRTPackWidthHigh_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back(EncodeVectorSelectOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMRTPackWidthHigh_Vec); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - } - - // Insert color components into different vector components. - CompletePixelShader_WriteToROV_ExtractPackLayout( - rt_index, i != 0, pack_width_temp, pack_offset_temp); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_BFI) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(14)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(pack_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(pack_width_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(pack_offset_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(source_and_scratch_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // bfi doesn't work with width 32 - handle it specially. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1 << i, 1)); - shader_code_.push_back(pack_width_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(pack_width_temp); - shader_code_.push_back( - EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); - shader_code_.push_back(5); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1 << i, 1)); - shader_code_.push_back(pack_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(pack_width_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(source_and_scratch_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(pack_temp); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - // Merge XY and ZW. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_OR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1)); - shader_code_.push_back(pack_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(pack_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b01001110, 1)); - shader_code_.push_back(pack_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Merge X and Y and into the data register. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_OR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back(EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, - 1 << data_component, 1)); - shader_code_.push_back(i ? data_high_temp : data_low_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(pack_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); - shader_code_.push_back(pack_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - if (i != 0) { - // Upper 32 bits stored. - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - } - } - - // Release pack_temp, pack_width_temp, pack_offset_temp. - PopSystemTemp(3); } void DxbcShaderTranslator::CompletePixelShader_WriteToROV() { - bool color_targets_written; - if (is_depth_only_pixel_shader_) { - color_targets_written = false; + // Discard samples with alpha to coverage. + CompletePixelShader_ROV_AlphaToCoverage(); + + // 2 VGPR (at most, as temp when packing during blending) or 1 SGPR. + uint32_t temp = PushSystemTemp(); + + // Do late depth/stencil test (which includes writing) if needed or deferred + // depth writing. + if (ROV_IsDepthStencilEarly()) { + // Write modified depth/stencil. + for (uint32_t i = 0; i < 4; ++i) { + // Get if need to write to temp1.x. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1 << (4 + i)); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Check if need to write. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(temp); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Write the new depth/stencil. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_STORE_UAV_TYPED) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D11_SB_OPERAND_TYPE_UNORDERED_ACCESS_VIEW, 0b1111, 2)); + shader_code_.push_back(ROV_GetEDRAMUAVIndex()); + shader_code_.push_back(uint32_t(UAVRegister::kEDRAM)); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); + shader_code_.push_back(system_temp_rov_depth_stencil_); + ++stat_.instruction_count; + ++stat_.c_texture_store_instructions; + + // Close the write check. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Go to the next sample (samples are at +0, +80, +1, +81, so need to do + // +80, -79, +80 and -81 after each sample). + if (i < 3) { + system_constants_used_ |= 1ull + << kSysConst_EDRAMResolutionSquareScale_Index; + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IMAD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back((i & 1) ? -78 - i : 80); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMResolutionSquareScale_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMResolutionSquareScale_Vec); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temp_rov_params_); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + } + } } else { - color_targets_written = writes_color_target(0) || writes_color_target(1) || - writes_color_target(2) || writes_color_target(3); + ROV_DepthStencilTest(); } - // *************************************************************************** - // Calculate the offsets for the first sample in the EDRAM. - // *************************************************************************** + // Check if any sample is still covered after depth testing and writing, skip + // color writing completely in this case. + CompletePixelShader_ROV_CheckAnyCovered(false, temp, 0); - uint32_t edram_coord_pixel_temp = PushSystemTemp(); - uint32_t edram_coord_pixel_depth_temp = PushSystemTemp(); + // Apply the exponent bias after alpha to coverage because it needs the + // unbiased alpha from the shader. + for (uint32_t i = 0; i < 4; ++i) { + CompletePixelShader_ApplyColorExpBias(i); + } - // Load SV_Position in edram_coord_pixel_temp.xy as an integer. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_FTOU) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_INPUT, kSwizzleXYZW, 1)); - shader_code_.push_back(uint32_t(InOutRegister::kPSInPosition)); - ++stat_.instruction_count; - ++stat_.conversion_instruction_count; + // Write color values. + for (uint32_t i = 0; i < 4; ++i) { + if (!writes_color_target(i)) { + continue; + } - // Get guest pixel position as if increased resolution is disabled - addresses - // within the quad with 2x resolution will be calculated later. - system_constants_used_ |= 1ull << kSysConst_EDRAMResolutionScaleLog2_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_EDRAMResolutionScaleLog2_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMResolutionScaleLog2_Vec); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; + uint32_t keep_mask_vec = kSysConst_EDRAMRTKeepMask_Vec + (i >> 1); + uint32_t keep_mask_component = (i & 1) * 2; - // Convert the position from pixels to samples. - system_constants_used_ |= 1ull << kSysConst_SampleCountLog2_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ISHL) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_SampleCountLog2_Comp | - ((kSysConst_SampleCountLog2_Comp + 1) << 2), - 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_SampleCountLog2_Vec); - ++stat_.instruction_count; - ++stat_.int_instruction_count; + // Check if color writing is disabled - special keep mask constant case, + // both 32bpp parts are forced UINT32_MAX, but also check whether the shader + // has written anything to this target at all. - // Load X tile index to edram_coord_pixel_temp.z, part 1 of the division by - // 80 - get the high 32 bits of the result of the multiplication by - // 0xCCCCCCCD. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_UMUL) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0100, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back( - EncodeZeroComponentOperand(D3D10_SB_OPERAND_TYPE_NULL, 0)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back( - EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); - shader_code_.push_back(0xCCCCCCCDu); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Load tile index to edram_coord_pixel_temp.zw. Part 2 of the division by - // 80 - right shift the high bits of x*0xCCCCCCCD by 6. And divide by 16 by - // right shifting by 4. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1100, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b01100100, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(6); - shader_code_.push_back(4); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Write tile-relative offset to XY. Subtract the tile index * 80x16 from the - // position. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IMAD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(12)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b11101110, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(uint32_t(-80)); - shader_code_.push_back(uint32_t(-16)); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // Multiply tile Y index by the pitch and add X tile index to it to - // edram_coord_pixel_temp.z. - system_constants_used_ |= 1ull << kSysConst_EDRAMPitchTiles_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_UMAD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0100, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_EDRAMPitchTiles_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMPitchTiles_Vec); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Swap 40 sample columns within the tile for the depth buffer into - // edram_coord_pixel_depth_temp.x - shaders uploading depth to the EDRAM by - // aliasing a color render target expect this. - - // 1) Check in which half of the tile the sample is. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ULT) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(edram_coord_pixel_depth_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back( - EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); - shader_code_.push_back(40); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // 2) Get the value to add to the tile-relative X sample index. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(edram_coord_pixel_depth_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(edram_coord_pixel_depth_temp); - shader_code_.push_back( - EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); - shader_code_.push_back(40); - shader_code_.push_back( - EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); - shader_code_.push_back(uint32_t(-40)); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - // 3) Actually swap the 40 sample columns. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(edram_coord_pixel_depth_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(edram_coord_pixel_depth_temp); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // Calculate the address in the EDRAM buffer. - - if (color_targets_written) { - // 1a) Get dword offset within the tile to edram_coord_pixel_temp.x. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_UMAD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + // Combine both parts of the keep mask to check if both are 0xFFFFFFFF. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTKeepMask_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); shader_code_.push_back( EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back( - EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); - shader_code_.push_back(80); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - } - - // 1b) Do the same for depth/stencil to edram_coord_pixel_depth_temp.x. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_UMAD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(edram_coord_pixel_depth_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back( - EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); - shader_code_.push_back(80); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(edram_coord_pixel_depth_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - if (color_targets_written) { - // 2a) Combine the tile offset and the offset within the tile to - // edram_coord_pixel_temp.x. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_UMAD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back( - EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); - shader_code_.push_back(1280); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - } - - // 2b) Do the same for depth/stencil to edram_coord_pixel_depth_temp.x. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_UMAD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(edram_coord_pixel_depth_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back( - EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); - shader_code_.push_back(1280); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(edram_coord_pixel_depth_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Adjust the offsets for 64 bits per pixel, and add EDRAM bases of color - // render targets. - - uint32_t rt_64bpp_temp = 0; - - if (color_targets_written) { - rt_64bpp_temp = PushSystemTemp(); - - // Get which render targets are 64bpp, as log2 of dword count per pixel. - system_constants_used_ |= 1ull << kSysConst_EDRAMRTPackWidthHigh_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(17)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(rt_64bpp_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, kSwizzleXYZW, 3)); + shader_code_.push_back(temp); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, keep_mask_component, 3)); shader_code_.push_back(cbuffer_index_system_constants_); shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMRTPackWidthHigh_Vec); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); + shader_code_.push_back(keep_mask_vec); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, keep_mask_component + 1, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(keep_mask_vec); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Flip the bits so both UINT32_MAX would result in 0 - not writing. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_NOT) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(temp); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Get the bits that will be used for checking wherther the render target + // has been written to on the taken execution path - if the write mask is + // empty, AND zero with the test bit to always get zero. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); shader_code_.push_back(0); ++stat_.instruction_count; ++stat_.movc_instruction_count; - // Multiply the offsets by 1 or 2 depending on the number of bits per pixel. - // It's okay to do this here because everything in the equation (at least - // for Xenia's representation of the EDRAM - may not be true on the real - // console) needs to be multiplied by 2 - Y tile index (the same as - // multipying the pitch by 2), X tile index (it addresses pairs of tiles in - // this case), and the offset within a pair of tiles. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ISHL) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(rt_64bpp_temp); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // Add the EDRAM bases for each render target. - system_constants_used_ |= 1ull << kSysConst_EDRAMBaseDwords_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, kSwizzleXYZW, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMBaseDwords_Vec); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - } - - // Add the EDRAM base for depth. - system_constants_used_ |= 1ull << kSysConst_EDRAMDepthBaseDwords_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(edram_coord_pixel_depth_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(edram_coord_pixel_depth_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_EDRAMDepthBaseDwords_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMDepthBaseDwords_Vec); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // Perform all the depth/stencil-related operations, and get the samples that - // have passed the depth test. - uint32_t coverage_temp = PushSystemTemp(); - CompletePixelShader_WriteToROV_GetCoverage(coverage_temp); - CompletePixelShader_WriteToROV_DepthStencil(edram_coord_pixel_depth_temp, - coverage_temp); - - // *************************************************************************** - // Write to color render targets. - // *************************************************************************** - - if (color_targets_written) { - // Apply the exponent bias after having done alpha to coverage, which needs - // the original alpha from the shader. - CompletePixelShader_ApplyColorExpBias(); - - system_constants_used_ |= 1ull << kSysConst_EDRAMRTFlags_Index; - - // Get if any sample is covered to exit earlier if all have failed the depth - // test: samples 02 and 13. - uint32_t coverage_any_temp = PushSystemTemp(); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_OR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1)); - shader_code_.push_back(coverage_any_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(coverage_temp); - shader_code_.push_back( - EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b01001110, 1)); - shader_code_.push_back(coverage_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Get if any sample is covered. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_OR) | + // Check if the render target was written to on the execution path. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); shader_code_.push_back( EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(coverage_any_temp); + shader_code_.push_back(temp); shader_code_.push_back( EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(coverage_any_temp); + shader_code_.push_back(temp); shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); - shader_code_.push_back(coverage_any_temp); + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1 << (8 + i)); ++stat_.instruction_count; ++stat_.uint_instruction_count; - // Discard the pixel if it's not covered. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_RETC) | + // Check if need to write anything to the render target. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_ZERO) | + D3D10_SB_INSTRUCTION_TEST_NONZERO) | ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); shader_code_.push_back( EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(coverage_any_temp); + shader_code_.push_back(temp); ++stat_.instruction_count; ++stat_.dynamic_flow_control_count; - // Release coverage_any_temp. - PopSystemTemp(); - - // Mask disabled color writes. - uint32_t rt_write_masks_temp = PushSystemTemp(); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(12)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(rt_write_masks_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, kSwizzleXYZW, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMRTFlags_Vec); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(kRTFlag_WriteR_Shift); - shader_code_.push_back(kRTFlag_WriteR_Shift); - shader_code_.push_back(kRTFlag_WriteR_Shift); - shader_code_.push_back(kRTFlag_WriteR_Shift); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(system_temp_color_written_); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(system_temp_color_written_); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(rt_write_masks_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Prevent going out of EDRAM bounds. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ULT) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(rt_write_masks_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(1280 * 2048); - shader_code_.push_back(1280 * 2048); - shader_code_.push_back(1280 * 2048); - shader_code_.push_back(1280 * 2048); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(system_temp_color_written_); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(system_temp_color_written_); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(rt_write_masks_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Release rt_write_masks_temp. - PopSystemTemp(); - - // Apply pixel width and height scale. - system_constants_used_ |= 1ull << kSysConst_EDRAMResolutionScaleLog2_Index; - for (uint32_t i = 0; i < 2; ++i) { - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ISHL) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_EDRAMResolutionScaleLog2_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMResolutionScaleLog2_Vec); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - } - - // Choose the pixel for 2x scaling. - uint32_t resolution_scale_pixel_temp = PushSystemTemp(); - - // 1) Convert pixel position to integer. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_FTOU) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1)); - shader_code_.push_back(resolution_scale_pixel_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_INPUT, kSwizzleXYZW, 1)); - shader_code_.push_back(uint32_t(InOutRegister::kPSInPosition)); - ++stat_.instruction_count; - ++stat_.conversion_instruction_count; - - // 2) For 2x, get the current pixel in the quad. For 1x, write 0 for it. - system_constants_used_ |= 1ull << kSysConst_EDRAMResolutionScaleLog2_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + // Add the EDRAM bases of the render target to system_temp_rov_params_.zw. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTBaseDwordsScaled_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1)); - shader_code_.push_back(resolution_scale_pixel_temp); + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1100, 1)); + shader_code_.push_back(system_temp_rov_params_); shader_code_.push_back(EncodeVectorSwizzledOperand( D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(resolution_scale_pixel_temp); + shader_code_.push_back(system_temp_rov_params_); shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_EDRAMResolutionScaleLog2_Comp, 3)); + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, i, 3)); shader_code_.push_back(cbuffer_index_system_constants_); shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMResolutionScaleLog2_Vec); + shader_code_.push_back(kSysConst_EDRAMRTBaseDwordsScaled_Vec); ++stat_.instruction_count; - ++stat_.uint_instruction_count; + ++stat_.int_instruction_count; - // 3) Calculate dword offset of the pixel in the quad. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_UMAD) | + // Get if not blending to pack the color once for all 4 samples. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTBlendFactorsOps_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IEQ) | ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); shader_code_.push_back( EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(resolution_scale_pixel_temp); + shader_code_.push_back(temp); shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); - shader_code_.push_back(resolution_scale_pixel_temp); + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, i, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTBlendFactorsOps_Vec); shader_code_.push_back( EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); - shader_code_.push_back(2); + shader_code_.push_back(0x00010001); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Check if not blending. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); shader_code_.push_back( EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(resolution_scale_pixel_temp); + shader_code_.push_back(temp); ++stat_.instruction_count; - ++stat_.uint_instruction_count; + ++stat_.dynamic_flow_control_count; - // 4) Multiply the quad pixel offset by dword count per pixel for each RT. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ISHL) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(resolution_scale_pixel_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(resolution_scale_pixel_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(rt_64bpp_temp); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // 5) Add the quad pixel offsets. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(resolution_scale_pixel_temp); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // Release resolution_scale_pixel_temp. - PopSystemTemp(); - - // Get what render targets need gamma conversion. - uint32_t rt_gamma_temp = PushSystemTemp(); - system_constants_used_ |= 1ull << kSysConst_Flags_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(12)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(rt_gamma_temp); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, kSysConst_Flags_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_Flags_Vec); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(kSysFlag_Color0Gamma); - shader_code_.push_back(kSysFlag_Color1Gamma); - shader_code_.push_back(kSysFlag_Color2Gamma); - shader_code_.push_back(kSysFlag_Color3Gamma); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Get what render targets need blending (if only write mask is used and no - // blending, skip blending). - uint32_t rt_blend_temp = PushSystemTemp(); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(12)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(rt_blend_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, kSwizzleXYZW, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMRTFlags_Vec); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(kRTFlag_Blend); - shader_code_.push_back(kRTFlag_Blend); - shader_code_.push_back(kRTFlag_Blend); - shader_code_.push_back(kRTFlag_Blend); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Get what render targets need to be read (for write mask and blending). - uint32_t rt_overwritten_temp = PushSystemTemp(); - // First, ignore components that don't exist in the render target at all - - // treat them as overwritten. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_UBFE) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(17)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(rt_overwritten_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(4); - shader_code_.push_back(4); - shader_code_.push_back(4); - shader_code_.push_back(4); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(kRTFlag_FormatUnusedR_Shift); - shader_code_.push_back(kRTFlag_FormatUnusedR_Shift); - shader_code_.push_back(kRTFlag_FormatUnusedR_Shift); - shader_code_.push_back(kRTFlag_FormatUnusedR_Shift); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, kSwizzleXYZW, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMRTFlags_Vec); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_OR) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(rt_overwritten_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(system_temp_color_written_); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(rt_overwritten_temp); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - // Then, check if the write mask + unused components is 1111 - if yes (and - // not blending), the pixel will be totally overwritten and no need to load - // the old pixel value. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IEQ) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(rt_overwritten_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(rt_overwritten_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0b1111); - shader_code_.push_back(0b1111); - shader_code_.push_back(0b1111); - shader_code_.push_back(0b1111); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - // Force load the previous pixel if blending. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(12)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(rt_overwritten_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(rt_blend_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(0); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(rt_overwritten_temp); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - for (uint32_t i = 0; i < 4; ++i) { - if (!writes_color_target(i)) { - continue; - } - - // Check if the render target needs to be written to. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + // Clamp the color to the render target's representable range - will be + // packed. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTClamp_Index; + for (uint32_t j = 0; j < 2; ++j) { shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(system_temp_color_written_); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - - // Load the format flags: - // X - color is fixed-point (kROVRTFormatFlagTemp_ColorFixed). - // Y - alpha is fixed-point (kROVRTFormatFlagTemp_AlphaFixed). - // Z - format is 2:10:10:10 floating-point (kROVRTFormatFlagTemp_Float10). - // W - format is 16-bit floating-point (kROVRTFormatFlagTemp_Float16). - uint32_t format_flags_temp = PushSystemTemp(); - system_constants_used_ |= 1ull << kSysConst_EDRAMRTFlags_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(12)); + ENCODE_D3D10_SB_OPCODE_TYPE(j ? D3D10_SB_OPCODE_MIN + : D3D10_SB_OPCODE_MAX) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); shader_code_.push_back( EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(format_flags_temp); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, i, 3)); + shader_code_.push_back(system_temps_color_[i]); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temps_color_[i]); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + j ? 0b11101010 : 0b01000000, 3)); shader_code_.push_back(cbuffer_index_system_constants_); shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMRTFlags_Vec); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(kRTFlag_FormatFixed); - shader_code_.push_back(kRTFlag_FormatFixed | kRTFlag_FormatFloat10); - shader_code_.push_back(kRTFlag_FormatFloat10); - shader_code_.push_back(kRTFlag_FormatFloat16); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - // Get per-sample EDRAM addresses offsets. - uint32_t edram_coord_sample_temp = PushSystemTemp(); - - // 1) Choose the strides according to the resolution scale (1x or 2x2x). - system_constants_used_ |= 1ull - << kSysConst_EDRAMResolutionScaleLog2_Index; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(17)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(edram_coord_sample_temp); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, - kSysConst_EDRAMResolutionScaleLog2_Comp, 3)); - shader_code_.push_back(cbuffer_index_system_constants_); - shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); - shader_code_.push_back(kSysConst_EDRAMResolutionScaleLog2_Vec); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0); - shader_code_.push_back(320); - shader_code_.push_back(4); - shader_code_.push_back(324); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(0); - shader_code_.push_back(80); - shader_code_.push_back(1); - shader_code_.push_back(81); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - // 2) Multiply the relative sample offset by sample size. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ISHL) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(edram_coord_sample_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(edram_coord_sample_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(rt_64bpp_temp); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // 3) Add the first sample EDRAM addresses to the sample offsets. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(edram_coord_sample_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(edram_coord_pixel_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(edram_coord_sample_temp); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - // Allocate registers for raw pixel data (lower 32 bits and, if needed, - // upper 32 bits) for reading and writing pixel data (can't really access - // ROV in a loop, it seems, at least on Nvidia as of November 13, 2018 - - // generating an access violation in pipeline creation). - uint32_t data_low_temp = PushSystemTemp(); - uint32_t data_high_temp = PushSystemTemp(); - - // Check if need to load the previous values in the render target. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_ZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(rt_overwritten_temp); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - - // Lower/upper bits loop of render target loading. - for (uint32_t j = 0; j < 2; ++j) { - // Only load the upper 32 bits if the format is 64bpp, and adjust the - // addresses to the upper 32 bits. - if (j != 0) { - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(rt_64bpp_temp); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(edram_coord_sample_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(edram_coord_sample_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(1); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - } - - // Sample loop. - // The `if`s are REQUIRED - interlocking is done per-sample, not - // per-pixel! - for (uint32_t k = 0; k < 4; ++k) { - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, k, 1)); - shader_code_.push_back(coverage_temp); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_LD_UAV_TYPED) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1 << k, 1)); - shader_code_.push_back(j ? data_high_temp : data_low_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, k, 1)); - shader_code_.push_back(edram_coord_sample_temp); - shader_code_.push_back(EncodeVectorReplicatedOperand( - D3D11_SB_OPERAND_TYPE_UNORDERED_ACCESS_VIEW, 0, 2)); - shader_code_.push_back(GetEDRAMUAVIndex()); - shader_code_.push_back(uint32_t(UAVRegister::kEDRAM)); - ++stat_.instruction_count; - ++stat_.texture_load_instructions; - - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - } - - // Restore the addresses for the lower 32 bits, since they're needed for - // storing, and close the 64bpp conditional. - if (j != 0) { - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(edram_coord_sample_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(edram_coord_sample_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(uint32_t(-1)); - shader_code_.push_back(uint32_t(-1)); - shader_code_.push_back(uint32_t(-1)); - shader_code_.push_back(uint32_t(-1)); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - } - } - - // Done loading the previous values as raw. - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - - // Begin the coverage loop. - uint32_t samples_remaining_temp = PushSystemTemp(); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(samples_remaining_temp); - shader_code_.push_back( - EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); - shader_code_.push_back(4); - ++stat_.instruction_count; - ++stat_.mov_instruction_count; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_LOOP) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - - // Check if the sample is covered. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(coverage_temp); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - - // Allocate temporary registers for the new color (so it can be used as - // scratch with blending, which may give different results for different - // samples), for loading the previous color and for the write mask. This - // is done because some operations - clamping, gamma correction - should - // be done only for the source color. If no need to get the previous - // color, will just assume use the 1111 write mask for the movc. - uint32_t src_color_temp = PushSystemTemp(); - uint32_t dest_color_temp = PushSystemTemp(); - uint32_t write_mask_temp = PushSystemTemp(); - - // Copy the pixel color to the per-sample scratch. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(src_color_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(system_temps_color_ + i); - ++stat_.instruction_count; - ++stat_.mov_instruction_count; - - // Check if need to process the previous value in the render target. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_ZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(rt_overwritten_temp); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - - // Unpack the previous value in the render target to blend and to apply - // the write mask. - CompletePixelShader_WriteToROV_UnpackColor(data_low_temp, data_high_temp, - 0, i, format_flags_temp, - dest_color_temp); - - // Blend if needed. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(rt_blend_temp); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - // Convert the destination to linear before blending - to an intermediate - // register because write masking will use dest_color_temp too. - // https://steamcdn-a.akamaihd.net/apps/valve/2008/GDC2008_PostProcessingInTheOrangeBox.pdf - uint32_t dest_color_linear_temp = PushSystemTemp(); - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(dest_color_linear_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(dest_color_temp); - ++stat_.instruction_count; - ++stat_.mov_instruction_count; - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(rt_gamma_temp); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - CompletePixelShader_GammaCorrect(dest_color_linear_temp, false); - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - CompletePixelShader_WriteToROV_Blend(i, format_flags_temp, src_color_temp, - dest_color_linear_temp); - - // Release dest_color_linear_temp. - PopSystemTemp(); - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - - // Mask the components to overwrite. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(write_mask_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(system_temp_color_written_); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(1 << 0); - shader_code_.push_back(1 << 1); - shader_code_.push_back(1 << 2); - shader_code_.push_back(1 << 3); - ++stat_.instruction_count; - ++stat_.uint_instruction_count; - - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - - // If not using the previous color, set the write mask to 1111 to ignore - // the uninitialized register with the previous color. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(write_mask_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(1); - ++stat_.instruction_count; - ++stat_.mov_instruction_count; - - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - - // Clamp to the representable range after blending (for float10 and - // float16, clamping must not be done during blending) and before storing. - CompletePixelShader_WriteToROV_ClampColor(i, src_color_temp, - src_color_temp); - - // Convert to gamma space after blending. - // https://steamcdn-a.akamaihd.net/apps/valve/2008/GDC2008_PostProcessingInTheOrangeBox.pdf - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(rt_gamma_temp); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - CompletePixelShader_GammaCorrect(src_color_temp, true); - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - - // Keep previous values of the components where needed. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(src_color_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(write_mask_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(src_color_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(dest_color_temp); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - - // Write the new color, which may have been modified by blending. - CompletePixelShader_WriteToROV_PackColor(data_low_temp, data_high_temp, 0, - i, format_flags_temp, - src_color_temp); - - // Release src_color_temp, dest_color_temp and write_mask_temp. - PopSystemTemp(3); - - // Close the conditional for whether the sample is covered. - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - - // Go to the next coverage loop iteration - rotate coverage and packed - // color values (after 4 iterations they will be back to normal). - uint32_t rotate_temps[] = {coverage_temp, data_low_temp, data_high_temp}; - for (uint32_t j = 0; j < xe::countof(rotate_temps); ++j) { - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(rotate_temps[j]); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, 0b00111001, 1)); - shader_code_.push_back(rotate_temps[j]); - ++stat_.instruction_count; - ++stat_.mov_instruction_count; - } - - // Check if this is the last sample to process and break. - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(samples_remaining_temp); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(samples_remaining_temp); - shader_code_.push_back( - EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); - shader_code_.push_back(uint32_t(-1)); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_BREAKC) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_ZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(samples_remaining_temp); - ++stat_.instruction_count; - - // Close the coverage loop. - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDLOOP) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - - // Store the new color values. Lower/upper bits loop. - for (uint32_t j = 0; j < 2; ++j) { - // Only store the upper 32 bits if the format is 64bpp, and adjust the - // addresses to the upper 32 bits. - if (j != 0) { - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, i, 1)); - shader_code_.push_back(rt_64bpp_temp); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1)); - shader_code_.push_back(edram_coord_sample_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); - shader_code_.push_back(edram_coord_sample_temp); - shader_code_.push_back(EncodeVectorSwizzledOperand( - D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(1); - shader_code_.push_back(1); - ++stat_.instruction_count; - ++stat_.int_instruction_count; - } - - // Sample loop. - // The `if`s are REQUIRED - interlocking is done per-sample, - // not per-pixel! - for (uint32_t k = 0; k < 4; ++k) { - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | - ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( - D3D10_SB_INSTRUCTION_TEST_NONZERO) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, k, 1)); - shader_code_.push_back(coverage_temp); - ++stat_.instruction_count; - ++stat_.dynamic_flow_control_count; - - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_STORE_UAV_TYPED) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); - shader_code_.push_back(EncodeVectorMaskedOperand( - D3D11_SB_OPERAND_TYPE_UNORDERED_ACCESS_VIEW, 0b1111, 2)); - shader_code_.push_back(GetEDRAMUAVIndex()); - shader_code_.push_back(uint32_t(UAVRegister::kEDRAM)); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, k, 1)); - shader_code_.push_back(edram_coord_sample_temp); - shader_code_.push_back( - EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, k, 1)); - shader_code_.push_back(j ? data_high_temp : data_low_temp); - ++stat_.instruction_count; - ++stat_.c_texture_store_instructions; - - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - } - - // Close the 64bpp conditional. No need to subtract 1 from the sample - // EDRAM addresses since we don't need them anymore for the current - // render target. - if (j != 0) { - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); - ++stat_.instruction_count; - } - } - - // Release format_flags_temp, edram_coord_sample_temp, data_low_temp, - // data_high_temp and samples_remaining_temp. - PopSystemTemp(5); - - // Close the check whether the RT is used. - shader_code_.push_back( - ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + shader_code_.push_back(kSysConst_EDRAMRTClamp_Vec + i); ++stat_.instruction_count; + ++stat_.float_instruction_count; } - // Release rt_gamma_temp, rt_blend_temp and rt_overwritten_temp. - PopSystemTemp(3); + // Pack the color once if blending. + ROV_PackPreClampedColor(i, system_temps_color_[i], system_temps_subroutine_, + 0, temp, 0, temp, 1); + + // Blending is enabled. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Get if the blending source color is fixed-point for clamping if it is. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTFormatFlags_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, i, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTFormatFlags_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(kRTFormatFlag_FixedPointColor); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Check if the blending source color is fixed-point and needs clamping. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(temp); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Clamp the blending source color if needed. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTClamp_Index; + for (uint32_t j = 0; j < 2; ++j) { + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(j ? D3D10_SB_OPCODE_MIN + : D3D10_SB_OPCODE_MAX) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(system_temps_color_[i]); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temps_color_[i]); + shader_code_.push_back(EncodeVectorReplicatedOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, j * 2, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTClamp_Vec + i); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + } + + // Close the fixed-point color check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Get if the blending source alpha is fixed-point for clamping if it is. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTFormatFlags_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, i, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTFormatFlags_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(kRTFormatFlag_FixedPointAlpha); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Check if the blending source alpha is fixed-point and needs clamping. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(temp); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Clamp the blending source alpha if needed. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTClamp_Index; + for (uint32_t j = 0; j < 2; ++j) { + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(j ? D3D10_SB_OPCODE_MIN + : D3D10_SB_OPCODE_MAX) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_color_[i]); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_color_[i]); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, j * 2 + 1, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTClamp_Vec + i); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + } + + // Close the fixed-point alpha check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Break register dependency in the color sample subroutine. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); + shader_code_.push_back(0); + shader_code_.push_back(0); + shader_code_.push_back(0); + shader_code_.push_back(0); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + + // Close the blending check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Blend, mask and write all samples. + for (uint32_t j = 0; j < 4; ++j) { + // Get if the sample is covered. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(temp); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1 << j); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Do ROP for the sample if it's covered. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CALLC) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(temp); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_LABEL, 1)); + shader_code_.push_back(label_rov_color_sample_[i]); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Go to the next sample (samples are at +0, +80, +1, +81, so need to do + // +80, -79, +80 and -81 after each sample). + system_constants_used_ |= 1ull + << kSysConst_EDRAMResolutionSquareScale_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IMAD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(14)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1100, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); + shader_code_.push_back(0); + shader_code_.push_back(0); + shader_code_.push_back(uint32_t((j & 1) ? -78 - j : 80)); + shader_code_.push_back(uint32_t(((j & 1) ? -78 - j : 80) * 2)); + shader_code_.push_back(EncodeVectorReplicatedOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMResolutionSquareScale_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMResolutionSquareScale_Vec); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temp_rov_params_); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + } + + // Revert adding the EDRAM bases of the render target to + // system_temp_rov_params_.zw. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTBaseDwordsScaled_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1100, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back(EncodeVectorReplicatedOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, i, 3) | + ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); + shader_code_.push_back(ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER( + D3D10_SB_OPERAND_MODIFIER_NEG)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTBaseDwordsScaled_Vec); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Close the render target write check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; } - // Release edram_coord_pixel_temp, edram_coord_pixel_depth_temp, - // coverage_temp, and, if used, rt_64bpp_temp. - PopSystemTemp(color_targets_written ? 4 : 3); + // Release temp. + PopSystemTemp(); } void DxbcShaderTranslator::CompletePixelShader() { @@ -6084,7 +4756,7 @@ void DxbcShaderTranslator::CompletePixelShader() { } shader_code_.push_back( EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); - shader_code_.push_back(system_temps_color_); + shader_code_.push_back(system_temps_color_[0]); if (i == 0) { // Alpha < reference. shader_code_.push_back( @@ -6153,7 +4825,7 @@ void DxbcShaderTranslator::CompletePixelShader() { ++stat_.instruction_count; ++stat_.uint_instruction_count; } - // Discard the pixel if has failed the text. + // Discard the pixel if has failed the test. shader_code_.push_back( ENCODE_D3D10_SB_OPCODE_TYPE(edram_rov_used_ ? D3D10_SB_OPCODE_RETC : D3D10_SB_OPCODE_DISCARD) | @@ -6185,5 +4857,3283 @@ void DxbcShaderTranslator::CompletePixelShader() { } } +void DxbcShaderTranslator::CompleteShaderCode_ROV_DepthTo24BitSubroutine() { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_LABEL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back(EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_LABEL, 1)); + shader_code_.push_back(label_rov_depth_to_24bit_); + + // Extract the depth format to Y. Take 1 SGPR. + system_constants_used_ |= 1ull << kSysConst_Flags_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, kSysConst_Flags_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_Flags_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(kSysFlag_ROVDepthFloat24); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Convert according to the format. Release 1 SGPR. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // *************************************************************************** + // 20e4 conversion begins here, using 1 VGPR. + // CFloat24 from d3dref9.dll. + // *************************************************************************** + + // Assuming the depth is already clamped to [0, 2) (in all places, the depth + // is written with the saturate flag set). + + // Check if the number is too small to be represented as normalized 20e4. + // Y = f32 < 0x38800000 + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ULT) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0x38800000); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Handle denormalized numbers separately. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Y = f32 >> 23 + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(23); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Y = 113 - (f32 >> 23) + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(113); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1) | + ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); + shader_code_.push_back( + ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER(D3D10_SB_OPERAND_MODIFIER_NEG)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Don't allow the shift to overflow, since in DXBC the lower 5 bits of the + // shift amount are used (otherwise 0 becomes 8). + // Y = min(113 - (f32 >> 23), 24) + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_UMIN) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(24); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // biased_f32 = (f32 & 0x7FFFFF) | 0x800000 + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_BFI) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(9); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(23); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // biased_f32 = ((f32 & 0x7FFFFF) | 0x800000) >> min(113 - (f32 >> 23), 24) + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Not denormalized? + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Bias the exponent. + // biased_f32 = f32 + 0xC8000000 + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0xC8000000u); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Close the denormal check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Build the 20e4 number. + // Y = (biased_f32 >> 3) & 1 + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_UBFE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(3); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // f24 = biased_f32 + 3 + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(3); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // f24 = biased_f32 + 3 + ((biased_f32 >> 3) & 1) + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // f24 = ((biased_f32 + 3 + ((biased_f32 >> 3) & 1)) >> 3) & 0xFFFFFF + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_UBFE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(24); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(3); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // *************************************************************************** + // 20e4 conversion ends here. + // *************************************************************************** + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // *************************************************************************** + // Unorm24 conversion begins here. + // *************************************************************************** + + // Multiply by float(0xFFFFFF). + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0x4B7FFFFF); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Round to the nearest even integer. This seems to be the correct way: + // rounding towards zero gives 0xFF instead of 0x100 in clear shaders in, for + // instance, Halo 3, but other clear shaders in it are also broken if 0.5 is + // added before ftou instead of round_ne. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ROUND_NE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Convert to fixed-point. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_FTOU) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.conversion_instruction_count; + + // *************************************************************************** + // Unorm24 conversion ends here. + // *************************************************************************** + + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // End the subroutine. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_RET) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; +} + +void DxbcShaderTranslator:: + CompleteShaderCode_ROV_DepthStencilSampleSubroutine() { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_LABEL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back(EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_LABEL, 1)); + shader_code_.push_back(label_rov_depth_stencil_sample_); + + // Load the old depth/stencil value to VGPR [0].z. + // VGPR [0].x = new depth + // VGPR [0].z = old depth/stencil + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_LD_UAV_TYPED) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0100, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back(EncodeVectorReplicatedOperand( + D3D11_SB_OPERAND_TYPE_UNORDERED_ACCESS_VIEW, 0, 2)); + shader_code_.push_back(ROV_GetEDRAMUAVIndex()); + shader_code_.push_back(uint32_t(UAVRegister::kEDRAM)); + ++stat_.instruction_count; + ++stat_.texture_load_instructions; + + // Extract the old depth part to VGPR [0].w. + // VGPR [0].x = new depth + // VGPR [0].z = old depth/stencil + // VGPR [0].w = old depth + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(8); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Get the difference between the new and the old depth, > 0 - greater, == 0 - + // equal, < 0 - less, to VGPR [1].x. + // VGPR [0].x = new depth + // VGPR [0].z = old depth/stencil + // VGPR [0].w = old depth + // VGPR [1].x = depth difference + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1) | + ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); + shader_code_.push_back( + ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER(D3D10_SB_OPERAND_MODIFIER_NEG)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Check if the depth is "less" or "greater or equal" to VGPR [0].y. + // VGPR [0].x = new depth + // VGPR [0].y = depth difference less than 0 + // VGPR [0].z = old depth/stencil + // VGPR [0].w = old depth + // VGPR [1].x = depth difference + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ILT) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Choose the passed depth function bits for "less" or for "greater" to VGPR + // [0].y. + // VGPR [0].x = new depth + // VGPR [0].y = depth function passed bits for "less" or "greater" + // VGPR [0].z = old depth/stencil + // VGPR [0].w = old depth + // VGPR [1].x = depth difference + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(kSysFlag_ROVDepthPassIfLess); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(kSysFlag_ROVDepthPassIfGreater); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + + // Do the "equal" testing to VGPR [0].y. + // VGPR [0].x = new depth + // VGPR [0].y = depth function passed bits + // VGPR [0].z = old depth/stencil + // VGPR [0].w = old depth + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(kSysFlag_ROVDepthPassIfEqual); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + + // Mask the resulting bits with the ones that should pass to VGPR [0].y. + // VGPR [0].x = new depth + // VGPR [0].y = masked depth function passed bits + // VGPR [0].z = old depth/stencil + // VGPR [0].w = old depth + system_constants_used_ |= 1ull << kSysConst_Flags_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, kSysConst_Flags_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_Flags_Vec); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Set bit 0 of the result to 0 (passed) or 1 (reject) based on the result of + // the depth test. + // VGPR [0].x = new depth + // VGPR [0].y = depth test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = old depth + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + + // If the depth test has failed, don't change the depth. + // VGPR [0].x = new depth + // VGPR [0].y = depth test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = old depth + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + + // Extract the depth write flag to SGPR [1].x. + // VGPR [0].x = new depth + // VGPR [0].y = depth test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = old depth + // SGPR [1].x = depth write mask + system_constants_used_ |= 1ull << kSysConst_Flags_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, kSysConst_Flags_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_Flags_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(kSysFlag_ROVDepthWrite); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // If depth writing is disabled, don't change the depth. + // VGPR [0].x = new depth + // VGPR [0].y = depth test failure + // VGPR [0].z = old depth/stencil + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + + // Create packed depth/stencil, with the stencil value unchanged at this + // point. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth test failure + // VGPR [0].z = old depth/stencil + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_BFI) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(24); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(8); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Extract the stencil test bit to SGPR [0].w. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth test failure + // VGPR [0].z = old depth/stencil + // SGPR [0].w = stencil test enabled + system_constants_used_ |= 1ull << kSysConst_Flags_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, kSysConst_Flags_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_Flags_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(kSysFlag_ROVStencilTest); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Check if stencil test is enabled. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth test failure + // VGPR [0].z = old depth/stencil + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Copy the read-masked stencil reference to SGPR [0].w. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth test failure + // VGPR [0].z = old depth/stencil + // SGPR [0].w = read-masked stencil reference + // TODO(Triang3l): Front/back face. + system_constants_used_ |= (1ull << kSysConst_EDRAMStencilReference_Index) | + (1ull << kSysConst_EDRAMStencilReadMask_Index); + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMStencilReference_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMStencilReference_Vec); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMStencilReadMask_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMStencilReadMask_Vec); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Read-mask the old stencil value to VGPR [1].x. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth test failure + // VGPR [0].z = old depth/stencil + // SGPR [0].w = read-masked stencil reference + // VGPR [1].x = read-masked old stencil + // TODO(Triang3l): Front/back face. + system_constants_used_ |= 1ull << kSysConst_EDRAMStencilReadMask_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMStencilReadMask_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMStencilReadMask_Vec); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Get the difference between the new and the old stencil, > 0 - greater, + // == 0 - equal, < 0 - less, to VGPR [0].w. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = stencil difference + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1) | + ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); + shader_code_.push_back( + ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER(D3D10_SB_OPERAND_MODIFIER_NEG)); + shader_code_.push_back(system_temps_subroutine_ + 1); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Check if the stencil is "less" or "greater or equal" to VGPR [1].x. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = stencil difference + // VGPR [1].x = stencil difference less than 0 + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ILT) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Choose the passed depth function bits for "less" or for "greater" to VGPR + // [0].y. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = stencil difference + // VGPR [1].x = stencil function passed bits for "less" or "greater" + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0b001); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0b100); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + + // Do the "equal" testing to VGPR [0].w. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = stencil function passed bits + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0b010); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + + // Get the stencil function bits to SGPR [1].x. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = stencil function passed bits + // SGPR [1].x = stencil function + system_constants_used_ |= (1ull << kSysConst_EDRAMStencilFront_Index) | + (1ull << kSysConst_EDRAMStencilBack_Index); + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(13)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_INPUT, 0, 1)); + shader_code_.push_back(uint32_t(InOutRegister::kPSInFrontFace)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMStencilSide_Comparison_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMStencilFront_Vec); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMStencilSide_Comparison_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMStencilBack_Vec); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + + // Mask the resulting bits with the ones that should pass to VGPR [0].w. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = masked stencil function passed bits + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Choosing the stencil operation and combining the depth and the stencil test + // results, depending on the facing of the primitive. + + // Select the face. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_INPUT, 0, 1)); + shader_code_.push_back(uint32_t(InOutRegister::kPSInFrontFace)); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + system_constants_used_ |= (1ull << kSysConst_EDRAMStencilFront_Index) | + (1ull << kSysConst_EDRAMStencilBack_Index); + for (uint32_t i = 0; i < 2; ++i) { + uint32_t stencil_op_vec; + if (i) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + stencil_op_vec = kSysConst_EDRAMStencilBack_Vec; + } else { + stencil_op_vec = kSysConst_EDRAMStencilFront_Vec; + } + + // Choose the stencil pass operation depending on whether depth test has + // failed to VGPR [1].x. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = stencil test result + // VGPR [1].x = pass or depth fail operation + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(13)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMStencilSide_DepthFail_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(stencil_op_vec); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMStencilSide_Pass_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(stencil_op_vec); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + + // Choose the final operation to VGPR [1].x according to whether stencil + // test has passed. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = stencil test result + // VGPR [1].x = stencil operation + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMStencilSide_Fail_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(stencil_op_vec); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + } + + // Close the facing check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Merge the depth/stencil test results to VGPR [0].y. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth/stencil test failure + // VGPR [0].z = old depth/stencil + // VGPR [1].x = stencil operation + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + + // Extract the "keep" mask to VGPR [0].w. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth/stencil test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = stencil keep mask + // VGPR [1].x = stencil operation + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_IBFE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(kStencilOp_Flag_CurrentMask_Shift); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Mask the 8 stencil bits to know if saturation is required after adding. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth/stencil test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = stencil keep mask + // VGPR [1].x = stencil operation + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_USHR) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(24); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Mask the old stencil with the keep mask to VGPR [0].w. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth/stencil test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = new stencil accumulator + // VGPR [1].x = stencil operation + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Extract the value to add to VGPR [1].y. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth/stencil test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = new stencil accumulator + // VGPR [1].x = stencil operation + // VGPR [1].y = number to add to the old stencil + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_IBFE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(2); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(kStencilOp_Flag_Add_Shift); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Add the number to stencil. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth/stencil test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = new stencil accumulator + // VGPR [1].x = stencil operation + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Extract the saturation flag to VGPR [1].y. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth/stencil test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = new stencil accumulator + // VGPR [1].x = stencil operation + // VGPR [1].y = saturate flag + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(kStencilOp_Flag_Saturate); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Check if need to saturate. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth/stencil test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = new stencil accumulator + // VGPR [1].x = stencil operation + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Saturate. + for (uint32_t i = 0; i < 2; ++i) { + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(i ? D3D10_SB_OPCODE_IMIN + : D3D10_SB_OPCODE_IMAX) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(i ? 0xFF : 0); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + } + + // Close the saturation check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Extract the inversion mask to VGPR [1].y. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth/stencil test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = new stencil accumulator + // VGPR [1].x = stencil operation + // VGPR [1].y = stencil inversion mask + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_IBFE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(kStencilOp_Flag_Invert_Shift); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Invert stencil if needed. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth/stencil test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = new stencil accumulator + // VGPR [1].x = stencil operation + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_XOR) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Extract if need to replace the stencil with the reference to VGPR [1].x. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth/stencil test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = new stencil accumulator + // VGPR [1].x = replace flag + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(kStencilOp_Flag_NewMask); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Replace the new stencil with the reference if needed. + // TODO(Triang3l): Two sides. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth/stencil test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = new stencil accumulator + system_constants_used_ |= 1ull << kSysConst_EDRAMStencilReference_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMStencilReference_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMStencilReference_Vec); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + + // Apply the write mask to the new stencil, also dropping the upper 24 bits. + // TODO(Triang3l): Two sides. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth/stencil test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = masked new stencil accumulator + system_constants_used_ |= 1ull << kSysConst_EDRAMStencilWriteMask_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMStencilWriteMask_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMStencilWriteMask_Vec); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Invert the write mask for keeping the old stencil and the depth bits to + // SGPR [1].x. + // TODO(Triang3l): Two sides. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth/stencil test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = masked new stencil accumulator + // SGPR [1].x = inverse of the write mask + system_constants_used_ |= 1ull << kSysConst_EDRAMStencilWriteMask_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_NOT) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, + kSysConst_EDRAMStencilWriteMask_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMStencilWriteMask_Vec); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Remove the bits that will be replaced from the new combined depth/stencil. + // VGPR [0].x = masked new depth/stencil + // VGPR [0].y = depth/stencil test failure + // VGPR [0].z = old depth/stencil + // VGPR [0].w = masked new stencil accumulator + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Merge the old and the new stencil. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth/stencil test failure + // VGPR [0].z = old depth/stencil + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_OR) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Close the stencil test check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Check if need to write - if depth/stencil is different - to VGPR [0].z. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth/stencil test failure + // VGPR [0].z = whether depth/stencil has changed + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_INE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0100, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Check if need to write. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth/stencil test failure + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + bool depth_stencil_early = ROV_IsDepthStencilEarly(); + + if (depth_stencil_early) { + // Get if early depth/stencil write is enabled to SGPR [0].z. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth/stencil test failure + // SGPR [0].z = whether early depth/stencil write is enabled + system_constants_used_ |= 1ull << kSysConst_Flags_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0100, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, kSysConst_Flags_Comp, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_Flags_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(kSysFlag_ROVDepthStencilEarlyWrite); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Check if need to write early. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth/stencil test failure + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + } + + // Write the new depth/stencil. + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth/stencil test failure + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_STORE_UAV_TYPED) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D11_SB_OPERAND_TYPE_UNORDERED_ACCESS_VIEW, 0b1111, 2)); + shader_code_.push_back(ROV_GetEDRAMUAVIndex()); + shader_code_.push_back(uint32_t(UAVRegister::kEDRAM)); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.c_texture_store_instructions; + + if (depth_stencil_early) { + // Need to still run the shader to know whether to write the depth/stencil + // value. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Set bit 4 of the result if need to write later (after checking if the + // sample is not discarded by a kill instruction, alphatest or + // alpha-to-coverage). + // VGPR [0].x = new depth/stencil + // VGPR [0].y = depth/stencil test failure, deferred write bits + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_OR) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1 << 4); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Close the early depth/stencil check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + } + + // Close the write check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // End the subroutine. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_RET) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; +} + +void DxbcShaderTranslator::CompleteShaderCode_ROV_ColorSampleSubroutine( + uint32_t rt_index) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_LABEL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back(EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_LABEL, 1)); + shader_code_.push_back(label_rov_color_sample_[rt_index]); + + uint32_t keep_mask_vec = kSysConst_EDRAMRTKeepMask_Vec + (rt_index >> 1); + uint32_t keep_mask_component = (rt_index & 1) * 2; + uint32_t keep_mask_swizzle = (rt_index & 1) ? 0b1110 : 0b0100; + + // *************************************************************************** + // Checking if color loading must be done - if any component needs to be kept + // or if blending is enabled. + // *************************************************************************** + + // Check if need to keep any components to SGPR [0].z. + // VGPRs [0].xy - packed source color/alpha if not blending. + // SGPR [0].z - whether any components must be kept (OR of keep masks). + system_constants_used_ |= 1ull << kSysConst_EDRAMRTKeepMask_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_OR) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0100, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, keep_mask_component, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(keep_mask_vec); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, keep_mask_component + 1, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(keep_mask_vec); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Blending isn't done if it's 1 * source + 0 * destination. But since the + // previous color also needs to be loaded if any original components need to + // be kept, force the blend control to something with blending in this case + // in SGPR [0].z. + // VGPRs [0].xy - packed source color/alpha if not blending. + // SGPR [0].z - blending mode used to check if need to load. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTBlendFactorsOps_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0100, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTBlendFactorsOps_Vec); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + + // Get if the blend control requires loading the color to SGPR [0].z. + // VGPRs [0].xy - packed source color/alpha if not blending. + // SGPR [0].z - whether need to load the color. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_INE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0100, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0x00010001); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Check if need to do something with the previous color. + // VGPRs [0].xy - packed source color/alpha if not blending. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // *************************************************************************** + // Loading the previous color to SGPR [0].zw. + // *************************************************************************** + + // Get if the format is 64bpp to SGPR [0].z. + // VGPRs [0].xy - packed source color/alpha if not blending. + // SGPR [0].z - whether the render target is 64bpp. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTFormatFlags_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0100, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTFormatFlags_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(kRTFormatFlag_64bpp); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Check if the format is 64bpp. + // VGPRs [0].xy - packed source color/alpha if not blending. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Load the lower 32 bits of the 64bpp color to VGPR [0].z. + // VGPRs [0].xy - packed source color/alpha if not blending. + // VGPR [0].z - lower 32 bits of the packed color. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_LD_UAV_TYPED) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0100, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back(EncodeVectorReplicatedOperand( + D3D11_SB_OPERAND_TYPE_UNORDERED_ACCESS_VIEW, 0, 2)); + shader_code_.push_back(ROV_GetEDRAMUAVIndex()); + shader_code_.push_back(uint32_t(UAVRegister::kEDRAM)); + ++stat_.instruction_count; + ++stat_.texture_load_instructions; + + // Get the address of the upper 32 bits of the color to VGPR [0].w. + // VGPRs [0].xy - packed source color/alpha if not blending. + // VGPR [0].z - lower 32 bits of the packed color. + // VGPR [0].w - address of the upper 32 bits of the packed color. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Load the upper 32 bits of the 64bpp color to VGPR [0].w. + // VGPRs [0].xy - packed source color/alpha if not blending. + // VGPRs [0].zw - packed destination color/alpha. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_LD_UAV_TYPED) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorReplicatedOperand( + D3D11_SB_OPERAND_TYPE_UNORDERED_ACCESS_VIEW, 0, 2)); + shader_code_.push_back(ROV_GetEDRAMUAVIndex()); + shader_code_.push_back(uint32_t(UAVRegister::kEDRAM)); + ++stat_.instruction_count; + ++stat_.texture_load_instructions; + + // The color is 32bpp. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Load the 32bpp color to VGPR [0].z. + // VGPRs [0].xy - packed source color/alpha if not blending. + // VGPR [0].z - packed 32bpp destination color. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_LD_UAV_TYPED) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0100, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back(EncodeVectorReplicatedOperand( + D3D11_SB_OPERAND_TYPE_UNORDERED_ACCESS_VIEW, 0, 2)); + shader_code_.push_back(ROV_GetEDRAMUAVIndex()); + shader_code_.push_back(uint32_t(UAVRegister::kEDRAM)); + ++stat_.instruction_count; + ++stat_.texture_load_instructions; + + // Break register dependency in VGPR [0].w if the color is 32bpp. + // VGPRs [0].xy - packed source color/alpha if not blending. + // VGPRs [0].zw - packed destination color/alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + + // Close the color load check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Get if blending is enabled to SGPR [1].x. + // VGPRs [0].xy - packed source color/alpha if not blending. + // VGPRs [0].zw - packed destination color/alpha. + // SGPR [1].x - whether blending is enabled. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTBlendFactorsOps_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_INE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTBlendFactorsOps_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0x00010001); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Check if need to blend. + // VGPRs [0].xy - packed source color/alpha if not blending. + // VGPRs [0].zw - packed destination color/alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Now, when blending is enabled, registers [0].xy are used as scratch. + + // Unpack the destination color to VGPRs [1].xyzw, using [0].xy as temps. The + // destination color never needs clamping because out-of-range values can't be + // loaded. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - destination color/alpha. + ROV_UnpackColor(rt_index, system_temps_subroutine_, 2, + system_temps_subroutine_ + 1, system_temps_subroutine_, 0, + system_temps_subroutine_, 1); + + // *************************************************************************** + // Color blending. + // *************************************************************************** + + // Extract the color min/max bit to SGPR [0].x. + // SGPR [0].x - whether min/max should be used for color. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - destination color/alpha. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTBlendFactorsOps_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTBlendFactorsOps_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1 << (5 + 1)); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Check if need to do min/max for color. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - destination color/alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Extract the color min (0) or max (1) bit to SGPR [0].x. + // SGPR [0].x - whether min or max should be used for color. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - destination color/alpha. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTBlendFactorsOps_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTBlendFactorsOps_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1 << 5); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Check if need to do min or max for color. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - destination color/alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + for (uint32_t i = 0; i < 2; ++i) { + if (i) { + // Need to do min. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + } + + // Do min/max of the colors without applying the factors to VGPRs [1].xyz. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - blended color, destination alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE( + i ? D3D10_SB_OPCODE_MIN : D3D10_SB_OPCODE_MAX) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temps_color_[rt_index]); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + } + + // Close the min or max check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Need to do blend colors with the factors. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Extract the source color factor to SGPR [0].x. + // SGPR [0].x - source color factor index. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - destination color/alpha. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTBlendFactorsOps_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTBlendFactorsOps_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back((1 << 5) - 1); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Check if the source color factor is not zero - if it is, the source must be + // ignored completely, and Infinity and NaN in it shouldn't affect blending. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Open the switch for choosing the source color blend factor. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - destination color/alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_SWITCH) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Write the source color factor to VGPRs [2].xyz. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - destination color/alpha. + // VGPRs [2].xyz - unclamped source color factor. + ROV_HandleColorBlendFactorCases(system_temps_color_[rt_index], + system_temps_subroutine_ + 1, + system_temps_subroutine_ + 2); + + // Close the source color factor switch. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDSWITCH) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Get if the render target color is fixed-point and the source color factor + // needs clamping to SGPR [0].x. + // SGPR [0].x - whether color is fixed-point. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - destination color/alpha. + // VGPRs [2].xyz - unclamped source color factor. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTFormatFlags_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTFormatFlags_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(kRTFormatFlag_FixedPointColor); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Check if the source color factor needs clamping. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Clamp the source color factor in VGPRs [2].xyz. + // SGPR [0].x - whether color is fixed-point. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - destination color/alpha. + // VGPRs [2].xyz - source color factor. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTClamp_Index; + for (uint32_t i = 0; i < 2; ++i) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE( + i ? D3D10_SB_OPCODE_MIN : D3D10_SB_OPCODE_MAX) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(system_temps_subroutine_ + 2); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temps_subroutine_ + 2); + shader_code_.push_back(EncodeVectorReplicatedOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, i * 2, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTClamp_Vec + rt_index); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + } + + // Close the source color factor clamping check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Apply the factor to the source color. + // SGPR [0].x - whether color is fixed-point. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - destination color/alpha. + // VGPRs [2].xyz - unclamped source color part without addition sign. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(system_temps_subroutine_ + 2); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temps_color_[rt_index]); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temps_subroutine_ + 2); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Check if the source color part needs clamping after the multiplication. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - destination color/alpha. + // VGPRs [2].xyz - unclamped source color part without addition sign. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Clamp the source color part. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - destination color/alpha. + // VGPRs [2].xyz - source color part without addition sign. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTClamp_Index; + for (uint32_t i = 0; i < 2; ++i) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE( + i ? D3D10_SB_OPCODE_MIN : D3D10_SB_OPCODE_MAX) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(system_temps_subroutine_ + 2); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temps_subroutine_ + 2); + shader_code_.push_back(EncodeVectorReplicatedOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, i * 2, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTClamp_Vec + rt_index); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + } + + // Close the source color part clamping check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Extract the source color sign to SGPR [0].x. + // SGPR [0].x - source color sign as zero for 1 and non-zero for -1. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - destination color/alpha. + // VGPRs [2].xyz - source color part without addition sign. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTBlendFactorsOps_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTBlendFactorsOps_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1 << (5 + 2)); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Apply the source color sign. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - destination color/alpha. + // VGPRs [2].xyz - source color part. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(system_temps_subroutine_ + 2); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1) | + ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); + shader_code_.push_back( + ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER(D3D10_SB_OPERAND_MODIFIER_NEG)); + shader_code_.push_back(system_temps_subroutine_ + 2); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temps_subroutine_ + 2); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + + // The source color factor is zero. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Write zero to the source color part. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - destination color/alpha. + // VGPRs [2].xyz - source color part. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(system_temps_subroutine_ + 2); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_IMMEDIATE32, kSwizzleXYZW, 0)); + shader_code_.push_back(0); + shader_code_.push_back(0); + shader_code_.push_back(0); + shader_code_.push_back(0); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + + // Close the source color factor zero check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Extract the destination color factor to SGPR [0].x. + // SGPR [0].x - destination color factor index. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - destination color/alpha. + // VGPRs [2].xyz - source color part. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTBlendFactorsOps_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_UBFE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(5); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(8); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTBlendFactorsOps_Vec); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Check if the destination color factor is not zero. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Open the switch for choosing the destination color blend factor. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - destination color/alpha. + // VGPRs [2].xyz - source color part. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_SWITCH) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Write the destination color factor to VGPRs [3].xyz. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - destination color/alpha. + // VGPRs [2].xyz - source color part. + // VGPRs [3].xyz - unclamped destination color factor. + ROV_HandleColorBlendFactorCases(system_temps_color_[rt_index], + system_temps_subroutine_ + 1, + system_temps_subroutine_ + 3); + + // Close the destination color factor switch. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDSWITCH) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Get if the render target color is fixed-point and the destination color + // factor needs clamping to SGPR [0].x. + // SGPR [0].x - whether color is fixed-point. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - destination color/alpha. + // VGPRs [2].xyz - source color part. + // VGPRs [3].xyz - unclamped destination color factor. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTFormatFlags_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTFormatFlags_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(kRTFormatFlag_FixedPointColor); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Check if the destination color factor needs clamping. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Clamp the destination color factor in VGPRs [3].xyz. + // SGPR [0].x - whether color is fixed-point. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - destination color/alpha. + // VGPRs [2].xyz - source color part. + // VGPRs [3].xyz - destination color factor. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTClamp_Index; + for (uint32_t i = 0; i < 2; ++i) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE( + i ? D3D10_SB_OPCODE_MIN : D3D10_SB_OPCODE_MAX) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(system_temps_subroutine_ + 3); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temps_subroutine_ + 3); + shader_code_.push_back(EncodeVectorReplicatedOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, i * 2, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTClamp_Vec + rt_index); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + } + + // Close the destination color factor clamping check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Apply the factor to the destination color in VGPRs [1].xyz. + // SGPR [0].x - whether color is fixed-point. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - unclamped destination color part without addition sign. + // VGPR [1].w - destination alpha. + // VGPRs [2].xyz - source color part. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temps_subroutine_ + 3); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Check if the destination color part needs clamping after the + // multiplication. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - unclamped destination color part without addition sign. + // VGPR [1].w - destination alpha. + // VGPRs [2].xyz - source color part. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Clamp the destination color part. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - destination color part without addition sign. + // VGPR [1].w - destination alpha. + // VGPRs [2].xyz - source color part. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTClamp_Index; + for (uint32_t i = 0; i < 2; ++i) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE( + i ? D3D10_SB_OPCODE_MIN : D3D10_SB_OPCODE_MAX) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back(EncodeVectorReplicatedOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, i * 2, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTClamp_Vec + rt_index); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + } + + // Close the destination color part clamping check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Extract the destination color sign to SGPR [0].x. + // SGPR [0].x - destination color sign as zero for 1 and non-zero for -1. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - destination color part without addition sign. + // VGPR [1].w - destination alpha. + // VGPRs [2].xyz - source color part. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTBlendFactorsOps_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTBlendFactorsOps_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1 << 5); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Select the sign for destination multiply-add as 1.0 or -1.0 to SGPR [0].x. + // SGPR [0].x - destination color sign as float. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - destination color part without addition sign. + // VGPR [1].w - destination alpha. + // VGPRs [2].xyz - source color part. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0xBF800000u); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0x3F800000u); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + + // Perform color blending to VGPRs [1].xyz. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - unclamped blended color. + // VGPR [1].w - destination alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temps_subroutine_ + 2); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // The destination color factor is zero. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Write the source color part without applying the destination color. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - unclamped blended color. + // VGPR [1].w - destination alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temps_subroutine_ + 2); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + + // Close the destination color factor zero check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Clamp the color in VGPRs [1].xyz before packing. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTClamp_Index; + for (uint32_t i = 0; i < 2; ++i) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE( + i ? D3D10_SB_OPCODE_MIN : D3D10_SB_OPCODE_MAX) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0111, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back(EncodeVectorReplicatedOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, i * 2, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTClamp_Vec + rt_index); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + } + + // Close the color min/max enabled check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // *************************************************************************** + // Alpha blending. + // *************************************************************************** + + // Extract the alpha min/max bit to SGPR [0].x. + // SGPR [0].x - whether min/max should be used for alpha. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTBlendFactorsOps_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTBlendFactorsOps_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1 << (21 + 1)); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Check if need to do min/max for alpha. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Extract the alpha min (0) or max (1) bit to SGPR [0].x. + // SGPR [0].x - whether min or max should be used for alpha. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTBlendFactorsOps_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTBlendFactorsOps_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1 << 21); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Check if need to do min or max for alpha. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + for (uint32_t i = 0; i < 2; ++i) { + if (i) { + // Need to do min. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + } + + // Do min/max of the alphas without applying the factors to VGPRs [1].xyz. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color/alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE( + i ? D3D10_SB_OPCODE_MIN : D3D10_SB_OPCODE_MAX) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_color_[rt_index]); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + } + + // Close the min or max check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Need to do blend colors with the factors. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Extract the source alpha factor to SGPR [0].x. + // SGPR [0].x - source alpha factor index. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTBlendFactorsOps_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_UBFE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(5); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(16); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTBlendFactorsOps_Vec); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Check if the source alpha factor is not zero. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Open the switch for choosing the source alpha blend factor. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_SWITCH) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Write the source alpha factor to VGPR [0].x. + // VGPR [0].x - unclamped source alpha factor. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha. + ROV_HandleAlphaBlendFactorCases(system_temps_color_[rt_index], + system_temps_subroutine_ + 1, + system_temps_subroutine_, 0); + + // Close the source alpha factor switch. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDSWITCH) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Get if the render target alpha is fixed-point and the source alpha factor + // needs clamping to SGPR [0].y. + // VGPR [0].x - unclamped source alpha factor. + // SGPR [0].y - whether alpha is fixed-point. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTFormatFlags_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTFormatFlags_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(kRTFormatFlag_FixedPointAlpha); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Check if the source alpha factor needs clamping. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Clamp the source alpha factor in VGPR [0].x. + // VGPR [0].x - source alpha factor. + // SGPR [0].y - whether alpha is fixed-point. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTClamp_Index; + for (uint32_t i = 0; i < 2; ++i) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE( + i ? D3D10_SB_OPCODE_MIN : D3D10_SB_OPCODE_MAX) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, i * 2 + 1, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTClamp_Vec + rt_index); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + } + + // Close the source alpha factor clamping check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Apply the factor to the source alpha. + // VGPR [0].x - unclamped source alpha part without addition sign. + // SGPR [0].y - whether alpha is fixed-point. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_color_[rt_index]); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Check if the source alpha part needs clamping after the multiplication. + // VGPR [0].x - unclamped source alpha part without addition sign. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Clamp the source alpha part. + // VGPR [0].x - source alpha part without addition sign. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTClamp_Index; + for (uint32_t i = 0; i < 2; ++i) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE( + i ? D3D10_SB_OPCODE_MIN : D3D10_SB_OPCODE_MAX) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, i * 2 + 1, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTClamp_Vec + rt_index); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + } + + // Close the source alpha part clamping check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Extract the source alpha sign to SGPR [0].y. + // VGPR [0].x - source alpha part without addition sign. + // SGPR [0].y - source alpha sign as zero for 1 and non-zero for -1. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTBlendFactorsOps_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1 << (21 + 2)); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Apply the source alpha sign. + // VGPR [0].x - source alpha part. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(10)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1) | + ENCODE_D3D10_SB_OPERAND_EXTENDED(1)); + shader_code_.push_back( + ENCODE_D3D10_SB_EXTENDED_OPERAND_MODIFIER(D3D10_SB_OPERAND_MODIFIER_NEG)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + + // The source alpha factor is zero. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Write zero to the source alpha part. + // VGPR [0].x - source alpha part. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + + // Close the source alpha factor zero check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Extract the destination alpha factor to SGPR [1].y. + // VGPR [0].x - source alpha part. + // SGPR [0].y - destination alpha factor index. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTBlendFactorsOps_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_UBFE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(5); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(24); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTBlendFactorsOps_Vec); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Check if the destination alpha factor is not zero. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Open the switch for choosing the destination alpha blend factor. + // VGPR [0].x - source alpha part. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_SWITCH) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Write the destination alpha factor to VGPR [0].y. + // VGPR [0].x - source alpha part. + // VGPR [0].y - unclamped destination alpha factor. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha. + ROV_HandleAlphaBlendFactorCases(system_temps_color_[rt_index], + system_temps_subroutine_ + 1, + system_temps_subroutine_, 1); + + // Close the destination alpha factor switch. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDSWITCH) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Get if the render target alpha is fixed-point and the destination alpha + // factor needs clamping to SGPR [2].x. + // VGPR [0].x - source alpha part. + // VGPR [0].y - unclamped destination alpha factor. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha. + // SGPR [2].x - whether alpha is fixed-point. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTFormatFlags_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_ + 2); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTFormatFlags_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(kRTFormatFlag_FixedPointAlpha); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Check if the destination alpha factor needs clamping. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_ + 2); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Clamp the destination alpha factor in VGPR [0].y. + // VGPR [0].x - source alpha part. + // VGPR [0].y - destination alpha factor. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha. + // SGPR [2].x - whether alpha is fixed-point. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTClamp_Index; + for (uint32_t i = 0; i < 2; ++i) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE( + i ? D3D10_SB_OPCODE_MIN : D3D10_SB_OPCODE_MAX) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, i * 2 + 1, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTClamp_Vec + rt_index); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + } + + // Close the destination alpha factor clamping check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Apply the factor to the destination alpha in VGPR [1].w. + // VGPR [0].x - source alpha part. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - unclamped destination alpha part without addition sign. + // SGPR [2].x - whether alpha is fixed-point. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // Check if the destination alpha part needs clamping after the + // multiplication. + // VGPR [0].x - source alpha part. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - unclamped destination alpha part without addition sign. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_ + 2); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Clamp the destination alpha part. + // VGPR [0].x - source alpha part. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha part without addition sign. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTClamp_Index; + for (uint32_t i = 0; i < 2; ++i) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE( + i ? D3D10_SB_OPCODE_MIN : D3D10_SB_OPCODE_MAX) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, i * 2 + 1, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTClamp_Vec + rt_index); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + } + + // Close the destination alpha factor clamping check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Extract the destination alpha sign to SGPR [0].y. + // VGPR [0].x - source alpha part. + // SGPR [0].y - destination alpha sign as zero for 1 and non-zero for -1. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha part without addition sign. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTBlendFactorsOps_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTBlendFactorsOps_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1 << 21); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Select the sign for destination multiply-add as 1.0 or -1.0 to SGPR [0].y. + // VGPR [0].x - source alpha part. + // SGPR [0].y - destination alpha sign as float. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - destination alpha part without addition sign. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0010, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0xBF800000u); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0x3F800000u); + ++stat_.instruction_count; + ++stat_.movc_instruction_count; + + // Perform alpha blending to VGPR [1].w. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - unclamped blended alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + + // The destination alpha factor is zero. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Write the source alpha part without applying the destination alpha. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyz - blended color. + // VGPR [1].w - unclamped blended alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOV) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.mov_instruction_count; + + // Close the destination alpha factor zero check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Clamp the alpha in VGPR [1].w before packing. + // VGPRs [0].zw - packed destination color/alpha. + // VGPRs [1].xyzw - blended color/alpha. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTClamp_Index; + for (uint32_t i = 0; i < 2; ++i) { + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE( + i ? D3D10_SB_OPCODE_MIN : D3D10_SB_OPCODE_MAX) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1000, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, i * 2 + 1, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTClamp_Vec + rt_index); + ++stat_.instruction_count; + ++stat_.float_instruction_count; + } + + // Close the alpha min/max enabled check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Pack the new color/alpha to VGPRs [0].xy, using VGPRs [2].xy as temporary. + // VGPRs [0].xy - packed new color/alpha. + // VGPRs [0].zw - packed old color/alpha. + ROV_PackPreClampedColor( + rt_index, system_temps_subroutine_ + 1, system_temps_subroutine_, 0, + system_temps_subroutine_ + 2, 0, system_temps_subroutine_ + 2, 1); + + // Close the blending check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // *************************************************************************** + // Write mask application + // *************************************************************************** + + // Apply the keep mask to the previous packed color/alpha in VGPRs [0].zw. + // VGPRs [0].xy - packed new color/alpha. + // VGPRs [0].zw - masked packed old color/alpha. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTKeepMask_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1100, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, keep_mask_swizzle << 4, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(keep_mask_vec); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Invert the keep mask into SGPRs [1].xy. + // VGPRs [0].xy - packed new color/alpha. + // VGPRs [0].zw - masked packed old color/alpha. + // SGPRs [1].xy - inverted keep mask (write mask). + system_constants_used_ |= 1ull << kSysConst_EDRAMRTKeepMask_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_NOT) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + shader_code_.push_back(EncodeVectorSwizzledOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, keep_mask_swizzle, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(keep_mask_vec); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Apply the write mask to the new color/alpha in VGPRs [0].xy. + // VGPRs [0].xy - masked packed new color/alpha. + // VGPRs [0].zw - masked packed old color/alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1)); + shader_code_.push_back(system_temps_subroutine_ + 1); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Combine the masked colors into VGPRs [0].xy. + // VGPRs [0].xy - packed resulting color/alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_OR) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b00000100, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b00001110, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Close the previous color load check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // *************************************************************************** + // Writing the color + // *************************************************************************** + + // Get if the format is 64bpp to SGPR [0].z. + // VGPRs [0].xy - packed resulting color/alpha. + // SGPR [0].z - whether the render target is 64bpp. + system_constants_used_ |= 1ull << kSysConst_EDRAMRTFormatFlags_Index; + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_AND) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0100, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back(EncodeVectorSelectOperand( + D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER, rt_index, 3)); + shader_code_.push_back(cbuffer_index_system_constants_); + shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants)); + shader_code_.push_back(kSysConst_EDRAMRTFormatFlags_Vec); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(kRTFormatFlag_64bpp); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Check if the format is 64bpp. + // VGPRs [0].xy - packed resulting color/alpha. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // Store the lower 32 bits of the 64bpp color. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_STORE_UAV_TYPED) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D11_SB_OPERAND_TYPE_UNORDERED_ACCESS_VIEW, 0b1111, 2)); + shader_code_.push_back(ROV_GetEDRAMUAVIndex()); + shader_code_.push_back(uint32_t(UAVRegister::kEDRAM)); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.c_texture_store_instructions; + + // Get the address of the upper 32 bits of the color to VGPR [0].z (can't use + // [0].x because components when not blending, packing is done once for all + // samples). + // VGPRs [0].xy - packed resulting color/alpha. + // VGPR [0].z - address of the upper 32 bits of the packed color. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0100, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(1); + ++stat_.instruction_count; + ++stat_.int_instruction_count; + + // Store the upper 32 bits of the 64bpp color. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_STORE_UAV_TYPED) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D11_SB_OPERAND_TYPE_UNORDERED_ACCESS_VIEW, 0b1111, 2)); + shader_code_.push_back(ROV_GetEDRAMUAVIndex()); + shader_code_.push_back(uint32_t(UAVRegister::kEDRAM)); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.c_texture_store_instructions; + + // The color is 32bpp. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ELSE) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // Store the 32bpp color. + shader_code_.push_back( + ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_STORE_UAV_TYPED) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(8)); + shader_code_.push_back(EncodeVectorMaskedOperand( + D3D11_SB_OPERAND_TYPE_UNORDERED_ACCESS_VIEW, 0b1111, 2)); + shader_code_.push_back(ROV_GetEDRAMUAVIndex()); + shader_code_.push_back(uint32_t(UAVRegister::kEDRAM)); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(system_temp_rov_params_); + shader_code_.push_back( + EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.c_texture_store_instructions; + + // Close the 64bpp/32bpp conditional. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + + // End the subroutine. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_RET) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + ++stat_.static_flow_control_count; +} + } // namespace gpu } // namespace xe diff --git a/src/xenia/gpu/shader.h b/src/xenia/gpu/shader.h index ed2dcf8fd..8dce339e1 100644 --- a/src/xenia/gpu/shader.h +++ b/src/xenia/gpu/shader.h @@ -618,9 +618,13 @@ class Shader { // Returns true if the given color target index [0-3]. bool writes_color_target(int i) const { return writes_color_targets_[i]; } - // Returns true if the pixel shader can potentially have early depth/stencil - // testing enabled, provided alpha testing is disabled. - bool early_z_allowed() const { return early_z_allowed_; } + // True if the shader overrides the pixel depth. + bool writes_depth() const { return writes_depth_; } + + // True if Xenia can automatically enable early depth/stencil for the pixel + // shader when RB_DEPTHCONTROL EARLY_Z_ENABLE is not set, provided alpha + // testing and alpha to coverage are disabled. + bool implicit_early_z_allowed() const { return implicit_early_z_allowed_; } // True if the shader was translated and prepared without error. bool is_valid() const { return is_valid_; } @@ -670,7 +674,8 @@ class Shader { std::vector texture_bindings_; ConstantRegisterMap constant_register_map_ = {0}; bool writes_color_targets_[4] = {false, false, false, false}; - bool early_z_allowed_ = true; + bool writes_depth_ = false; + bool implicit_early_z_allowed_ = true; std::vector memexport_stream_constants_; bool is_valid_ = false; diff --git a/src/xenia/gpu/shader_translator.cc b/src/xenia/gpu/shader_translator.cc index a01055f3e..c3cd78ad6 100644 --- a/src/xenia/gpu/shader_translator.cc +++ b/src/xenia/gpu/shader_translator.cc @@ -65,7 +65,7 @@ void ShaderTranslator::Reset() { writes_color_targets_[i] = false; } writes_depth_ = false; - early_z_allowed_ = true; + implicit_early_z_allowed_ = true; memexport_alloc_count_ = 0; memexport_eA_written_ = 0; std::memset(&memexport_eM_written_, 0, sizeof(memexport_eM_written_)); @@ -155,6 +155,12 @@ bool ShaderTranslator::TranslateInternal(Shader* shader) { if (memexport_eA_written_ == 0) { memexport_stream_constants_.clear(); } + if (!memexport_stream_constants_.empty()) { + // TODO(Triang3l): Investigate what happens to memexport when the pixel + // fails the depth/stencil test, but in Direct3D 11 UAV writes disable early + // depth/stencil. + implicit_early_z_allowed_ = false; + } StartTranslation(); @@ -190,7 +196,8 @@ bool ShaderTranslator::TranslateInternal(Shader* shader) { for (size_t i = 0; i < xe::countof(writes_color_targets_); ++i) { shader->writes_color_targets_[i] = writes_color_targets_[i]; } - shader->early_z_allowed_ = early_z_allowed_; + shader->writes_depth_ = writes_depth_; + shader->implicit_early_z_allowed_ = implicit_early_z_allowed_; shader->memexport_stream_constants_.clear(); for (uint32_t memexport_stream_constant : memexport_stream_constants_) { shader->memexport_stream_constants_.push_back(memexport_stream_constant); @@ -290,7 +297,7 @@ void ShaderTranslator::GatherInstructionInformation( if (op.has_vector_op()) { const auto& opcode_info = alu_vector_opcode_infos_[static_cast(op.vector_opcode())]; - early_z_allowed_ &= !opcode_info.disable_early_z; + implicit_early_z_allowed_ &= !opcode_info.disable_implicit_early_z; for (size_t i = 0; i < opcode_info.argument_count; ++i) { if (op.src_is_temp(i + 1) && (op.src_reg(i + 1) & 0x40)) { uses_register_dynamic_addressing_ = true; @@ -302,7 +309,7 @@ void ShaderTranslator::GatherInstructionInformation( writes_color_targets_[op.vector_dest()] = true; } else if (op.vector_dest() == 61) { writes_depth_ = true; - early_z_allowed_ = false; + implicit_early_z_allowed_ = false; } } if (memexport_alloc_count_ > 0 && @@ -339,7 +346,7 @@ void ShaderTranslator::GatherInstructionInformation( if (op.has_scalar_op()) { const auto& opcode_info = alu_scalar_opcode_infos_[static_cast(op.scalar_opcode())]; - early_z_allowed_ &= !opcode_info.disable_early_z; + implicit_early_z_allowed_ &= !opcode_info.disable_implicit_early_z; if (opcode_info.argument_count == 1 && op.src_is_temp(3) && (op.src_reg(3) & 0x40)) { uses_register_dynamic_addressing_ = true; @@ -350,7 +357,7 @@ void ShaderTranslator::GatherInstructionInformation( writes_color_targets_[op.scalar_dest()] = true; } else if (op.scalar_dest() == 61) { writes_depth_ = true; - early_z_allowed_ = false; + implicit_early_z_allowed_ = false; } } if (memexport_alloc_count_ > 0 && diff --git a/src/xenia/gpu/shader_translator.h b/src/xenia/gpu/shader_translator.h index 292c96bed..dac02fc0c 100644 --- a/src/xenia/gpu/shader_translator.h +++ b/src/xenia/gpu/shader_translator.h @@ -15,6 +15,7 @@ #include #include +#include "xenia/base/math.h" #include "xenia/base/string_buffer.h" #include "xenia/gpu/shader.h" #include "xenia/gpu/ucode.h" @@ -56,11 +57,20 @@ class ShaderTranslator { } // True if the current shader writes to a color target on any execution path. bool writes_color_target(int i) const { return writes_color_targets_[i]; } + bool writes_any_color_target() const { + for (size_t i = 0; i < xe::countof(writes_color_targets_); ++i) { + if (writes_color_targets_[i]) { + return true; + } + } + return false; + } // True if the current shader overrides the pixel depth. bool writes_depth() const { return writes_depth_; } - // True if the pixel shader can potentially have early depth/stencil testing - // enabled, provided alpha testing is disabled. - bool early_z_allowed() const { return early_z_allowed_; } + // True if Xenia can automatically enable early depth/stencil for the pixel + // shader when RB_DEPTHCONTROL EARLY_Z_ENABLE is not set, provided alpha + // testing and alpha to coverage are disabled. + bool implicit_early_z_allowed() const { return implicit_early_z_allowed_; } // A list of all vertex bindings, populated before translation occurs. const std::vector& vertex_bindings() const { return vertex_bindings_; @@ -163,7 +173,7 @@ class ShaderTranslator { const char* name; size_t argument_count; int src_swizzle_component_count; - bool disable_early_z; + bool disable_implicit_early_z; }; bool TranslateInternal(Shader* shader); @@ -247,7 +257,7 @@ class ShaderTranslator { bool uses_register_dynamic_addressing_ = false; bool writes_color_targets_[4] = {false, false, false, false}; bool writes_depth_ = false; - bool early_z_allowed_ = true; + bool implicit_early_z_allowed_ = true; uint32_t memexport_alloc_count_ = 0; // For register allocation in implementations - what was used after each