Mesa (master): meta: Add support for integer blits.

Eric Anholt anholt at kemper.freedesktop.org
Fri Feb 21 18:44:37 UTC 2014


Module: Mesa
Branch: master
Commit: f2f337c6d57b16901c0b21beb14793cb9fef8568
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=f2f337c6d57b16901c0b21beb14793cb9fef8568

Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 10 23:44:54 2014 -0800

meta: Add support for integer blits.

Compared to i965, the code generated doesn't use the AVG instruction.  But
I'm not sure that multisampled integer resolves are really that important
to worry about.

Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>

---

 src/mesa/drivers/common/meta.h      |   10 ++++++
 src/mesa/drivers/common/meta_blit.c |   68 +++++++++++++++++++++++++++++++----
 2 files changed, 71 insertions(+), 7 deletions(-)

diff --git a/src/mesa/drivers/common/meta.h b/src/mesa/drivers/common/meta.h
index c7a21fc..fcf45c4 100644
--- a/src/mesa/drivers/common/meta.h
+++ b/src/mesa/drivers/common/meta.h
@@ -221,9 +221,19 @@ struct blit_shader_table {
    struct blit_shader sampler_cubemap_array;
 };
 
+/**
+ * Indices in the blit_state->msaa_shaders[] array
+ *
+ * Note that setup_glsl_msaa_blit_shader() assumes that the _INT enums are one
+ * more than the non-_INT version and _UINT is one beyond that.
+ */
 enum blit_msaa_shader {
    BLIT_MSAA_SHADER_2D_MULTISAMPLE_RESOLVE,
+   BLIT_MSAA_SHADER_2D_MULTISAMPLE_RESOLVE_INT,
+   BLIT_MSAA_SHADER_2D_MULTISAMPLE_RESOLVE_UINT,
    BLIT_MSAA_SHADER_2D_MULTISAMPLE_COPY,
+   BLIT_MSAA_SHADER_2D_MULTISAMPLE_COPY_INT,
+   BLIT_MSAA_SHADER_2D_MULTISAMPLE_COPY_UINT,
    BLIT_MSAA_SHADER_2D_MULTISAMPLE_DEPTH_RESOLVE,
    BLIT_MSAA_SHADER_2D_MULTISAMPLE_DEPTH_COPY,
    BLIT_MSAA_SHADER_COUNT,
diff --git a/src/mesa/drivers/common/meta_blit.c b/src/mesa/drivers/common/meta_blit.c
index 7f5416d..34b58d9 100644
--- a/src/mesa/drivers/common/meta_blit.c
+++ b/src/mesa/drivers/common/meta_blit.c
@@ -95,9 +95,24 @@ setup_glsl_msaa_blit_shader(struct gl_context *ctx,
    enum blit_msaa_shader shader_index;
    const char *samplers[] = {
       [BLIT_MSAA_SHADER_2D_MULTISAMPLE_RESOLVE] = "sampler2DMS",
+      [BLIT_MSAA_SHADER_2D_MULTISAMPLE_RESOLVE_INT] = "isampler2DMS",
+      [BLIT_MSAA_SHADER_2D_MULTISAMPLE_RESOLVE_UINT] = "usampler2DMS",
       [BLIT_MSAA_SHADER_2D_MULTISAMPLE_COPY] = "sampler2DMS",
+      [BLIT_MSAA_SHADER_2D_MULTISAMPLE_COPY_INT] = "isampler2DMS",
+      [BLIT_MSAA_SHADER_2D_MULTISAMPLE_COPY_UINT] = "usampler2DMS",
    };
    bool dst_is_msaa = false;
+   GLenum src_datatype;
+   const char *vec4_prefix;
+
+   if (src_rb) {
+      src_datatype = _mesa_get_format_datatype(src_rb->Format);
+   } else {
+      /* depth-or-color glCopyTexImage fallback path that passes a NULL rb and
+       * doesn't handle integer.
+       */
+      src_datatype = GL_UNSIGNED_NORMALIZED;
+   }
 
    if (ctx->DrawBuffer->Visual.samples > 1) {
       /* If you're calling meta_BlitFramebuffer with the destination
@@ -135,6 +150,21 @@ setup_glsl_msaa_blit_shader(struct gl_context *ctx,
       shader_index = BLIT_MSAA_SHADER_2D_MULTISAMPLE_RESOLVE;
    }
 
+   /* We rely on the enum being sorted this way. */
+   STATIC_ASSERT(BLIT_MSAA_SHADER_2D_MULTISAMPLE_RESOLVE_INT ==
+                 BLIT_MSAA_SHADER_2D_MULTISAMPLE_RESOLVE + 1);
+   STATIC_ASSERT(BLIT_MSAA_SHADER_2D_MULTISAMPLE_RESOLVE_UINT ==
+                 BLIT_MSAA_SHADER_2D_MULTISAMPLE_RESOLVE + 2);
+   if (src_datatype == GL_INT) {
+      shader_index++;
+      vec4_prefix = "i";
+   } else if (src_datatype == GL_UNSIGNED_INT) {
+      shader_index += 2;
+      vec4_prefix = "u";
+   } else {
+      vec4_prefix = "";
+   }
+
    if (blit->msaa_shaders[shader_index]) {
       _mesa_UseProgram(blit->msaa_shaders[shader_index]);
       return;
@@ -199,11 +229,25 @@ setup_glsl_msaa_blit_shader(struct gl_context *ctx,
       int samples = MAX2(src_rb->NumSamples, 1);
       char *sample_resolve;
       const char *arb_sample_shading_extension_string;
+      const char *merge_function;
 
       if (dst_is_msaa) {
          arb_sample_shading_extension_string = "#extension GL_ARB_sample_shading : enable";
          sample_resolve = ralloc_asprintf(mem_ctx, "   out_color = texelFetch(texSampler, ivec2(texCoords), gl_SampleID);");
+         merge_function = "";
       } else {
+         if (src_datatype == GL_INT) {
+            merge_function =
+               "ivec4 merge(ivec4 a, ivec4 b) { return (a >> ivec4(1)) + (b >> ivec4(1)) + (a & b & ivec4(1)); }\n";
+         } else if (src_datatype == GL_UNSIGNED_INT) {
+            merge_function =
+               "uvec4 merge(uvec4 a, uvec4 b) { return (a >> uvec4(1)) + (b >> uvec4(1)) + (a & b & uvec4(1)); }\n";
+         } else {
+            /* The divide will happen at the end for floats. */
+            merge_function =
+               "vec4 merge(vec4 a, vec4 b) { return (a + b); }\n";
+         }
+
          arb_sample_shading_extension_string = "";
 
          /* We're assuming power of two samples for this resolution procedure.
@@ -218,8 +262,8 @@ setup_glsl_msaa_blit_shader(struct gl_context *ctx,
          sample_resolve = rzalloc_size(mem_ctx, 1);
          for (int i = 0; i < samples; i++) {
             ralloc_asprintf_append(&sample_resolve,
-                                   "   vec4 sample_1_%d = texelFetch(texSampler, ivec2(texCoords), %d);\n",
-                                   i, i);
+                                   "   %svec4 sample_1_%d = texelFetch(texSampler, ivec2(texCoords), %d);\n",
+                                   vec4_prefix, i, i);
          }
          /* Now, merge each pair of samples, then merge each pair of those,
           * etc.
@@ -227,7 +271,8 @@ setup_glsl_msaa_blit_shader(struct gl_context *ctx,
          for (int step = 2; step <= samples; step *= 2) {
             for (int i = 0; i < samples; i += step) {
                ralloc_asprintf_append(&sample_resolve,
-                                      "vec4 sample_%d_%d = sample_%d_%d + sample_%d_%d;\n",
+                                      "   %svec4 sample_%d_%d = merge(sample_%d_%d, sample_%d_%d);\n",
+                                      vec4_prefix,
                                       step, i,
                                       step / 2, i,
                                       step / 2, i + step / 2);
@@ -235,9 +280,15 @@ setup_glsl_msaa_blit_shader(struct gl_context *ctx,
          }
 
          /* Scale the final result. */
-         ralloc_asprintf_append(&sample_resolve,
-                                "   out_color = sample_%d_0 / %f;\n",
-                                samples, (float)samples);
+         if (src_datatype == GL_UNSIGNED_INT || src_datatype == GL_INT) {
+            ralloc_asprintf_append(&sample_resolve,
+                                   "   out_color = sample_%d_0;\n",
+                                   samples);
+         } else {
+            ralloc_asprintf_append(&sample_resolve,
+                                   "   out_color = sample_%d_0 / %f;\n",
+                                   samples, (float)samples);
+         }
       }
 
       vs_source = ralloc_asprintf(mem_ctx,
@@ -256,14 +307,17 @@ setup_glsl_msaa_blit_shader(struct gl_context *ctx,
                                   "%s\n"
                                   "uniform %s texSampler;\n"
                                   "in vec2 texCoords;\n"
-                                  "out vec4 out_color;\n"
+                                  "out %svec4 out_color;\n"
                                   "\n"
+                                  "%s" /* merge_function */
                                   "void main()\n"
                                   "{\n"
                                   "%s\n" /* sample_resolve */
                                   "}\n",
                                   arb_sample_shading_extension_string,
                                   samplers[shader_index],
+                                  vec4_prefix,
+                                  merge_function,
                                   sample_resolve);
    }
 




More information about the mesa-commit mailing list