From 5ac80b1859d50916a80bb424f0733abdb806744f Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 15 Feb 2025 15:44:17 +0900 Subject: [PATCH] [qfcc] Add support for sampled images It's currently `@sampler(...)`, but I'm not sure about the name (should it be `@sampled_image`, `@sampled` or similar?). However, glsl-builtins.c uses `@image` and `@sampler` now, so one step closer to my shaders compiling again. --- tools/qfcc/include/image.h | 4 + tools/qfcc/source/glsl-builtins.c | 230 ++++++++++++++---------------- tools/qfcc/source/glsl-layout.c | 7 +- tools/qfcc/source/image.c | 24 ++++ tools/qfcc/source/qc-parse.y | 16 ++- tools/qfcc/source/target_spirv.c | 4 +- 6 files changed, 156 insertions(+), 129 deletions(-) diff --git a/tools/qfcc/include/image.h b/tools/qfcc/include/image.h index bb805b5d4..286b6be04 100644 --- a/tools/qfcc/include/image.h +++ b/tools/qfcc/include/image.h @@ -71,5 +71,9 @@ 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); +const type_t *sampler_type (const type_t *type); + +bool is_image (const type_t *type) __attribute__((pure)); +bool is_sampled_image (const type_t *type) __attribute__((pure)); #endif//__image_h diff --git a/tools/qfcc/source/glsl-builtins.c b/tools/qfcc/source/glsl-builtins.c index 3db83bd4c..7b4ff1441 100644 --- a/tools/qfcc/source/glsl-builtins.c +++ b/tools/qfcc/source/glsl-builtins.c @@ -615,103 +615,94 @@ SRC_LINE //texture functions static const char *glsl_texture_size_functions = SRC_LINE -"#define __sampler(t,d,m,a,s) @handle t##sampler##d##m##a##s" "\n" -"#define _sampler(d,m,a,s) __sampler(,d,m,a,s),__sampler(i,d,m,a,s),__sampler(u,d,m,a,s)\n" -"@generic(gsamplerLod=[_sampler(1D,,,)," "\n" -" _sampler(2D,,,)," "\n" -" _sampler(3D,,,)," "\n" -" _sampler(Cube,,,)," "\n" -" _sampler(1D,,Array,)," "\n" -" _sampler(2D,,Array,)," "\n" -" _sampler(Cube,,Array,)," "\n" -" _sampler(1D,,,Shadow)," "\n" -" _sampler(2D,,,Shadow)," "\n" -" _sampler(Cube,,,Shadow)," "\n" -" _sampler(1D,,Array,Shadow)," "\n" -" _sampler(2D,,Array,Shadow)," "\n" -" _sampler(Cube,,Array,Shadow)]," "\n" -" gsampler=[_sampler(2DRect,,,)," "\n" -" _sampler(2D,MS,,)," "\n" -" _sampler(2D,MS,Array,)," "\n" -" _sampler(Buffer,,Array,)," "\n" -" _sampler(2DRect,,,Shadow)]) {" "\n" +"#define uint unsigned" "\n" +"#define __sampler(...) @sampler(@image(__VA_ARGS__))" "\n" +"#define _sampler(...) __sampler(float __VA_OPT__(,) __VA_ARGS__), \\\n" +" __sampler(int __VA_OPT__(,) __VA_ARGS__), \\\n" +" __sampler(uint __VA_OPT__(,) __VA_ARGS__)" "\n" +"@generic(gsamplerLod=[_sampler(1D), _sampler(1D,Array)," "\n" +" _sampler(2D), _sampler(2D,Array)," "\n" +" _sampler(Cube), _sampler(Cube,Array)," "\n" +" _sampler(3D)," "\n" +" _sampler(1D,Depth), _sampler(1D,Array,Depth),\n" +" _sampler(2D,Depth), _sampler(2D,Array,Depth),\n" +" _sampler(Cube,Depth), _sampler(Cube,Array,Depth)],\n" +" gsampler=[_sampler(2D,MS), _sampler(2D,MS,Array)," "\n" +" _sampler(Rect), _sampler(Buffer)," "\n" +" _sampler(Rect,Depth)]) {" "\n" "gsamplerLod.size_type textureSize(gsamplerLod sampler, int lod) = " SPV(OpImageQuerySizeLod) ";" "\n" "gsampler.size_type textureSize(gsampler sampler) = " SPV(OpImageQuerySize) ";" "\n" "};" "\n" "#undef __sampler" "\n" "#undef _sampler" "\n" +"#undef uint" "\n" ; static const char *glsl_texture_lod_functions = SRC_LINE -"#define __sampler(t,d,m,a,s) @handle t##sampler##d##m##a##s" "\n" -"#define _sampler(d,m,a,s) __sampler(,d,m,a,s),__sampler(i,d,m,a,s),__sampler(u,d,m,a,s)\n" -"@generic(gsamplerLod=[_sampler(1D,,,)," "\n" -" _sampler(2D,,,)," "\n" -" _sampler(3D,,,)," "\n" -" _sampler(Cube,,,)," "\n" -" _sampler(1D,,Array,)," "\n" -" _sampler(2D,,Array,)," "\n" -" _sampler(Cube,,Array,)," "\n" -" _sampler(1D,,,Shadow)," "\n" -" _sampler(2D,,,Shadow)," "\n" -" _sampler(Cube,,,Shadow)," "\n" -" _sampler(1D,,Array,Shadow)," "\n" -" _sampler(2D,,Array,Shadow)," "\n" -" _sampler(Cube,,Array,Shadow)]) {" "\n" +"#define uint unsigned" "\n" +"#define __sampler(...) @sampler(@image(__VA_ARGS__))" "\n" +"#define _sampler(...) __sampler(float __VA_OPT__(,) __VA_ARGS__), \\\n" +" __sampler(int __VA_OPT__(,) __VA_ARGS__), \\\n" +" __sampler(uint __VA_OPT__(,) __VA_ARGS__)" "\n" +"@generic(gsamplerLod=[_sampler(1D), _sampler(1D,Array)," "\n" +" _sampler(2D), _sampler(2D,Array)," "\n" +" _sampler(Cube), _sampler(Cube,Array)," "\n" +" _sampler(3D)," "\n" +" _sampler(1D,Depth), _sampler(1D,Array,Depth),\n" +" _sampler(2D,Depth), _sampler(2D,Array,Depth),\n" +" _sampler(Cube,Depth), _sampler(Cube,Array,Depth)]) {\n" "vec2 textureQueryLod(gsamplerLod sampler, gsamplerLod.lod_coord P) = " SPV(OpImageQueryLod) ";" "\n" "};" "\n" "#undef __sampler" "\n" "#undef _sampler" "\n" +"#undef uint" "\n" ; static const char *glsl_texture_levels_functions = SRC_LINE -"#define __sampler(t,d,m,a,s) @handle t##sampler##d##m##a##s" "\n" -"#define _sampler(d,m,a,s) __sampler(,d,m,a,s),__sampler(i,d,m,a,s),__sampler(u,d,m,a,s)\n" -"@generic(gsamplerLod=[_sampler(1D,,,)," "\n" -" _sampler(2D,,,)," "\n" -" _sampler(3D,,,)," "\n" -" _sampler(Cube,,,)," "\n" -" _sampler(1D,,Array,)," "\n" -" _sampler(2D,,Array,)," "\n" -" _sampler(Cube,,Array,)," "\n" -" _sampler(1D,,,Shadow)," "\n" -" _sampler(2D,,,Shadow)," "\n" -" _sampler(Cube,,,Shadow)," "\n" -" _sampler(1D,,Array,Shadow)," "\n" -" _sampler(2D,,Array,Shadow)," "\n" -" _sampler(Cube,,Array,Shadow)]," "\n" -" gsamplerMS=[_sampler(2D,MS,,)," "\n" -" _sampler(2D,MS,Array,)]) {" "\n" +"#define uint unsigned" "\n" +"#define __sampler(...) @sampler(@image(__VA_ARGS__))" "\n" +"#define _sampler(...) __sampler(float __VA_OPT__(,) __VA_ARGS__), \\\n" +" __sampler(int __VA_OPT__(,) __VA_ARGS__), \\\n" +" __sampler(uint __VA_OPT__(,) __VA_ARGS__)" "\n" +"@generic(gsamplerLod=[_sampler(1D), _sampler(1D,Array)," "\n" +" _sampler(2D), _sampler(2D,Array)," "\n" +" _sampler(Cube), _sampler(Cube,Array)," "\n" +" _sampler(3D)," "\n" +" _sampler(1D,Depth), _sampler(1D,Array,Depth),\n" +" _sampler(2D,Depth), _sampler(2D,Array,Depth),\n" +" _sampler(Cube,Depth), _sampler(Cube,Array,Depth)],\n" +" gsamplerMS=[_sampler(2D,MS), _sampler(2D,MS,Array)]) {" "\n" "int textureQueryLevels(gsamplerLod sampler) = " SPV(OpImageQueryLevels) ";" "\n" "int textureSamples(gsamplerMS sampler) = " SPV(OpImageQuerySamples) ";" "\n" "};" "\n" "#undef __sampler" "\n" "#undef _sampler" "\n" +"#undef uint" "\n" ; static const char *glsl_other_texture_functions = SRC_LINE +"#define uint unsigned" "\n" "#define gvec4 @vector(gsampler.sample_type, 4)" "\n" "#define gtex_coord gsampler.tex_coord" "\n" "#define gshadow_coord gsamplerSh.shadow_coord" "\n" "#define gproj_coord gsampler.proj_coord" "\n" -"#define __sampler(t,d,m,a,s) @handle t##sampler##d##m##a##s" "\n" -"#define _sampler(d,m,a,s) __sampler(,d,m,a,s),__sampler(i,d,m,a,s),__sampler(u,d,m,a,s)\n" -"@generic(gsampler=[_sampler(1D,,,)," "\n" -" _sampler(2D,,,)," "\n" -" _sampler(3D,,,)," "\n" -" _sampler(Cube,,,)," "\n" -" _sampler(1D,,Array,)," "\n" -" _sampler(2D,,Array,)," "\n" -" _sampler(Cube,,Array,)]," "\n" -" gsamplerSh=[__sampler(,1D,,,Shadow)," "\n" -" __sampler(,2D,,,Shadow)," "\n" -" __sampler(,Cube,,,Shadow)," "\n" -" __sampler(,1D,,Array,Shadow)," "\n" -" __sampler(,2D,,Array,Shadow)]," "\n" -" gsamplerCAS=[__sampler(,Cube,,Array,Shadow)]) {" "\n" +"#define __sampler(...) @sampler(@image(__VA_ARGS__))" "\n" +"#define _sampler(...) __sampler(float __VA_OPT__(,) __VA_ARGS__), \\\n" +" __sampler(int __VA_OPT__(,) __VA_ARGS__), \\\n" +" __sampler(uint __VA_OPT__(,) __VA_ARGS__)" "\n" +"@generic(gsampler=[_sampler(1D), _sampler(1D,Array)," "\n" +" _sampler(2D), _sampler(2D,Array)," "\n" +" _sampler(Cube), _sampler(Cube,Array)," "\n" +" _sampler(3D)]," "\n" +" gsamplerSh=[__sampler(float,1D,Depth)," "\n" +" __sampler(float,1D,Array,Depth)," "\n" +" __sampler(float,2D,Depth)," "\n" +" __sampler(float,2D,Array,Depth)," "\n" +" __sampler(float,Cube,Depth)]," "\n" +" gsamplerCAS=[__sampler(float,Cube,Array,Depth)]) {" "\n" "gvec4 texture(gsampler sampler, gtex_coord P)" "\n" "= " SPV(OpImageSampleExplicitLod) "\n" "[sampler, P, =ImageOperands.Lod, 0f];" "\n" @@ -730,29 +721,30 @@ SRC_LINE "#undef _sampler" "\n" "#undef gtex_coord" "\n" "#undef gvec4" "\n" +"#undef uint" "\n" ; static const char *glsl_frag_texture_functions = SRC_LINE +"#define uint unsigned" "\n" "#define gvec4 @vector(gsampler.sample_type, 4)" "\n" "#define gtex_coord gsampler.tex_coord" "\n" "#define gshadow_coord gsamplerSh.shadow_coord" "\n" "#define gproj_coord gsampler.proj_coord" "\n" -"#define __sampler(t,d,m,a,s) @handle t##sampler##d##m##a##s" "\n" -"#define _sampler(d,m,a,s) __sampler(,d,m,a,s),__sampler(i,d,m,a,s),__sampler(u,d,m,a,s)\n" -"@generic(gsampler=[_sampler(1D,,,)," "\n" -" _sampler(2D,,,)," "\n" -" _sampler(3D,,,)," "\n" -" _sampler(Cube,,,)," "\n" -" _sampler(1D,,Array,)," "\n" -" _sampler(2D,,Array,)," "\n" -" _sampler(Cube,,Array,)]," "\n" -" gsamplerSh=[__sampler(,1D,,,Shadow)," "\n" -" __sampler(,2D,,,Shadow)," "\n" -" __sampler(,Cube,,,Shadow)," "\n" -" __sampler(,1D,,Array,Shadow)," "\n" -" __sampler(,2D,,Array,Shadow)]," "\n" -" gsamplerCAS=[__sampler(,Cube,,Array,Shadow)]) {" "\n" +"#define __sampler(...) @sampler(@image(__VA_ARGS__))" "\n" +"#define _sampler(...) __sampler(float __VA_OPT__(,) __VA_ARGS__), \\\n" +" __sampler(int __VA_OPT__(,) __VA_ARGS__), \\\n" +" __sampler(uint __VA_OPT__(,) __VA_ARGS__)" "\n" +"@generic(gsampler=[_sampler(1D), _sampler(1D,Array)," "\n" +" _sampler(2D), _sampler(2D,Array)," "\n" +" _sampler(Cube), _sampler(Cube,Array)," "\n" +" _sampler(3D)]," "\n" +" gsamplerSh=[__sampler(float,1D,Depth)," "\n" +" __sampler(float,1D,Array,Depth)," "\n" +" __sampler(float,2D,Depth)," "\n" +" __sampler(float,2D,Array,Depth)," "\n" +" __sampler(float,Cube,Depth)]," "\n" +" gsamplerCAS=[__sampler(float,Cube,Array,Depth)]) {" "\n" "gvec4 texture(gsampler sampler, gtex_coord P, float bias)" "\n" "= " SPV(OpImageSampleImplicitLod) "\n" "[sampler, P, =ImageOperands.Bias, bias];" "\n" @@ -777,26 +769,28 @@ SRC_LINE "#undef _sampler" "\n" "#undef gtex_coord" "\n" "#undef gvec4" "\n" +"#undef uint" "\n" ; static const char *glsl_common_texture_functions = SRC_LINE +"#define uint unsigned" "\n" "#define gvec4 @vector(gsampler.sample_type, 4)" "\n" "#define gvec4B @vector(gsamplerB.sample_type, 4)" "\n" "#define gvec4MS @vector(gsamplerMS.sample_type, 4)" "\n" "#define gtex_coord gsampler.tex_coord" "\n" "#define gshadow_coord gsamplerSh.shadow_coord" "\n" "#define gproj_coord gsampler.proj_coord" "\n" -"#define __sampler(t,d,m,a,s) @handle t##sampler##d##m##a##s" "\n" -"#define _sampler(d,m,a,s) __sampler(,d,m,a,s),__sampler(i,d,m,a,s),__sampler(u,d,m,a,s)\n" -"@generic(gsampler=[_sampler(1D,,,)," "\n" -" _sampler(2D,,,)," "\n" -" _sampler(3D,,,)," "\n" -" _sampler(1D,,Array,)," "\n" -" _sampler(2D,,Array,)]," "\n" -" gsamplerB=[__sampler(,Buffer,,,)]," "\n" -" gsamplerMS=[_sampler(2D,MS,,)," "\n" -" _sampler(2D,MS,Array,)]) {" "\n" +"#define __sampler(...) @sampler(@image(__VA_ARGS__))" "\n" +"#define _sampler(...) __sampler(float __VA_OPT__(,) __VA_ARGS__), \\\n" +" __sampler(int __VA_OPT__(,) __VA_ARGS__), \\\n" +" __sampler(uint __VA_OPT__(,) __VA_ARGS__)" "\n" +"@generic(gsampler=[_sampler(1D), _sampler(1D,Array)," "\n" +" _sampler(2D), _sampler(2D,Array)," "\n" +" _sampler(Cube), _sampler(Cube,Array)," "\n" +" _sampler(3D)]," "\n" +" gsamplerB=[_sampler(Buffer)]," "\n" +" gsamplerMS=[_sampler(2D,MS), _sampler(2D,MS,Array)]) {" "\n" "gvec4 texelFetch(gsampler sampler, gtex_coord P, int lod)" "\n" "= " SPV(OpImageFetch) "[sampler, P, =ImageOperands.Lod, lod];" "\n" "gvec4B texelFetch(gsamplerB sampler, int P)" "\n" @@ -818,16 +812,15 @@ SRC_LINE "#define gtex_coord gtexture.tex_coord" "\n" "#define gshadow_coord gtextureSh.shadow_coord" "\n" "#define gproj_coord gtexture.proj_coord" "\n" -"#define __texture(t,d,m,a,s) @handle t##texture##d##m##a##s" "\n" -"#define _texture(d,m,a,s) __texture(,d,m,a,s),__texture(i,d,m,a,s),__texture(u,d,m,a,s)\n" -"@generic(gtexture=[_texture(1D,,,)," "\n" -" _texture(2D,,,)," "\n" -" _texture(3D,,,)," "\n" -" _texture(1D,,Array,)," "\n" -" _texture(2D,,Array,)]," "\n" -" gtextureB=[__texture(,Buffer,,,)]," "\n" -" gtextureMS=[_texture(2D,MS,,)," "\n" -" _texture(2D,MS,Array,)]) {" "\n" +"#define __texture(...) @image(__VA_ARGS__ __VA_OPT__(,) Sampled)" "\n" +"#define _texture(...) __texture(float __VA_OPT__(,) __VA_ARGS__), \\\n" +" __texture(int __VA_OPT__(,) __VA_ARGS__), \\\n" +" __texture(uint __VA_OPT__(,) __VA_ARGS__)" "\n" +"@generic(gtexture=[_texture(1D), _texture(1D,Array)," "\n" +" _texture(2D), _texture(2D,Array)," "\n" +" _texture(3D)]," "\n" +" gtextureB=[_texture(Buffer)]," "\n" +" gtextureMS=[_texture(2D,MS), _texture(2D,MS,Array)]) {" "\n" "gvec4 texelFetch(gtexture texture, gtex_coord P, int lod)" "\n" "= " SPV(OpImageFetch) "[texture, P, =ImageOperands.Lod, lod];" "\n" "gvec4B texelFetch(gtextureB texture, int P)" "\n" @@ -843,6 +836,7 @@ SRC_LINE "#undef gvec4MS" "\n" "#undef gvec4B" "\n" "#undef gvec4" "\n" +"#undef uint" "\n" ; #if 0 "gvec4 textureLod(gsampler1D sampler, float P, float lod)" "\n" @@ -1056,25 +1050,21 @@ SRC_LINE "#define uint unsigned" "\n" "#define readonly" "\n" "#define writeonly" "\n" -"#define __image(t,d,m,a,s) @handle t##image##d##m##a##s" "\n" -"#define _image(d,m,a,s) __image(,d,m,a,s),__image(i,d,m,a,s),__image(u,d,m,a,s)\n" +"#define __image(t,...) @image(t __VA_OPT__(,) __VA_ARGS__)" "\n" +"#define _image(d,...) __image(float, d __VA_OPT__(,) __VA_ARGS__), \\" "\n" +" __image(int, d __VA_OPT__(,) __VA_ARGS__), \\" "\n" +" __image(uint, d __VA_OPT__(,) __VA_ARGS__)" "\n" "#define gvec4 @vector(gimage.sample_type, 4)" "\n" "#define gvec4MS @vector(gimageMS.sample_type, 4)" "\n" "#define IMAGE_PARAMS gimage image, gimage.image_coord P" "\n" "#define IMAGE_PARAMS_MS gimageMS image, gimageMS.image_coord P, int sample" "\n" "#define PIMAGE_PARAMS @reference(gimage) image, gimage.image_coord P" "\n" "#define PIMAGE_PARAMS_MS @reference(gimageMS) image, gimageMS.image_coord P, int sample" "\n" -"@generic(gimage=[_image(1D,,,)," "\n" -" _image(1D,,Array,)," "\n" -" _image(2D,,,)," "\n" -" _image(2D,,Array,)," "\n" -" _image(2DRect,,,)," "\n" -" _image(3D,,,)," "\n" -" _image(Cube,,,)," "\n" -" _image(Cube,,Array,)," "\n" -" _image(Buffer,,,)]," "\n" -" gimageMS=[_image(2D,MS,,)," "\n" -" _image(2D,MS,Array,)]) {" "\n" +"@generic(gimage=[_image(1D), _image(1D,Array)," "\n" +" _image(2D), _image(2D,Array)," "\n" +" _image(Cube), _image(Cube,Array)," "\n" +" _image(3D), _image(Rect), _image(Buffer)]," "\n" +" gimageMS=[_image(2D,MS), _image(2D,MS,Array)]) {" "\n" "gimage.size_type imageSize(readonly writeonly gimage image) = " SPV(OpImageQuerySize) ";" "\n" "gimageMS.size_type imageSize(readonly writeonly gimageMS image) = " SPV(OpImageQuerySize) ";" "\n" "int imageSamples(readonly writeonly gimageMS image) = " SPV(OpImageQuerySamples) ";" "\n" @@ -1181,12 +1171,14 @@ SRC_LINE "#define uint unsigned" "\n" "#define readonly" "\n" "#define writeonly" "\n" -"#define __spI(t,m) @handle t##subpassInput##m" "\n" -"#define _subpassInput(x,m) __spI(,m),__spI(i,m),__spI(u,m)" "\n" +"#define __spI(...) @image(__VA_ARGS__ __VA_OPT__(,) SubpassData)" "\n" +"#define _subpassInput(...) __spI(float __VA_OPT__(,) __VA_ARGS__), \\\n" +" __spI(int __VA_OPT__(,) __VA_ARGS__), \\\n" +" __spI(uint __VA_OPT__(,) __VA_ARGS__)" "\n" "#define gvec4 @vector(gsubpassInput.sample_type, 4)" "\n" "#define gvec4MS @vector(gsubpassInputMS.sample_type, 4)" "\n" -"@generic(gsubpassInput=[_subpassInput(,)]," "\n" -" gsubpassInputMS=[_subpassInput(,MS)]) {" "\n" +"@generic(gsubpassInput=[_subpassInput()]," "\n" +" gsubpassInputMS=[_subpassInput(MS)]) {" "\n" "gvec4 subpassLoad(gsubpassInput subpass)" "\n" "= " SPV(OpImageRead) "\n" "[subpass, @construct(gsubpassInput.image_coord, 0)];" "\n" diff --git a/tools/qfcc/source/glsl-layout.c b/tools/qfcc/source/glsl-layout.c index 3b9d783ab..8b9bd38ec 100644 --- a/tools/qfcc/source/glsl-layout.c +++ b/tools/qfcc/source/glsl-layout.c @@ -204,9 +204,7 @@ set_image_format (const type_t *type, const char *format) if (is_array (type)) { type = set_image_format (type, format); } else { - if (!is_handle (type) - && type->handle.type != &type_sampled_image - && type->handle.type != &type_image) { + if (!is_image (type) && !is_sampled_image (type)) { internal_error (0, "not an image type"); } auto htype = type->handle.type; @@ -1185,8 +1183,7 @@ layout_check_qualifier (const layout_qual_t *qual, specifier_t spec) // only images and not other opaque types, but qualifiers that // support opaque types in general also support images image_t *image = nullptr; - //FIXME nicer type check - if (type->handle.type == &type_image) { + if (is_image (type)) { image = &imageset.a[type->handle.extra]; } if (qual->var_type != var_opaque && image) { diff --git a/tools/qfcc/source/image.c b/tools/qfcc/source/image.c index 588400ced..c88777582 100644 --- a/tools/qfcc/source/image.c +++ b/tools/qfcc/source/image.c @@ -398,3 +398,27 @@ image_type (const type_t *type, const expr_t *params) auto sym = named_image_type (&image, &type_image, nullptr); return sym->type; } + +const type_t * +sampler_type (const type_t *type) +{ + if (!is_image (type)) { + error (0, "not an image type"); + return &type_int; + } + auto image = imageset.a[type->handle.extra]; + auto sym = named_image_type (&image, &type_sampled_image, nullptr); + return sym->type; +} + +bool is_image (const type_t *type) +{ + type = unalias_type (type); + return is_handle (type) && type->handle.type == &type_image; +} + +bool is_sampled_image (const type_t *type) +{ + type = unalias_type (type); + return is_handle (type) && type->handle.type == &type_image; +} diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 3f6f2df92..9c9d5c60c 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -156,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 IMAGE +%token NIL GOTO SWITCH CASE DEFAULT ENUM ALGEBRA IMAGE SAMPLER %token ARGS TYPEDEF EXTERN STATIC SYSTEM OVERLOAD NOT ATTRIBUTE %token STRUCT %token HANDLE INTRINSIC @@ -198,7 +198,8 @@ int yylex (YYSTYPE *yylval, YYLTYPE *yylloc); %type tag %type struct_specifier struct_list -%type enum_specifier algebra_specifier image_specifier +%type enum_specifier algebra_specifier +%type image_specifier sampler_specifier %type optional_enum_list enum_list enumerator_list enumerator %type enum_init %type array_decl @@ -1159,6 +1160,7 @@ typespec_reserved $$ = type_spec (algebra_subtype ($1.type, $3)); } | image_specifier + | sampler_specifier | enum_specifier | struct_specifier // NOTE: fields don't parse the way they should. This is not a problem @@ -1375,6 +1377,7 @@ type_ref | ENUM tag { $$ = forward_decl_expr ($2, 'e', nullptr); } | handle tag { $$ = forward_decl_expr ($2, 'h', $1.type); } | image_specifier { $$ = new_type_expr ($1.type); } + | sampler_specifier { $$ = new_type_expr ($1.type); } | CLASS_NAME { $$ = new_type_expr ($1->type); } | TYPE_NAME { @@ -1449,6 +1452,14 @@ image_specifier } ; +sampler_specifier + : SAMPLER '(' typespec[spec] ')' + { + auto spec = default_type ($spec, 0); + spec = type_spec (sampler_type (spec.type)); + $$ = spec; + } + ; enum_specifier : ENUM tag optional_enum_list { @@ -3094,6 +3105,7 @@ static keyword_t qf_keywords[] = { {"@undual", QC_UNDUAL, }, {"@image", QC_IMAGE, }, + {"@sampler", QC_SAMPLER, }, {"@construct", QC_CONSTRUCT, }, {"@generic", QC_GENERIC, }, diff --git a/tools/qfcc/source/target_spirv.c b/tools/qfcc/source/target_spirv.c index bd7197720..340704410 100644 --- a/tools/qfcc/source/target_spirv.c +++ b/tools/qfcc/source/target_spirv.c @@ -798,9 +798,7 @@ spirv_Type (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_image - || type->handle.type == &type_sampled_image)) { + } else if (is_image (type) || is_sampled_image (type)) { auto image = &imageset.a[type->handle.extra]; id = spirv_TypeImage (image, ctx); if (type->handle.type == &type_sampled_image) {