diff --git a/tools/qfcc/include/image.h b/tools/qfcc/include/image.h index 5e615ff20..f21f8027a 100644 --- a/tools/qfcc/include/image.h +++ b/tools/qfcc/include/image.h @@ -73,5 +73,8 @@ 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)); +bool image_type_promotes (const type_t *dst, const type_t *src) __attribute__((pure)); +bool image_type_demotes (const type_t *dst, const type_t *src) __attribute__((pure)); +bool image_type_assignable (const type_t *dst, const type_t *src) __attribute__((pure)); #endif//__image_h diff --git a/tools/qfcc/source/glsl-builtins.c b/tools/qfcc/source/glsl-builtins.c index c6779f21e..a3aab6e42 100644 --- a/tools/qfcc/source/glsl-builtins.c +++ b/tools/qfcc/source/glsl-builtins.c @@ -1050,10 +1050,10 @@ SRC_LINE "#define uint unsigned" "\n" "#define readonly" "\n" "#define writeonly" "\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 __image(...) @image(__VA_ARGS__ __VA_OPT__(,) Storage)" "\n" +"#define _image(...) __image(float __VA_OPT__(,) __VA_ARGS__), \\" "\n" +" __image(int __VA_OPT__(,) __VA_ARGS__), \\" "\n" +" __image(uint __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" diff --git a/tools/qfcc/source/image.c b/tools/qfcc/source/image.c index 93b0fdabf..aee396fe4 100644 --- a/tools/qfcc/source/image.c +++ b/tools/qfcc/source/image.c @@ -268,6 +268,9 @@ create_image_type (image_t *image, const type_t *htype) type_t type = { .type = ev_int, + .alignment = 1, + .width = 1, + .columns = 1, .meta = ty_handle, .handle.type = htype, .handle.extra = index, @@ -407,14 +410,78 @@ sampler_type (const type_t *type) return create_image_type (&image, &type_sampled_image); } -bool is_image (const type_t *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) +bool +is_sampled_image (const type_t *type) { type = unalias_type (type); return is_handle (type) && type->handle.type == &type_sampled_image; } + +bool +image_type_promotes (const type_t *dst, const type_t *src) +{ + //FIXME which is demote and which is promote? + if (!is_image (dst) && !is_sampled_image (dst) + && !is_image (src) && !is_sampled_image (src)) { + return false; + } + if (dst->handle.type != src->handle.type) { + return false; + } + auto dst_image = imageset.a[dst->handle.extra]; + auto src_image = imageset.a[src->handle.extra]; + // ignore sampled, format, and id + dst_image.format = 0; + src_image.format = 0; + dst_image.id = 0; + src_image.id = 0; + return memcmp (&dst_image, &src_image, sizeof (dst_image)) == 0; +} + +bool +image_type_demotes (const type_t *dst, const type_t *src) +{ + //FIXME which is demote and which is promote? + if (!is_image (dst) && !is_sampled_image (dst) + && !is_image (src) && !is_sampled_image (src)) { + return false; + } + if (dst->handle.type != src->handle.type) { + return false; + } + auto dst_image = imageset.a[dst->handle.extra]; + auto src_image = imageset.a[src->handle.extra]; + // ignore format and id + dst_image.format = 0; + src_image.format = 0; + dst_image.id = 0; + src_image.id = 0; + return memcmp (&dst_image, &src_image, sizeof (dst_image)) == 0; +} + +bool +image_type_assignable (const type_t *dst, const type_t *src) +{ + if (!is_image (dst) && !is_sampled_image (dst) + && !is_image (src) && !is_sampled_image (src)) { + return false; + } + if (dst->handle.type != src->handle.type) { + return false; + } + auto dst_image = imageset.a[dst->handle.extra]; + auto src_image = imageset.a[src->handle.extra]; + // ignore format and id + dst_image.format = 0; + src_image.format = 0; + dst_image.id = 0; + src_image.id = 0; + return memcmp (&dst_image, &src_image, sizeof (dst_image)) == 0; +} diff --git a/tools/qfcc/source/stub.c b/tools/qfcc/source/stub.c index f09e24394..2b348eedd 100644 --- a/tools/qfcc/source/stub.c +++ b/tools/qfcc/source/stub.c @@ -13,6 +13,7 @@ #include "tools/qfcc/include/defspace.h" #include "tools/qfcc/include/emit.h" #include "tools/qfcc/include/expr.h" +#include "tools/qfcc/include/image.h" #include "tools/qfcc/include/obj_file.h" #include "tools/qfcc/include/obj_type.h" #include "tools/qfcc/include/options.h" @@ -72,3 +73,8 @@ void dump_dot_type (void *_t, const char *filename){} char *fubar; const char *file_basename(const char *p, int keepdot) { return fubar;} __attribute__((const)) const type_t *get_type (const expr_t *e) {return nullptr;} +bool is_image (const type_t *type){return type->type;} +bool is_sampled_image (const type_t *type){return type->type;} +bool image_type_demotes (const type_t *dst, const type_t *src){return dst->type;} +bool image_type_promotes (const type_t *dst, const type_t *src){return dst->type;} +bool image_type_assignable (const type_t *dst, const type_t *src){return dst->type;} diff --git a/tools/qfcc/source/type.c b/tools/qfcc/source/type.c index 003b9833e..ce0915928 100644 --- a/tools/qfcc/source/type.c +++ b/tools/qfcc/source/type.c @@ -53,6 +53,7 @@ #include "tools/qfcc/include/diagnostic.h" #include "tools/qfcc/include/expr.h" #include "tools/qfcc/include/function.h" +#include "tools/qfcc/include/image.h" #include "tools/qfcc/include/obj_type.h" #include "tools/qfcc/include/options.h" #include "tools/qfcc/include/qfcc.h" @@ -1726,6 +1727,10 @@ type_assignable (const type_t *dst, const type_t *src) if (is_algebra (dst) || is_algebra (src)) { return algebra_type_assignable (dst, src); } + if ((is_image (dst) || is_sampled_image (dst)) + && (is_image (src) || is_sampled_image (src))) { + return image_type_assignable (dst, src); + } if (is_scalar (dst) && is_scalar (src)) { return true; } @@ -1792,6 +1797,10 @@ type_promotes (const type_t *dst, const type_t *src) dst = unalias_type (dst); src = unalias_type (src); + if ((is_image (dst) || is_sampled_image (dst)) + && (is_image (src) || is_sampled_image (src))) { + return image_type_promotes (dst, src); + } if (!is_math (dst) || !is_math (src)) { return false; } @@ -1836,6 +1845,10 @@ type_demotes (const type_t *dst, const type_t *src) dst = unalias_type (dst); src = unalias_type (src); + if ((is_image (dst) || is_sampled_image (dst)) + && (is_image (src) || is_sampled_image (src))) { + return image_type_demotes (dst, src); + } if (!is_math (dst) || !is_math (src)) { return false; }