mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-23 12:26:56 +02:00
spirv: emit OpName only with debug info
This commit is contained in:
@@ -1619,6 +1619,17 @@ void CheckRectListShaders() {
|
||||
ValidateSpirv(name, position_only.evaluation);
|
||||
}
|
||||
|
||||
// Words without OpName/OpString/OpLine, which only graphics debug dumps emit.
|
||||
size_t SpirvCodeWords(const std::vector<u32> &spirv) {
|
||||
size_t words = spirv.size();
|
||||
for (size_t offset = 5; offset < spirv.size(); offset += spirv[offset] >> 16u) {
|
||||
const auto opcode = static_cast<spv::Op>(spirv[offset] & 0xffffu);
|
||||
if (opcode == spv::OpName || opcode == spv::OpString || opcode == spv::OpLine)
|
||||
words -= spirv[offset] >> 16u;
|
||||
}
|
||||
return words;
|
||||
}
|
||||
|
||||
void CheckSpirvEmission(const TestCase &test, const std::vector<u32> &spirv) {
|
||||
std::vector<u32> result_types(spirv[3]);
|
||||
for (size_t offset = 5; offset < spirv.size();) {
|
||||
@@ -1679,6 +1690,7 @@ CompiledShader CompileCase(const TestCase &test, u32 host_subgroup_size = 64) {
|
||||
options.stage = ShaderType::Compute;
|
||||
options.profile = test.profile;
|
||||
options.dump_ir = true;
|
||||
options.emit_debug_info = true; // Checks find variables and functions by OpName.
|
||||
auto compute_info = test.compute_info;
|
||||
compute_info.host_subgroup_size = host_subgroup_size;
|
||||
options.input_info.compute = &compute_info;
|
||||
@@ -1750,7 +1762,7 @@ CompiledShader CompileCase(const TestCase &test, u32 host_subgroup_size = 64) {
|
||||
result.program.shader_info_complete = false;
|
||||
ShaderRecompiler::IR::CollectShaderInfo(result.program, options.input_info);
|
||||
result.spirv = ShaderRecompiler::Spirv::EmitProgram(
|
||||
result.program, options.input_info, 0u, *options.profile);
|
||||
result.program, options.input_info, 0u, *options.profile, true);
|
||||
const auto shader_data = result.program.bindings.descriptor_counts[
|
||||
static_cast<size_t>(ShaderRecompiler::IR::DescriptorBindingKind::ShaderData)];
|
||||
Require(test.name, "binding layout",
|
||||
@@ -1764,11 +1776,12 @@ CompiledShader CompileCase(const TestCase &test, u32 host_subgroup_size = 64) {
|
||||
ValidateSpirv(test.name, result.spirv);
|
||||
CheckSpirvEmission(test, result.spirv);
|
||||
if (test.max_spirv_words != 0u) {
|
||||
Require(test.name, "emitted shader size", result.spirv.size() <= test.max_spirv_words,
|
||||
"SPIR-V words=" + std::to_string(result.spirv.size()) +
|
||||
const auto words = SpirvCodeWords(result.spirv);
|
||||
Require(test.name, "emitted shader size", words <= test.max_spirv_words,
|
||||
"SPIR-V words=" + std::to_string(words) +
|
||||
", limit=" + std::to_string(test.max_spirv_words));
|
||||
std::printf("[compute] %s wave=%u SPIR-V words=%zu\n", test.name,
|
||||
result.program.wave_size, result.spirv.size());
|
||||
result.program.wave_size, words);
|
||||
}
|
||||
if (test.expected_buffer_resources) {
|
||||
std::vector<u32> resources;
|
||||
@@ -40580,7 +40593,7 @@ void CheckNestedPointerImageTable(VulkanHarness &vulkan) {
|
||||
compiled.program.info.samplers.size() == rows + 1u &&
|
||||
tools.Disassemble(compiled.spirv, &text) &&
|
||||
CountText(text, "OpImageSampleExplicitLod") == halves &&
|
||||
compiled.spirv.size() <= 8192u * halves,
|
||||
SpirvCodeWords(compiled.spirv) <= 8192u * halves,
|
||||
"59 sampler records hit the SGPR root limit or duplicated image sampling bodies");
|
||||
}
|
||||
if (large_samplers)
|
||||
|
||||
@@ -99,6 +99,7 @@ ShaderRecompiler::CompileOptions MakeCompileOptions(ShaderType stage) {
|
||||
ShaderRecompiler::CompileOptions options;
|
||||
options.stage = stage;
|
||||
options.user_data = user_data;
|
||||
options.emit_debug_info = true; // Checks find variables and functions by OpName.
|
||||
switch (stage) {
|
||||
case ShaderType::Vertex:
|
||||
options.input_info.vertex = &vertex;
|
||||
@@ -403,6 +404,11 @@ SpirvMetrics MeasureSpirv(const std::vector<uint32_t> &binary) {
|
||||
if (word_count == 0 || i + word_count > binary.size()) {
|
||||
break;
|
||||
}
|
||||
if (opcode == spv::OpName || opcode == spv::OpString || opcode == spv::OpLine) {
|
||||
metrics.words -= word_count; // Budgets measure the module without debug info.
|
||||
i += word_count;
|
||||
continue;
|
||||
}
|
||||
metrics.instructions++;
|
||||
switch (opcode) {
|
||||
case 11u: // OpExtInstImport
|
||||
@@ -10354,7 +10360,7 @@ void TestNewShaderRecompilerPlanningOnlyLoads() {
|
||||
ir.Emit(IR::ValueOpcode::ReferenceU32, {read});
|
||||
program.shader_info_complete = false;
|
||||
IR::CollectShaderInfo(program, options.input_info);
|
||||
const auto spirv = Spirv::EmitProgram(program, options.input_info);
|
||||
const auto spirv = Spirv::EmitProgram(program, options.input_info, 0, {}, true);
|
||||
CheckSpirvBinaryValidates(spirv);
|
||||
Check(spirv == result.spirv,
|
||||
"planning-only loads or references emitted GPU operands/instructions");
|
||||
@@ -11100,6 +11106,7 @@ void TestMeshExportStorage() {
|
||||
options.stage = ShaderType::Mesh;
|
||||
options.input_info.vertex = &input;
|
||||
options.user_data = user_data;
|
||||
options.emit_debug_info = true; // The checks find push data by its OpName.
|
||||
struct Case {
|
||||
uint32_t subgroup_size, push_data_start;
|
||||
bool split;
|
||||
@@ -14352,7 +14359,8 @@ void TestNewShaderRecompilerNativeBindingPlan() {
|
||||
const auto bindings = result.program.bindings;
|
||||
result.program.bindings = {};
|
||||
result.program.info.buffers[0].descriptor_index = UINT32_MAX;
|
||||
Check(ShaderRecompiler::Spirv::EmitProgram(result.program, options.input_info) == result.spirv &&
|
||||
Check(ShaderRecompiler::Spirv::EmitProgram(result.program, options.input_info, 0, {}, true) ==
|
||||
result.spirv &&
|
||||
result.program.bindings == bindings &&
|
||||
result.program.info.buffers[0].descriptor_index == 0,
|
||||
"repeated emission did not rebuild descriptor slots deterministically");
|
||||
@@ -16423,11 +16431,15 @@ void TestRepeatedExportsHaveOneInterface() {
|
||||
void CheckSpirvBlockSourceMapping(TestCompileResult &result) {
|
||||
using namespace ShaderRecompiler;
|
||||
const auto options = MakeCompileOptions(ShaderType::Compute);
|
||||
Check(SpirvInstructionOpcodeCount(result.spirv, spv::OpString) == 0 &&
|
||||
SpirvInstructionOpcodeCount(result.spirv, spv::OpLine) == 0,
|
||||
"default emission unexpectedly contains source mapping");
|
||||
const auto plain = Spirv::EmitProgram(result.program, options.input_info);
|
||||
Check(SpirvInstructionOpcodeCount(plain, spv::OpString) == 0 &&
|
||||
SpirvInstructionOpcodeCount(plain, spv::OpLine) == 0 &&
|
||||
SpirvInstructionOpcodeCount(plain, spv::OpName) == 0,
|
||||
"default emission unexpectedly contains debug info");
|
||||
const auto mapped =
|
||||
Spirv::EmitProgram(result.program, options.input_info, 0, {}, true);
|
||||
Check(SpirvInstructionOpcodeCount(mapped, spv::OpName) != 0,
|
||||
"debug emission omitted names");
|
||||
CheckSpirvBinaryValidates(mapped);
|
||||
uint32_t source = 0;
|
||||
uint32_t label = 0;
|
||||
@@ -16456,7 +16468,7 @@ void CheckSpirvBlockSourceMapping(TestCompileResult &result) {
|
||||
}
|
||||
Check(source != 0 && lines >= result.program.blocks.size(),
|
||||
"debug emission omitted native block source mapping");
|
||||
Check(Spirv::EmitProgram(result.program, options.input_info) == result.spirv,
|
||||
Check(Spirv::EmitProgram(result.program, options.input_info) == plain,
|
||||
"debug re-emission changed the default binary");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user