[Piglit] [PATCH] Test rendering to various miplevels of depth and stencil textures.
Chad Versace
chad.versace at linux.intel.com
Wed Apr 25 14:16:39 PDT 2012
Oops, this is texture test, not a renderbuffer test. Ignore the
comments about format s8. The comments about z32f and z32f_s8,
however, still apply.
On 04/25/2012 01:04 PM, Chad Versace wrote:
> I usually loathe Piglit's multiplexed tests and find them difficult
> to follow. But that wasn't the case with this test. Despite how many
> combinations you are testing, the source is straightforward to read.
>
> I have one request: that the naming scheme of the subtests be changed
> to allow the addition of future tests without renaming everything.
> In addition to testing combinations of formats z24_s8, z24, and z16,
> we need to also combinations involving s8, z32f, and z32f_s8.
>
> (In case I wasn't clear, I'm not requesting that you add subtests
> for those formats, just that you rename the subtests to help whoever
> does add those tests).
>
> For what it's worth, I suggest the naming scheme below. But disregard
> it if you don't like it.
>
>
> old name new name
> -------- --------
> stencil stencil=s8
> depth_x depth=z24_s8
> depth depth=z24
> d16 depth=z16
> depth_x_and_stencil depth=z24_s8_then_stencil=z24_s8
> stencil_and_depth_x stencil=z24_s8_then_depth=z24_s8
> depth_stencil_single_binding depthstencil=z24_s8
>
>
> This will allow us to add tests like this:
> depth=z24_then_stencil=s8
> depth=z32f_then_stencil=s8
> depthstencil=z32f_s8
>
>
> On 04/24/2012 10:39 AM, Paul Berry wrote:
>> This patch adds a new test, "depthstencil-render-miplevels", which
>> verifies that we can render to all miplevels of depth and stencil
>> textures. It exposes two bugs in Mesa's current i965 driver:
>>
>> - Miptree offsets aren't being calculated correctly for HiZ and
>> separate stencil buffers, causing miplevels to overlap in those
>> buffers.
>>
>> - When binding the same texture to the GL_DEPTH_ATTACHMENT and
>> GL_STENCIL_ATTACHMENT points, Mesa is trying to share internal data
>> structures even if the miplevels don't match; as a result,
>> transitioning from one miplevel to another doesn't work.
>>
>> The test is capable of running at any texture size (including
>> non-power-of-two texture sizes). However, because of some GPU hang
>> bugs in Mesa's current i965 driver, I've limited it to test at a
>> texture size of 1024x1024 for now.
>> ---
>> tests/all.tests | 17 +
>> tests/texturing/CMakeLists.gl.txt | 1 +
>> tests/texturing/depthstencil-render-miplevels.cpp | 349 +++++++++++++++++++++
>> 3 files changed, 367 insertions(+), 0 deletions(-)
>> create mode 100644 tests/texturing/depthstencil-render-miplevels.cpp
>>
>> diff --git a/tests/all.tests b/tests/all.tests
>> index bd16c42..dc746bc 100644
>> --- a/tests/all.tests
>> +++ b/tests/all.tests
>> @@ -725,6 +725,23 @@ add_plain_test(texturing, 'texture-packed-formats')
>> add_plain_test(texturing, 'texture-rg')
>> add_plain_test(texturing, 'tex-srgb')
>>
>> +# Note: for a reasonably thorough test we should be testing a variety
>> +# of texture sizes, some of which are not powers of two. For i965, a
>> +# particularly mean set of test sizes would be (146, 292, 585, 1024),
>> +# since this exercises all possible combinations of buffer alignments.
>> +#
>> +# However, existing i965 driver bugs cause GPU hangs for sizes 146,
>> +# 292, and 585. So, as a temporary measure, just test a size of 1024.
>> +for texture_size in (1024,):
>> + for test_type in ('stencil', 'depth_x', 'depth', 'd16',
>> + 'depth_x_and_stencil', 'depth_and_stencil',
>> + 'stencil_and_depth_x', 'stencil_and_depth',
>> + 'depth_stencil_shared', 'stencil_depth_shared',
>> + 'depth_stencil_single_binding'):
>> + test_name = 'depthstencil-render-miplevels {0} {1}'.format(
>> + texture_size, test_type)
>> + texturing[test_name] = PlainExecTest(test_name + ' -auto')
>> +
>
> Piglit really needs a way to place metadata like this into the test itself. One day...
>
>> def texwrap_test(args):
>> test = PlainExecTest(args + ['-fbo'])
>> test.runConcurrent = True
>> diff --git a/tests/texturing/CMakeLists.gl.txt b/tests/texturing/CMakeLists.gl.txt
>> index 6246a02..37b8bc7 100644
>> --- a/tests/texturing/CMakeLists.gl.txt
>> +++ b/tests/texturing/CMakeLists.gl.txt
>> @@ -24,6 +24,7 @@ IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
>> ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
>> piglit_add_executable (cubemap cubemap.c)
>> piglit_add_executable (depth-level-clamp depth-level-clamp.c)
>> +piglit_add_executable (depthstencil-render-miplevels depthstencil-render-miplevels.cpp)
>> piglit_add_executable (gen-compressed-teximage gen-compressed-teximage.c)
>> piglit_add_executable (gen-nonzero-unit gen-nonzero-unit.c)
>> piglit_add_executable (gen-teximage gen-teximage.c)
>> diff --git a/tests/texturing/depthstencil-render-miplevels.cpp b/tests/texturing/depthstencil-render-miplevels.cpp
>> new file mode 100644
>> index 0000000..4b818ec
>> --- /dev/null
>> +++ b/tests/texturing/depthstencil-render-miplevels.cpp
>> @@ -0,0 +1,349 @@
>> +/*
>> + * Copyright © 2012 Intel Corporation
>> + *
>> + * Permission is hereby granted, free of charge, to any person obtaining a
>> + * copy of this software and associated documentation files (the "Software"),
>> + * to deal in the Software without restriction, including without limitation
>> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
>> + * and/or sell copies of the Software, and to permit persons to whom the
>> + * Software is furnished to do so, subject to the following conditions:
>> + *
>> + * The above copyright notice and this permission notice (including the next
>> + * paragraph) shall be included in all copies or substantial portions of the
>> + * Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
>> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
>> + * IN THE SOFTWARE.
>> + */
>> +
>> +/** \file depthstencil-render-miplevels.cpp
>> + *
>> + * Test that data rendered to depth and stencil textures
>> + * always lands at the correct miplevel.
>> + *
>> + * This test operates by creating a set of texture buffers, attaching
>> + * them to a framebuffer one miplevel at a time, and rendering
>> + * different data into each miplevel. Then it verifies, using
>> + * glReadPixels, that the correct data appears at each miplevel.
>> + *
>> + * This is useful in diagnosing bugs such as:
>> + *
>> + * - Incorrect miplevels being attached to the framebuffer
>> + *
>> + * - Miplevels being laid out incorrectly in memory (e.g. in an
>> + * overlapping fashion)
>> + *
>> + * Usage: depthstencil-render-miplevels <texture_size> <buffer_combination>
>> + *
>> + * buffer_combination: buffer attachments:
>> + * stencil stencil->DEPTH_STENCIL
>> + * depth_x depth->DEPTH_STENCIL
>> + * depth depth->DEPTH_COMPONENT
>> + * d16 depth->DEPTH_COMPONENT16
>> + * depth_x_and_stencil depth->DEPTH_STENCIL, stencil->DEPTH_STENCIL
>> + * stencil_and_depth_x (as above, but stencil attached first)
>> + * depth_and_stencil depth->DEPTH_COMPONENT, stencil->DEPTH_STENCIL
>> + * stencil_and_depth (as above, but stencil attached first)
>> + * depth_stencil_shared depth->DEPTH_STENCIL<-stencil
>> + * stencil_depth_shared (as above, but stencil attached first)
>> + * depth_stencil_single_binding depth_stencil->DEPTH_STENCIL
>
> I like your attention to thoroughness in permuting order of attachment,
> as in depth_stencil vs stencil_depth.
>
>> + *
>> + * Note: the buffer attachments are diagrammed above as
>> + * "attachment_point->BUFFER_TYPE". So, for example:
>> + *
>> + * - "depth->DEPTH_COMPONENT, stencil->DEPTH_STENCIL" means there is a
>> + * texture of type GL_DEPTH_COMPONENT attached to
>> + * GL_DEPTH_ATTACHMENT, and a separate texture of type
>> + * GL_DEPTH_STENCIL attached to GL_STENCIL_ATTACHMENT.
>> + *
>> + * - "depth->DEPTH_STENCIL<-stencil" means there is a single texture
>> + * of type GL_DEPTH_STENCIL attached to both GL_DEPTH_ATTACHMENT and
>> + * GL_STENCIL_ATTACHMENT.
>> + *
>> + * - "depth_stencil->DEPTH_STENCIL" means there is a single texture of
>> + * type GL_DEPTH_STENCIL attached to the attachment point
>> + * GL_DEPTH_STENCIL_ATTACHMENT.
>> + */
>> +
>> +#include "piglit-util.h"
>> +
>> +int piglit_width = 16;
>> +int piglit_height = 16;
>> +int piglit_window_mode = GLUT_RGBA;
>> +
>> +namespace {
>> +
>> +GLuint color_tex;
>> +GLuint depth_tex;
>> +GLuint stencil_tex;
>> +bool attach_depth = false;
>> +bool attach_stencil = false;
>> +bool shared_attachment = false;
>> +bool attach_together = false;
>> +bool attach_stencil_first = false;
>> +bool depth_attachment_lacks_stencil = false;
>> +bool depth_attachment_16bit = false;
>> +int miplevel0_size;
>> +int max_miplevel;
>> +
>> +/**
>> + * Create a mipmapped texture with the given dimensions and internal format.
>> + */
>> +GLuint
>> +create_mipmapped_tex(GLenum internal_format)
>> +{
>> + GLenum format = internal_format == GL_DEPTH_COMPONENT16
>> + ? GL_DEPTH_COMPONENT : internal_format;
>> + GLenum type = format == GL_DEPTH_STENCIL
>> + ? GL_UNSIGNED_INT_24_8 : GL_UNSIGNED_BYTE;
>> + GLuint tex;
>> + glGenTextures(1, &tex);
>> + glBindTexture(GL_TEXTURE_2D, tex);
>> + for (int level = 0; level <= max_miplevel; ++level) {
>> + int dim = miplevel0_size >> level;
>> + glTexImage2D(GL_TEXTURE_2D, level, internal_format,
>> + dim, dim,
>> + 0,
>> + format, type, NULL);
>> + if (!piglit_check_gl_error(GL_NO_ERROR))
>> + piglit_report_result(PIGLIT_FAIL);
>> + }
>> + return tex;
>> +}
>> +
>> +/**
>> + * Attach the proper miplevel of each texture to the framebuffer
>> + */
>> +void
>> +set_up_framebuffer_for_miplevel(int level)
>> +{
>> + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
>> + GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
>> + color_tex, level);
>> + if (attach_together) {
>> + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
>> + GL_DEPTH_STENCIL_ATTACHMENT,
>> + GL_TEXTURE_2D, depth_tex, level);
>> + } else if (attach_stencil_first) {
>> + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
>> + GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
>> + stencil_tex, level);
>> + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
>> + GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
>> + depth_tex, level);
>> + } else {
>> + if (attach_depth) {
>> + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
>> + GL_DEPTH_ATTACHMENT,
>> + GL_TEXTURE_2D,
>> + depth_tex, level);
>> + }
>> + if (attach_stencil) {
>> + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
>> + GL_STENCIL_ATTACHMENT,
>> + GL_TEXTURE_2D,
>> + stencil_tex, level);
>> + }
>> + }
>> +
>> + /* Some implementations don't support certain buffer
>> + * combinations, and that's ok, provided that the
>> + * implementation reports GL_FRAMEBUFFER_UNSUPPORTED.
>> + * However, if the buffer combination was supported at
>> + * miplevel 0, it should be supported at all miplevels.
>> + */
>> + GLenum status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
>> + if (status == GL_FRAMEBUFFER_UNSUPPORTED && level == 0) {
>> + printf("This buffer combination is unsupported\n");
>> + piglit_report_result(PIGLIT_SKIP);
>> + } else if (status != GL_FRAMEBUFFER_COMPLETE) {
>> + printf("FBO incomplete at miplevel %d\n", level);
>> + piglit_report_result(PIGLIT_FAIL);
>> + }
>> +}
>> +
>> +/**
>> + * Using glClear, set the contents of the depth and stencil buffers
>> + * (if present) to a value that is unique to this miplevel.
>> + */
>> +void
>> +populate_miplevel(int level)
>> +{
>> + float float_value = float(level + 1) / (max_miplevel + 1);
>> + GLbitfield clear_mask = 0;
>> +
>> + if (attach_depth) {
>> + glClearDepth(float_value);
>> + clear_mask |= GL_DEPTH_BUFFER_BIT;
>> + }
>> + if (attach_stencil) {
>> + glClearStencil(level + 1);
>> + clear_mask |= GL_STENCIL_BUFFER_BIT;
>> + }
>> +
>> + glClear(clear_mask);
>> +}
>> +
>> +/**
>> + * Test that every pixel in the depth and stencil buffers (if present)
>> + * is equal to the value set by populate_miplevel.
>> + */
>> +bool
>> +test_miplevel(int level)
>> +{
>> + bool pass = true;
>> + int dim = miplevel0_size >> level;
>> + float float_value = float(level + 1) / (max_miplevel + 1);
>> +
>> + if (attach_depth) {
>> + printf("Probing miplevel %d depth\n", level);
>> + pass = piglit_probe_rect_depth(0, 0, dim, dim, float_value)
>> + && pass;
>> + }
>> +
>> + if (attach_stencil) {
>> + printf("Probing miplevel %d stencil\n", level);
>> + pass = piglit_probe_rect_stencil(0, 0, dim, dim, level + 1)
>> + && pass;
>> + }
>> +
>> + return pass;
>> +}
>> +
>> +void
>> +print_usage_and_exit(char *prog_name)
>> +{
>> + printf("Usage: %s <texture_size> <buffer_combination>\n"
>> + " buffer_combination: buffer attachments:\n"
>> + " stencil stencil->DEPTH_STENCIL\n"
>> + " depth_x depth->DEPTH_STENCIL\n"
>> + " depth depth->DEPTH_COMPONENT\n"
>> + " depth_x_and_stencil depth->DEPTH_STENCIL, stencil->DEPTH_STENCIL\n"
>> + " stencil_and_depth_x (as above, but stencil attached first)\n"
>> + " depth_and_stencil depth->DEPTH_COMPONENT, stencil->DEPTH_STENCIL\n"
>> + " stencil_and_depth (as above, but stencil attached first)\n"
>> + " depth_stencil_shared depth->DEPTH_STENCIL<-stencil\n"
>> + " stencil_depth_shared (as above, but stencil attached first)\n"
>> + " depth_stencil_single_binding depth/stencil->DEPTH_STENCIL\n",
>> + prog_name);
>> + piglit_report_result(PIGLIT_FAIL);
>> +}
>> +
>> +extern "C" void
>> +piglit_init(int argc, char **argv)
>> +{
>> + if (argc != 3) {
>> + print_usage_and_exit(argv[0]);
>> + }
>> +
>> + /* argv[1]: texture size */
>> + {
>> + char *endptr = NULL;
>> + miplevel0_size = strtol(argv[1], &endptr, 0);
>> + if (endptr != argv[1] + strlen(argv[1]))
>> + print_usage_and_exit(argv[0]);
>> +
>> + /* Now figure out the appropriate value of max_miplevel for this size. */
>> + max_miplevel = 0;
>> + while ((miplevel0_size >> (max_miplevel + 1)) > 0)
>> + ++max_miplevel;
>> + }
>> +
>> + /* argv[2]: buffer combination */
>> + if (strcmp(argv[2], "stencil") == 0) {
>> + attach_stencil = true;
>> + } else if (strcmp(argv[2], "depth_x") == 0) {
>> + attach_depth = true;
>> + } else if (strcmp(argv[2], "depth") == 0) {
>> + attach_depth = true;
>> + depth_attachment_lacks_stencil = true;
>> + } else if (strcmp(argv[2], "d16") == 0) {
>> + attach_depth = true;
>> + depth_attachment_lacks_stencil = true;
>> + depth_attachment_16bit = true;
>> + } else if (strcmp(argv[2], "depth_x_and_stencil") == 0) {
>> + attach_depth = true;
>> + attach_stencil = true;
>> + } else if (strcmp(argv[2], "depth_and_stencil") == 0) {
>> + attach_depth = true;
>> + attach_stencil = true;
>> + depth_attachment_lacks_stencil = true;
>> + } else if (strcmp(argv[2], "stencil_and_depth_x") == 0) {
>> + attach_depth = true;
>> + attach_stencil = true;
>> + attach_stencil_first = true;
>> + } else if (strcmp(argv[2], "stencil_and_depth") == 0) {
>> + attach_depth = true;
>> + attach_stencil = true;
>> + attach_stencil_first = true;
>> + depth_attachment_lacks_stencil = true;
>> + } else if (strcmp(argv[2], "depth_stencil_shared") == 0) {
>> + attach_depth = true;
>> + attach_stencil = true;
>> + shared_attachment = true;
>> + } else if (strcmp(argv[2], "stencil_depth_shared") == 0) {
>> + attach_depth = true;
>> + attach_stencil = true;
>> + shared_attachment = true;
>> + attach_stencil_first = true;
>> + } else if (strcmp(argv[2], "depth_stencil_single_binding") == 0) {
>> + attach_depth = true;
>> + attach_stencil = true;
>> + shared_attachment = true;
>> + attach_together = true;
>> + } else {
>> + print_usage_and_exit(argv[0]);
>> + }
>> +
>> + bool pass = true;
>> +
>> + color_tex = create_mipmapped_tex(GL_RGBA);
>> +
>> + if (attach_depth) {
>> + if (depth_attachment_16bit) {
>> + depth_tex = create_mipmapped_tex(GL_DEPTH_COMPONENT16);
>> + } else if (depth_attachment_lacks_stencil) {
>> + depth_tex = create_mipmapped_tex(GL_DEPTH_COMPONENT);
>> + } else {
>> + depth_tex = create_mipmapped_tex(GL_DEPTH_STENCIL);
>> + }
>> + }
>> +
>> + if (attach_stencil) {
>> + if (shared_attachment) {
>> + stencil_tex = depth_tex;
>> + } else {
>> + stencil_tex = create_mipmapped_tex(GL_DEPTH_STENCIL);
>> + }
>> + }
>> +
>> + GLuint fbo;
>> + glGenFramebuffers(1, &fbo);
>> + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
>> + glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
>> +
>> + for (int level = 0; level <= max_miplevel; ++level) {
>> + set_up_framebuffer_for_miplevel(level);
>> + populate_miplevel(level);
>> + }
>> + for (int level = 0; level <= max_miplevel; ++level) {
>> + set_up_framebuffer_for_miplevel(level);
>> + pass = test_miplevel(level) && pass;
>> + }
>> +
>> + piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
>> +}
>> +
>> +extern "C" enum piglit_result
>> +piglit_display()
>> +{
>> + /* Should never be reached */
>> + return PIGLIT_FAIL;
>> +}
>> +
>
>
>> +};
>
> There is so little C++ in Piglit, that closing brace looks
> out of place. Please annotate it with
> /* end namespace anonymous */
> or something similiar.
>
> ----
> Chad Versace
> chad.versace at linux.intel.com
> _______________________________________________
> Piglit mailing list
> Piglit at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/piglit
--
----
Chad Versace
chad.versace at linux.intel.com
More information about the Piglit
mailing list