From 1117d31b300c8904ae4b1c12a45fb7a2f4e2a54b Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 20 Sep 2024 12:24:51 +0900 Subject: [PATCH] [qfcc] Make some sideways progress with layouts I'm not sure it's the right directly, and qfcc's internals are starting to show their age. --- tools/qfcc/include/glsl-lang.h | 2 +- tools/qfcc/source/glsl-block.c | 4 +- tools/qfcc/source/glsl-builtins.c | 3 +- tools/qfcc/source/glsl-layout.c | 92 ++++++++++++++++++++++--------- tools/qfcc/source/glsl-parse.y | 3 +- 5 files changed, 73 insertions(+), 31 deletions(-) diff --git a/tools/qfcc/include/glsl-lang.h b/tools/qfcc/include/glsl-lang.h index cc063e037..6caf6949f 100644 --- a/tools/qfcc/include/glsl-lang.h +++ b/tools/qfcc/include/glsl-lang.h @@ -92,7 +92,7 @@ extern glsl_sublang_t glsl_frag_sublanguage; void glsl_block_clear (void); glsl_block_t *glsl_create_block (specifier_t spec, symbol_t *block_sym); -void glsl_finish_block (glsl_block_t *block); +void glsl_finish_block (glsl_block_t *block, specifier_t spec); void glsl_declare_block_instance (glsl_block_t *block, symbol_t *instance_name); glsl_block_t *glsl_get_block (const char *name, glsl_interface_t interface); symtab_t *glsl_optimize_attributes (attribute_t *attributes); diff --git a/tools/qfcc/source/glsl-block.c b/tools/qfcc/source/glsl-block.c index 15f9caaae..e70c31ce7 100644 --- a/tools/qfcc/source/glsl-block.c +++ b/tools/qfcc/source/glsl-block.c @@ -129,8 +129,10 @@ glsl_create_block (specifier_t spec, symbol_t *block_sym) } void -glsl_finish_block (glsl_block_t *block) +glsl_finish_block (glsl_block_t *block, specifier_t spec) { + spec.sym = block->name; + glsl_apply_attributes (block->attributes, spec); for (auto sym = block->members->symbols; sym; sym = sym->next) { if (sym->sy_type == sy_def) { //FIXME sc_extern isn't correct (problem with unsized arrays) diff --git a/tools/qfcc/source/glsl-builtins.c b/tools/qfcc/source/glsl-builtins.c index d4a61a57e..ef0ef2789 100644 --- a/tools/qfcc/source/glsl-builtins.c +++ b/tools/qfcc/source/glsl-builtins.c @@ -569,7 +569,8 @@ ivec3 textureSize(gsampler3D sampler, int lod) ivec2 textureSize(gsamplerCube sampler, int lod) int textureSize(sampler1DShadow sampler, int lod) ivec2 textureSize(sampler2DShadow sampler, int lod) -ivec2 textureSize(samplerCubeShadow sampler, int lod) ivec3 textureSize(gsamplerCubeArray sampler, int lod) +ivec2 textureSize(samplerCubeShadow sampler, int lod) +ivec3 textureSize(gsamplerCubeArray sampler, int lod) ivec3 textureSize(samplerCubeArrayShadow sampler, int lod) ivec2 textureSize(gsampler2DRect sampler) ivec2 textureSize(sampler2DRectShadow sampler) diff --git a/tools/qfcc/source/glsl-layout.c b/tools/qfcc/source/glsl-layout.c index d4a88044e..f994883af 100644 --- a/tools/qfcc/source/glsl-layout.c +++ b/tools/qfcc/source/glsl-layout.c @@ -45,6 +45,38 @@ #include "tools/qfcc/include/type.h" #include "tools/qfcc/include/value.h" +static void +glsl_layout_location_invalid (specifier_t spec, const expr_t *qual_name, + const expr_t *val) +{ + error (qual_name, "not allowed for vulkan"); +} + +static void +glsl_layout_location (specifier_t spec, const expr_t *qual_name, + const expr_t *val) +{ + notice (qual_name, "%s %s", expr_string (qual_name), + get_value_string (val->value)); +} + +static void +glsl_layout_binding (specifier_t spec, const expr_t *qual_name, + const expr_t *val) +{ + notice (qual_name, "%s %s", expr_string (qual_name), + get_value_string (val->value)); +} + +static void +glsl_layout_set_property (specifier_t spec, const expr_t *qual_name, + const expr_t *val) +{ + auto interface = glsl_iftype_from_sc (spec.storage); + notice (qual_name, "%s %s %s", glsl_interface_names[interface], + expr_string (qual_name), get_value_string (val->value)); +} + typedef enum { decl_var = 1 << 0, decl_qual = 1 << 1, @@ -65,8 +97,9 @@ typedef enum { typedef struct layout_qual_s { const char *name; - bool (*apply) (); - bool (*apply_expr) (); + void (*apply) (specifier_t spec, const expr_t *qual_name); + void (*apply_expr) (specifier_t spec, const expr_t *qual_name, + const expr_t *val); unsigned obj_mask; glsl_var_t var_type; unsigned if_mask; @@ -115,7 +148,7 @@ static layout_qual_t layout_qualifiers[] = { }, { .name = "binding", - .apply = E(nullptr), + .apply = E(glsl_layout_binding), .obj_mask = D(var)|D(block), .var_type = V(opaque), .if_mask = I(uniform)|I(buffer), @@ -151,14 +184,14 @@ static layout_qual_t layout_qualifiers[] = { .if_mask = I(uniform), }, { .name = "location", - .apply = E(nullptr), + .apply = E(glsl_layout_location_invalid), .obj_mask = D(var), .var_type = V(any), .if_mask = I(uniform)|I(buffer), }, { .name = "location", - .apply = E(nullptr), + .apply = E(glsl_layout_location), .obj_mask = D(var)|D(block)|D(member), .var_type = V(any), .if_mask = I(in)|I(out), @@ -293,37 +326,37 @@ static layout_qual_t layout_qualifiers[] = { }, { .name = "local_size_x", - .apply = E(nullptr), + .apply = E(glsl_layout_set_property), .obj_mask = D(qual), .if_mask = I(in), .stage_filter = C { "compute", nullptr }, }, { .name = "local_size_y", - .apply = E(nullptr), + .apply = E(glsl_layout_set_property), .obj_mask = D(qual), .if_mask = I(in), .stage_filter = C { "compute", nullptr }, }, { .name = "local_size_z", - .apply = E(nullptr), + .apply = E(glsl_layout_set_property), .obj_mask = D(qual), .if_mask = I(in), .stage_filter = C { "compute", nullptr }, }, { .name = "local_size_x_id", - .apply = E(nullptr), + .apply = E(glsl_layout_set_property), .obj_mask = D(qual), .if_mask = I(in), .stage_filter = C { "compute", nullptr }, }, { .name = "local_size_y_id", - .apply = E(nullptr), + .apply = E(glsl_layout_set_property), .obj_mask = D(qual), .if_mask = I(in), .stage_filter = C { "compute", nullptr }, }, { .name = "local_size_z_id", - .apply = E(nullptr), + .apply = E(glsl_layout_set_property), .obj_mask = D(qual), .if_mask = I(in), .stage_filter = C { "compute", nullptr }, @@ -704,18 +737,22 @@ layout_check_qualifier (const layout_qual_t *qual, specifier_t spec) } if (spec.sym) { auto sym = spec.sym; - if (is_handle (sym->type)) { - var_type = var_opaque; - } else if (is_scalar (sym->type)) { - var_type = var_scalar; - } else if (strcmp (sym->name, "gl_FragCoord") == 0) { - var_type = var_gl_FragCoord; - } else if (strcmp (sym->name, "gl_FragDepth") == 0) { - var_type = var_gl_FragDepth; - } - obj_mask = decl_var; - if (sym->table->parent && sym->table->parent->type == stab_struct) { - obj_mask = decl_member; + if (sym->type) { + if (is_handle (sym->type)) { + var_type = var_opaque; + } else if (spec.is_const && is_scalar (sym->type)) { + var_type = var_scalar; + } else if (strcmp (sym->name, "gl_FragCoord") == 0) { + var_type = var_gl_FragCoord; + } else if (strcmp (sym->name, "gl_FragDepth") == 0) { + var_type = var_gl_FragDepth; + } + obj_mask = decl_var; + if (sym->table->parent && sym->table->parent->type == stab_struct) { + obj_mask = decl_member; + } + } else { + obj_mask = decl_block; } } else { obj_mask = decl_qual; @@ -723,7 +760,9 @@ layout_check_qualifier (const layout_qual_t *qual, specifier_t spec) if (!(qual->obj_mask & obj_mask)) { return false; } - if (qual->var_type != var_type) { + if (obj_mask == decl_var + && qual->var_type != var_any + && qual->var_type != var_type) { return false; } if (!(qual->if_mask & if_mask)) { @@ -760,7 +799,6 @@ layout_apply_qualifier (const expr_t *qualifier, specifier_t spec) ? qualifier->expr.e2 : nullptr; - notice (qualifier, "%s %p", key.name, spec.sym); const layout_qual_t *qual; qual = bsearch (&key, layout_qualifiers, layout_qual_sz, layout_qual_cmp); if (!qual) { @@ -780,14 +818,14 @@ layout_apply_qualifier (const expr_t *qualifier, specifier_t spec) if (!val) { error (qualifier, "%s requires a value", key.name); } else { - qual->apply_expr (); + qual->apply_expr (spec, qualifier->expr.e1, val); } return; } else if (qual->apply) { if (!val) { error (qualifier, "%s does not take a value", key.name); } else { - qual->apply (); + qual->apply (spec, qualifier->expr.e1); } return; } else { diff --git a/tools/qfcc/source/glsl-parse.y b/tools/qfcc/source/glsl-parse.y index 1071c59fb..26132d869 100644 --- a/tools/qfcc/source/glsl-parse.y +++ b/tools/qfcc/source/glsl-parse.y @@ -628,10 +628,11 @@ block_declaration } struct_declaration_list '}' { + auto spec = $0; auto block = $3; if (block) { current_symtab = block->members->parent; - glsl_finish_block (block); + glsl_finish_block (block, spec); } $$ = block; }