[Mesa-dev] [PATCH 6/6] meta: Add support for integer blits.
Eric Anholt
eric at anholt.net
Wed Feb 19 17:30:23 PST 2014
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.
---
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);
}
--
1.9.rc1
More information about the mesa-dev
mailing list