shader: remove recompiler error-string propagation

This commit is contained in:
nmzik
2026-08-31 05:30:18 +04:00
parent 13533bd053
commit af8aecfdde
47 changed files with 2040 additions and 3253 deletions
@@ -1,5 +1,6 @@
#include "graphics/shader/recompiler/ir/passes/BindingLayout.h"
#include "common/assert.h"
#include "graphics/shader/recompiler/ir/ShaderIR.h"
#include <algorithm>
@@ -9,12 +10,17 @@
namespace Libs::Graphics::ShaderRecompiler::IR {
namespace {
constexpr auto FirstImageBinding = DescriptorBindingKind::Sampled1D;
constexpr auto FirstImageBinding = DescriptorBindingKind::Sampled1D;
constexpr uint32_t ImageBindingCount =
static_cast<uint32_t>(DescriptorBindingKind::StorageAtomic3D) -
static_cast<uint32_t>(FirstImageBinding) + 1u;
bool CollectUserData(const Program& program, std::vector<uint32_t>& result) {
[[noreturn]] void BindingFail(const char* message) {
EXIT("shader binding layout failed: %s", message);
std::abort();
}
std::vector<uint32_t> CollectUserData(const Program& program) {
std::array<bool, NumScalarRegs> registers {};
for (const auto* block: program.blocks) {
for (const auto& inst: *block) {
@@ -22,22 +28,22 @@ bool CollectUserData(const Program& program, std::vector<uint32_t>& result) {
continue;
}
if (inst.Arg(0).GetType() != Type::ScalarReg) {
return false;
BindingFail("typed shader contains an invalid user-data register");
}
const auto index = RegIndex(inst.Arg(0).ScalarRegister());
if (index >= NumScalarRegs) {
return false;
BindingFail("typed shader contains an invalid user-data register");
}
registers[index] = true;
}
}
result.clear();
std::vector<uint32_t> result;
for (uint32_t index = 0; index < registers.size(); index++) {
if (registers[index]) {
result.push_back(index);
}
}
return true;
return result;
}
void AddBinding(BindingLayout& layout, DescriptorBindingKind kind,
@@ -45,8 +51,8 @@ void AddBinding(BindingLayout& layout, DescriptorBindingKind kind,
layout.descriptors.push_back({kind, std::move(resources)});
}
bool UsesGds(const Program& program, bool& uses_gds) {
uses_gds = false;
bool UsesGds(const Program& program) {
bool uses_gds = false;
for (const auto* block: program.blocks) {
for (const auto& inst: *block) {
if (SharedAccessOf(inst.GetOpcode()) == SharedAccess::None) {
@@ -54,44 +60,36 @@ bool UsesGds(const Program& program, bool& uses_gds) {
}
const auto index = inst.Flags<MemoryFlags>().index;
if (index >= program.memory_info.size()) {
return false;
BindingFail("typed shader contains invalid shared-memory metadata");
}
const auto kind = program.memory_info[index].kind;
if (kind != ResourceKind::Lds && kind != ResourceKind::Gds) {
return false;
BindingFail("typed shader contains invalid shared-memory metadata");
}
uses_gds |= kind == ResourceKind::Gds;
}
}
return true;
return uses_gds;
}
} // namespace
bool AllocateBindings(Program& program, uint32_t push_constant_offset, std::string* error) {
void AllocateBindings(Program& program, uint32_t push_constant_offset) {
if (!program.shader_info_complete || program.binding_layout_complete) {
if (error != nullptr) {
*error = !program.shader_info_complete ? "shader info is not ready"
: "binding layout already allocated";
}
return false;
EXIT("shader binding layout failed: %s", !program.shader_info_complete
? "shader info is not ready"
: "binding layout already allocated");
}
if (push_constant_offset > NativePushConstantSize ||
push_constant_offset % sizeof(uint32_t) != 0) {
if (error != nullptr) {
*error = "push-constant offset exceeds the Vulkan minimum guarantee or is unaligned";
}
return false;
EXIT("shader binding layout failed: push-constant offset %u exceeds the Vulkan minimum "
"guarantee or is unaligned",
push_constant_offset);
}
BindingLayout next;
next.push_constant_offset = push_constant_offset;
if (!CollectUserData(program, next.user_data_registers)) {
if (error != nullptr) {
*error = "typed shader contains an invalid user-data register";
}
return false;
}
next.user_data_registers = CollectUserData(program);
next.memory_offset_dword = static_cast<uint32_t>(next.user_data_registers.size());
next.memory_offset_count = static_cast<uint32_t>(program.info.buffers.size());
@@ -107,26 +105,18 @@ bool AllocateBindings(Program& program, uint32_t push_constant_offset, std::stri
for (uint32_t i = 0; i < program.info.images.size(); i++) {
const auto kind = DescriptorBindingForImage(program.info.images[i]);
if (!kind.has_value()) {
if (error != nullptr) {
*error = "shader info contains an invalid image binding class";
}
return false;
EXIT("shader binding layout failed: image %u has an invalid binding class", i);
}
const auto group = static_cast<uint32_t>(*kind) - static_cast<uint32_t>(FirstImageBinding);
if (group >= image_groups.size()) {
if (error != nullptr) {
*error = "shader info contains an unmapped image binding class";
}
return false;
EXIT("shader binding layout failed: image %u has an unmapped binding class", i);
}
auto& resources = image_groups[group];
const auto dynamic = program.info.images[i].mip_mode == ImageMipMode::DynamicStorage;
const auto count = dynamic ? program.info.images[i].mip_count : 1u;
if (count == 0u || (!dynamic && program.info.images[i].mip_count != 1u)) {
if (error != nullptr) {
*error = "image has an invalid specialized mip descriptor count";
}
return false;
EXIT("shader binding layout failed: image %u has invalid specialized mip count %u", i,
program.info.images[i].mip_count);
}
resources.insert(resources.end(), count, i);
}
@@ -146,14 +136,7 @@ bool AllocateBindings(Program& program, uint32_t push_constant_offset, std::stri
}
AddBinding(next, DescriptorBindingKind::Samplers, std::move(resources));
}
bool uses_gds = false;
if (!UsesGds(program, uses_gds)) {
if (error != nullptr) {
*error = "typed shader contains invalid shared-memory metadata";
}
return false;
}
if (uses_gds) {
if (UsesGds(program)) {
AddBinding(next, DescriptorBindingKind::Gds);
}
if (program.info.uses_dma) {
@@ -178,7 +161,6 @@ bool AllocateBindings(Program& program, uint32_t push_constant_offset, std::stri
program.bindings = std::move(next);
program.binding_layout_complete = true;
return true;
}
const DescriptorBinding* FindBinding(const BindingLayout& layout, DescriptorBindingKind kind) {