This tests FBO setup with various combinations of multisample textures and `classic` multisample renderbuffers, and for each, checks:
- That the renderbuffers or textures can be created - Completeness status If the configuration is expected to work, additionally: - Actual sample count >= requested sample count - Sample positions meet spec requirements (all obtainable, and in [0,1] Covers the fixedsamplelocations and sample count consistency requirements in the spec. V2: - Don't specify window size, we don't care. - Add comment about internalformat defaulting. - Don't specify dims, sample count per attachment; attachment is either multisampled or not, dims are always the same. - Report each config result using subtests - Support testing different sample counts, and test 2/4/6/8/16 samples in all.tests. Unsupported sample counts are skipped. - Fixup for signature change of piglit_report_subtest_result. - Test some multisample array scenarios too. - Lookup enum names for some of the output, to make it easier to read. - Remove the bogus stencil texture case, it's not valid. - Skip subtests which can't work with the sample limits exposed by the driver, rather than just failing. Signed-off-by: Chris Forbes <chr...@ijw.co.nz> --- tests/all.tests | 4 + .../spec/arb_texture_multisample/CMakeLists.gl.txt | 1 + .../spec/arb_texture_multisample/fb-completeness.c | 304 +++++++++++++++++++++ 3 files changed, 309 insertions(+) create mode 100644 tests/spec/arb_texture_multisample/fb-completeness.c diff --git a/tests/all.tests b/tests/all.tests index 84e2696..184b172 100644 --- a/tests/all.tests +++ b/tests/all.tests @@ -861,6 +861,10 @@ add_plain_test(arb_point_sprite, 'point-sprite') arb_texture_multisample = Group() spec['ARB_texture_multisample'] = arb_texture_multisample add_concurrent_test(arb_texture_multisample, 'arb_texture_multisample-minmax') +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,)) # Group AMD_shader_stencil_export spec['AMD_shader_stencil_export'] = Group() diff --git a/tests/spec/arb_texture_multisample/CMakeLists.gl.txt b/tests/spec/arb_texture_multisample/CMakeLists.gl.txt index 90dae9e..d793256 100644 --- a/tests/spec/arb_texture_multisample/CMakeLists.gl.txt +++ b/tests/spec/arb_texture_multisample/CMakeLists.gl.txt @@ -11,5 +11,6 @@ link_libraries ( ) piglit_add_executable (arb_texture_multisample-minmax minmax.c) +piglit_add_executable (arb_texture_multisample-fb-completeness fb-completeness.c) # vim: ft=cmake: diff --git a/tests/spec/arb_texture_multisample/fb-completeness.c b/tests/spec/arb_texture_multisample/fb-completeness.c new file mode 100644 index 0000000..0267c21 --- /dev/null +++ b/tests/spec/arb_texture_multisample/fb-completeness.c @@ -0,0 +1,304 @@ +#include "piglit-util-gl-common.h" + +PIGLIT_GL_TEST_CONFIG_BEGIN + + config.supports_gl_compat_version = 30; + config.window_visual = PIGLIT_GL_VISUAL_RGB; + +PIGLIT_GL_TEST_CONFIG_END + +enum piglit_result +piglit_display(void) +{ + return PIGLIT_FAIL; +} + +#define SURFACE_WIDTH 64 +#define SURFACE_HEIGHT 64 +#define SURFACE_DEPTH 2 // for GL_TEXTURE_2D_MULTISAMPLE_ARRAY + +struct attachment_info +{ + GLenum target; + GLenum attachment; + bool multisample; + bool fixedsamplelocations; + GLuint format; // override internalformat; if zero, will choose something + // reasonable based on the attachment + int layer; // for GL_TEXTURE_2D_MULTISAMPLE_ARRAY, the layer to attach +}; + +struct test_info +{ + char const *name; + int expected; + struct attachment_info attachments[4]; +}; + +struct test_info tests[] = { + { "single_msaa_color", GL_FRAMEBUFFER_COMPLETE, + { { GL_TEXTURE_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT0, GL_TRUE, GL_TRUE }, + { 0 }, + } + }, + { "msaa_mrt_color", GL_FRAMEBUFFER_COMPLETE, + { { GL_TEXTURE_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT0, GL_TRUE, GL_TRUE }, + { GL_TEXTURE_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT1, GL_TRUE, GL_TRUE }, + { 0 }, + } + }, + { "msaa_mixed_texture_and_renderbuffer", GL_FRAMEBUFFER_COMPLETE, + { { GL_TEXTURE_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT0, GL_TRUE, GL_TRUE }, + { GL_RENDERBUFFER, GL_COLOR_ATTACHMENT0, GL_TRUE, GL_TRUE }, + { 0 }, + } + }, + { "mixed_msaa_and_plain", GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE, + { { GL_TEXTURE_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT0, GL_TRUE, GL_TRUE }, + { GL_RENDERBUFFER, GL_COLOR_ATTACHMENT1, GL_FALSE, GL_TRUE }, + { 0 }, + } + }, + { "msaa_mrt_color_nofixed", GL_FRAMEBUFFER_COMPLETE, + { { GL_TEXTURE_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT0, GL_TRUE, GL_FALSE }, + { GL_TEXTURE_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT1, GL_TRUE, GL_FALSE }, + { 0 }, + } + }, + { "mix_fixedmode", GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE, + { { GL_TEXTURE_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT0, GL_TRUE, GL_TRUE }, + { GL_TEXTURE_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT1, GL_TRUE, GL_FALSE }, + { 0 }, + } + }, + { "mix_fixedmode_with_renderbuffer", GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE, + { { GL_TEXTURE_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT0, GL_TRUE, GL_FALSE }, + { GL_RENDERBUFFER, GL_COLOR_ATTACHMENT1, GL_TRUE, GL_TRUE }, + { 0 }, + } + }, + { "msaa_depth", GL_FRAMEBUFFER_COMPLETE, + { { GL_TEXTURE_2D_MULTISAMPLE, GL_DEPTH_ATTACHMENT, GL_TRUE, GL_TRUE }, + { 0 }, + } + }, + { "msaa_depth_stencil", GL_FRAMEBUFFER_COMPLETE, + { { GL_TEXTURE_2D_MULTISAMPLE, GL_DEPTH_ATTACHMENT, GL_TRUE, GL_TRUE, + GL_DEPTH_STENCIL + }, + { 0 }, + } + }, + { "msaa_classic_stencil", GL_FRAMEBUFFER_COMPLETE, + { { GL_TEXTURE_2D_MULTISAMPLE, GL_COLOR_ATTACHMENT0, GL_TRUE, GL_TRUE }, + { GL_RENDERBUFFER, GL_STENCIL_ATTACHMENT, GL_TRUE, GL_TRUE }, + { 0 }, + } + }, + { "msaa_color_layer", GL_FRAMEBUFFER_COMPLETE, + { { GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_COLOR_ATTACHMENT0, GL_TRUE, GL_TRUE, + .layer=0 }, + { 0 }, + } + }, + { "msaa_color_nonzero_layer", GL_FRAMEBUFFER_COMPLETE, + { { GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_COLOR_ATTACHMENT0, GL_TRUE, GL_TRUE, + .layer=1 }, + { 0 }, + } + }, + { 0 }, +}; + +static GLuint +choose_format(struct attachment_info *att) +{ + if (att->format) + return att->format; + + switch(att->attachment) { + case GL_DEPTH_ATTACHMENT: + return GL_DEPTH_COMPONENT; + case GL_STENCIL_ATTACHMENT: + return GL_STENCIL_INDEX; + default: + return GL_RGBA; + } +} + +static enum piglit_result +check_sample_positions(int expected_sample_count) +{ + GLint samples; + int i; + + glGetIntegerv(GL_SAMPLES, &samples); + if (!piglit_check_gl_error(GL_NO_ERROR)) + return PIGLIT_FAIL; + + if (samples < expected_sample_count) { + printf("Expected sample count at least %d, got %d\n", + expected_sample_count, samples); + return PIGLIT_FAIL; + } + + for (i = 0; i < samples; i++) { + float sample_pos[2]; + + glGetMultisamplefv(GL_SAMPLE_POSITION, i, sample_pos); + + if (!piglit_check_gl_error(GL_NO_ERROR)) + return PIGLIT_FAIL; + + printf("Sample %d position %2.2f %2.2f\n", + i, sample_pos[0], sample_pos[1] ); + + if (sample_pos[0] < 0 || sample_pos[0] > 1 || + sample_pos[1] < 0 || sample_pos[1] > 1) { + printf("Sample %d out of range\n", i ); + return PIGLIT_FAIL; + } + } + + return PIGLIT_PASS; +} + +static enum piglit_result +exec_test(struct test_info *info, int sample_count) +{ + GLuint fb, tex, rb; + GLint result; + struct attachment_info *att; + GLint maxColorSamples, maxDepthSamples; + + glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorSamples); + glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &maxDepthSamples); + + glGenFramebuffers(1, &fb); + glBindFramebuffer(GL_FRAMEBUFFER, fb); + + printf("Testing fbo completeness for config '%s'\n", info->name); + + for (att=info->attachments; att->target; att++) { + int attachment_sample_count = att->multisample ? sample_count : 0; + printf(" Att target=%s att=%s samples=%d dims=%d,%d,%d fixed=%d\n", + piglit_get_gl_enum_name(att->target), + piglit_get_gl_enum_name(att->attachment), + attachment_sample_count, + SURFACE_WIDTH, SURFACE_HEIGHT, + att->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY ? SURFACE_DEPTH : 1, + att->fixedsamplelocations); + + switch (att->target) { + case GL_TEXTURE_2D_MULTISAMPLE: + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: + if (att->attachment == GL_DEPTH_ATTACHMENT && sample_count > maxDepthSamples) + return PIGLIT_SKIP; + if ((att->attachment == GL_COLOR_ATTACHMENT0 || + att->attachment == GL_COLOR_ATTACHMENT1) && sample_count > maxColorSamples) + return PIGLIT_SKIP; + } + + switch (att->target) { + case GL_TEXTURE_2D_MULTISAMPLE: + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex); + glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, + attachment_sample_count, choose_format(att), + SURFACE_WIDTH, SURFACE_HEIGHT, + att->fixedsamplelocations); + + if (!piglit_check_gl_error(GL_NO_ERROR)) + return PIGLIT_FAIL; + + glFramebufferTexture2D(GL_FRAMEBUFFER, att->attachment, + att->target, tex, 0); + break; + + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, tex); + glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, + attachment_sample_count, choose_format(att), + SURFACE_WIDTH, SURFACE_HEIGHT, SURFACE_DEPTH, + att->fixedsamplelocations); + + if (!piglit_check_gl_error(GL_NO_ERROR)) + return PIGLIT_FAIL; + + glFramebufferTextureLayer(GL_FRAMEBUFFER, att->attachment, + tex, 0, att->layer); + break; + + case GL_RENDERBUFFER: + /* RENDERBUFFER has fixedsamplelocations implicitly */ + assert(att->fixedsamplelocations); + glGenRenderbuffers(1, &rb); + glBindRenderbuffer(GL_RENDERBUFFER, rb); + if (att->multisample) { + glRenderbufferStorageMultisample(GL_RENDERBUFFER, + attachment_sample_count, choose_format(att), + SURFACE_WIDTH, SURFACE_HEIGHT); + } + else { + /* non-MSAA renderbuffer */ + glRenderbufferStorage(GL_RENDERBUFFER, choose_format(att), + SURFACE_WIDTH, SURFACE_HEIGHT); + } + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, + att->attachment, att->target, rb); + + if (!piglit_check_gl_error(GL_NO_ERROR)) + return PIGLIT_FAIL; + break; + + default: + assert(!"Unsupported target"); + } + } + + result = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (result != info->expected) { + printf("glCheckFramebufferStatus: expected %s, got %s\n", + piglit_get_gl_enum_name(info->expected), + piglit_get_gl_enum_name(result)); + return PIGLIT_FAIL; + } + + if (result == GL_FRAMEBUFFER_COMPLETE && info->attachments->multisample) + return check_sample_positions(sample_count); + + return PIGLIT_PASS; +} + +void +usage(int argc, char **argv) +{ + printf("usage: %s <sample-count>\n", argv[0]); + piglit_report_result(PIGLIT_SKIP); +} + +void +piglit_init(int argc, char **argv) +{ + struct test_info *info; + enum piglit_result result = PIGLIT_PASS; + int sample_count; + int max_samples; + + if (argc != 2) + usage(argc, argv); + + sample_count = atoi(argv[1]); + glGetIntegerv(GL_MAX_SAMPLES, &max_samples); + if (sample_count > max_samples) { + printf("Sample count of %d not supported.\n", sample_count); + piglit_report_result(PIGLIT_SKIP); + } + + for (info = tests; info->name; info++) + piglit_report_subtest_result(exec_test(info, sample_count), info->name); + + piglit_report_result(result); +} -- 1.8.1.4 _______________________________________________ Piglit mailing list Piglit@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/piglit