[Piglit] [PATCH V3 7/8] arb_texture_multisample: add new targets to texelFetch
Chris Forbes
chrisf at ijw.co.nz
Tue Feb 26 02:18:09 PST 2013
Allows verification of texelFetch with all six flavors of MS sampler.
- Put lod/sample_index in the fourth channel of the texture, so we
can verify that the correct lod/sample was sampled.
- For multisample targets, render the test pattern rather than uploading
it. GL won't let us do a direct upload into these texture targets, and
the alternative (upload to a staging texture; copy to target) is
even messier.
- Accept sample count as an extra parameter after sampler
- Add existing swizzle option to usage string
- Use smaller formats for multisample tests, to avoid running into some
hardware limits.
This replaces the earlier arb_texture_multisample-texel-fetch-execution
and arb_texture_multisample-texel-fetch-execution-array tests, and is
much more thorough (it showed Gen7 was still messed up :( !)
V3: - Increase window height so we can test 8x.
- Don't break the format-based extension checks.
Signed-off-by: Chris Forbes <chrisf at ijw.co.nz>
---
tests/all.tests | 6 +
tests/texturing/shaders/common.c | 34 ++++--
tests/texturing/shaders/common.h | 2 +
tests/texturing/shaders/texelFetch.c | 226 +++++++++++++++++++++++++++++++----
4 files changed, 238 insertions(+), 30 deletions(-)
diff --git a/tests/all.tests b/tests/all.tests
index 5ab0a2d..a041515 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -867,6 +867,12 @@ for sample_count in MSAA_SAMPLE_COUNTS:
# fb-completeness
spec['ARB_texture_multisample/fb-completeness/%d' % (sample_count,)] = \
concurrent_test('arb_texture_multisample-fb-completeness %d' % (sample_count,))
+ # texel-fetch execution
+ for stage in ['vs','fs']:
+ for sampler in samplers_atm:
+ spec['ARB_texture_multisample/texelFetch/%d-%s-%s' % (
+ sample_count, stage, sampler)] = \
+ concurrent_test('texelFetch %s %s %d' % (stage, sampler, sample_count))
add_concurrent_test(arb_texture_multisample, 'arb_texture_multisample-texstate')
add_concurrent_test(arb_texture_multisample, 'arb_texture_multisample-sample-mask')
add_concurrent_test(arb_texture_multisample, 'arb_texture_multisample-sample-mask-value')
diff --git a/tests/texturing/shaders/common.c b/tests/texturing/shaders/common.c
index 120e424..0b13d47 100644
--- a/tests/texturing/shaders/common.c
+++ b/tests/texturing/shaders/common.c
@@ -151,10 +151,11 @@ compute_miplevel_info()
miplevels = (int) log2f(max_dimension) + 1;
if (sampler.target == GL_TEXTURE_RECTANGLE ||
- sampler.target == GL_TEXTURE_BUFFER ||
- sampler.target == GL_TEXTURE_2D_MULTISAMPLE ||
- sampler.target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
+ sampler.target == GL_TEXTURE_BUFFER)
miplevels = 1;
+ if (sampler.target == GL_TEXTURE_2D_MULTISAMPLE ||
+ sampler.target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
+ miplevels = sample_count;
/* Compute the size of each miplevel */
level_size = malloc(miplevels * sizeof(int *));
@@ -165,7 +166,11 @@ compute_miplevel_info()
level_size[l] = malloc(3 * sizeof(int));
for (i = 0; i < 3 - is_array; i++)
- level_size[l][i] = max2(level_size[l-1][i] / 2, 1);
+ if (has_samples())
+ /* same size for all sample planes */
+ level_size[l][i] = level_size[l-1][i];
+ else
+ level_size[l][i] = max2(level_size[l-1][i] / 2, 1);
if (is_array)
level_size[l][2] = base_size[2];
@@ -190,6 +195,13 @@ has_slices()
}
bool
+has_samples()
+{
+ return sampler.target == GL_TEXTURE_2D_MULTISAMPLE ||
+ sampler.target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
+}
+
+bool
is_array_sampler()
{
return sampler.target == GL_TEXTURE_1D_ARRAY ||
@@ -279,15 +291,20 @@ select_sampler(const char *name)
sampler.type = samplers[i].type;
sampler.target = samplers[i].target;
+ /* Use 32bpc sized formats where possible; drop down to 16bpc for
+ * testing multisample targets to avoid hitting some hardware limits.
+ * on i965.
+ */
+
if (name[0] == 'i') {
sampler.data_type = GL_INT;
sampler.format = GL_RGBA_INTEGER;
- sampler.internal_format = GL_RGBA32I;
+ sampler.internal_format = has_samples() ? GL_RGBA16I : GL_RGBA32I;
sampler.return_type = "ivec4";
} else if (name[0] == 'u') {
sampler.data_type = GL_UNSIGNED_INT;
sampler.format = GL_RGBA_INTEGER;
- sampler.internal_format = GL_RGBA32UI;
+ sampler.internal_format = has_samples() ? GL_RGBA16UI : GL_RGBA32UI;
sampler.return_type = "uvec4";
} else if (strstr(name, "Shadow")) {
/* Shadow Sampler */
@@ -298,7 +315,7 @@ select_sampler(const char *name)
} else {
sampler.data_type = GL_FLOAT;
sampler.format = GL_RGBA;
- sampler.internal_format = GL_RGBA32F;
+ sampler.internal_format = has_samples() ? GL_RGBA16F : GL_RGBA32F;
sampler.return_type = "vec4";
}
@@ -321,12 +338,15 @@ require_GL_features(enum shader_target test_stage)
switch (sampler.internal_format) {
case GL_RGBA32I:
+ case GL_RGBA16I:
piglit_require_extension("GL_EXT_texture_integer");
break;
case GL_RGBA32UI:
+ case GL_RGBA16UI:
piglit_require_gl_version(30);
break;
case GL_RGBA32F:
+ case GL_RGBA16F:
piglit_require_extension("GL_ARB_texture_float");
break;
}
diff --git a/tests/texturing/shaders/common.h b/tests/texturing/shaders/common.h
index a4e8cd7..878faec 100644
--- a/tests/texturing/shaders/common.h
+++ b/tests/texturing/shaders/common.h
@@ -81,6 +81,7 @@ struct sampler_info
/** Whether or not we're using GL_EXT_texture_swizzle */
bool swizzling;
+int sample_count;
extern int shader_version;
/**
@@ -97,6 +98,7 @@ float max2(float x, float y);
bool has_height();
bool has_slices();
+bool has_samples();
bool is_array_sampler();
bool is_shadow_sampler();
diff --git a/tests/texturing/shaders/texelFetch.c b/tests/texturing/shaders/texelFetch.c
index 50e91a6..ebfdfe0 100644
--- a/tests/texturing/shaders/texelFetch.c
+++ b/tests/texturing/shaders/texelFetch.c
@@ -84,11 +84,13 @@ PIGLIT_GL_TEST_CONFIG_BEGIN
config.supports_gl_core_version = 31;
config.window_width = 355;
- config.window_height = 250;
+ config.window_height = 350;
config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
PIGLIT_GL_TEST_CONFIG_END
+#define MAX_LOD_OR_SAMPLES 8.0
+
/** Vertex shader attribute locations */
const int pos_loc = 0;
const int texcoord_loc = 1;
@@ -121,7 +123,7 @@ compute_divisors(int lod, float *divisors)
divisors[0] = max2(level_size[lod][0] - 1, 1);
divisors[1] = max2(level_size[lod][1] - 1, 1);
divisors[2] = max2(level_size[lod][2] - 1, 1);
- divisors[3] = 1.0;
+ divisors[3] = MAX_LOD_OR_SAMPLES;
if (sampler.data_type != GL_UNSIGNED_INT)
divisors[0] = -divisors[0];
@@ -133,6 +135,8 @@ piglit_display()
int i, l, z;
bool pass = true;
+ glViewport(0, 0, piglit_width, piglit_height);
+
glClearColor(0.1, 0.1, 0.1, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
@@ -261,6 +265,150 @@ generate_VBOs()
glEnableVertexAttribArray(texcoord_loc);
}
+/* like piglit_draw_rect(), but works in a core context too.
+ * pretty silly and wasteful (binds a throwaway VAO and BO) */
+static void
+draw_rect_core(int x, int y, int w, int h)
+{
+ float verts[4][4];
+ GLuint bo, vao;
+
+ verts[0][0] = x;
+ verts[0][1] = y;
+ verts[0][2] = 0.0;
+ verts[0][3] = 1.0;
+ verts[1][0] = x + w;
+ verts[1][1] = y;
+ verts[1][2] = 0.0;
+ verts[1][3] = 1.0;
+ verts[2][0] = x + w;
+ verts[2][1] = y + h;
+ verts[2][2] = 0.0;
+ verts[2][3] = 1.0;
+ verts[3][0] = x;
+ verts[3][1] = y + h;
+ verts[3][2] = 0.0;
+ verts[3][3] = 1.0;
+
+ glGenVertexArrays(1, &vao);
+ glBindVertexArray(vao);
+
+ glGenBuffers(1, &bo);
+ glBindBuffer(GL_ARRAY_BUFFER, bo);
+ glBufferData(GL_ARRAY_BUFFER, 4 * 4 * sizeof(float),
+ verts, GL_STATIC_DRAW);
+ glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
+ glEnableVertexAttribArray(0);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glBindVertexArray(0);
+ glDeleteBuffers(1, &bo);
+ glDeleteVertexArrays(1, &vao);
+}
+
+/**
+ * Generate the same test pattern as generate_texture() does, but do it in the shader.
+ * This is a silly workaround for not being able to just upload directly.
+ */
+static void
+upload_multisample_data(GLuint tex, int width, int height,
+ int layers, int samples)
+{
+ GLuint oldFBO, FBO;
+ int si;
+ char *fs_code;
+ int vs, fs;
+ int staging_program = 0;
+ int layer_loc = 0;
+ int si_loc = 0;
+
+ glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (GLint *) &oldFBO);
+ if (is_array_sampler())
+ glTexImage3DMultisample(sampler.target,
+ samples, sampler.internal_format,
+ width, height, layers, GL_TRUE);
+ else
+ glTexImage2DMultisample(sampler.target,
+ samples, sampler.internal_format,
+ width, height, GL_TRUE);
+ if (!piglit_check_gl_error(GL_NO_ERROR)) {
+ printf("Error creating multisample texture\n");
+ piglit_report_result(PIGLIT_FAIL);
+ }
+
+ vs = piglit_compile_shader_text(GL_VERTEX_SHADER,
+ "#version 130\n"
+ "#extension GL_ARB_explicit_attrib_location: require\n"
+ "layout(location=0) in vec4 pos;\n"
+ "void main() {\n"
+ " gl_Position = pos;\n"
+ "}\n");
+ asprintf(&fs_code,
+ "#version 130\n"
+ "#extension GL_ARB_explicit_attrib_location: require\n"
+ "#extension GL_ARB_fragment_coord_conventions: require\n"
+ "uniform int layer;\n"
+ "uniform int si;\n"
+ "layout(pixel_center_integer) in vec4 gl_FragCoord;\n"
+ "layout(location=0) out %s o;\n"
+ "void main() {\n"
+ " o = %s(%sgl_FragCoord.x, gl_FragCoord.y, layer, si);\n"
+ "}\n",
+ sampler.return_type,
+ sampler.return_type,
+ sampler.data_type == GL_UNSIGNED_INT ? "" : "-");
+ fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_code);
+ if (!fs) {
+ printf("Failed to compile staging program.\n");
+ piglit_report_result(PIGLIT_FAIL);
+ }
+ staging_program = piglit_link_simple_program(vs,fs);
+ if (!piglit_link_check_status(staging_program))
+ piglit_report_result(PIGLIT_FAIL);
+
+ layer_loc = glGetUniformLocation(staging_program, "layer");
+ si_loc = glGetUniformLocation(staging_program, "si");
+
+ glUseProgram(staging_program);
+ if (!piglit_check_gl_error(GL_NO_ERROR)) {
+ printf("glUseProgram failed\n");
+ piglit_report_result(PIGLIT_FAIL);
+ }
+
+ glGenFramebuffers(1, &FBO);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO);
+ glViewport(0, 0, width, height);
+
+ glEnable(GL_SAMPLE_MASK);
+
+ for (si=0; si < samples; si++) {
+ glUniform1i(si_loc, si);
+ glSampleMaski(0, 1<<si);
+
+ if (is_array_sampler()) {
+ int layer;
+ for(layer = 0; layer < layers; layer++) {
+ glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ tex, 0, layer);
+ glUniform1i(layer_loc, layer);
+ draw_rect_core(-1, -1, 2, 2);
+ }
+ }
+ else {
+ glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ sampler.target, tex, 0);
+
+ glUniform1i(layer_loc, 0);
+ draw_rect_core(-1, -1, 2, 2);
+ }
+ }
+
+ glDisable(GL_SAMPLE_MASK);
+
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, oldFBO);
+}
+
/**
* Create texel data.
*/
@@ -281,18 +429,21 @@ generate_texture()
glGenTextures(1, &tex);
glBindTexture(target, tex);
- if (sampler.target == GL_TEXTURE_RECTANGLE) {
- glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- } else {
- glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
- glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ if (!has_samples()) {
+ if (sampler.target == GL_TEXTURE_RECTANGLE) {
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ } else {
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ }
+ glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ if (swizzling)
+ glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA,
+ (GLint *) sampler.swizzle);
}
- glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- if (swizzling)
- glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA,
- (GLint *) sampler.swizzle);
expected_colors = calloc(miplevels, sizeof(float **));
@@ -321,24 +472,24 @@ generate_texture()
f_ptr[0] = nx;
f_ptr[1] = y;
f_ptr[2] = z;
- f_ptr[3] = 1.0;
+ f_ptr[3] = l;
i_ptr[0] = nx;
i_ptr[1] = y;
i_ptr[2] = z;
- i_ptr[3] = 1;
+ i_ptr[3] = l;
u_ptr[0] = nx;
u_ptr[1] = y;
u_ptr[2] = z;
- u_ptr[3] = 1;
+ u_ptr[3] = l;
compute_divisors(l, divisors);
expected_ptr[0] = f_ptr[0]/divisors[0];
expected_ptr[1] = f_ptr[1]/divisors[1];
expected_ptr[2] = f_ptr[2]/divisors[2];
- expected_ptr[3] = 1.0;
+ expected_ptr[3] = f_ptr[3]/divisors[3];
swizzle(expected_ptr);
f_ptr += 4;
@@ -365,8 +516,14 @@ generate_texture()
break;
}
- upload_miplevel_data(target, l, level_image);
+ if (!has_samples())
+ upload_miplevel_data(target, l, level_image);
}
+
+ if (has_samples())
+ upload_multisample_data(tex, level_size[0][0],
+ level_size[0][1], level_size[0][2],
+ sample_count);
}
/**
@@ -381,9 +538,11 @@ coordinate_size()
case GL_TEXTURE_2D:
case GL_TEXTURE_1D_ARRAY:
case GL_TEXTURE_RECTANGLE:
+ case GL_TEXTURE_2D_MULTISAMPLE:
return 2;
case GL_TEXTURE_3D:
case GL_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
return 3;
default:
assert(!"Should not get here.");
@@ -432,6 +591,7 @@ generate_GLSL(enum shader_target test_stage)
case VS:
asprintf(&vs_code,
"#version %d\n"
+ "%s\n"
"#define ivec1 int\n"
"flat out %s color;\n"
"in vec4 pos;\n"
@@ -443,6 +603,7 @@ generate_GLSL(enum shader_target test_stage)
" gl_Position = pos;\n"
"}\n",
shader_version,
+ has_samples() ? "#extension GL_ARB_texture_multisample: require" : "",
sampler.return_type, sampler.name,
offset_func,
coordinate_size(),
@@ -475,6 +636,7 @@ generate_GLSL(enum shader_target test_stage)
shader_version);
asprintf(&fs_code,
"#version %d\n"
+ "%s\n"
"#define ivec1 int\n"
"flat in ivec4 tc;\n"
"uniform vec4 divisor;\n"
@@ -485,6 +647,7 @@ generate_GLSL(enum shader_target test_stage)
" gl_FragColor = color/divisor;\n"
"}\n",
shader_version,
+ has_samples() ? "#extension GL_ARB_texture_multisample: require" : "",
sampler.name,
offset_func,
coordinate_size(),
@@ -545,6 +708,8 @@ supported_sampler()
case GL_TEXTURE_1D_ARRAY:
case GL_TEXTURE_2D_ARRAY:
case GL_TEXTURE_RECTANGLE:
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
return true;
}
return false;
@@ -554,7 +719,7 @@ void
fail_and_show_usage()
{
printf("Usage: texelFetch [140] [offset] <vs|fs> <sampler type> "
- "[piglit args...]\n");
+ "[sample_count] [swizzle] [piglit args...]\n");
piglit_report_result(PIGLIT_FAIL);
}
@@ -593,6 +758,21 @@ piglit_init(int argc, char **argv)
if (!sampler_found && (sampler_found = select_sampler(argv[i])))
continue;
+ /* Maybe it's the sample count? */
+ if (sampler_found && has_samples() && !sample_count) {
+ if ((sample_count = atoi(argv[i]))) {
+ /* check it */
+ GLint max_samples;
+ glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
+ if (sample_count > max_samples) {
+ printf("Sample count of %d not supported, >MAX_SAMPLES\n",
+ sample_count);
+ piglit_report_result(PIGLIT_SKIP);
+ }
+ }
+ continue;
+ }
+
if (!swizzling && (swizzling = parse_swizzle(argv[i])))
continue;
@@ -614,14 +794,14 @@ piglit_init(int argc, char **argv)
tex_location = glGetUniformLocation(prog, "tex");
divisor_loc = glGetUniformLocation(prog, "divisor");
- glUseProgram(prog);
-
- glUniform1i(tex_location, 0);
-
/* Create textures and set miplevel info */
set_base_size();
compute_miplevel_info();
generate_texture();
generate_VBOs();
+
+ glUseProgram(prog);
+
+ glUniform1i(tex_location, 0);
}
--
1.8.1.4
More information about the Piglit
mailing list