[qfcc] Emit spirv image type encodings

Access qualifiers aren't supported yet, and some of the image handling
is a bit messy (currently tied to glsl when it should be general), but
the basics are there. However, now I've got to sort out the execution
model (need Fragment or GLCompute for ImplicitLod).
This commit is contained in:
Bill Currie 2025-01-09 01:29:38 +09:00
parent 99b1859aac
commit 4998968169
4 changed files with 111 additions and 19 deletions

View file

@ -99,12 +99,18 @@ typedef struct glsl_image_s {
bool multisample;
char sampled;
unsigned format;
uint32_t id;
} glsl_image_t;
typedef struct glsl_sampled_image_s {
const type_t *image_type;
} glsl_sampled_image_t;
typedef struct DARRAY_TYPE (glsl_image_t) glsl_imageset_t;
extern glsl_imageset_t glsl_imageset;
extern type_t type_glsl_image;
extern type_t type_glsl_sampler;
extern type_t type_glsl_sampled_image;
typedef struct glsl_sublang_s {
const char *name;

View file

@ -50,10 +50,19 @@ static struct_def_t glsl_image_struct[] = {
{}
};
static struct_def_t glsl_sampled_image_struct[] = {
{"image_type", &type_ptr},
{}
};
type_t type_glsl_image = {
.type = ev_invalid,
.meta = ty_struct,
};
type_t type_glsl_sampled_image = {
.type = ev_invalid,
.meta = ty_struct,
};
type_t type_glsl_sampler = {
.type = ev_int,
.meta = ty_handle,
@ -348,6 +357,7 @@ SRC_LINE
"#define lowp" "\n"
"#define uint unsigned" "\n"
"#define uvec2 uivec2" "\n"
"#define sampler(t,d,m,a,s) @handle t##sampler##d##m##a##s" "\n"
"@generic(genFType=@vector(float)," "\n"
" genDType=@vector(double)," "\n"
" genIType=@vector(int)," "\n"
@ -357,7 +367,19 @@ SRC_LINE
" vec=[vec2,vec3,vec4,dvec2,dvec3,dvec4]," "\n"
" ivec=[ivec2,ivec3,ivec4]," "\n"
" uvec=[uivec2,uivec3,uivec4]," "\n"
" bvec=[bvec2,bvec3,bvec4]) {" "\n"
" bvec=[bvec2,bvec3,bvec4]," "\n"
" gsampler2DArray=[sampler(,2D,,Array,)," "\n"
" sampler(i,2D,,Array,)," "\n"
" sampler(u,2D,,Array,)]," "\n"
" gsampler1D=[sampler(,1D,,,)," "\n"
" sampler(i,1D,,,)," "\n"
" sampler(u,1D,,,)]," "\n"
" gsampler2D=[sampler(,2D,,,)," "\n"
" sampler(i,2D,,,)," "\n"
" sampler(u,2D,,,)]," "\n"
" gsampler3D=[sampler(,3D,,,)," "\n"
" sampler(i,3D,,,)," "\n"
" sampler(u,3D,,,)]) {" "\n"
"genFType radians(genFType degrees);" "\n"
"genFType degrees(genFType radians);" "\n"
"genFType sin(genFType angle);" "\n"
@ -377,7 +399,7 @@ SRC_LINE
//exponential functions
SRC_LINE
"genFType pow(genFType x, genFType y);" "\n"
"genFType exp(genFType x);" "\n"
"genFType exp(genFType x) = " GLSL(27) ";" "\n"
"genFType log(genFType x);" "\n"
"genFType exp2(genFType x);" "\n"
"genFType log2(genFType x);" "\n"
@ -584,6 +606,10 @@ SRC_LINE
"genIType findLSB(genUType value);" "\n"
"genIType findMSB(highp genIType value);" "\n"
"genIType findMSB(highp genUType value);" "\n"
"vec4 texture(gsampler1D sampler, float P ) = " SPV(87) ";" "\n"
"vec4 texture(gsampler2D sampler, vec2 P ) = " SPV(87) ";" "\n"
"vec4 texture(gsampler3D sampler, vec3 P ) = " SPV(87) ";" "\n"
"vec4 texture(gsampler2DArray sampler, vec3 P ) = " SPV(87) ";" "\n"
"};" "\n"
"#undef out" "\n"
"#undef highp" "\n"
@ -952,9 +978,12 @@ glsl_init_common (rua_ctx_t *ctx)
pr.module = &module;
make_structure ("@image", 's', glsl_image_struct, &type_glsl_image);
make_structure ("@sampled_image", 's', glsl_sampled_image_struct,
&type_glsl_sampled_image);
make_handle ("@sampler", &type_glsl_sampler);
chain_type (&type_glsl_image);
chain_type (&type_glsl_sampler);
chain_type (&type_glsl_sampled_image);
DARRAY_RESIZE (&glsl_imageset, 0);

View file

@ -1616,6 +1616,7 @@ typedef struct {
const char *substr;
int val;
const type_t *type;
const type_t *htype;
} image_sub_t;
static image_sub_t * __attribute__((pure))
@ -1633,19 +1634,31 @@ static symbol_t *
glsl_parse_image (const char *token, rua_ctx_t *ctx)
{
static image_sub_t image_type[] = {
{ .substr = "sampler", .val = 0, .type = &type_float },
{ .substr = "image", .val = 1, .type = &type_float },
{ .substr = "texture", .val = 2, .type = &type_float },
{ .substr = "isampler", .val = 0, .type = &type_int },
{ .substr = "iimage", .val = 1, .type = &type_int },
{ .substr = "itexture", .val = 2, .type = &type_int },
{ .substr = "usampler", .val = 0, .type = &type_uint },
{ .substr = "uimage", .val = 1, .type = &type_uint },
{ .substr = "utexture", .val = 2, .type = &type_uint },
{ .substr = "i", .val = 1, .type = &type_int },
{ .substr = "u", .val = 1, .type = &type_uint },
{ .substr = "", .val = 1, .type = &type_float },
{ .substr = "sampler", .val = 1, .type = &type_float,
.htype = &type_glsl_sampled_image },
{ .substr = "image", .val = 2, .type = &type_float,
.htype = &type_glsl_image },
{ .substr = "texture", .val = 1, .type = &type_float,
.htype = &type_glsl_image },
{ .substr = "isampler", .val = 1, .type = &type_int,
.htype = &type_glsl_sampled_image },
{ .substr = "iimage", .val = 2, .type = &type_int,
.htype = &type_glsl_image },
{ .substr = "itexture", .val = 1, .type = &type_int,
.htype = &type_glsl_image },
{ .substr = "usampler", .val = 1, .type = &type_uint,
.htype = &type_glsl_sampled_image },
{ .substr = "uimage", .val = 2, .type = &type_uint,
.htype = &type_glsl_image },
{ .substr = "utexture", .val = 1, .type = &type_uint,
.htype = &type_glsl_image },
// subpassInput is dimension in spir-v
{ .substr = "i", .val = 2, .type = &type_int,
.htype = &type_glsl_image },
{ .substr = "u", .val = 2, .type = &type_uint,
.htype = &type_glsl_image },
{ .substr = "", .val = 2, .type = &type_float,
.htype = &type_glsl_image },
{}
};
static image_sub_t image_dim[] = {
@ -1696,17 +1709,16 @@ glsl_parse_image (const char *token, rua_ctx_t *ctx)
glsl_image_t image = {
.sample_type = type.type,
.dim = dim->val,
.depth = 0, //XXX what sets this?
.depth = 0, //set below for shadow samplers
.arrayed = array.val,
.multisample = ms.val,
.sampled = type.val,
.format = 0, //unknown (comes from layout)
};
if (type.val == 0) { // sampler
auto shad = *find_image_sub (image_shadow, token + offset);
offset += strlen (shad.substr);
if (shad.val) {
type.substr = "samplerShadow";
}
image.depth = shad.val;
}
if (token[offset]) {
goto invalid;
@ -1721,18 +1733,23 @@ glsl_parse_image (const char *token, rua_ctx_t *ctx)
}
}
if (!index) {
if (!glsl_imageset.size) {
DARRAY_APPEND (&glsl_imageset, (glsl_image_t) { } );
}
index = glsl_imageset.size;
DARRAY_APPEND (&glsl_imageset, image);
}
auto sym = new_symbol (token);
sym = find_handle (sym, &type_int);
sym->type = find_type (sym->type);
//FIXME the type isn't chained yet and so doesn't need to be const, but
// symbols keep the type in a const pointer.
auto t = (type_t *) sym->type;
if (t->handle.extra) {
internal_error (0, "image type handle alread set");
internal_error (0, "image type handle already set");
}
t->handle.type = type.htype;
t->handle.extra = index;
return sym;

View file

@ -421,6 +421,38 @@ spirv_TypeBool (const type_t *type, spirvctx_t *ctx)
return id;
}
static unsigned
spirv_TypeImage (glsl_image_t *image, spirvctx_t *ctx)
{
if (image->id) {
return image->id;
}
unsigned tid = type_id (image->sample_type, ctx);
auto globals = ctx->module->globals;
image->id = spirv_id (ctx);
auto insn = spirv_new_insn (SpvOpTypeImage, 9, globals);
INSN (insn, 1) = image->id;
INSN (insn, 2) = tid;
INSN (insn, 3) = image->dim;
INSN (insn, 4) = image->depth;
INSN (insn, 5) = image->arrayed;
INSN (insn, 6) = image->multisample;
INSN (insn, 7) = image->sampled;
INSN (insn, 8) = image->format;
return image->id;
}
static unsigned
spirv_TypeSampledImage (unsigned image_id, spirvctx_t *ctx)
{
auto globals = ctx->module->globals;
unsigned id = spirv_id (ctx);
auto insn = spirv_new_insn (SpvOpTypeSampledImage, 3, globals);
INSN (insn, 1) = id;
INSN (insn, 2) = image_id;
return id;
}
static unsigned
spirv_TypeFunction (symbol_t *fsym, spirvctx_t *ctx)
{
@ -521,6 +553,14 @@ type_id (const type_t *type, spirvctx_t *ctx)
id = spirv_TypeStruct (type, ctx);
} else if (is_boolean (type)) {
id = spirv_TypeBool (type, ctx);
} else if (is_handle (type)
&& (type->handle.type == &type_glsl_image
|| type->handle.type == &type_glsl_sampled_image)) {
auto image = &glsl_imageset.a[type->handle.extra];
id = spirv_TypeImage (image, ctx);
if (type->handle.type == &type_glsl_sampled_image) {
id = spirv_TypeSampledImage (id, ctx);
}
}
if (!id) {
dstring_t *str = dstring_newstr ();