mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-04 16:31:30 +00:00
[qfcc] Parse @image() in Ruamoko
I'll probably tweak the syntax a little (make placement of the type more flexible and not generate an error if either type or other arguments are missing), but I think I like it result: typedef @image(int, 2D, Array, R8) bimage; typedef @image(float, 3D, Rgba8) fimage; typedef @image(float, Cube, Rgba8) cube; typedef @image(float, Array, Cube) cube_array;
This commit is contained in:
parent
28604add29
commit
6af42e979e
3 changed files with 149 additions and 2 deletions
|
@ -70,4 +70,6 @@ void image_init_types (void);
|
|||
symbol_t *named_image_type (image_t *image, const type_t *htype,
|
||||
const char *name);
|
||||
|
||||
const type_t *image_type (const type_t *type, const expr_t *params);
|
||||
|
||||
#endif//__image_h
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
#include "tools/qfcc/include/expr.h"
|
||||
#include "tools/qfcc/include/diagnostic.h"
|
||||
#include "tools/qfcc/include/image.h"
|
||||
#include "tools/qfcc/include/spirv_grammar.h"
|
||||
#include "tools/qfcc/include/spirv.h"
|
||||
#include "tools/qfcc/include/struct.h"
|
||||
#include "tools/qfcc/include/symtab.h"
|
||||
#include "tools/qfcc/include/type.h"
|
||||
|
@ -279,3 +281,120 @@ named_image_type (image_t *image, const type_t *htype, const char *name)
|
|||
|
||||
return sym;
|
||||
}
|
||||
|
||||
const type_t *
|
||||
image_type (const type_t *type, const expr_t *params)
|
||||
{
|
||||
if (!type || !(is_float (type) || is_int (type) || is_uint (type))
|
||||
|| !is_scalar (type)) {
|
||||
error (params, "invalid type for @image");
|
||||
return &type_int;
|
||||
}
|
||||
if (is_error (params)) {
|
||||
return &type_int;
|
||||
}
|
||||
if (params->type != ex_list) {
|
||||
internal_error (params, "not a list");
|
||||
}
|
||||
image_t image = {
|
||||
.sample_type = type,
|
||||
.dim = ~0u,
|
||||
.format = ~0u,
|
||||
};
|
||||
int count = list_count (¶ms->list);
|
||||
const expr_t *args[count + 1] = {};
|
||||
list_scatter (¶ms->list, args);
|
||||
bool err = false;
|
||||
for (int i = 0; i < count; i++) {
|
||||
uint32_t val;
|
||||
if (args[i]->type != ex_symbol) {
|
||||
error (args[i], "invalid argument for @image");
|
||||
err = true;
|
||||
continue;
|
||||
}
|
||||
const char *name = args[i]->symbol->name;
|
||||
if (spirv_enum_val_silent ("Dim", name, &val)) {
|
||||
if (image.dim != ~0u) {
|
||||
error (args[i], "multiple spec for image dimension");
|
||||
err = true;
|
||||
}
|
||||
image.dim = val;
|
||||
continue;
|
||||
}
|
||||
if (spirv_enum_val_silent ("ImageFormat", name, &val)) {
|
||||
if (image.format != ~0u) {
|
||||
error (args[i], "multiple spec for image format");
|
||||
err = true;
|
||||
}
|
||||
image.format = val;
|
||||
continue;
|
||||
}
|
||||
if (strcasecmp ("Depth", name) == 0) {
|
||||
if (image.depth) {
|
||||
error (args[i], "multiple spec for image depth");
|
||||
err = true;
|
||||
}
|
||||
image.depth = 1;
|
||||
continue;
|
||||
}
|
||||
if (strcasecmp ("Array", name) == 0
|
||||
|| strcasecmp ("Arrayed", name) == 0) {
|
||||
if (image.arrayed) {
|
||||
error (args[i], "multiple spec for image array");
|
||||
err = true;
|
||||
}
|
||||
image.arrayed = true;
|
||||
continue;
|
||||
}
|
||||
if (strcasecmp ("MS", name) == 0) {
|
||||
if (image.multisample) {
|
||||
error (args[i], "multiple spec for image multisample");
|
||||
err = true;
|
||||
}
|
||||
image.multisample = true;
|
||||
continue;
|
||||
}
|
||||
if (strcasecmp ("Sampled", name) == 0) {
|
||||
if (image.sampled) {
|
||||
error (args[i], "multiple spec for image sampling");
|
||||
err = true;
|
||||
}
|
||||
image.sampled = 1;
|
||||
continue;
|
||||
}
|
||||
if (strcasecmp ("Storage", name) == 0) {
|
||||
if (image.sampled) {
|
||||
error (args[i], "multiple spec for image sampling");
|
||||
err = true;
|
||||
}
|
||||
image.sampled = 2;
|
||||
continue;
|
||||
}
|
||||
error (args[i], "invalid argument for @image: %s", name);
|
||||
err = true;
|
||||
}
|
||||
if (image.dim == img_subpassdata) {
|
||||
if (image.sampled) {
|
||||
error (0, "multiple spec for image sampling");
|
||||
err = true;
|
||||
}
|
||||
if (image.format && image.format != ~0u) {
|
||||
error (0, "multiple spec for image format");
|
||||
err = true;
|
||||
}
|
||||
image.format = SpvImageFormatUnknown;
|
||||
image.sampled = 2;
|
||||
}
|
||||
if (image.dim == ~0u) {
|
||||
error (0, "image dimenion not specified");
|
||||
err = true;
|
||||
}
|
||||
if (image.format == ~0u) {
|
||||
image.format = SpvImageFormatUnknown;
|
||||
}
|
||||
if (err) {
|
||||
return &type_int;
|
||||
}
|
||||
auto sym = named_image_type (&image, &type_image, nullptr);
|
||||
return sym->type;
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
#include "tools/qfcc/include/expr.h"
|
||||
#include "tools/qfcc/include/function.h"
|
||||
#include "tools/qfcc/include/grab.h"
|
||||
#include "tools/qfcc/include/image.h"
|
||||
#include "tools/qfcc/include/method.h"
|
||||
#include "tools/qfcc/include/options.h"
|
||||
#include "tools/qfcc/include/qfcc.h"
|
||||
|
@ -155,7 +156,7 @@ int yylex (YYSTYPE *yylval, YYLTYPE *yylloc);
|
|||
|
||||
%token LOCAL WHILE DO IF ELSE FOR BREAK CONTINUE
|
||||
%token RETURN AT_RETURN
|
||||
%token NIL GOTO SWITCH CASE DEFAULT ENUM ALGEBRA
|
||||
%token NIL GOTO SWITCH CASE DEFAULT ENUM ALGEBRA IMAGE
|
||||
%token ARGS TYPEDEF EXTERN STATIC SYSTEM OVERLOAD NOT ATTRIBUTE
|
||||
%token <op> STRUCT
|
||||
%token HANDLE INTRINSIC
|
||||
|
@ -197,7 +198,7 @@ int yylex (YYSTYPE *yylval, YYLTYPE *yylloc);
|
|||
|
||||
%type <symbol> tag
|
||||
%type <spec> struct_specifier struct_list
|
||||
%type <spec> enum_specifier algebra_specifier
|
||||
%type <spec> enum_specifier algebra_specifier image_specifier
|
||||
%type <symbol> optional_enum_list enum_list enumerator_list enumerator
|
||||
%type <symbol> enum_init
|
||||
%type <expr> array_decl
|
||||
|
@ -724,6 +725,12 @@ pop_scope (symtab_t *current)
|
|||
return parent;
|
||||
}
|
||||
|
||||
static const expr_t *
|
||||
number_as_symbol (const rua_tok_t *tok, rua_ctx_t *ctx)
|
||||
{
|
||||
return new_name_expr (tok->text);
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%expect 2
|
||||
|
@ -1151,6 +1158,7 @@ typespec_reserved
|
|||
{
|
||||
$$ = type_spec (algebra_subtype ($1.type, $3));
|
||||
}
|
||||
| image_specifier
|
||||
| enum_specifier
|
||||
| struct_specifier
|
||||
// NOTE: fields don't parse the way they should. This is not a problem
|
||||
|
@ -1424,6 +1432,22 @@ algebra_specifier
|
|||
}
|
||||
;
|
||||
|
||||
image_specifier
|
||||
: IMAGE '(' TYPE_SPEC[spec] ','
|
||||
{
|
||||
// allow 2D to be parsed as a symbol instead of 2.0 (double/decimal)
|
||||
$<pointer>$ = ctx->language->parse_number;
|
||||
ctx->language->parse_number = number_as_symbol;
|
||||
}[parse_number]
|
||||
expr_list ')'
|
||||
{
|
||||
auto type = $spec.type;
|
||||
auto spec = type_spec (image_type (type, $expr_list));
|
||||
$$ = spec;
|
||||
ctx->language->parse_number = $<pointer>parse_number;
|
||||
}
|
||||
;
|
||||
|
||||
enum_specifier
|
||||
: ENUM tag optional_enum_list
|
||||
{
|
||||
|
@ -3068,6 +3092,8 @@ static keyword_t qf_keywords[] = {
|
|||
{"@dual", QC_DUAL, },
|
||||
{"@undual", QC_UNDUAL, },
|
||||
|
||||
{"@image", QC_IMAGE, },
|
||||
|
||||
{"@construct", QC_CONSTRUCT, },
|
||||
{"@generic", QC_GENERIC, },
|
||||
{"@function", QC_AT_FUNCTION, },
|
||||
|
|
Loading…
Reference in a new issue