mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-06 17:32:05 +00:00
[qfcc] Extend handles to support image types
Images are just handles, but they have additional type data like dimensionality, array, etc that distinguishes between the image types.
This commit is contained in:
parent
03c47f8af7
commit
c16a8411bc
6 changed files with 203 additions and 3 deletions
|
@ -28,6 +28,8 @@
|
|||
#ifndef __glsl_lang_h
|
||||
#define __glsl_lang_h
|
||||
|
||||
#include "QF/darray.h"
|
||||
|
||||
typedef struct specifier_s specifier_t;
|
||||
typedef struct attribute_s attribute_t;
|
||||
typedef struct expr_s expr_t;
|
||||
|
@ -78,6 +80,31 @@ typedef struct glsl_block_s {
|
|||
symbol_t *instance_name;
|
||||
} glsl_block_t;
|
||||
|
||||
typedef enum {
|
||||
glid_1d,
|
||||
glid_2d,
|
||||
glid_3d,
|
||||
glid_cube,
|
||||
glid_rect,
|
||||
glid_buffer,
|
||||
glid_subpassdata,
|
||||
} glsl_imagedim_t;
|
||||
|
||||
typedef struct glsl_image_s {
|
||||
const type_t *sample_type;
|
||||
glsl_imagedim_t dim;
|
||||
char depth;
|
||||
bool arrayed;
|
||||
bool multisample;
|
||||
char sampled;
|
||||
unsigned format;
|
||||
} glsl_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;
|
||||
|
||||
typedef struct glsl_sublang_s {
|
||||
const char *name;
|
||||
const char **interface_default_names;
|
||||
|
|
|
@ -68,4 +68,6 @@ struct def_s * emit_structure (const char *name, int su, struct_def_t *defs,
|
|||
struct defspace_s *space,
|
||||
enum storage_class_e storage);
|
||||
|
||||
struct symbol_s *make_handle (const char *name, type_t *type);
|
||||
|
||||
#endif//__struct_h
|
||||
|
|
|
@ -68,6 +68,11 @@ typedef struct ty_alias_s {
|
|||
const struct type_s *full_type; ///< full alias chain
|
||||
} ty_alias_t;
|
||||
|
||||
typedef struct ty_handle_s {
|
||||
const type_t *type; ///< descriptor for extra
|
||||
unsigned extra; ///< handle for extra
|
||||
} ty_handle_t;
|
||||
|
||||
typedef struct type_s {
|
||||
etype_t type; ///< ev_invalid means structure/array etc
|
||||
unsigned id; ///< internal id for registerd types
|
||||
|
@ -90,6 +95,7 @@ typedef struct type_s {
|
|||
struct algebra_s *algebra;
|
||||
struct multivector_s *multivec;
|
||||
ty_alias_t alias;
|
||||
ty_handle_t handle;
|
||||
};
|
||||
attribute_t *attributes;
|
||||
struct type_s *next;
|
||||
|
|
|
@ -33,6 +33,30 @@
|
|||
#include "tools/qfcc/include/qfcc.h"
|
||||
#include "tools/qfcc/include/rua-lang.h"
|
||||
#include "tools/qfcc/include/spirv.h"
|
||||
#include "tools/qfcc/include/struct.h"
|
||||
#include "tools/qfcc/include/type.h"
|
||||
|
||||
glsl_imageset_t glsl_imageset = DARRAY_STATIC_INIT (16);
|
||||
|
||||
static struct_def_t glsl_image_struct[] = {
|
||||
{"type", &type_ptr},
|
||||
{"dim", &type_uint}, //FIXME enum
|
||||
{"depth", &type_uint}, //FIXME enum
|
||||
{"arrayed", &type_bool},
|
||||
{"multisample", &type_bool},
|
||||
{"sampled", &type_uint}, //FIXME enum
|
||||
{"format", &type_uint}, //FIXME enum
|
||||
{}
|
||||
};
|
||||
|
||||
type_t type_glsl_image = {
|
||||
.type = ev_invalid,
|
||||
.meta = ty_struct,
|
||||
};
|
||||
type_t type_glsl_sampler = {
|
||||
.type = ev_int,
|
||||
.meta = ty_handle,
|
||||
};
|
||||
|
||||
#define SRC_LINE_EXP2(l,f) "#line " #l " " #f "\n"
|
||||
#define SRC_LINE_EXP(l,f) SRC_LINE_EXP2(l,f)
|
||||
|
@ -921,6 +945,13 @@ glsl_init_common (void)
|
|||
static module_t module; //FIXME probably not what I want
|
||||
pr.module = &module;
|
||||
|
||||
make_structure ("@image", 's', glsl_image_struct, &type_glsl_image);
|
||||
make_handle ("@sampler", &type_glsl_sampler);
|
||||
chain_type (&type_glsl_image);
|
||||
chain_type (&type_glsl_sampler);
|
||||
|
||||
DARRAY_RESIZE (&glsl_imageset, 0);
|
||||
|
||||
spirv_set_addressing_model (pr.module, SpvAddressingModelLogical);
|
||||
spirv_set_memory_model (pr.module, SpvMemoryModelGLSL450);
|
||||
|
||||
|
|
|
@ -1554,7 +1554,7 @@ static keyword_t glsl_keywords[] = {
|
|||
{"textureBuffer", GLSL_TYPE_SPEC},
|
||||
{"itextureBuffer", GLSL_TYPE_SPEC},
|
||||
{"utextureBuffer", GLSL_TYPE_SPEC},
|
||||
{"sampler", GLSL_TYPE_SPEC},
|
||||
{"sampler", GLSL_TYPE_SPEC, .spec = {.type = &type_glsl_sampler}},
|
||||
{"samplerShadow", GLSL_TYPE_SPEC},
|
||||
{"subpassInput", GLSL_TYPE_SPEC},
|
||||
{"isubpassInput", GLSL_TYPE_SPEC},
|
||||
|
@ -1635,14 +1635,141 @@ glsl_directive (const char *token)
|
|||
return directive;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const char *substr;
|
||||
int val;
|
||||
const type_t *type;
|
||||
} image_sub_t;
|
||||
|
||||
static image_sub_t * __attribute__((pure))
|
||||
find_image_sub (image_sub_t *sub, const char *str)
|
||||
{
|
||||
for (; sub->substr; sub++) {
|
||||
if (strncmp (sub->substr, str, strlen(sub->substr)) == 0) {
|
||||
return sub;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static symbol_t *
|
||||
glsl_parse_image (const char *token)
|
||||
{
|
||||
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 },
|
||||
// subpassInput is dimension in spir-v
|
||||
{}
|
||||
};
|
||||
static image_sub_t image_dim[] = {
|
||||
{ "2DRect", glid_rect }, // so 2D doesn't falsly match
|
||||
{ "1D", glid_1d },
|
||||
{ "2D", glid_2d },
|
||||
{ "3D", glid_3d },
|
||||
{ "Cube", glid_cube },
|
||||
{ "Buffer", glid_buffer },
|
||||
{ "subpassInput", glid_subpassdata },
|
||||
{}
|
||||
};
|
||||
static image_sub_t image_ms[] = {
|
||||
{ "MS", true },
|
||||
{ "", false },
|
||||
{}
|
||||
};
|
||||
static image_sub_t image_array[] = {
|
||||
{ "Array", true },
|
||||
{ "", false },
|
||||
{}
|
||||
};
|
||||
static image_sub_t image_shadow[] = {
|
||||
{ "Shadow", true },
|
||||
{ "", false },
|
||||
{}
|
||||
};
|
||||
|
||||
int offset = 0;
|
||||
auto type = *find_image_sub (image_type, token + offset);// always succeeds
|
||||
offset += strlen (type.substr);
|
||||
auto dim = find_image_sub (image_dim, token + offset);
|
||||
if (!dim) {
|
||||
goto invalid;
|
||||
}
|
||||
offset += strlen (dim->substr);
|
||||
if (!is_float (type.type)) {
|
||||
type.substr++; // skip over type char
|
||||
}
|
||||
if (dim->val == glid_subpassdata) {
|
||||
type.substr = dim->substr;
|
||||
}
|
||||
auto ms = *find_image_sub (image_ms, token + offset);
|
||||
offset += strlen (ms.substr);
|
||||
auto array = *find_image_sub (image_array, token + offset);
|
||||
offset += strlen (array.substr);
|
||||
|
||||
glsl_image_t image = {
|
||||
.sample_type = type.type,
|
||||
.dim = dim->val,
|
||||
.depth = 0, //XXX what sets this?
|
||||
.arrayed = array.val,
|
||||
.multisample = ms.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";
|
||||
}
|
||||
}
|
||||
if (token[offset]) {
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
unsigned index = 0;
|
||||
// slot 0 is never used
|
||||
for (unsigned i = 1; i < glsl_imageset.size; i++) {
|
||||
if (memcmp (&glsl_imageset.a[i], &image, sizeof (image)) == 0) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!index) {
|
||||
index = glsl_imageset.size;
|
||||
DARRAY_APPEND (&glsl_imageset, image);
|
||||
}
|
||||
|
||||
auto sym = new_symbol (token);
|
||||
sym = find_handle (sym, &type_int);
|
||||
//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");
|
||||
}
|
||||
t->handle.extra = index;
|
||||
|
||||
return sym;
|
||||
invalid:
|
||||
internal_error (0, "invalid image type: %s", token);
|
||||
}
|
||||
|
||||
static int
|
||||
glsl_process_keyword (rua_val_t *lval, keyword_t *keyword, const char *token)
|
||||
{
|
||||
if (keyword->value == GLSL_STRUCT) {
|
||||
lval->op = token[0];
|
||||
} else if (keyword->value == GLSL_TYPE_SPEC && !keyword->spec.type) {
|
||||
auto sym = new_symbol (token);
|
||||
sym = find_handle (sym, &type_int);
|
||||
auto sym = glsl_parse_image (token);
|
||||
keyword->spec.type = sym->type;
|
||||
lval->spec = keyword->spec;
|
||||
} else if (keyword->use_name) {
|
||||
|
|
|
@ -441,3 +441,10 @@ emit_structure (const char *name, int su, struct_def_t *defs,
|
|||
}
|
||||
return struct_def;
|
||||
}
|
||||
|
||||
symbol_t *
|
||||
make_handle (const char *name, type_t *type)
|
||||
{
|
||||
auto tag = new_symbol (name);
|
||||
return find_tag (ty_handle, tag, type);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue