1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
5 * Copyright (c) 2014-2016 The Khronos Group Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 */ /*-------------------------------------------------------------------*/
24 #include "glcShaderMultisampleInterpolationTests.hpp"
26 #include "deRandom.hpp"
27 #include "deStringUtil.hpp"
28 #include "gluContextInfo.hpp"
29 #include "gluDrawUtil.hpp"
30 #include "gluPixelTransfer.hpp"
31 #include "gluShaderProgram.hpp"
33 #include "glwFunctions.hpp"
34 #include "tcuCommandLine.hpp"
35 #include "tcuStringTemplate.hpp"
36 #include "tcuSurface.hpp"
37 #include "tcuTestLog.hpp"
41 static bool operator<(tcu::Vec4 const& k1, tcu::Vec4 const& k2)
47 else if (k1.y() == k2.y())
49 return k1.x() < k2.x();
65 static std::string specializeVersion(std::string const& source, glu::GLSLVersion version,
66 std::string const& sampler = "", std::string const& outType = "",
67 std::string const& qualifier = "", std::string const& assignment = "",
68 std::string const& condition = "")
70 DE_ASSERT(version == glu::GLSL_VERSION_310_ES || version >= glu::GLSL_VERSION_440);
71 std::map<std::string, std::string> args;
72 args["VERSION_DECL"] = glu::getGLSLVersionDeclaration(version);
73 args["SAMPLER"] = sampler;
74 args["OUT_TYPE"] = outType;
75 args["QUALIFIER"] = qualifier;
76 args["ASSIGNMENT"] = assignment;
77 args["CONDITION"] = condition;
78 if (version == glu::GLSL_VERSION_310_ES)
80 args["OES_SMI_EN"] = "#extension GL_OES_shader_multisample_interpolation : enable\n";
81 args["OES_SMI_RQ"] = "#extension GL_OES_shader_multisample_interpolation : require\n";
82 args["OES_SMI_CH"] = "#if !GL_OES_shader_multisample_interpolation\n"
85 args["OES_SV_EN"] = "#extension GL_OES_sample_variables : enable\n";
89 args["OES_SMI_EN"] = "";
90 args["OES_SMI_RQ"] = "";
91 args["OES_SMI_CH"] = "";
92 args["OES_SV_EN"] = "";
94 return tcu::StringTemplate(source.c_str()).specialize(args);
97 class ShaderMultisampleInterpolationApiCase : public TestCase
100 ShaderMultisampleInterpolationApiCase(Context& context, const char* name, const char* description,
101 glu::GLSLVersion glslVersion);
102 ~ShaderMultisampleInterpolationApiCase();
104 IterateResult iterate();
107 glu::GLSLVersion m_glslVersion;
110 ShaderMultisampleInterpolationApiCase::ShaderMultisampleInterpolationApiCase(Context& context, const char* name,
111 const char* description,
112 glu::GLSLVersion glslVersion)
113 : TestCase(context, name, description), m_glslVersion(glslVersion)
115 DE_ASSERT(glslVersion == glu::GLSL_VERSION_310_ES || glslVersion >= glu::GLSL_VERSION_440);
118 ShaderMultisampleInterpolationApiCase::~ShaderMultisampleInterpolationApiCase()
122 ShaderMultisampleInterpolationApiCase::IterateResult ShaderMultisampleInterpolationApiCase::iterate()
124 TestLog& log = m_testCtx.getLog();
125 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
128 if (m_glslVersion == glu::GLSL_VERSION_310_ES &&
129 !m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation"))
131 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "GL_OES_shader_multisample_interpolation");
135 static char const* vss = "${VERSION_DECL}\n"
137 "in highp vec4 a_position;\n"
138 "in highp vec4 a_color;\n"
139 "sample out highp vec4 v_color;\n"
142 " gl_Position = a_position;\n"
146 static char const* fss = "${VERSION_DECL}\n"
148 "sample in highp vec4 v_color;\n"
149 "out highp vec4 o_color;\n"
152 " o_color = v_color;\n"
155 glu::ShaderProgram program(m_context.getRenderContext(),
156 glu::makeVtxFragSources(specializeVersion(vss, m_glslVersion).c_str(),
157 specializeVersion(fss, m_glslVersion).c_str()));
161 TCU_FAIL("Compile failed");
166 static char const* fss = "${VERSION_DECL}\n"
168 "sample in highp vec4 v_color;\n"
169 "out highp vec4 o_color;\n"
173 " o_color = v_color;\n"
176 glu::ShaderProgram program(m_context.getRenderContext(),
177 glu::makeVtxFragSources(specializeVersion(vss, m_glslVersion).c_str(),
178 specializeVersion(fss, m_glslVersion).c_str()));
182 TCU_FAIL("Compile failed");
186 GLfloat minFragmentInterpolationOffset = 0.0f;
187 gl.getFloatv(GL_MIN_FRAGMENT_INTERPOLATION_OFFSET, &minFragmentInterpolationOffset);
188 if (minFragmentInterpolationOffset > -0.5f)
193 GLfloat maxFragmentInterpolationOffset = 0.0f;
194 gl.getFloatv(GL_MAX_FRAGMENT_INTERPOLATION_OFFSET, &maxFragmentInterpolationOffset);
195 if (maxFragmentInterpolationOffset < 0.5f)
200 GLint fragmentInterpolationOffsetBits = 0;
201 gl.getIntegerv(GL_FRAGMENT_INTERPOLATION_OFFSET_BITS, &fragmentInterpolationOffsetBits);
202 if (fragmentInterpolationOffsetBits < 4)
207 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, isOk ? "Pass" : "Fail");
211 class ShaderMultisampleInterpolationBaseCase : public TestCase
214 ShaderMultisampleInterpolationBaseCase(Context& context, const char* name, const char* description,
215 glu::GLSLVersion glslVersion, char const* qualifier, char const* assignment,
216 char const* condition, bool unique, GLenum internalFormat,
217 tcu::TextureFormat const& texFormat, const char* m_sampler,
218 const char* m_outType, GLfloat min, GLfloat max, GLint samples);
219 ~ShaderMultisampleInterpolationBaseCase();
221 IterateResult iterate();
224 glu::GLSLVersion m_glslVersion;
225 std::string m_qualifier;
226 std::string m_assignment;
227 std::string m_condition;
229 GLenum m_internalFormat;
230 tcu::TextureFormat m_texFormat;
231 std::string m_sampler;
232 std::string m_outType;
243 int countUniquePixels(tcu::ConstPixelBufferAccess const& pixels);
244 int countUniquePixels(const std::vector<tcu::Vec4>& pixels);
247 ShaderMultisampleInterpolationBaseCase::ShaderMultisampleInterpolationBaseCase(
248 Context& context, const char* name, const char* description, glu::GLSLVersion glslVersion, char const* qualifier,
249 char const* assignment, char const* condition, bool unique, GLenum internalFormat,
250 tcu::TextureFormat const& texFormat, const char* sampler, const char* outType, GLfloat min, GLfloat max,
252 : TestCase(context, name, description)
253 , m_glslVersion(glslVersion)
254 , m_qualifier(qualifier)
255 , m_assignment(assignment)
256 , m_condition(condition)
258 , m_internalFormat(internalFormat)
259 , m_texFormat(texFormat)
266 DE_ASSERT(glslVersion == glu::GLSL_VERSION_310_ES || glslVersion >= glu::GLSL_VERSION_440);
269 ShaderMultisampleInterpolationBaseCase::~ShaderMultisampleInterpolationBaseCase()
273 ShaderMultisampleInterpolationBaseCase::IterateResult ShaderMultisampleInterpolationBaseCase::iterate()
275 TestLog& log = m_testCtx.getLog();
276 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
278 bool supportsRgba32f = false;
280 if (m_glslVersion == glu::GLSL_VERSION_310_ES &&
281 !m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation"))
283 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "GL_OES_shader_multisample_interpolation");
287 supportsRgba32f = isContextTypeGLCore(m_context.getRenderContext().getType()) ?
289 (m_context.getContextInfo().isExtensionSupported("GL_EXT_color_buffer_float") ||
290 m_context.getContextInfo().isExtensionSupported("GL_ARB_color_buffer_float"));
292 if (m_internalFormat == GL_RGBA32F && !supportsRgba32f)
294 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Internalformat rgba32f not supported");
299 if (((m_texFormat.type == tcu::TextureFormat::FLOAT) && (m_texFormat.order == tcu::TextureFormat::RGBA)) ||
300 ((m_texFormat.type == tcu::TextureFormat::FLOAT) && (m_texFormat.order == tcu::TextureFormat::RG)) ||
301 ((m_texFormat.type == tcu::TextureFormat::FLOAT) && (m_texFormat.order == tcu::TextureFormat::R)) ||
302 ((m_texFormat.type == tcu::TextureFormat::HALF_FLOAT) && (m_texFormat.order == tcu::TextureFormat::RGBA)))
304 gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, m_internalFormat, GL_SAMPLES, 1, &maxSamples);
305 if (m_samples > maxSamples)
307 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED,
308 "Test sample count greater than samples that the format supports");
312 else if (m_texFormat.type == tcu::TextureFormat::SIGNED_INT8 ||
313 m_texFormat.type == tcu::TextureFormat::UNSIGNED_INT8)
315 gl.getIntegerv(GL_MAX_INTEGER_SAMPLES, &maxSamples);
316 if (m_samples > maxSamples)
318 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Test sample count greater than MAX_INTEGER_SAMPLES");
324 gl.getIntegerv(GL_MAX_SAMPLES, &maxSamples);
325 if (m_samples > maxSamples)
327 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Test sample count greater than MAX_SAMPLES");
332 // Create a multisample texture, or a regular texture if samples is zero.
334 gl.genTextures(1, &tex);
335 gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);
336 gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_samples, m_internalFormat, WIDTH, HEIGHT, GL_FALSE);
338 // Create a framebuffer with the texture attached.
340 gl.genFramebuffers(1, &fboMs);
341 gl.bindFramebuffer(GL_FRAMEBUFFER, fboMs);
342 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, tex, 0);
343 gl.viewport(0, 0, WIDTH, HEIGHT);
345 static deUint16 const quadIndices[] = { 0, 1, 2, 2, 1, 3 };
348 // Draw with one of the fragment input qualifiers and with one of the
349 // interpolate functions. Cross-check the result in the shader and
350 // output the final interpolated value.
352 static char const* vss = "${VERSION_DECL}\n"
354 "layout(location = 0) in highp vec2 a_position;\n"
355 "layout(location = 1) in highp vec4 a_color;\n"
356 "out highp vec4 v_colorBase;\n"
357 "${QUALIFIER} out highp vec4 v_color;\n"
360 " v_colorBase = a_color;\n"
361 " v_color = a_color;\n"
362 " gl_Position = vec4(a_position, 0.0, 1.0);\n"
365 static char const* fss = "${VERSION_DECL}\n"
368 "in highp vec4 v_colorBase;\n"
369 "${QUALIFIER} in highp vec4 v_color;\n"
370 "layout(location = 0) out highp ${OUT_TYPE} o_color;\n"
373 " highp vec4 temp = ${ASSIGNMENT};\n"
374 " bool condition = ${CONDITION};\n"
375 " o_color = ${OUT_TYPE}(temp.x, temp.y, condition, 1);\n"
378 glu::ShaderProgram program(
379 m_context.getRenderContext(),
380 glu::makeVtxFragSources(
381 specializeVersion(vss, m_glslVersion, m_sampler, m_outType, m_qualifier, m_assignment, m_condition)
383 specializeVersion(fss, m_glslVersion, m_sampler, m_outType, m_qualifier, m_assignment, m_condition)
388 TCU_FAIL("Compile failed");
391 static float const position[] = {
392 -1.0f, -1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f, +1.0f,
395 const float color[] = {
396 m_min, m_min, 0.0f, 1.0f, m_min, m_max, 0.0f, 1.0f, m_max, m_min, 0.0f, 1.0f, m_max, m_max, 0.0f, 1.0f,
399 gl.useProgram(program.getProgram());
401 glu::VertexArrayBinding vertexArrays[] = {
402 glu::va::Float("a_position", 2, 4, 0, &position[0]), glu::va::Float("a_color", 4, 4, 0, &color[0]),
404 glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays),
405 &vertexArrays[0], glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));
407 GLU_EXPECT_NO_ERROR(gl.getError(), "Draw quad");
410 gl.bindFramebuffer(GL_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer());
411 gl.deleteFramebuffers(1, &fboMs);
413 GLsizei width = WIDTH * m_samples;
416 gl.genRenderbuffers(1, &rbo);
417 gl.bindRenderbuffer(GL_RENDERBUFFER, rbo);
418 gl.renderbufferStorage(GL_RENDERBUFFER, m_internalFormat, width, HEIGHT);
421 gl.genFramebuffers(1, &fbo);
422 gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
423 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
424 gl.viewport(0, 0, width, HEIGHT);
427 // Resolve the mutli-sample texture into a render-buffer sized such that
428 // the width can hold all samples of a pixel.
430 static char const* vss = "${VERSION_DECL}\n"
431 "in highp vec2 a_position;\n"
434 " gl_Position = vec4(a_position, 0.0, 1.0);\n"
437 static char const* fss = "${VERSION_DECL}\n"
438 "uniform highp ${SAMPLER}MS u_texMS;\n"
439 "uniform int u_samples;\n"
440 "layout(location = 0) out highp ${OUT_TYPE} o_color;\n"
443 " ivec2 coord = ivec2(int(gl_FragCoord.x) / u_samples, gl_FragCoord.y);\n"
444 " int sampleId = int(gl_FragCoord.x) % u_samples;\n"
445 " o_color = texelFetch(u_texMS, coord, sampleId);\n"
448 glu::ShaderProgram program(
449 m_context.getRenderContext(),
450 glu::makeVtxFragSources(specializeVersion(vss, m_glslVersion, m_sampler, m_outType).c_str(),
451 specializeVersion(fss, m_glslVersion, m_sampler, m_outType).c_str()));
455 TCU_FAIL("Compile failed");
458 static float const position[] = {
459 -1.0f, -1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f, +1.0f,
462 gl.useProgram(program.getProgram());
463 gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_samples"), m_samples);
464 gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_texMS"), 0);
466 glu::VertexArrayBinding vertexArrays[] = {
467 glu::va::Float("a_position", 2, 4, 0, &position[0]),
469 glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays),
470 &vertexArrays[0], glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));
472 GLU_EXPECT_NO_ERROR(gl.getError(), "Draw quad");
475 // Verify the results.
476 tcu::TextureLevel results(m_texFormat, width, HEIGHT);
477 tcu::PixelBufferAccess pixels = results.getAccess();
478 std::vector<tcu::Vec4> result(pixels.getHeight() * pixels.getWidth());
481 if (pixels.getFormat().type == tcu::TextureFormat::SIGNED_INT8)
483 std::vector<GLint> data(pixels.getHeight() * pixels.getWidth() * 4);
484 gl.readPixels(0, 0, pixels.getWidth(), pixels.getHeight(), GL_RGBA_INTEGER, GL_INT, &data[0]);
485 for (unsigned int i = 0; i < data.size(); i += 4)
488 tcu::Vec4((GLfloat)data[i], (GLfloat)data[i + 1], (GLfloat)data[i + 2], (GLfloat)data[i + 3]);
490 uniquePixels = countUniquePixels(result);
492 else if (pixels.getFormat().type == tcu::TextureFormat::UNSIGNED_INT8)
494 std::vector<GLuint> data(pixels.getHeight() * pixels.getWidth() * 4);
495 gl.readPixels(0, 0, pixels.getWidth(), pixels.getHeight(), GL_RGBA_INTEGER, GL_UNSIGNED_INT, &data[0]);
496 for (unsigned int i = 0; i < data.size(); i += 4)
499 tcu::Vec4((GLfloat)data[i], (GLfloat)data[i + 1], (GLfloat)data[i + 2], (GLfloat)data[i + 3]);
501 uniquePixels = countUniquePixels(result);
505 glu::readPixels(m_context.getRenderContext(), 0, 0, pixels);
506 uniquePixels = countUniquePixels(pixels);
509 int expectedUnique = WIDTH * HEIGHT * ((m_unique) ? m_samples : 1);
510 if (uniquePixels < expectedUnique)
512 // There are duplicate pixel values meaning interpolation didn't work as expected.
515 for (int y = 0; y < pixels.getHeight(); ++y)
517 for (int x = 0; x < pixels.getWidth(); ++x)
520 if (pixels.getFormat().type == tcu::TextureFormat::SIGNED_INT8 ||
521 pixels.getFormat().type == tcu::TextureFormat::UNSIGNED_INT8)
523 pixel = result[y * WIDTH + x];
527 pixel = pixels.getPixel(x, y);
531 // The ${CONDITION} check in the shader failed.
537 gl.bindFramebuffer(GL_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer());
538 gl.deleteFramebuffers(1, &fbo);
540 gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
541 gl.deleteRenderbuffers(1, &rbo);
543 gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
544 gl.deleteTextures(1, &tex);
546 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, isOk ? "Pass" : "Fail");
550 int ShaderMultisampleInterpolationBaseCase::countUniquePixels(tcu::ConstPixelBufferAccess const& pixels)
552 std::set<tcu::Vec4> uniquePixels;
554 for (int y = 0; y < pixels.getHeight(); ++y)
556 for (int x = 0; x < pixels.getWidth(); ++x)
558 uniquePixels.insert(pixels.getPixel(x, y));
562 return (int)uniquePixels.size();
565 int ShaderMultisampleInterpolationBaseCase::countUniquePixels(const std::vector<tcu::Vec4>& pixels)
567 std::set<tcu::Vec4> uniquePixels;
569 for (unsigned int i = 0; i < pixels.size(); ++i)
571 uniquePixels.insert(pixels[i]);
574 return (int)uniquePixels.size();
577 ShaderMultisampleInterpolationTests::ShaderMultisampleInterpolationTests(Context& context, glu::GLSLVersion glslVersion)
578 : TestCaseGroup(context, "shader_multisample_interpolation", "Shader Multisample Interpolation tests")
579 , m_glslVersion(glslVersion)
583 ShaderMultisampleInterpolationTests::~ShaderMultisampleInterpolationTests()
587 void ShaderMultisampleInterpolationTests::init()
594 { "samples_1", 1 }, { "samples_2", 2 }, { "samples_4", 4 },
597 // shader_multisample_interpolation.api
598 tcu::TestCaseGroup* apiGroup = new tcu::TestCaseGroup(m_testCtx, "api", "API verification");
599 apiGroup->addChild(new ShaderMultisampleInterpolationApiCase(m_context, "api", "API verification", m_glslVersion));
605 char const* qualifier;
606 char const* assignment;
607 char const* condition;
610 { "base", "", "v_color", "true", false },
611 { "sample", "sample", "v_color", "true", true },
612 { "centroid", "centroid", "v_color", "true", false },
613 { "interpolate_at_sample", "", "interpolateAtSample(v_colorBase, gl_SampleID)", "true", true },
614 { "interpolate_at_sample_check", "sample", "interpolateAtSample(v_colorBase, gl_SampleID)", "temp == v_color",
616 { "interpolate_at_centroid", "", "interpolateAtCentroid(v_colorBase)", "true", false },
617 { "interpolate_at_centroid_check", "centroid", "interpolateAtCentroid(v_colorBase)", "temp == v_color", false },
618 { "interpolate_at_offset", "", "interpolateAtOffset(v_colorBase, gl_SamplePosition - 0.5)", "true", true },
619 { "interpolate_at_offset_check", "sample", "interpolateAtOffset(v_colorBase, gl_SamplePosition - 0.5)",
620 "temp == v_color", true },
623 // shader_multisample_interpolation.render
624 tcu::TestCaseGroup* renderGroup = new tcu::TestCaseGroup(m_testCtx, "render", "Rendering tests");
625 addChild(renderGroup);
626 for (int caseId = 0; caseId < DE_LENGTH_OF_ARRAY(cases); ++caseId)
628 tcu::TestCaseGroup* group = new tcu::TestCaseGroup(m_testCtx, cases[caseId].name, "");
629 renderGroup->addChild(group);
633 GLenum internalFormat;
634 tcu::TextureFormat textureFormat;
640 { "rgba8", GL_RGBA8, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
641 "sampler2D", "vec4", 0.0f, 1.0f },
642 { "rgba8i", GL_RGBA8I, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT8),
643 "isampler2D", "ivec4", -128.0f, 127.0f },
644 { "rgba8ui", GL_RGBA8UI, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT8),
645 "usampler2D", "uvec4", 0.0f, 255.0f },
646 { "rgba32f", GL_RGBA32F, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT),
647 "sampler2D", "vec4", 0.0f, 1.0f },
649 for (int format = 0; format < DE_LENGTH_OF_ARRAY(formats); ++format)
651 tcu::TestCaseGroup* formatGroup = new tcu::TestCaseGroup(m_testCtx, formats[format].name, "");
652 group->addChild(formatGroup);
654 for (int sample = 0; sample < DE_LENGTH_OF_ARRAY(samples); ++sample)
656 formatGroup->addChild(new ShaderMultisampleInterpolationBaseCase(
657 m_context, samples[sample].name, "", m_glslVersion, cases[caseId].qualifier,
658 cases[caseId].assignment, cases[caseId].condition, cases[caseId].unique,
659 formats[format].internalFormat, formats[format].textureFormat, formats[format].sampler,
660 formats[format].outType, formats[format].min, formats[format].max, samples[sample].samples));