mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-04 08:25:34 +00:00
[qfcc] Implement the image format layout qualifier
It doesn't really work yet for multiple reasons (eg, not an exact match with the spir-v names, and the type system itself being a little inadequate), but gotta start somewhere.
This commit is contained in:
parent
10505451eb
commit
ad51881a60
3 changed files with 92 additions and 30 deletions
|
@ -146,4 +146,7 @@ bool glsl_on_include (const char *name, rua_ctx_t *ctx);
|
|||
void glsl_include (int behavior, void *scanner);
|
||||
void glsl_multiview (int behavior, void *scanner);
|
||||
|
||||
symbol_t *glsl_image_type (glsl_image_t *image, const type_t *htype,
|
||||
const char *name);
|
||||
|
||||
#endif//__glsl_lang_h
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include "QF/alloc.h"
|
||||
|
@ -182,10 +183,62 @@ glsl_layout_set (const layout_qual_t *qual, specifier_t spec,
|
|||
set_attribute (&spec.sym->attributes, name, val);
|
||||
}
|
||||
|
||||
static const type_t *
|
||||
set_image_format (const type_t *type, const char *format)
|
||||
{
|
||||
bool reference = false;
|
||||
unsigned tag = 0;
|
||||
if (is_reference (type)) {
|
||||
reference = true;
|
||||
tag = type->fldptr.tag;
|
||||
type = dereference_type (type);
|
||||
}
|
||||
bool array = false;
|
||||
int count = 0;
|
||||
if (is_array (type)) {
|
||||
array = true;
|
||||
count = type_count (type);
|
||||
type = dereference_type (type);
|
||||
}
|
||||
if (is_array (type)) {
|
||||
type = set_image_format (type, format);
|
||||
} else {
|
||||
if (!is_handle (type)
|
||||
&& type->handle.type != &type_glsl_sampled_image
|
||||
&& type->handle.type != &type_glsl_image) {
|
||||
internal_error (0, "not an image type");
|
||||
}
|
||||
auto htype = type->handle.type;
|
||||
auto image = glsl_imageset.a[type->handle.extra];
|
||||
if (image.format == SpvImageFormatUnknown) {
|
||||
image.format = spirv_enum_val ("ImageFormat", format);
|
||||
} else {
|
||||
error (0, "format already set");
|
||||
}
|
||||
int len = strlen (format);
|
||||
char fmt[len + 1];
|
||||
for (int i = 0; i < len + 1; i++) {
|
||||
fmt[i] = tolower (format[i]);
|
||||
}
|
||||
auto sym = glsl_image_type (&image, htype, va (0, ".image:%s", fmt));
|
||||
type = sym->type;
|
||||
}
|
||||
if (array) {
|
||||
type = array_type (type, count);
|
||||
}
|
||||
if (reference) {
|
||||
type = tagged_reference_type (tag, type);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
static void
|
||||
glsl_layout_format (const layout_qual_t *qual, specifier_t spec,
|
||||
const expr_t *qual_name)
|
||||
{
|
||||
auto type = spec.sym->type;
|
||||
type = set_image_format (type, qual->name);
|
||||
spec.sym->type = type;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -1639,6 +1639,41 @@ image_property (const type_t *type, const attribute_t *attr)
|
|||
return type->handle.type->property (type, attr);
|
||||
}
|
||||
|
||||
symbol_t *
|
||||
glsl_image_type (glsl_image_t *image, const type_t *htype, const char *name)
|
||||
{
|
||||
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) {
|
||||
if (!glsl_imageset.size) {
|
||||
DARRAY_APPEND (&glsl_imageset, (glsl_image_t) { } );
|
||||
}
|
||||
index = glsl_imageset.size;
|
||||
DARRAY_APPEND (&glsl_imageset, *image);
|
||||
}
|
||||
|
||||
auto sym = new_symbol (name);
|
||||
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 already set");
|
||||
}
|
||||
t->handle.type = htype;
|
||||
t->handle.extra = index;
|
||||
t->property = image_property;
|
||||
sym->type = find_type (sym->type);
|
||||
|
||||
return sym;
|
||||
}
|
||||
|
||||
static symbol_t *
|
||||
glsl_parse_image (const char *token, rua_ctx_t *ctx)
|
||||
{
|
||||
|
@ -1733,36 +1768,7 @@ glsl_parse_image (const char *token, rua_ctx_t *ctx)
|
|||
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) {
|
||||
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 already set");
|
||||
}
|
||||
t->handle.type = type.htype;
|
||||
t->handle.extra = index;
|
||||
t->property = image_property;
|
||||
|
||||
return sym;
|
||||
return glsl_image_type (&image, type.htype, token);
|
||||
invalid:
|
||||
internal_error (0, "invalid image type: %s", token);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue