glsl: add support for the imageSamples function
authorIlia Mirkin <imirkin@alum.mit.edu>
Fri, 28 Aug 2015 03:22:18 +0000 (23:22 -0400)
committerIlia Mirkin <imirkin@alum.mit.edu>
Thu, 10 Sep 2015 21:38:49 +0000 (17:38 -0400)
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/glsl/builtin_functions.cpp

index cdc016e39714511724223248b539cad0d6e23016..06a29bcfb10e6859bc97cbdc6c1726378a69da6f 100644 (file)
@@ -539,7 +539,8 @@ private:
       IMAGE_FUNCTION_SUPPORTS_FLOAT_DATA_TYPE = (1 << 3),
       IMAGE_FUNCTION_READ_ONLY = (1 << 4),
       IMAGE_FUNCTION_WRITE_ONLY = (1 << 5),
-      IMAGE_FUNCTION_AVAIL_ATOMIC = (1 << 6)
+      IMAGE_FUNCTION_AVAIL_ATOMIC = (1 << 6),
+      IMAGE_FUNCTION_MS_ONLY = (1 << 7),
    };
 
    /**
@@ -750,6 +751,9 @@ private:
    ir_function_signature *_image_size_prototype(const glsl_type *image_type,
                                                 unsigned num_arguments,
                                                 unsigned flags);
+   ir_function_signature *_image_samples_prototype(const glsl_type *image_type,
+                                                   unsigned num_arguments,
+                                                   unsigned flags);
    ir_function_signature *_image(image_prototype_ctr prototype,
                                  const glsl_type *image_type,
                                  const char *intrinsic_name,
@@ -2685,8 +2689,10 @@ builtin_builder::add_image_function(const char *name,
    ir_function *f = new(mem_ctx) ir_function(name);
 
    for (unsigned i = 0; i < ARRAY_SIZE(types); ++i) {
-      if (types[i]->sampler_type != GLSL_TYPE_FLOAT ||
-          (flags & IMAGE_FUNCTION_SUPPORTS_FLOAT_DATA_TYPE))
+      if ((types[i]->sampler_type != GLSL_TYPE_FLOAT ||
+           (flags & IMAGE_FUNCTION_SUPPORTS_FLOAT_DATA_TYPE)) &&
+          (types[i]->sampler_dimensionality == GLSL_SAMPLER_DIM_MS ||
+           !(flags & IMAGE_FUNCTION_MS_ONLY)))
          f->add_signature(_image(prototype, types[i], intrinsic_name,
                                  num_arguments, flags));
    }
@@ -2754,6 +2760,12 @@ builtin_builder::add_image_functions(bool glsl)
                       "__intrinsic_image_size",
                       &builtin_builder::_image_size_prototype, 1,
                       flags | IMAGE_FUNCTION_SUPPORTS_FLOAT_DATA_TYPE);
+
+   add_image_function(glsl ? "imageSamples" : "__intrinsic_image_samples",
+                      "__intrinsic_image_samples",
+                      &builtin_builder::_image_samples_prototype, 1,
+                      flags | IMAGE_FUNCTION_SUPPORTS_FLOAT_DATA_TYPE |
+                      IMAGE_FUNCTION_MS_ONLY);
 }
 
 ir_variable *
@@ -4981,6 +4993,31 @@ builtin_builder::_image_size_prototype(const glsl_type *image_type,
    return sig;
 }
 
+ir_function_signature *
+builtin_builder::_image_samples_prototype(const glsl_type *image_type,
+                                          unsigned num_arguments,
+                                          unsigned flags)
+{
+   ir_variable *image = in_var(image_type, "image");
+   ir_function_signature *sig =
+      new_sig(glsl_type::int_type, shader_samples, 1, image);
+
+   /* Set the maximal set of qualifiers allowed for this image
+    * built-in.  Function calls with arguments having fewer
+    * qualifiers than present in the prototype are allowed by the
+    * spec, but not with more, i.e. this will make the compiler
+    * accept everything that needs to be accepted, and reject cases
+    * like loads from write-only or stores to read-only images.
+    */
+   image->data.image_read_only = true;
+   image->data.image_write_only = true;
+   image->data.image_coherent = true;
+   image->data.image_volatile = true;
+   image->data.image_restrict = true;
+
+   return sig;
+}
+
 ir_function_signature *
 builtin_builder::_image(image_prototype_ctr prototype,
                         const glsl_type *image_type,