shader: keep derived frontend metadata with its owner

This commit is contained in:
nmzik
2026-09-11 19:18:35 +04:00
parent 20e57994cf
commit 5a31de7955
5 changed files with 18 additions and 44 deletions
@@ -53,8 +53,7 @@ const char* StageName(ShaderType stage) {
}
}
void LogDispatcherFallback(const CompileOptions& options, const CFG::Graph& cfg, const char* phase,
const std::string& reason) {
void LogDispatcherFallback(const CompileOptions& options, const CFG::Graph& cfg, const char* phase) {
const auto* block = cfg.FindBlock(cfg.failure_block);
const auto start = block != nullptr ? block->start_pc : UINT32_MAX;
const auto end = block != nullptr ? block->end_pc : UINT32_MAX;
@@ -68,7 +67,7 @@ void LogDispatcherFallback(const CompileOptions& options, const CFG::Graph& cfg,
CFG::FailureKindToString(cfg.failure_kind).c_str(), cfg.failure_block, start, end,
static_cast<uint64_t>(predecessors), static_cast<uint64_t>(successors),
static_cast<uint64_t>(cfg.blocks.size()), static_cast<uint64_t>(cfg.natural_loops.size()),
static_cast<uint64_t>(cfg.back_edges.size()), reason.c_str());
static_cast<uint64_t>(cfg.back_edges.size()), cfg.unsupported_reason.c_str());
}
enum class EmbeddedFetchValueType {
@@ -550,27 +549,22 @@ TranslateResult TranslateProgram(std::span<const uint32_t> code, const CompileOp
GetDumpLabel(options), StageName(options.stage), options.shader_hash,
static_cast<uint64_t>(cfg.blocks.size()), static_cast<uint64_t>(cfg.natural_loops.size()),
static_cast<uint64_t>(cfg.back_edges.size()), phase_ms());
bool dispatcher_fallback = false;
std::string dispatcher_reason;
if (cfg.irreducible) {
dispatcher_fallback = true;
dispatcher_reason = cfg.unsupported_reason;
LogDispatcherFallback(options, cfg, "build", dispatcher_reason);
LogDispatcherFallback(options, cfg, "build");
} else {
const auto unstructured_cfg = cfg;
LOGF("%s phase begin: stage=%s hash=0x%016" PRIx64 " CFG Structurize\n",
GetDumpLabel(options), StageName(options.stage), options.shader_hash);
if (!CFG::Structurize(cfg)) {
dispatcher_fallback = true;
dispatcher_reason = cfg.unsupported_reason;
const auto failure_kind = cfg.failure_kind;
const auto failure_block = cfg.failure_block;
LogDispatcherFallback(options, cfg, "structurize", dispatcher_reason);
LogDispatcherFallback(options, cfg, "structurize");
auto failure_reason = std::move(cfg.unsupported_reason);
cfg = unstructured_cfg;
cfg.unsupported = true;
cfg.failure_kind = failure_kind;
cfg.failure_block = failure_block;
cfg.unsupported_reason = dispatcher_reason;
cfg.unsupported_reason = std::move(failure_reason);
} else {
LOGF("%s structured CFG success: blocks=%" PRIu64 "\n", GetDumpLabel(options),
static_cast<uint64_t>(cfg.blocks.size()));
@@ -594,16 +588,13 @@ TranslateResult TranslateProgram(std::span<const uint32_t> code, const CompileOp
}
}
Frontend::TranslateOptions translate_options {
.stage = options.stage,
.wave_size = options.wave_size,
.shader_hash = options.shader_hash,
.user_data_base = options.user_data_base,
.user_data_count = static_cast<uint32_t>(options.user_data.size()),
.dispatcher_fallback = dispatcher_fallback,
.cfg_failure_kind = cfg.failure_kind,
.fallback_reason = dispatcher_reason.empty() ? cfg.unsupported_reason : dispatcher_reason,
.input_info = options.input_info,
.embedded_fetch = embedded_fetch.loads.empty() ? nullptr : &embedded_fetch,
.stage = options.stage,
.wave_size = options.wave_size,
.shader_hash = options.shader_hash,
.user_data_base = options.user_data_base,
.user_data_count = static_cast<uint32_t>(options.user_data.size()),
.input_info = options.input_info,
.embedded_fetch = embedded_fetch.loads.empty() ? nullptr : &embedded_fetch,
};
LOGF("%s phase begin: stage=%s hash=0x%016" PRIx64 " IR TranslateProgram\n",
GetDumpLabel(options), StageName(options.stage), options.shader_hash);
@@ -111,11 +111,6 @@ IR::MemoryInfo MemoryInfoFromDecoded(const Decoder::Instruction& decoded) {
memory.image_sample_flags = decoded.image_sample_flags;
memory.image_dimension = decoded.image_dimension;
memory.image_address_components = decoded.image_address_components;
memory.image_nsa_dwords = decoded.image_nsa_dwords;
for (uint32_t index = 0; index < Decoder::MaxImageNsaAddressComponents; index++) {
memory.image_nsa_addr[index] = decoded.image_nsa_addr[index];
}
memory.memory_segment = decoded.memory_segment;
memory.address_is_full =
memory.kind == ResourceKind::Flat ||
(memory.kind == ResourceKind::Global && decoded.src1.kind == Decoder::OperandKind::Vgpr);
@@ -125,8 +120,6 @@ IR::MemoryInfo MemoryInfoFromDecoded(const Decoder::Instruction& decoded) {
memory.image_has_mip = decoded.opcode == Decoder::Opcode::IMAGE_LOAD_MIP ||
decoded.opcode == Decoder::Opcode::IMAGE_STORE_MIP;
memory.image_r128 = decoded.image_r128;
memory.glc = decoded.glc;
memory.slc = decoded.slc;
memory.idxen = decoded.idxen;
memory.offen = decoded.offen;
memory.resource = ResourceIndexFromOperand(decoded.src1);
@@ -954,9 +954,9 @@ IR::Program TranslateProgram(const Decoder::Program& decoded, const CFG::Graph&
break;
default: break; // ValidateTranslateOptions rejects unsupported stages.
}
result.dispatcher_fallback = options.dispatcher_fallback;
result.cfg_failure_kind = options.cfg_failure_kind;
result.fallback_reason = options.fallback_reason;
result.dispatcher_fallback = cfg.irreducible || cfg.unsupported;
result.cfg_failure_kind = cfg.failure_kind;
result.fallback_reason = cfg.unsupported_reason;
if (options.embedded_fetch != nullptr) {
result.info.vertex_offset_sgpr = options.embedded_fetch->vertex_offset_sgpr;
result.info.instance_offset_sgpr = options.embedded_fetch->instance_offset_sgpr;
@@ -5,7 +5,6 @@
#include "graphics/shader/recompiler/ir/ShaderIR.h"
#include <cstdint>
#include <string_view>
#include <vector>
namespace Libs::Graphics::ShaderRecompiler::Frontend {
@@ -29,9 +28,6 @@ struct TranslateOptions {
uint64_t shader_hash = 0;
uint32_t user_data_base = 0;
uint32_t user_data_count = 64;
bool dispatcher_fallback = false;
CFG::FailureKind cfg_failure_kind = CFG::FailureKind::None;
std::string_view fallback_reason;
ShaderStageInputInfo input_info;
const EmbeddedFetchPlan* embedded_fetch = nullptr;
};
+2 -8
View File
@@ -57,17 +57,12 @@ struct MemoryInfo {
uint32_t image_sample_flags = 0;
Decoder::ImageDimension image_dimension = Decoder::ImageDimension::Unknown;
uint32_t image_address_components = 0;
uint32_t image_nsa_dwords = 0;
uint32_t image_nsa_addr[Decoder::MaxImageNsaAddressComponents] = {};
uint32_t memory_segment = 0;
bool address_is_full = false;
bool data_signed = false;
bool typed = false;
bool formatted = false;
bool image_has_mip = false;
bool image_r128 = false;
bool glc = false;
bool slc = false;
bool idxen = false;
bool offen = false;
bool planning_only = false;
@@ -540,9 +535,8 @@ struct Program: ResourcePlan {
CFG::FailureKind cfg_failure_kind = CFG::FailureKind::None;
std::string fallback_reason;
std::vector<BlockInfo> block_info;
// Decoded MIMG/VMEM metadata carries details such as RDNA2 NSA address registers and
// storage-image swizzles. Typed memory instructions carry a dense index into these shader-local
// tables until those fields are consumed by emission.
// Typed memory and export instructions reference shader-local metadata by dense index.
// Decoder-only details (such as NSA register numbers) have already become IR operands.
std::vector<ExportInfo> export_info;
std::vector<Value> dynamic_reads;
bool shader_info_complete = false;