shader: use Khronos definitions and simplify compiler ownership

This commit is contained in:
nmzik
2026-09-11 18:42:05 +04:00
parent 47b26e497f
commit 1d1f00bdef
28 changed files with 2048 additions and 2153 deletions
+57 -84
View File
@@ -1392,7 +1392,7 @@ CompiledShader CompileCase(const TestCase &test, u32 host_subgroup_size = 64) {
compute_info.host_subgroup_size = host_subgroup_size;
options.input_info.compute = &compute_info;
options.user_data = user_data;
options.scratch_dwords = test.compute_info.scratch_size_dwords;
if (test.has_compute_info) {
options.wave_size = test.compute_info.wave_size;
}
@@ -1598,86 +1598,59 @@ std::array<u32, 64> MakeSampledTextureData(Prospero::BufferFormat format) {
namespace TestSpv {
enum : u32 {
ExecutionModelVertex = 0,
AddressingModelLogical = 0,
MemoryModelGLSL450 = 1,
CapabilityShader = 1,
StorageClassInput = 1,
StorageClassOutput = 3,
FunctionControlNone = 0,
DecorationBlock = 2,
DecorationBuiltIn = 11,
DecorationLocation = 30,
BuiltInPosition = 0,
OpTypeVoid = 19,
OpTypeInt = 21,
OpTypeFloat = 22,
OpTypeVector = 23,
OpTypeStruct = 30,
OpTypePointer = 32,
OpTypeFunction = 33,
OpConstant = 43,
OpFunction = 54,
OpFunctionEnd = 56,
OpVariable = 59,
OpLoad = 61,
OpStore = 62,
OpAccessChain = 65,
OpDecorate = 71,
OpMemberDecorate = 72,
OpCompositeConstruct = 80,
OpCompositeExtract = 81,
OpLabel = 248,
OpReturn = 253,
};
std::vector<u32> MakePassthroughVertexSpirv(bool layered, float clip_w = 1.0f) {
using ShaderRecompiler::Spirv::Builder;
Builder b;
const auto void_type = b.Type(OpTypeVoid);
const auto uint_type = b.Type(OpTypeInt, {32, 0});
const auto int_type = b.Type(OpTypeInt, {32, 1});
const auto float_type = b.Type(OpTypeFloat, {32});
const auto vec2_type = b.Type(OpTypeVector, {float_type, 2});
const auto vec4_type = b.Type(OpTypeVector, {float_type, 4});
const auto per_vertex_type = b.DecoratedType(
OpTypeStruct, {vec4_type},
{{OpDecorate, {DecorationBlock}},
{OpMemberDecorate, {0, DecorationBuiltIn, BuiltInPosition}}});
const auto void_type = b.Type(spv::OpTypeVoid);
const auto uint_type = b.Type(spv::OpTypeInt, {32, 0});
const auto int_type = b.Type(spv::OpTypeInt, {32, 1});
const auto float_type = b.Type(spv::OpTypeFloat, {32});
const auto vec2_type = b.Type(spv::OpTypeVector, {float_type, 2});
const auto vec4_type = b.Type(spv::OpTypeVector, {float_type, 4});
const auto per_vertex_type =
b.DecoratedType(spv::OpTypeStruct, {vec4_type},
{{spv::OpDecorate, {spv::DecorationBlock}},
{spv::OpMemberDecorate,
{0, spv::DecorationBuiltIn, spv::BuiltInPosition}}});
const auto ptr_input_vec2 =
b.Type(OpTypePointer, {StorageClassInput, vec2_type});
b.Type(spv::OpTypePointer, {spv::StorageClassInput, vec2_type});
const auto ptr_input_vec4 =
b.Type(OpTypePointer, {StorageClassInput, vec4_type});
b.Type(spv::OpTypePointer, {spv::StorageClassInput, vec4_type});
const auto ptr_output_vec4 =
b.Type(OpTypePointer, {StorageClassOutput, vec4_type});
b.Type(spv::OpTypePointer, {spv::StorageClassOutput, vec4_type});
const auto ptr_output_per_vertex =
b.Type(OpTypePointer, {StorageClassOutput, per_vertex_type});
const auto func_type = b.Type(OpTypeFunction, {void_type});
const auto const_u32_0 = b.Constant(OpConstant, uint_type, {0});
const auto const_f32_0 = b.Constant(OpConstant, float_type, {0x00000000u});
b.Type(spv::OpTypePointer, {spv::StorageClassOutput, per_vertex_type});
const auto func_type = b.Type(spv::OpTypeFunction, {void_type});
const auto const_u32_0 = b.Constant(spv::OpConstant, uint_type, {0});
const auto const_f32_0 =
b.Constant(spv::OpConstant, float_type, {0x00000000u});
const auto const_f32_w =
b.Constant(OpConstant, float_type, {std::bit_cast<u32>(clip_w)});
const auto in_pos = b.DefineGlobalVariable(ptr_input_vec2, StorageClassInput);
b.Constant(spv::OpConstant, float_type, {std::bit_cast<u32>(clip_w)});
const auto in_pos =
b.DefineGlobalVariable(ptr_input_vec2, spv::StorageClassInput);
const auto in_color =
b.DefineGlobalVariable(ptr_input_vec4, StorageClassInput);
b.DefineGlobalVariable(ptr_input_vec4, spv::StorageClassInput);
const auto out_color =
b.DefineGlobalVariable(ptr_output_vec4, StorageClassOutput);
b.DefineGlobalVariable(ptr_output_vec4, spv::StorageClassOutput);
const auto per_vertex =
b.DefineGlobalVariable(ptr_output_per_vertex, StorageClassOutput);
b.DefineGlobalVariable(ptr_output_per_vertex, spv::StorageClassOutput);
u32 instance = 0;
u32 layer = 0;
std::vector<u32> interfaces = {in_pos, in_color, per_vertex, out_color};
if (layered) {
instance = b.DefineGlobalVariable(
b.Type(OpTypePointer, {StorageClassInput, int_type}), StorageClassInput);
b.Type(spv::OpTypePointer, {spv::StorageClassInput, int_type}),
spv::StorageClassInput);
layer = b.DefineGlobalVariable(
b.Type(OpTypePointer, {StorageClassOutput, int_type}), StorageClassOutput);
b.AddAnnotation({OpDecorate, instance, DecorationBuiltIn, 43}); // InstanceIndex
b.AddAnnotation({OpDecorate, layer, DecorationBuiltIn, 9}); // Layer
b.Type(spv::OpTypePointer, {spv::StorageClassOutput, int_type}),
spv::StorageClassOutput);
b.AddAnnotation({spv::OpDecorate, instance, spv::DecorationBuiltIn,
spv::BuiltInInstanceIndex});
b.AddAnnotation(
{spv::OpDecorate, layer, spv::DecorationBuiltIn, spv::BuiltInLayer});
b.RequireVersion(0x00010500u);
b.RequireCapability(69); // ShaderLayer
b.RequireCapability(spv::CapabilityShaderLayer);
interfaces.insert(interfaces.end(), {instance, layer});
}
const auto main = b.AllocateId();
@@ -1689,32 +1662,33 @@ std::vector<u32> MakePassthroughVertexSpirv(bool layered, float clip_w = 1.0f) {
const auto position = b.AllocateId();
const auto position_ptr = b.AllocateId();
b.RequireCapability(CapabilityShader);
b.AddMemoryModel({AddressingModelLogical, MemoryModelGLSL450});
b.AddEntryPoint(ExecutionModelVertex, main, "main", interfaces);
b.AddAnnotation({OpDecorate, in_pos, DecorationLocation, 0});
b.AddAnnotation({OpDecorate, in_color, DecorationLocation, 1});
b.AddAnnotation({OpDecorate, out_color, DecorationLocation, 0});
b.RequireCapability(spv::CapabilityShader);
b.AddMemoryModel({spv::AddressingModelLogical, spv::MemoryModelGLSL450});
b.AddEntryPoint(spv::ExecutionModelVertex, main, "main", interfaces);
b.AddAnnotation({spv::OpDecorate, in_pos, spv::DecorationLocation, 0});
b.AddAnnotation({spv::OpDecorate, in_color, spv::DecorationLocation, 1});
b.AddAnnotation({spv::OpDecorate, out_color, spv::DecorationLocation, 0});
b.AddFunction({OpFunction, void_type, main, FunctionControlNone, func_type});
b.AddFunction({OpLabel, label});
b.AddFunction({OpLoad, vec2_type, pos2, in_pos});
b.AddFunction({OpLoad, vec4_type, color4, in_color});
b.AddFunction({OpCompositeExtract, float_type, pos_x, pos2, 0});
b.AddFunction({OpCompositeExtract, float_type, pos_y, pos2, 1});
b.AddFunction({OpCompositeConstruct, vec4_type, position, pos_x, pos_y,
b.AddFunction({spv::OpFunction, void_type, main, spv::FunctionControlMaskNone,
func_type});
b.AddFunction({spv::OpLabel, label});
b.AddFunction({spv::OpLoad, vec2_type, pos2, in_pos});
b.AddFunction({spv::OpLoad, vec4_type, color4, in_color});
b.AddFunction({spv::OpCompositeExtract, float_type, pos_x, pos2, 0});
b.AddFunction({spv::OpCompositeExtract, float_type, pos_y, pos2, 1});
b.AddFunction({spv::OpCompositeConstruct, vec4_type, position, pos_x, pos_y,
const_f32_0, const_f32_w});
b.AddFunction(
{OpAccessChain, ptr_output_vec4, position_ptr, per_vertex, const_u32_0});
b.AddFunction({OpStore, position_ptr, position});
b.AddFunction({OpStore, out_color, color4});
b.AddFunction({spv::OpAccessChain, ptr_output_vec4, position_ptr, per_vertex,
const_u32_0});
b.AddFunction({spv::OpStore, position_ptr, position});
b.AddFunction({spv::OpStore, out_color, color4});
if (layered) {
const auto index = b.AllocateId();
b.AddFunction({OpLoad, int_type, index, instance});
b.AddFunction({OpStore, layer, index});
b.AddFunction({spv::OpLoad, int_type, index, instance});
b.AddFunction({spv::OpStore, layer, index});
}
b.AddFunction({OpReturn});
b.AddFunction({OpFunctionEnd});
b.AddFunction({spv::OpReturn});
b.AddFunction({spv::OpFunctionEnd});
return b.Build();
}
@@ -23866,7 +23840,6 @@ void CheckIndirectImageKeySwitch() {
AllocateBindings(program);
ShaderComputeInputInfo compute{};
ShaderRecompiler::Spirv::AnalyzeProgramRequirements(program);
auto spirv = ShaderRecompiler::Spirv::EmitProgram(program,
{.compute = &compute});
ValidateSpirv(name, spirv);