| /*------------------------------------------------------------------------- |
| * OpenGL Conformance Test Suite |
| * ----------------------------- |
| * |
| * Copyright (c) 2014-2016 The Khronos Group Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ /*! |
| * \file |
| * \brief |
| */ /*-------------------------------------------------------------------*/ |
| |
| /** |
| */ /*! |
| * \file gl4cShaderTextureImageSamplesTests.cpp |
| * \brief Implements conformance tests for GL_ARB_shader_texture_image_samples functionality |
| */ /*-------------------------------------------------------------------*/ |
| |
| #include "gl4cShaderTextureImageSamplesTests.hpp" |
| #include "gluContextInfo.hpp" |
| #include "gluDefs.hpp" |
| #include "glwEnums.hpp" |
| #include "glwFunctions.hpp" |
| #include "tcuRenderTarget.hpp" |
| #include "tcuTestLog.hpp" |
| |
| #include <string> |
| #include <vector> |
| |
| namespace glcts |
| { |
| /** Constructor. |
| * |
| * @param context Rendering context |
| * @param name Test name |
| * @param description Test description |
| */ |
| ShaderTextureImageSamplesTestBase::ShaderTextureImageSamplesTestBase(deqp::Context& context, const char* name, |
| const char* description) |
| : deqp::TestCase(context, name, description) |
| , m_internalformat_n_samples_count(0) |
| , m_internalformat_n_samples_data(DE_NULL) |
| , m_bo_id(0) |
| , m_cs_id(0) |
| , m_po_id(0) |
| , m_to_id(0) |
| , m_to_depth(3) |
| , m_to_height(4) |
| , m_to_width(8) |
| { |
| /* Left blank intentionally */ |
| } |
| |
| /** Compiles a compute shader and optionally attaches it to a program object, which the |
| * method can then try to link. |
| * |
| * Shader object ID will be stored in m_cs_id. |
| * Program object ID will be stored in m_po_id. |
| * |
| * @param cs_body Source code of the compute shader to use for compilation. |
| * @param should_link_po true if the method should also attempt to link the program object. |
| * @param should_succeed true if the compilation and linking (depending on @param should_link_po) |
| * processes should succeed, false otherwise. If GL implementation |
| * is found not to accept a valid compute shader, the method will |
| * throw a TestError exception. |
| * |
| * Upon failure, the method *does not* delete the program & shader objects. |
| * |
| * @return true if the compilation / linking process was successful, false otherwise. |
| **/ |
| bool ShaderTextureImageSamplesTestBase::buildComputeProgram(const char* cs_body, bool should_link_po, |
| bool should_succeed) |
| { |
| bool result = false; |
| |
| /* Deinitialize any program / shader objects that may have already been initialized |
| * for this test instance. |
| */ |
| deinitProgramAndShaderObjects(); |
| |
| /* Create the objects */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| m_cs_id = gl.createShader(GL_COMPUTE_SHADER); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed."); |
| |
| m_po_id = gl.createProgram(); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed."); |
| |
| /* Set up the shader object */ |
| gl.shaderSource(m_cs_id, 1, /* count */ |
| &cs_body, DE_NULL); /* length */ |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); |
| |
| /* Compile the shader object */ |
| glw::GLint compile_status = GL_FALSE; |
| |
| gl.compileShader(m_cs_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed."); |
| |
| gl.getShaderiv(m_cs_id, GL_COMPILE_STATUS, &compile_status); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed."); |
| |
| if (compile_status != GL_TRUE) |
| { |
| if (should_succeed) |
| { |
| TCU_FAIL("Shader compilation failed."); |
| } |
| |
| goto end; |
| } |
| else |
| { |
| if (!should_succeed) |
| { |
| TCU_FAIL("Shader compilation has succeeded, even though it should not have."); |
| } |
| } |
| |
| if (should_link_po) |
| { |
| /* Prepare the program object for linking */ |
| gl.attachShader(m_po_id, m_cs_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed."); |
| |
| /* Link the program object */ |
| glw::GLint link_status = GL_FALSE; |
| |
| gl.linkProgram(m_po_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed."); |
| |
| gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed."); |
| |
| if (link_status != GL_TRUE) |
| { |
| if (should_succeed) |
| { |
| TCU_FAIL("Program linking failed."); |
| } |
| |
| goto end; |
| } |
| } |
| |
| result = true; |
| end: |
| return result; |
| } |
| |
| /** Deinitializes all GL objects that may have been created during test execution. */ |
| void ShaderTextureImageSamplesTestBase::deinit() |
| { |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| deinitProgramAndShaderObjects(); |
| |
| if (m_bo_id != 0) |
| { |
| gl.deleteBuffers(1, &m_bo_id); |
| |
| m_bo_id = 0; |
| } |
| |
| if (m_internalformat_n_samples_data != DE_NULL) |
| { |
| delete[] m_internalformat_n_samples_data; |
| |
| m_internalformat_n_samples_data = DE_NULL; |
| } |
| |
| if (m_to_id != 0) |
| { |
| gl.deleteTextures(1, &m_to_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed."); |
| |
| m_to_id = 0; |
| } |
| } |
| |
| /** Deinitializes program & shader objects that may have been created |
| * during test execution. |
| **/ |
| void ShaderTextureImageSamplesTestBase::deinitProgramAndShaderObjects() |
| { |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| if (m_cs_id != 0) |
| { |
| gl.deleteShader(m_cs_id); |
| |
| m_cs_id = 0; |
| } |
| |
| if (m_po_id != 0) |
| { |
| gl.deleteProgram(m_po_id); |
| |
| m_po_id = 0; |
| } |
| } |
| |
| /** Executes the functional test as described in CTS_ARB_shader_texture_image_samples. |
| * |
| * This method throws a TestError exception if OpenGL implementation reports any |
| * error OR the "samples" value reported by OpenGL is found to be incorrect. |
| * |
| * @param sampler_type Tells which sampler type should be used for the test. Note that |
| * even though sampler type enum values are named after texture samplers, |
| * the actual ES SL types used during the test will depend on whether |
| * the caller requested images or textures to be used (see @param test_type) |
| * @param test_type Tells whether the test should verify image or texture samplers. |
| **/ |
| void ShaderTextureImageSamplesTestBase::executeFunctionalTest(const _sampler_type& sampler_type, |
| const _test_type& test_type) |
| { |
| std::string cs_body; |
| const char* cs_template_code = "#version 430\n" |
| "\n" |
| "#extension GL_ARB_shader_texture_image_samples : require\n" |
| "\n" |
| "layout(local_size_x = 1) in;\n" |
| "\n" |
| "buffer Result\n" |
| "{\n" |
| " int samples;\n" |
| "};\n" |
| "\n" |
| "SAMPLER_TYPE data;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " samples = SAMPLES_MODIFIER\n" |
| "}\n"; |
| |
| /* Any program or shader objects lying around at this point? If so, release them |
| * before we proceed. |
| */ |
| deinitProgramAndShaderObjects(); |
| |
| /* Construct the shader body */ |
| const std::string samples_modifier_token = "SAMPLES_MODIFIER"; |
| size_t samples_modifier_token_location = std::string::npos; |
| std::string samples_modifier_token_value; |
| std::string sampler_type_string; |
| const std::string sampler_type_token = "SAMPLER_TYPE"; |
| size_t sampler_type_token_location = std::string::npos; |
| std::string sampler_type_token_value; |
| |
| switch (test_type) |
| { |
| case TEST_TYPE_IMAGE: |
| { |
| samples_modifier_token_value = "imageSamples(data);\n"; |
| |
| switch (sampler_type) |
| { |
| case SAMPLER_TYPE_ISAMPLER2DMS: |
| { |
| sampler_type_string = "iimage2DMS"; |
| sampler_type_token_value = "layout(rgba8i) uniform iimage2DMS"; |
| |
| break; |
| } |
| |
| case SAMPLER_TYPE_ISAMPLER2DMSARRAY: |
| { |
| sampler_type_string = "iimage2DMSArray"; |
| sampler_type_token_value = "layout(rgba8i) uniform iimage2DMSArray"; |
| |
| break; |
| } |
| |
| case SAMPLER_TYPE_SAMPLER2DMS: |
| { |
| sampler_type_string = "image2DMS"; |
| sampler_type_token_value = "layout(rgba8) uniform image2DMS"; |
| |
| break; |
| } |
| |
| case SAMPLER_TYPE_SAMPLER2DMSARRAY: |
| { |
| sampler_type_string = "image2DMSArray"; |
| sampler_type_token_value = "layout(rgba8) uniform image2DMSArray"; |
| |
| break; |
| } |
| |
| case SAMPLER_TYPE_USAMPLER2DMS: |
| { |
| sampler_type_string = "uimage2DMS"; |
| sampler_type_token_value = "layout(rgba8ui) uniform uimage2DMS"; |
| |
| break; |
| } |
| |
| case SAMPLER_TYPE_USAMPLER2DMSARRAY: |
| { |
| sampler_type_string = "uimage2DMSArray"; |
| sampler_type_token_value = "layout(rgba8ui) uniform uimage2DMSArray"; |
| |
| break; |
| } |
| |
| default: |
| { |
| TCU_FAIL("Unrecognized sampler type"); |
| } |
| } /* switch (sampler_type) */ |
| |
| break; |
| } /* case TEST_TYPE_IMAGE: */ |
| |
| case TEST_TYPE_TEXTURE: |
| { |
| samples_modifier_token_value = "textureSamples(data);\n"; |
| |
| switch (sampler_type) |
| { |
| case SAMPLER_TYPE_ISAMPLER2DMS: |
| { |
| sampler_type_string = "isampler2DMS"; |
| sampler_type_token_value = "uniform isampler2DMS"; |
| |
| break; |
| } |
| |
| case SAMPLER_TYPE_ISAMPLER2DMSARRAY: |
| { |
| sampler_type_string = "isampler2DMSArray"; |
| sampler_type_token_value = "uniform isampler2DMSArray"; |
| |
| break; |
| } |
| |
| case SAMPLER_TYPE_SAMPLER2DMS: |
| { |
| sampler_type_string = "sampler2DMS"; |
| sampler_type_token_value = "uniform sampler2DMS"; |
| |
| break; |
| } |
| |
| case SAMPLER_TYPE_SAMPLER2DMSARRAY: |
| { |
| sampler_type_string = "sampler2DMSArray"; |
| sampler_type_token_value = "uniform sampler2DMSArray"; |
| |
| break; |
| } |
| |
| case SAMPLER_TYPE_USAMPLER2DMS: |
| { |
| sampler_type_string = "usampler2DMS"; |
| sampler_type_token_value = "uniform usampler2DMS"; |
| |
| break; |
| } |
| |
| case SAMPLER_TYPE_USAMPLER2DMSARRAY: |
| { |
| sampler_type_string = "usampler2DMSArray"; |
| sampler_type_token_value = "uniform usampler2DMSArray"; |
| |
| break; |
| } |
| |
| default: |
| { |
| TCU_FAIL("Unrecognized sampler type"); |
| } |
| } /* switch (sampler_type) */ |
| |
| break; |
| } /* case TEST_TYPE_TEXTURE: */ |
| |
| default: |
| { |
| TCU_FAIL("Unrecognized test type"); |
| } |
| } /* switch (test_type) */ |
| |
| cs_body = cs_template_code; |
| |
| while ((samples_modifier_token_location = cs_body.find(samples_modifier_token)) != std::string::npos) |
| { |
| cs_body.replace(samples_modifier_token_location, samples_modifier_token.length(), samples_modifier_token_value); |
| } |
| |
| while ((sampler_type_token_location = cs_body.find(sampler_type_token)) != std::string::npos) |
| { |
| cs_body.replace(sampler_type_token_location, sampler_type_token.length(), sampler_type_token_value); |
| } |
| |
| /* Build the compute program */ |
| if (!buildComputeProgram(cs_body.c_str(), true, /* should_link_po */ |
| true)) /* should_succeed */ |
| { |
| TCU_FAIL("Could not link a test program"); |
| } |
| |
| /* Set up SSBO */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.shaderStorageBlockBinding(m_po_id, 0, /* storageBlockIndex */ |
| 0); /* storageBlockBinding */ |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderStorageBlockBinding() call failed."); |
| |
| gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, /* index */ |
| m_bo_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed."); |
| |
| /* Determine what numbers of samples we can use for GL_RGBA8, GL_RGBA8I |
| * or GL_RGBA8UI internalformats. Specific choice depends on the sampler type |
| * requested bty the caller. |
| */ |
| glw::GLenum texture_internalformat = GL_NONE; |
| glw::GLenum texture_target = GL_NONE; |
| |
| if (sampler_type == SAMPLER_TYPE_ISAMPLER2DMS || sampler_type == SAMPLER_TYPE_ISAMPLER2DMSARRAY) |
| { |
| texture_internalformat = GL_RGBA8I; |
| } |
| else if (sampler_type == SAMPLER_TYPE_SAMPLER2DMS || sampler_type == SAMPLER_TYPE_SAMPLER2DMSARRAY) |
| { |
| texture_internalformat = GL_RGBA8; |
| } |
| else |
| { |
| texture_internalformat = GL_RGBA8UI; |
| } |
| |
| if (sampler_type == SAMPLER_TYPE_ISAMPLER2DMS || sampler_type == SAMPLER_TYPE_SAMPLER2DMS || |
| sampler_type == SAMPLER_TYPE_USAMPLER2DMS) |
| { |
| texture_target = GL_TEXTURE_2D_MULTISAMPLE; |
| } |
| else |
| { |
| texture_target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY; |
| } |
| |
| gl.getInternalformativ(texture_target, texture_internalformat, GL_NUM_SAMPLE_COUNTS, 1, /* bufSize */ |
| &m_internalformat_n_samples_count); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ() call failed."); |
| |
| if (m_internalformat_n_samples_count < 1) |
| { |
| TCU_FAIL("Invalid value returned by glGetInternalformativ() for a GL_NUM_SAMPLE_COUNTS query"); |
| } |
| |
| m_internalformat_n_samples_data = new glw::GLint[m_internalformat_n_samples_count]; |
| |
| gl.getInternalformativ(texture_target, texture_internalformat, GL_SAMPLES, m_internalformat_n_samples_count, |
| m_internalformat_n_samples_data); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ() call failed."); |
| |
| /* Iterate over all sample counts. For each iteration, set up texture storage, |
| * run one work-item which will store the value retrieved by one of the two new |
| * ES SL functions into the buffer object. Once that happens, map the buffer |
| * object storage contents into process space and validate the value */ |
| for (int n_value = 0; n_value < m_internalformat_n_samples_count; ++n_value) |
| { |
| if (test_type == TEST_TYPE_IMAGE) |
| { |
| /* Shader images do not necessarily support all sample counts. */ |
| int max_image_samples; |
| |
| gl.getIntegerv(GL_MAX_IMAGE_SAMPLES, &max_image_samples); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv(GL_MAX_IMAGE_SAMPLES) call failed."); |
| |
| if (m_internalformat_n_samples_data[n_value] > max_image_samples) |
| continue; |
| } |
| |
| gl.genTextures(1, &m_to_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed."); |
| |
| gl.bindTexture(texture_target, m_to_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); |
| |
| if (texture_target == GL_TEXTURE_2D_MULTISAMPLE) |
| { |
| gl.texStorage2DMultisample(texture_target, m_internalformat_n_samples_data[n_value], texture_internalformat, |
| m_to_width, m_to_height, GL_FALSE); /* fixedsamplelocations */ |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() call failed"); |
| } |
| else |
| { |
| DE_ASSERT(texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY); |
| |
| gl.texStorage3DMultisample(texture_target, m_internalformat_n_samples_data[n_value], texture_internalformat, |
| m_to_width, m_to_height, m_to_depth, GL_TRUE); /* fixedsamplelocations */ |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3DMultisample() call failed"); |
| } |
| |
| /* If we're running the "image" test, bind the texture to zeroth image unit */ |
| if (test_type == TEST_TYPE_IMAGE) |
| { |
| gl.bindImageTexture(0, /* unit */ |
| m_to_id, 0, /* level */ |
| GL_FALSE, /* layered */ |
| 0, /* lyer */ |
| GL_READ_ONLY, texture_internalformat); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture() call failed."); |
| } |
| |
| /* Dispatch a compute request */ |
| gl.useProgram(m_po_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); |
| |
| gl.dispatchCompute(1, /* num_groups_x */ |
| 1, /* num_groups_y */ |
| 1); /* num_groups_z */ |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute() call failed."); |
| |
| gl.memoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier() call failed."); |
| |
| /* Map the buffer object storage into process space */ |
| const void* bo_ptr = gl.mapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY); |
| glw::GLint expected_value = 0; |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed"); |
| |
| expected_value = m_internalformat_n_samples_data[n_value]; |
| |
| if (*(int*)bo_ptr != expected_value) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message << "Value reported for the " << sampler_type_string << " test [" |
| << *(int*)bo_ptr << "] " |
| " is different from the expected one [" |
| << expected_value << "]." << tcu::TestLog::EndMessage; |
| |
| TCU_FAIL("Invalid value reported by ES SL function"); |
| } |
| |
| /* Safe to unmap the BO at this point */ |
| gl.unmapBuffer(GL_ARRAY_BUFFER); |
| |
| gl.deleteTextures(1, &m_to_id); |
| m_to_id = 0; |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed."); |
| } /* for (all "n samples" values) */ |
| } |
| |
| /** Initializes all GL objects required to run the test. Also throws a |
| * NotSupportedError exception if GL_ARB_shader_texture_image_samples is not |
| * reported as a supported extension. |
| **/ |
| void ShaderTextureImageSamplesTestBase::init() |
| { |
| /* Make sure GL_ARB_shader_texture_image_samples is supported before continuing */ |
| if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_texture_image_samples")) |
| { |
| throw tcu::NotSupportedError("GL_ARB_shader_texture_image_samples extension is not supported."); |
| } |
| |
| /* Allocate BO storage to hold the result int value */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.genBuffers(1, &m_bo_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed."); |
| |
| gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); |
| |
| gl.bufferData(GL_ARRAY_BUFFER, sizeof(int), DE_NULL, /* data */ |
| GL_STATIC_DRAW); /* usage */ |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed."); |
| } |
| |
| /** Constructor. |
| * |
| * @param context Rendering context handle. |
| **/ |
| ShaderTextureImageSampleFunctionalTest::ShaderTextureImageSampleFunctionalTest(deqp::Context& context, |
| const char* test_name) |
| : ShaderTextureImageSamplesTestBase(context, test_name, "Verifies that the new ES SL functions (imageSamples() and " |
| "textureSamples() ) work as per spec for all supported " |
| "numbers of samples + texture target combinations.") |
| { |
| type_to_test = test_name[0] == 'i' ? TEST_TYPE_IMAGE : TEST_TYPE_TEXTURE; |
| } |
| |
| /** Initializes all GL objects required to run the test. Also throws a |
| * NotSupportedError exception if testing images and GL_MAX_IMAGE_SAMPLES = 0. |
| **/ |
| void ShaderTextureImageSampleFunctionalTest::init() |
| { |
| ShaderTextureImageSamplesTestBase::init(); |
| |
| if (type_to_test == TEST_TYPE_IMAGE) |
| { |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| glw::GLint max_image_samples; |
| gl.getIntegerv(GL_MAX_IMAGE_SAMPLES, &max_image_samples); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed."); |
| |
| if (max_image_samples == 0) |
| { |
| throw tcu::NotSupportedError("GL_MAX_IMAGE_SAMPLES == 0"); |
| } |
| } |
| } |
| |
| /** Executes test iteration. |
| * |
| * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. |
| */ |
| tcu::TestNode::IterateResult ShaderTextureImageSampleFunctionalTest::iterate() |
| { |
| for (unsigned int n_sampler_type = 0; n_sampler_type < SAMPLER_TYPE_COUNT; ++n_sampler_type) |
| { |
| _sampler_type sampler_type = (_sampler_type)n_sampler_type; |
| |
| for (unsigned int n_test_type = 0; n_test_type < TEST_TYPE_COUNT; ++n_test_type) |
| { |
| _test_type test_type = (_test_type)n_test_type; |
| |
| if (test_type == type_to_test) |
| { |
| executeFunctionalTest(sampler_type, test_type); |
| } |
| } /* for (all test types) */ |
| } /* for (all sampler types) */ |
| |
| /* Test case passed */ |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| |
| return STOP; |
| } |
| |
| /** Constructor. |
| * |
| * @param context Rendering context handle. |
| **/ |
| ShaderTextureImageSamplesGLSLExtensionEnableTest::ShaderTextureImageSamplesGLSLExtensionEnableTest( |
| deqp::Context& context) |
| : ShaderTextureImageSamplesTestBase( |
| context, "glsl_extension_enable", |
| "Verifies a shader with \"#extension GL_ARB_shader_texture_image_samples : enable\" " |
| "line defines a corresponding pre-processor macro.") |
| { |
| /* Left blank on purpose */ |
| } |
| |
| /** Executes test iteration. |
| * |
| * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. |
| */ |
| tcu::TestNode::IterateResult ShaderTextureImageSamplesGLSLExtensionEnableTest::iterate() |
| { |
| const char* cs_body = "#version 440\n" |
| "\n" |
| "#extension GL_ARB_shader_texture_image_samples : enable\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| "#ifndef GL_ARB_shader_texture_image_samples\n" |
| " force_compilation_error\n" |
| "#endif\n" |
| "}\n"; |
| |
| if (!buildComputeProgram(cs_body, false, /* should_link_po */ |
| true)) /* should_succeed */ |
| { |
| TCU_FAIL("GL_ARB_shader_image_load_store preprocessor #define is not set to the value of 1"); |
| } |
| |
| /* Test case passed */ |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| |
| return STOP; |
| } |
| |
| /** Constructor. |
| * |
| * @param context Rendering context handle. |
| **/ |
| ShaderTextureImageSamplesGLSLExtensionRequireTest::ShaderTextureImageSamplesGLSLExtensionRequireTest( |
| deqp::Context& context) |
| : ShaderTextureImageSamplesTestBase( |
| context, "glsl_extension_require", |
| "Verifies a shader with \"#extension GL_ARB_shader_texture_image_samples : require\" " |
| "line compiles without error.") |
| { |
| /* Left blank on purpose */ |
| } |
| |
| /** Executes test iteration. |
| * |
| * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. |
| */ |
| tcu::TestNode::IterateResult ShaderTextureImageSamplesGLSLExtensionRequireTest::iterate() |
| { |
| const char* cs_body = "#version 440\n" |
| "\n" |
| "#extension GL_ARB_shader_texture_image_samples : require\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| "}\n"; |
| |
| if (!buildComputeProgram(cs_body, false, /* should_link_po */ |
| true)) /* should_succeed */ |
| { |
| TCU_FAIL("A valid compute program has failed to build"); |
| } |
| |
| /* Test case passed */ |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| |
| return STOP; |
| } |
| |
| /** Constructor. |
| * |
| * @param context Rendering context. |
| */ |
| ShaderTextureImageSamplesTests::ShaderTextureImageSamplesTests(deqp::Context& context) |
| : TestCaseGroup(context, "shader_texture_image_samples_tests", |
| "Contains conformance tests that verify GL implementation's support " |
| "for GL_ARB_shader_texture_image_samples extension.") |
| { |
| } |
| |
| /** Initializes the test group contents. */ |
| void ShaderTextureImageSamplesTests::init() |
| { |
| addChild(new ShaderTextureImageSampleFunctionalTest(m_context, "image_functional_test")); |
| addChild(new ShaderTextureImageSampleFunctionalTest(m_context, "texture_functional_test")); |
| addChild(new ShaderTextureImageSamplesGLSLExtensionEnableTest(m_context)); |
| addChild(new ShaderTextureImageSamplesGLSLExtensionRequireTest(m_context)); |
| } |
| |
| } /* glcts namespace */ |