[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.
This commit is contained in:
Bill Currie 2024-09-20 12:24:51 +09:00
parent 34fc2108ea
commit 1117d31b30
5 changed files with 73 additions and 31 deletions

View file

@ -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);

View file

@ -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)

View file

@ -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)

View file

@ -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,9 +737,10 @@ layout_check_qualifier (const layout_qual_t *qual, specifier_t spec)
}
if (spec.sym) {
auto sym = spec.sym;
if (sym->type) {
if (is_handle (sym->type)) {
var_type = var_opaque;
} else if (is_scalar (sym->type)) {
} 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;
@ -717,13 +751,18 @@ layout_check_qualifier (const layout_qual_t *qual, specifier_t spec)
if (sym->table->parent && sym->table->parent->type == stab_struct) {
obj_mask = decl_member;
}
} else {
obj_mask = decl_block;
}
} else {
obj_mask = decl_qual;
}
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 {

View file

@ -628,10 +628,11 @@ block_declaration
}
struct_declaration_list '}'
{
auto spec = $<spec>0;
auto block = $<block>3;
if (block) {
current_symtab = block->members->parent;
glsl_finish_block (block);
glsl_finish_block (block, spec);
}
$$ = block;
}