Merge remote-tracking branch 'xenia-master/master' into canary_experimental

This commit is contained in:
Herman S.
2026-03-06 14:10:00 +09:00
65 changed files with 1497 additions and 2231 deletions

View File

@@ -65,7 +65,7 @@ using namespace ucode;
DxbcShaderTranslator::DxbcShaderTranslator(
ui::GraphicsProvider::GpuVendorID vendor_id, bool bindless_resources_used,
bool edram_rov_used, bool gamma_render_target_as_srgb,
bool edram_rov_used, bool gamma_render_target_as_unorm8,
bool msaa_2x_supported, uint32_t draw_resolution_scale_x,
uint32_t draw_resolution_scale_y, bool force_emit_source_map)
: a_(shader_code_, statistics_),
@@ -73,7 +73,7 @@ DxbcShaderTranslator::DxbcShaderTranslator(
vendor_id_(vendor_id),
bindless_resources_used_(bindless_resources_used),
edram_rov_used_(edram_rov_used),
gamma_render_target_as_srgb_(gamma_render_target_as_srgb),
gamma_render_target_as_unorm8_(gamma_render_target_as_unorm8),
msaa_2x_supported_(msaa_2x_supported),
draw_resolution_scale_x_(draw_resolution_scale_x),
draw_resolution_scale_y_(draw_resolution_scale_y),
@@ -222,9 +222,10 @@ void DxbcShaderTranslator::PopSystemTemp(uint32_t count) {
}
void DxbcShaderTranslator::PWLGammaToLinear(
uint32_t target_temp, uint32_t target_temp_component, uint32_t source_temp,
uint32_t source_temp_component, bool source_pre_saturated, uint32_t temp1,
uint32_t temp1_component, uint32_t temp2, uint32_t temp2_component) {
dxbc::Assembler& a, uint32_t target_temp, uint32_t target_temp_component,
uint32_t source_temp, uint32_t source_temp_component,
bool source_pre_saturated, uint32_t temp1, uint32_t temp1_component,
uint32_t temp2, uint32_t temp2_component) {
// The source is needed only once to begin building the result, so it can be
// the same as the destination.
assert_true(temp1 != target_temp || temp1_component != target_temp_component);
@@ -245,25 +246,25 @@ void DxbcShaderTranslator::PWLGammaToLinear(
// Using `source >= threshold` comparisons because the input might have not
// been saturated yet, and thus it may be NaN - since it will be saturated to
// 0 later, the 0...64/255 case should be selected for it.
a_.OpGE(temp2_dest, source_src, dxbc::Src::LF(96.0f / 255.0f));
a_.OpIf(true, temp2_src);
a.OpGE(temp2_dest, source_src, dxbc::Src::LF(96.0f / 255.0f));
a.OpIf(true, temp2_src);
// [96/255 ... 1
a_.OpGE(temp2_dest, source_src, dxbc::Src::LF(192.0f / 255.0f));
a_.OpMovC(temp1_dest, temp2_src, dxbc::Src::LF(8.0f / 1024.0f),
dxbc::Src::LF(4.0f / 1024.0f));
a_.OpMovC(temp2_dest, temp2_src, dxbc::Src::LF(-1024.0f),
dxbc::Src::LF(-256.0f));
a_.OpElse();
a.OpGE(temp2_dest, source_src, dxbc::Src::LF(192.0f / 255.0f));
a.OpMovC(temp1_dest, temp2_src, dxbc::Src::LF(8.0f / 1024.0f),
dxbc::Src::LF(4.0f / 1024.0f));
a.OpMovC(temp2_dest, temp2_src, dxbc::Src::LF(-1024.0f),
dxbc::Src::LF(-256.0f));
a.OpElse();
// 0 ... 96/255)
a_.OpGE(temp2_dest, source_src, dxbc::Src::LF(64.0f / 255.0f));
a_.OpMovC(temp1_dest, temp2_src, dxbc::Src::LF(2.0f / 1024.0f),
dxbc::Src::LF(1.0f / 1024.0f));
a_.OpMovC(temp2_dest, temp2_src, dxbc::Src::LF(-64.0f), dxbc::Src::LF(0.0f));
a_.OpEndIf();
a.OpGE(temp2_dest, source_src, dxbc::Src::LF(64.0f / 255.0f));
a.OpMovC(temp1_dest, temp2_src, dxbc::Src::LF(2.0f / 1024.0f),
dxbc::Src::LF(1.0f / 1024.0f));
a.OpMovC(temp2_dest, temp2_src, dxbc::Src::LF(-64.0f), dxbc::Src::LF(0.0f));
a.OpEndIf();
if (!source_pre_saturated) {
// Saturate the input, and flush NaN to 0.
a_.OpMov(target_dest, source_src, true);
a.OpMov(target_dest, source_src, true);
}
// linear = gamma * (255 * 1024) * scale + offset
// As both 1024 and the scale are powers of 2, and 1024 * scale is not smaller
@@ -272,22 +273,22 @@ void DxbcShaderTranslator::PWLGammaToLinear(
// gamma * (255 * 1024 * scale) - or the option chosen here, as long as
// 1024 is applied before the scale since the scale is < 1 (specifically at
// least 1/1024), and it may make very small values denormal.
a_.OpMul(target_dest, source_pre_saturated ? source_src : target_src,
dxbc::Src::LF(255.0f * 1024.0f));
a_.OpMAd(target_dest, target_src, temp1_src, temp2_src);
a.OpMul(target_dest, source_pre_saturated ? source_src : target_src,
dxbc::Src::LF(255.0f * 1024.0f));
a.OpMAd(target_dest, target_src, temp1_src, temp2_src);
// linear += trunc(linear * scale)
a_.OpMul(temp1_dest, target_src, temp1_src);
a_.OpRoundZ(temp1_dest, temp1_src);
a_.OpAdd(target_dest, target_src, temp1_src);
a.OpMul(temp1_dest, target_src, temp1_src);
a.OpRoundZ(temp1_dest, temp1_src);
a.OpAdd(target_dest, target_src, temp1_src);
// linear *= 1/1023
a_.OpMul(target_dest, target_src, dxbc::Src::LF(1.0f / 1023.0f));
a.OpMul(target_dest, target_src, dxbc::Src::LF(1.0f / 1023.0f));
}
void DxbcShaderTranslator::PreSaturatedLinearToPWLGamma(
uint32_t target_temp, uint32_t target_temp_component, uint32_t source_temp,
uint32_t source_temp_component, uint32_t temp_or_target,
uint32_t temp_or_target_component, uint32_t temp_non_target,
uint32_t temp_non_target_component) {
dxbc::Assembler& a, uint32_t target_temp, uint32_t target_temp_component,
uint32_t source_temp, uint32_t source_temp_component,
uint32_t temp_or_target, uint32_t temp_or_target_component,
uint32_t temp_non_target, uint32_t temp_non_target_component) {
// The source may be the same as the target, but in this case it can't also be
// used as a temporary variable.
assert_true(target_temp != source_temp ||
@@ -317,28 +318,28 @@ void DxbcShaderTranslator::PreSaturatedLinearToPWLGamma(
// Get the scale (into temp_or_target) and the offset (into temp_non_target)
// for the piece.
a_.OpGE(temp_non_target_dest, source_src, dxbc::Src::LF(128.0f / 1023.0f));
a_.OpIf(true, temp_non_target_src);
a.OpGE(temp_non_target_dest, source_src, dxbc::Src::LF(128.0f / 1023.0f));
a.OpIf(true, temp_non_target_src);
// [128/1023 ... 1
a_.OpGE(temp_non_target_dest, source_src, dxbc::Src::LF(512.0f / 1023.0f));
a_.OpMovC(temp_or_target_dest, temp_non_target_src,
dxbc::Src::LF(1023.0f / 8.0f), dxbc::Src::LF(1023.0f / 4.0f));
a_.OpMovC(temp_non_target_dest, temp_non_target_src,
dxbc::Src::LF(128.0f / 255.0f), dxbc::Src::LF(64.0f / 255.0f));
a_.OpElse();
a.OpGE(temp_non_target_dest, source_src, dxbc::Src::LF(512.0f / 1023.0f));
a.OpMovC(temp_or_target_dest, temp_non_target_src,
dxbc::Src::LF(1023.0f / 8.0f), dxbc::Src::LF(1023.0f / 4.0f));
a.OpMovC(temp_non_target_dest, temp_non_target_src,
dxbc::Src::LF(128.0f / 255.0f), dxbc::Src::LF(64.0f / 255.0f));
a.OpElse();
// 0 ... 128/1023)
a_.OpGE(temp_non_target_dest, source_src, dxbc::Src::LF(64.0f / 1023.0f));
a_.OpMovC(temp_or_target_dest, temp_non_target_src,
dxbc::Src::LF(1023.0f / 2.0f), dxbc::Src::LF(1023.0f));
a_.OpMovC(temp_non_target_dest, temp_non_target_src,
dxbc::Src::LF(32.0f / 255.0f), dxbc::Src::LF(0.0f));
a_.OpEndIf();
a.OpGE(temp_non_target_dest, source_src, dxbc::Src::LF(64.0f / 1023.0f));
a.OpMovC(temp_or_target_dest, temp_non_target_src,
dxbc::Src::LF(1023.0f / 2.0f), dxbc::Src::LF(1023.0f));
a.OpMovC(temp_non_target_dest, temp_non_target_src,
dxbc::Src::LF(32.0f / 255.0f), dxbc::Src::LF(0.0f));
a.OpEndIf();
// gamma = trunc(linear * scale) * (1.0 / 255.0) + offset
a_.OpMul(target_dest, source_src, temp_or_target_src);
a_.OpRoundZ(target_dest, target_src);
a_.OpMAd(target_dest, target_src, dxbc::Src::LF(1.0f / 255.0f),
temp_non_target_src);
a.OpMul(target_dest, source_src, temp_or_target_src);
a.OpRoundZ(target_dest, target_src);
a.OpMAd(target_dest, target_src, dxbc::Src::LF(1.0f / 255.0f),
temp_non_target_src);
}
void DxbcShaderTranslator::RemapAndConvertVertexIndices(
@@ -2135,7 +2136,8 @@ constexpr DxbcShaderTranslator::SystemConstantRdef
{"xe_texture_swizzled_signs", ShaderRdefTypeIndex::kUint4Array2,
sizeof(uint32_t) * 4 * 2},
{"xe_textures_resolved", ShaderRdefTypeIndex::kUint, sizeof(uint32_t)},
{"xe_textures_resolution_scaled", ShaderRdefTypeIndex::kUint,
sizeof(uint32_t)},
{"xe_sample_count_log2", ShaderRdefTypeIndex::kUint2,
sizeof(uint32_t) * 2},
{"xe_alpha_test_reference", ShaderRdefTypeIndex::kFloat, sizeof(float)},