| /*------------------------------------------------------------------------- |
| * 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 |
| */ /*-------------------------------------------------------------------*/ |
| |
| #include "esextcGeometryShaderLayeredRenderingBoundaryCondition.hpp" |
| |
| #include "gluDefs.hpp" |
| #include "glwEnums.hpp" |
| #include "glwFunctions.hpp" |
| #include "tcuTestLog.hpp" |
| #include <cstring> |
| #include <sstream> |
| #include <string> |
| |
| namespace glcts |
| { |
| /* Configure constant values */ |
| const glw::GLint GeometryShaderLayeredRenderingBoundaryCondition::m_width = 4; |
| const glw::GLint GeometryShaderLayeredRenderingBoundaryCondition::m_height = 4; |
| const glw::GLint GeometryShaderLayeredRenderingBoundaryCondition::m_max_depth = 4; |
| const glw::GLint GeometryShaderLayeredRenderingBoundaryCondition::m_texture_components = 4; |
| |
| /** Constructor |
| * |
| * @param context Test context |
| * @param name Test case's name |
| * @param description Test case's desricption |
| **/ |
| GeometryShaderLayeredRenderingBoundaryCondition::GeometryShaderLayeredRenderingBoundaryCondition( |
| Context& context, const ExtParameters& extParams, const char* name, const char* description) |
| : TestCaseBase(context, extParams, name, description) |
| , m_draw_mode(GL_TEXTURE_3D) |
| , m_n_points(0) |
| , m_is_fbo_layered(false) |
| , m_fbo_draw_id(0) |
| , m_fbo_read_id(0) |
| , m_fs_id(0) |
| , m_gs_id(0) |
| , m_po_id(0) |
| , m_vao_id(0) |
| , m_vs_id(0) |
| { |
| unsigned char blue[] = { 0, 0, 255, 255 }; |
| unsigned char green[] = { 0, 255, 0, 255 }; |
| unsigned char red[] = { 255, 0, 0, 255 }; |
| unsigned char white[] = { 255, 255, 255, 255 }; |
| |
| m_blue_color = new unsigned char[m_texture_components]; |
| m_green_color = new unsigned char[m_texture_components]; |
| m_red_color = new unsigned char[m_texture_components]; |
| m_white_color = new unsigned char[m_texture_components]; |
| |
| memcpy(m_blue_color, blue, sizeof(blue)); |
| memcpy(m_green_color, green, sizeof(green)); |
| memcpy(m_red_color, red, sizeof(red)); |
| memcpy(m_white_color, white, sizeof(white)); |
| } |
| |
| GeometryShaderLayeredRenderingBoundaryCondition::~GeometryShaderLayeredRenderingBoundaryCondition(void) |
| { |
| if (m_blue_color) |
| { |
| delete[] m_blue_color; |
| m_blue_color = 0; |
| } |
| |
| if (m_green_color) |
| { |
| delete[] m_green_color; |
| m_green_color = 0; |
| } |
| |
| if (m_red_color) |
| { |
| delete[] m_red_color; |
| m_red_color = 0; |
| } |
| if (m_white_color) |
| { |
| delete[] m_white_color; |
| m_white_color = 0; |
| } |
| } |
| |
| /** Check if given data contains the same values as reference pixel |
| * |
| * @param width Texture width |
| * @param height Texture height |
| * @param pixelSize Size of pixel |
| * @param textureData buffer with data read from texture |
| * @param referencePixel contains expected color value |
| * @param attachment Attachment number (written to log on failure) |
| * @param layer Layer number (written to log on failure) |
| * |
| * @return true If all data in scope from textureData contains the same color as in referencePixel |
| * false in other case |
| **/ |
| bool GeometryShaderLayeredRenderingBoundaryCondition::comparePixels(glw::GLint width, glw::GLint height, |
| glw::GLint pixelSize, |
| const unsigned char* textureData, |
| const unsigned char* referencePixel, int attachment, |
| int layer) |
| { |
| unsigned int rowWidth = pixelSize * width; |
| |
| for (int y = 0; y < height; ++y) |
| { |
| for (int x = 0; x < width; ++x) |
| { |
| const unsigned char* renderedData = textureData + y * rowWidth + x * m_texture_components; |
| |
| if (memcmp(referencePixel, renderedData, m_texture_components) != 0) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data for [x=" << x << " y=" << y |
| << " attachment=" << attachment << " layer=" << layer << "] " |
| << "[" << (int)renderedData[0] << ", " << (int)renderedData[1] << ", " |
| << (int)renderedData[2] << ", " << (int)renderedData[3] << "]" |
| << " are different from reference data [" << (int)referencePixel[0] << ", " |
| << (int)referencePixel[1] << ", " << (int)referencePixel[2] << ", " |
| << (int)referencePixel[3] << "] !" << tcu::TestLog::EndMessage; |
| return false; |
| } /* if (data comparison failed) */ |
| } /* for (all columns) */ |
| } /* for (all rows) */ |
| return true; |
| } |
| |
| /** Deinitializes GLES objects created during the test. |
| * |
| */ |
| void GeometryShaderLayeredRenderingBoundaryCondition::deinit(void) |
| { |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Reset OpenGL ES state */ |
| gl.useProgram(0); |
| gl.bindVertexArray(0); |
| gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); |
| gl.bindFramebuffer(GL_READ_FRAMEBUFFER, 0); |
| |
| for (unsigned int i = 0; i < m_textures_info.size(); i++) |
| { |
| gl.bindTexture(m_textures_info[i].m_texture_target, 0); |
| } |
| |
| if (m_po_id != 0) |
| { |
| gl.deleteProgram(m_po_id); |
| } |
| |
| if (m_fs_id != 0) |
| { |
| gl.deleteShader(m_fs_id); |
| } |
| |
| if (m_gs_id != 0) |
| { |
| gl.deleteShader(m_gs_id); |
| } |
| |
| if (m_vs_id != 0) |
| { |
| gl.deleteShader(m_vs_id); |
| } |
| |
| for (unsigned int i = 0; i < m_textures_info.size(); i++) |
| { |
| gl.deleteTextures(1, &m_textures_info[i].m_id); |
| } |
| |
| if (m_fbo_read_id != 0) |
| { |
| gl.deleteFramebuffers(1, &m_fbo_read_id); |
| } |
| |
| if (m_fbo_draw_id != 0) |
| { |
| gl.deleteFramebuffers(1, &m_fbo_draw_id); |
| } |
| |
| if (m_vao_id != 0) |
| { |
| gl.deleteVertexArrays(1, &m_vao_id); |
| } |
| |
| /* Release base class */ |
| TestCaseBase::deinit(); |
| } |
| |
| /** Returns code for Geometry Shader. |
| * |
| * @return NULL |
| **/ |
| const char* GeometryShaderLayeredRenderingBoundaryCondition::getGeometryShaderCode() |
| { |
| return 0; |
| } |
| |
| /** Returns code for Fragment Shader |
| * @return pointer to literal with Fragment Shader code |
| **/ |
| const char* GeometryShaderLayeredRenderingBoundaryCondition::getFragmentShaderCode() |
| { |
| static const char* result = "${VERSION}\n" |
| "\n" |
| "precision highp float;\n" |
| "\n" |
| "flat in int layer_id;\n" |
| " out vec4 color;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " color = vec4(1, 1, 1, 1);\n" |
| "}\n"; |
| return result; |
| } |
| |
| /** Returns code for Vertex Shader |
| * |
| * @return pointer to literal with Vertex Shader code |
| **/ |
| const char* GeometryShaderLayeredRenderingBoundaryCondition::getVertexShaderCode() |
| { |
| static const char* result = "${VERSION}\n" |
| "\n" |
| "precision highp float;\n" |
| "\n" |
| "flat out int layer_id;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " layer_id = 0;\n" |
| "}\n"; |
| |
| return result; |
| } |
| |
| /** Initializes GLES objects used during the test. |
| * |
| **/ |
| void GeometryShaderLayeredRenderingBoundaryCondition::initTest(void) |
| { |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Create shader and program objects */ |
| const char* fsCode = getFragmentShaderCode(); |
| const char* gsCode = getGeometryShaderCode(); |
| const char* vsCode = getVertexShaderCode(); |
| |
| m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); |
| m_vs_id = gl.createShader(GL_VERTEX_SHADER); |
| m_gs_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER); |
| m_po_id = gl.createProgram(); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating program/shader objects."); |
| |
| if (!buildProgram(m_po_id, (fsCode) ? m_fs_id : 0, (fsCode) ? 1 : 0 /* part */, (fsCode) ? &fsCode : 0, |
| (gsCode) ? m_gs_id : 0, (gsCode) ? 1 : 0 /* part */, (gsCode) ? &gsCode : 0, |
| (vsCode) ? m_vs_id : 0, (vsCode) ? 1 : 0 /* part */, (vsCode) ? &vsCode : 0)) |
| { |
| TCU_FAIL("Could not create a program object from a valid vertex/geometry/fragment shader!"); |
| } |
| |
| /* Set up framebuffer objects */ |
| gl.genFramebuffers(1, &m_fbo_read_id); |
| gl.genFramebuffers(1, &m_fbo_draw_id); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating framebuffer objects!"); |
| |
| /* Set up vertex array object */ |
| gl.genVertexArrays(1, &m_vao_id); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating vertex array object!"); |
| |
| for (unsigned int i = 0; i < m_textures_info.size(); i++) |
| { |
| gl.genTextures(1, &m_textures_info[i].m_id); |
| } |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating texture objects!"); |
| } |
| |
| /** Executes the test. |
| * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. |
| * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. |
| * Note the function throws exception should an error occur! |
| **/ |
| tcu::TestNode::IterateResult GeometryShaderLayeredRenderingBoundaryCondition::iterate(void) |
| { |
| /* check if EXT_geometry_shader extension is supported */ |
| if (!m_is_geometry_shader_extension_supported) |
| { |
| throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); |
| } |
| |
| initTest(); |
| |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Bind draw framebuffer */ |
| gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_draw_id); |
| |
| /* Set up all textures */ |
| unsigned char buffer[m_width * m_height * m_max_depth * m_texture_components]; |
| |
| memset(buffer, 0, sizeof(buffer)); |
| |
| for (unsigned int i = 0; i < m_textures_info.size(); i++) |
| { |
| gl.bindTexture(m_textures_info[i].m_texture_target, m_textures_info[i].m_id); |
| gl.texStorage3D(m_textures_info[i].m_texture_target, 1, GL_RGBA8, m_width, m_height, |
| m_textures_info[i].m_depth); |
| gl.texSubImage3D(m_textures_info[i].m_texture_target, 0, 0, 0, 0, m_width, m_height, m_textures_info[i].m_depth, |
| GL_RGBA, GL_UNSIGNED_BYTE, buffer); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error configuring a texture object!"); |
| } |
| |
| /* Set up draw buffers */ |
| { |
| glw::GLenum* drawBuffers = new glw::GLenum[m_textures_info.size()]; |
| |
| for (unsigned int i = 0; i < m_textures_info.size(); i++) |
| { |
| drawBuffers[i] = m_textures_info[i].m_draw_buffer; |
| } |
| |
| gl.drawBuffers((glw::GLsizei)m_textures_info.size(), drawBuffers); |
| |
| delete[] drawBuffers; |
| drawBuffers = 0; |
| } |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting draw buffers!"); |
| |
| /* Configure draw FBO so that it uses texture attachments */ |
| for (unsigned int i = 0; i < m_textures_info.size(); i++) |
| { |
| if (m_is_fbo_layered) |
| { |
| gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, m_textures_info[i].m_draw_buffer, m_textures_info[i].m_id, |
| 0 /* level */); |
| } |
| else |
| { |
| gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, m_textures_info[i].m_draw_buffer, m_textures_info[i].m_id, |
| 0 /* level */, i /* layer */); |
| } |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error configuring framebuffer objects!"); |
| } /* for (all textures considered) */ |
| |
| /* Verify draw framebuffer is considered complete */ |
| glw::GLenum fboCompleteness = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER); |
| |
| if (fboCompleteness != GL_FRAMEBUFFER_COMPLETE) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message << "Draw FBO is incomplete: " |
| << "[" << fboCompleteness << "]" << tcu::TestLog::EndMessage; |
| |
| TCU_FAIL("Draw FBO is incomplete."); |
| } |
| |
| /* Set up viewport */ |
| gl.viewport(0, 0, m_width, m_height); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting up viewport!"); |
| |
| /** Bind a vertex array object */ |
| gl.bindVertexArray(m_vao_id); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error configuring vertex array object!"); |
| |
| /* Render */ |
| gl.useProgram(m_po_id); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error using program object!"); |
| |
| gl.drawArrays(m_draw_mode, 0, m_n_points); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed!"); |
| |
| /* Bind read framebuffer object. */ |
| gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read_id); |
| |
| /* Compare the rendered data against reference representation */ |
| unsigned int min_depth = 0; |
| |
| if (m_textures_info.size() > 0) |
| { |
| min_depth = m_textures_info[0].m_depth; |
| |
| for (unsigned int nTexture = 1; nTexture < m_textures_info.size(); nTexture++) |
| { |
| if (min_depth > (unsigned)m_textures_info[nTexture].m_depth) |
| { |
| min_depth = m_textures_info[nTexture].m_depth; |
| } |
| } |
| } |
| |
| for (unsigned int nTexture = 0; nTexture < m_textures_info.size(); nTexture++) |
| { |
| for (unsigned int nLayer = 0; nLayer < min_depth; nLayer++) |
| { |
| /* Configure read FBO's color attachment */ |
| gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_textures_info[nTexture].m_id, 0, |
| nLayer); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up read framebuffer!"); |
| |
| /* Verify read framebuffer is considered complete */ |
| glw::GLenum _fboCompleteness = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER); |
| |
| if (_fboCompleteness != GL_FRAMEBUFFER_COMPLETE) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message << "Read FBO is incomplete: " |
| << "[" << _fboCompleteness << "]" << tcu::TestLog::EndMessage; |
| |
| TCU_FAIL("Read FBO is incomplete."); |
| } |
| gl.viewport(0, 0, m_width, m_height); |
| |
| /* Read the rendered data */ |
| gl.readPixels(0 /* x */, 0 /* y */, m_width /* width */, m_height /* height */, GL_RGBA, GL_UNSIGNED_BYTE, |
| buffer); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not read pixels using glReadPixels()"); |
| |
| /* Retrieve reference color for layer */ |
| unsigned char expectedData[m_texture_components]; |
| |
| getReferenceColor(nLayer, expectedData, m_texture_components); |
| |
| /* Compare the retrieved data with reference data */ |
| if (!comparePixels(m_width, m_height, m_texture_components, buffer, expectedData, nTexture, nLayer)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| return STOP; |
| } /* if (data comparison failed) */ |
| } /* for (all layers) */ |
| } /* for (all texture objects) */ |
| |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| return STOP; |
| } |
| |
| /** Constructor |
| * |
| * @param context Test context |
| * @param name Test case's name |
| * @param description Test case's desricption |
| **/ |
| GeometryShaderLayeredRenderingBoundaryConditionVariousTextures:: |
| GeometryShaderLayeredRenderingBoundaryConditionVariousTextures(Context& context, const ExtParameters& extParams, |
| const char* name, const char* description) |
| : GeometryShaderLayeredRenderingBoundaryCondition(context, extParams, name, description) |
| { |
| TextureInfo texInfo; |
| |
| texInfo.m_depth = 2; |
| texInfo.m_draw_buffer = GL_COLOR_ATTACHMENT0; |
| texInfo.m_id = 0; |
| texInfo.m_texture_target = GL_TEXTURE_3D; |
| |
| m_textures_info.push_back(texInfo); |
| |
| texInfo.m_depth = 4; |
| texInfo.m_draw_buffer = GL_COLOR_ATTACHMENT1; |
| texInfo.m_id = 0; |
| texInfo.m_texture_target = GL_TEXTURE_3D; |
| |
| m_textures_info.push_back(texInfo); |
| |
| m_draw_mode = GL_POINTS; |
| m_n_points = 1; |
| m_is_fbo_layered = true; |
| } |
| |
| /** Returns code for Fragment Shader |
| * |
| * @return pointer to literal with Fragment Shader code |
| **/ |
| const char* GeometryShaderLayeredRenderingBoundaryConditionVariousTextures::getFragmentShaderCode() |
| { |
| static const char* result = "${VERSION}\n" |
| "\n" |
| "precision highp float;\n" |
| "\n" |
| "flat in int layer_id;\n" |
| "layout(location=0) out vec4 color0;\n" |
| "layout(location=1) out vec4 color1;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " vec4 color;\n" |
| " switch (layer_id)\n" |
| " {\n" |
| " case 0: color = vec4(1, 0, 0, 1); break;\n" |
| " case 1: color = vec4(0, 1, 0, 1); break;\n" |
| " case 2: color = vec4(0, 0, 1, 1); break;\n" |
| " case 3: color = vec4(1, 1, 1, 1); break;\n" |
| " default: color = vec4(0, 0, 0, 0); break;\n" |
| " }\n" |
| " color0 = color;\n" |
| " color1 = color;\n" |
| "}\n"; |
| return result; |
| } |
| |
| /** Returns code for Geometry Shader |
| * |
| * @return pointer to literal with Geometry Shader code |
| **/ |
| const char* GeometryShaderLayeredRenderingBoundaryConditionVariousTextures::getGeometryShaderCode() |
| { |
| static const char* result = "${VERSION}\n" |
| "\n" |
| "${GEOMETRY_SHADER_REQUIRE}\n" |
| "\n" |
| "precision highp float;\n" |
| "\n" |
| "#define MAX_VERTICES 16\n" |
| "#define N_LAYERS 2\n" |
| "\n" |
| "layout(points) in;\n" |
| "layout(triangle_strip, max_vertices=MAX_VERTICES) out;\n" |
| "\n" |
| "precision highp float;\n" |
| "\n" |
| "flat out int layer_id;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " for (int n = 0;n < N_LAYERS;++n)\n" |
| " {\n" |
| " gl_Layer = n;\n" |
| " layer_id = gl_Layer;\n" |
| " gl_Position = vec4(1, 1, 0, 1);\n" |
| " EmitVertex();\n" |
| "\n" |
| " gl_Layer = n;\n" |
| " layer_id = gl_Layer;\n" |
| " gl_Position = vec4(1, -1, 0, 1);\n" |
| " EmitVertex();\n" |
| "\n" |
| " gl_Layer = n;\n" |
| " layer_id = gl_Layer;\n" |
| " gl_Position = vec4(-1, 1, 0, 1);\n" |
| " EmitVertex();\n" |
| "\n" |
| " gl_Layer = n;\n" |
| " layer_id = gl_Layer;\n" |
| " gl_Position = vec4(-1, -1, 0, 1);\n" |
| " EmitVertex();\n" |
| "\n" |
| " EndPrimitive();\n" |
| " }\n" |
| "}\n"; |
| return result; |
| } |
| |
| /** Get reference color for test result verification |
| * @param layerIndex index of layer |
| * @param colorBuffer will be used to store the requested data(buffor size should be greater than or equal colorBufferSize) |
| * @param colorBufferSize components number |
| **/ |
| void GeometryShaderLayeredRenderingBoundaryConditionVariousTextures::getReferenceColor(glw::GLint layerIndex, |
| unsigned char* colorBuffer, |
| int colorBufferSize) |
| { |
| if (layerIndex == 0) |
| { |
| memcpy(colorBuffer, m_red_color, colorBufferSize); |
| } |
| else if (layerIndex == 1) |
| { |
| memcpy(colorBuffer, m_green_color, colorBufferSize); |
| } |
| else |
| { |
| memset(colorBuffer, 0, colorBufferSize); |
| } |
| } |
| |
| /** Constructor |
| * |
| * @param context Test context |
| * @param name Test case's name |
| * @param description Test case's description |
| **/ |
| GeometryShaderLayeredRenderingBoundaryConditionNoGS::GeometryShaderLayeredRenderingBoundaryConditionNoGS( |
| Context& context, const ExtParameters& extParams, const char* name, const char* description) |
| : GeometryShaderLayeredRenderingBoundaryCondition(context, extParams, name, description) |
| { |
| TextureInfo texInfo; |
| |
| texInfo.m_depth = 4; |
| texInfo.m_draw_buffer = GL_COLOR_ATTACHMENT0; |
| texInfo.m_id = 0; |
| texInfo.m_texture_target = GL_TEXTURE_3D; |
| |
| m_textures_info.push_back(texInfo); |
| |
| m_draw_mode = GL_TRIANGLE_FAN; |
| m_n_points = 4; |
| m_is_fbo_layered = true; |
| } |
| |
| /** Get reference color for test result verification |
| * @param layerIndex index of layer |
| * @param colorBuffer will be used to store the requested data(buffer size should be greater than or equal colorBufferSize) |
| * @param colorBufferSize components number |
| **/ |
| void GeometryShaderLayeredRenderingBoundaryConditionNoGS::getReferenceColor(glw::GLint layerIndex, |
| unsigned char* colorBuffer, |
| int colorBufferSize) |
| { |
| if (layerIndex == 0) |
| { |
| memcpy(colorBuffer, m_white_color, colorBufferSize); |
| } |
| else |
| { |
| memset(colorBuffer, 0, colorBufferSize); |
| } |
| } |
| |
| /** Returns code for Vertex Shader |
| * @return pointer to literal with Vertex Shader code |
| **/ |
| const char* GeometryShaderLayeredRenderingBoundaryConditionNoGS::getVertexShaderCode() |
| { |
| static const char* result = "${VERSION}\n" |
| "\n" |
| "precision highp float;\n" |
| "\n" |
| "flat out int layer_id;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " layer_id = 0;\n" |
| "\n" |
| " switch (gl_VertexID)\n" |
| " {\n" |
| " case 0: gl_Position = vec4(-1, -1, 0, 1); break;\n" |
| " case 1: gl_Position = vec4(-1, 1, 0, 1); break;\n" |
| " case 2: gl_Position = vec4( 1, 1, 0, 1); break;\n" |
| " default: gl_Position = vec4( 1, -1, 0, 1); break;\n" |
| " }\n" |
| "}\n"; |
| return result; |
| } |
| |
| /** Constructor |
| * |
| * @param context Test context |
| * @param name Test case's name |
| * @param description Test case's desricption |
| **/ |
| GeometryShaderLayeredRenderingBoundaryConditionNoLayerSet::GeometryShaderLayeredRenderingBoundaryConditionNoLayerSet( |
| Context& context, const ExtParameters& extParams, const char* name, const char* description) |
| : GeometryShaderLayeredRenderingBoundaryCondition(context, extParams, name, description) |
| { |
| TextureInfo texInfo; |
| |
| texInfo.m_depth = 4; |
| texInfo.m_draw_buffer = GL_COLOR_ATTACHMENT0; |
| texInfo.m_id = 0; |
| texInfo.m_texture_target = GL_TEXTURE_3D; |
| |
| m_textures_info.push_back(texInfo); |
| |
| m_draw_mode = GL_POINTS; |
| m_n_points = 1; |
| m_is_fbo_layered = true; |
| } |
| |
| /** Returns code for Geometry Shader |
| * @return pointer to literal with Geometry Shader code |
| **/ |
| const char* GeometryShaderLayeredRenderingBoundaryConditionNoLayerSet::getGeometryShaderCode() |
| { |
| static const char* result = "${VERSION}\n" |
| "\n" |
| "${GEOMETRY_SHADER_REQUIRE}\n" |
| "\n" |
| "precision highp float;\n" |
| "\n" |
| "#define MAX_VERTICES 4\n" |
| "\n" |
| "layout(points) in;\n" |
| "layout(triangle_strip, max_vertices=MAX_VERTICES) out;\n" |
| "\n" |
| "precision highp float;\n" |
| "\n" |
| "flat out int layer_id;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " layer_id = 0;\n" |
| " gl_Position = vec4(1, 1, 0, 1);\n" |
| " EmitVertex();\n" |
| "\n" |
| " layer_id = 0;\n" |
| " gl_Position = vec4(1, -1, 0, 1);\n" |
| " EmitVertex();\n" |
| "\n" |
| " layer_id = 0;\n" |
| " gl_Position = vec4(-1, 1, 0, 1);\n" |
| " EmitVertex();\n" |
| "\n" |
| " layer_id = 0;\n" |
| " gl_Position = vec4(-1, -1, 0, 1);\n" |
| " EmitVertex();\n" |
| "\n" |
| " EndPrimitive();\n" |
| "}\n"; |
| return result; |
| } |
| |
| /** Get reference color for test result verification |
| * @param layerIndex index of layer |
| * @param colorBuffer will be used to store the requested data(buffer size should be greater than or equal colorBufferSize) |
| * @param colorBufferSize components number |
| **/ |
| void GeometryShaderLayeredRenderingBoundaryConditionNoLayerSet::getReferenceColor(glw::GLint layerIndex, |
| unsigned char* colorBuffer, |
| int colorBufferSize) |
| { |
| if (layerIndex == 0) |
| { |
| memcpy(colorBuffer, m_white_color, colorBufferSize); |
| } |
| else |
| { |
| memset(colorBuffer, 0, colorBufferSize); |
| } |
| } |
| |
| /** Constructor |
| * |
| * @param context Test context |
| * @param name Test case's name |
| * @param description Test case's desricption |
| **/ |
| GeometryShaderLayeredRenderingBoundaryConditionNoLayeredFBO:: |
| GeometryShaderLayeredRenderingBoundaryConditionNoLayeredFBO(Context& context, const ExtParameters& extParams, |
| const char* name, const char* description) |
| : GeometryShaderLayeredRenderingBoundaryCondition(context, extParams, name, description) |
| { |
| TextureInfo texInfo; |
| |
| texInfo.m_depth = 4; |
| texInfo.m_draw_buffer = GL_COLOR_ATTACHMENT0; |
| texInfo.m_id = 0; |
| texInfo.m_texture_target = GL_TEXTURE_3D; |
| |
| m_textures_info.push_back(texInfo); |
| |
| m_draw_mode = GL_POINTS; |
| m_n_points = 1; |
| m_is_fbo_layered = false; |
| } |
| |
| /** Returns code for Geometry Shader |
| * @return pointer to literal with Geometry Shader code |
| **/ |
| const char* GeometryShaderLayeredRenderingBoundaryConditionNoLayeredFBO::getGeometryShaderCode() |
| { |
| static const char* result = "${VERSION}\n" |
| "\n" |
| "${GEOMETRY_SHADER_REQUIRE}\n" |
| "\n" |
| "precision highp float;\n" |
| "\n" |
| "#define MAX_VERTICES 4\n" |
| "\n" |
| "layout(points) in;\n" |
| "layout(triangle_strip, max_vertices=MAX_VERTICES) out;\n" |
| "\n" |
| "precision highp float;\n" |
| "\n" |
| "flat out int layer_id;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " gl_Layer = 1;\n" |
| "\n" |
| " layer_id = gl_Layer;\n" |
| " gl_Position = vec4(1, 1, 0, 1);\n" |
| " EmitVertex();\n" |
| "\n" |
| " layer_id = gl_Layer;\n" |
| " gl_Position = vec4(1, -1, 0, 1);\n" |
| " EmitVertex();\n" |
| "\n" |
| " layer_id = gl_Layer;\n" |
| " gl_Position = vec4(-1, 1, 0, 1);\n" |
| " EmitVertex();\n" |
| "\n" |
| " layer_id = gl_Layer;\n" |
| " gl_Position = vec4(-1, -1, 0, 1);\n" |
| " EmitVertex();\n" |
| "\n" |
| " EndPrimitive();\n" |
| "}\n"; |
| return result; |
| } |
| |
| /** Get reference color for test result verification |
| * @param layerIndex index of layer |
| * @param colorBuffer will be used to store the requested data(buffer size should be greater than or equal colorBufferSize) |
| * @param colorBufferSize components number |
| **/ |
| void GeometryShaderLayeredRenderingBoundaryConditionNoLayeredFBO::getReferenceColor(glw::GLint layerIndex, |
| unsigned char* colorBuffer, |
| int colorBufferSize) |
| { |
| if (layerIndex == 0) |
| { |
| memcpy(colorBuffer, m_white_color, colorBufferSize); |
| } |
| else |
| { |
| memset(colorBuffer, 0, colorBufferSize); |
| } |
| } |
| |
| } // namespace glcts |