| /*------------------------------------------------------------------------- |
| * drawElements Quality Program EGL Module |
| * --------------------------------------- |
| * |
| * Copyright 2014 The Android Open Source Project |
| * |
| * 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 EGL image tests. |
| *//*--------------------------------------------------------------------*/ |
| #include "teglImageFormatTests.hpp" |
| |
| #include "tcuTestLog.hpp" |
| #include "tcuSurface.hpp" |
| #include "tcuTexture.hpp" |
| #include "tcuTextureUtil.hpp" |
| #include "tcuImageCompare.hpp" |
| #include "tcuCommandLine.hpp" |
| |
| #include "egluNativeDisplay.hpp" |
| #include "egluNativeWindow.hpp" |
| #include "egluNativePixmap.hpp" |
| #include "egluConfigFilter.hpp" |
| #include "egluUtil.hpp" |
| |
| #include "gluTexture.hpp" |
| #include "gluPixelTransfer.hpp" |
| #include "gluTextureUtil.hpp" |
| |
| #include <GLES2/gl2.h> |
| #include <GLES2/gl2ext.h> |
| #include <EGL/eglext.h> |
| |
| #include <vector> |
| #include <string> |
| #include <set> |
| |
| using std::vector; |
| using std::set; |
| using std::string; |
| |
| namespace deqp |
| { |
| namespace egl |
| { |
| |
| namespace |
| { |
| |
| // \todo [2013-04-09 pyry] Use glu::Program |
| class Program |
| { |
| public: |
| Program (const char* vertexSource, const char* fragmentSource) |
| : m_program (0) |
| , m_vertexShader (0) |
| , m_fragmentShader (0) |
| , m_isOk (false) |
| { |
| m_program = glCreateProgram(); |
| m_vertexShader = glCreateShader(GL_VERTEX_SHADER); |
| m_fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); |
| |
| try |
| { |
| bool vertexCompileOk = false; |
| bool fragmentCompileOk = false; |
| bool linkOk = false; |
| |
| for (int ndx = 0; ndx < 2; ndx++) |
| { |
| const char* source = ndx ? fragmentSource : vertexSource; |
| const deUint32 shader = ndx ? m_fragmentShader : m_vertexShader; |
| int compileStatus = 0; |
| bool& compileOk = ndx ? fragmentCompileOk : vertexCompileOk; |
| |
| glShaderSource(shader, 1, &source, DE_NULL); |
| glCompileShader(shader); |
| glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus); |
| |
| compileOk = (compileStatus == GL_TRUE); |
| } |
| |
| if (vertexCompileOk && fragmentCompileOk) |
| { |
| int linkStatus = 0; |
| |
| glAttachShader(m_program, m_vertexShader); |
| glAttachShader(m_program, m_fragmentShader); |
| glLinkProgram(m_program); |
| glGetProgramiv(m_program, GL_LINK_STATUS, &linkStatus); |
| |
| linkOk = (linkStatus == GL_TRUE); |
| } |
| |
| m_isOk = linkOk; |
| } |
| catch (...) |
| { |
| glDeleteShader(m_vertexShader); |
| glDeleteShader(m_fragmentShader); |
| glDeleteProgram(m_program); |
| throw; |
| } |
| } |
| |
| ~Program (void) |
| { |
| glDeleteShader(m_vertexShader); |
| glDeleteShader(m_fragmentShader); |
| glDeleteProgram(m_program); |
| } |
| |
| bool isOk (void) const { return m_isOk; } |
| deUint32 getProgram (void) const {return m_program; } |
| |
| private: |
| deUint32 m_program; |
| deUint32 m_vertexShader; |
| deUint32 m_fragmentShader; |
| bool m_isOk; |
| }; |
| |
| } // anonymous |
| |
| namespace Image |
| { |
| |
| class EglExt |
| { |
| public: |
| EglExt (void) |
| { |
| eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress("eglCreateImageKHR"); |
| eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress("eglDestroyImageKHR"); |
| |
| glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) eglGetProcAddress("glEGLImageTargetTexture2DOES"); |
| glEGLImageTargetRenderbufferStorageOES = (PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) eglGetProcAddress("glEGLImageTargetRenderbufferStorageOES"); |
| } |
| |
| PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR; |
| PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR; |
| |
| PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES; |
| PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glEGLImageTargetRenderbufferStorageOES; |
| |
| private: |
| }; |
| |
| struct TestSpec |
| { |
| std::string name; |
| std::string desc; |
| |
| enum ApiContext |
| { |
| API_GLES2 = 0, |
| //API_VG |
| //API_GLES1 |
| |
| API_LAST |
| }; |
| |
| struct Operation |
| { |
| enum Type |
| { |
| TYPE_CREATE = 0, |
| TYPE_RENDER, |
| TYPE_MODIFY, |
| |
| TYPE_LAST |
| }; |
| |
| ApiContext requiredApi; |
| int apiIndex; |
| Type type; |
| int operationIndex; |
| }; |
| |
| vector<ApiContext> contexts; |
| vector<Operation> operations; |
| |
| }; |
| |
| class ImageApi |
| { |
| public: |
| ImageApi (int contextId, tcu::TestLog& log, tcu::egl::Display& display, tcu::egl::Surface* surface); |
| virtual ~ImageApi (void) {} |
| |
| virtual EGLImageKHR create (int operationNdx, tcu::Texture2D& ref) = 0; |
| virtual bool render (int operationNdx, EGLImageKHR img, const tcu::Texture2D& reference) = 0; |
| virtual void modify (int operationNdx, EGLImageKHR img, tcu::Texture2D& reference) = 0; |
| |
| virtual void checkRequiredExtensions (set<string>& extensions, TestSpec::Operation::Type type, int operationNdx) = 0; |
| |
| protected: |
| int m_contextId; |
| tcu::TestLog& m_log; |
| tcu::egl::Display& m_display; |
| tcu::egl::Surface* m_surface; |
| }; |
| |
| ImageApi::ImageApi (int contextId, tcu::TestLog& log, tcu::egl::Display& display, tcu::egl::Surface* surface) |
| : m_contextId (contextId) |
| , m_log (log) |
| , m_display (display) |
| , m_surface (surface) |
| { |
| } |
| |
| class GLES2ImageApi : public ImageApi |
| { |
| public: |
| enum Create |
| { |
| CREATE_TEXTURE2D_RGB8 = 0, |
| CREATE_TEXTURE2D_RGB565, |
| CREATE_TEXTURE2D_RGBA8, |
| CREATE_TEXTURE2D_RGBA5_A1, |
| CREATE_TEXTURE2D_RGBA4, |
| |
| CREATE_CUBE_MAP_POSITIVE_X_RGBA8, |
| CREATE_CUBE_MAP_NEGATIVE_X_RGBA8, |
| CREATE_CUBE_MAP_POSITIVE_Y_RGBA8, |
| CREATE_CUBE_MAP_NEGATIVE_Y_RGBA8, |
| CREATE_CUBE_MAP_POSITIVE_Z_RGBA8, |
| CREATE_CUBE_MAP_NEGATIVE_Z_RGBA8, |
| |
| CREATE_CUBE_MAP_POSITIVE_X_RGB8, |
| CREATE_CUBE_MAP_NEGATIVE_X_RGB8, |
| CREATE_CUBE_MAP_POSITIVE_Y_RGB8, |
| CREATE_CUBE_MAP_NEGATIVE_Y_RGB8, |
| CREATE_CUBE_MAP_POSITIVE_Z_RGB8, |
| CREATE_CUBE_MAP_NEGATIVE_Z_RGB8, |
| |
| CREATE_RENDER_BUFFER_DEPTH16, |
| CREATE_RENDER_BUFFER_RGBA4, |
| CREATE_RENDER_BUFFER_RGB5_A1, |
| CREATE_RENDER_BUFFER_RGB565, |
| CREATE_RENDER_BUFFER_STENCIL, |
| |
| CREATE_LAST |
| }; |
| |
| enum Render |
| { |
| RENDER_TEXTURE2D = 0, |
| |
| // \note Not supported |
| RENDER_CUBE_MAP_POSITIVE_X, |
| RENDER_CUBE_MAP_NEGATIVE_X, |
| RENDER_CUBE_MAP_POSITIVE_Y, |
| RENDER_CUBE_MAP_NEGATIVE_Y, |
| RENDER_CUBE_MAP_POSITIVE_Z, |
| RENDER_CUBE_MAP_NEGATIVE_Z, |
| |
| RENDER_READ_PIXELS_RENDERBUFFER, |
| RENDER_DEPTHBUFFER, |
| |
| RENDER_TRY_ALL, |
| |
| RENDER_LAST |
| }; |
| |
| enum Modify |
| { |
| MODIFY_TEXSUBIMAGE_RGBA8, |
| MODIFY_TEXSUBIMAGE_RGBA5_A1, |
| MODIFY_TEXSUBIMAGE_RGBA4, |
| MODIFY_TEXSUBIMAGE_RGB8, |
| MODIFY_TEXSUBIMAGE_RGB565, |
| MODIFY_RENDERBUFFER_CLEAR_COLOR, |
| MODIFY_RENDERBUFFER_CLEAR_DEPTH, |
| MODIFY_RENDERBUFFER_CLEAR_STENCIL, |
| |
| MODIFY_LAST |
| }; |
| |
| GLES2ImageApi (int contextId, tcu::TestLog& log, tcu::egl::Display& display, tcu::egl::Surface* surface, EGLConfig config); |
| ~GLES2ImageApi (void); |
| |
| EGLImageKHR create (int operationNdx, tcu::Texture2D& ref); |
| EGLImageKHR createTexture2D (tcu::Texture2D& ref, GLenum target, GLenum format, GLenum type); |
| EGLImageKHR createRenderBuffer (tcu::Texture2D& ref, GLenum type); |
| |
| bool render (int operationNdx, EGLImageKHR img, const tcu::Texture2D& reference); |
| bool renderTexture2D (EGLImageKHR img, const tcu::Texture2D& reference); |
| bool renderDepth (EGLImageKHR img, const tcu::Texture2D& reference); |
| bool renderReadPixelsRenderBuffer (EGLImageKHR img, const tcu::Texture2D& reference); |
| bool renderTryAll (EGLImageKHR img, const tcu::Texture2D& reference); |
| |
| // \note Not supported |
| bool renderCubeMap (EGLImageKHR img, const tcu::Surface& reference, GLenum face); |
| |
| void modify (int operationNdx, EGLImageKHR img, tcu::Texture2D& reference); |
| void modifyTexSubImage (EGLImageKHR img, tcu::Texture2D& reference, GLenum format, GLenum type); |
| void modifyRenderbufferClearColor (EGLImageKHR img, tcu::Texture2D& reference); |
| void modifyRenderbufferClearDepth (EGLImageKHR img, tcu::Texture2D& reference); |
| void modifyRenderbufferClearStencil (EGLImageKHR img, tcu::Texture2D& reference); |
| |
| void checkRequiredExtensions (set<string>& extensions, TestSpec::Operation::Type type, int operationNdx); |
| |
| private: |
| tcu::egl::Context* m_context; |
| EglExt m_eglExt; |
| }; |
| |
| GLES2ImageApi::GLES2ImageApi (int contextId, tcu::TestLog& log, tcu::egl::Display& display, tcu::egl::Surface* surface, EGLConfig config) |
| : ImageApi (contextId, log, display, surface) |
| , m_context (DE_NULL) |
| { |
| EGLint attriblist[] = |
| { |
| EGL_CONTEXT_CLIENT_VERSION, 2, |
| EGL_NONE |
| }; |
| |
| EGLint configId = -1; |
| TCU_CHECK_EGL_CALL(eglGetConfigAttrib(m_display.getEGLDisplay(), config, EGL_CONFIG_ID, &configId)); |
| m_log << tcu::TestLog::Message << "Creating gles2 context with config id: " << configId << " context: " << m_contextId << tcu::TestLog::EndMessage; |
| m_context = new tcu::egl::Context(m_display, config, attriblist, EGL_OPENGL_ES_API); |
| TCU_CHECK_EGL_MSG("Failed to create GLES2 context"); |
| |
| m_context->makeCurrent(*m_surface, *m_surface); |
| TCU_CHECK_EGL_MSG("Failed to make context current"); |
| } |
| |
| GLES2ImageApi::~GLES2ImageApi (void) |
| { |
| delete m_context; |
| } |
| |
| EGLImageKHR GLES2ImageApi::create (int operationNdx, tcu::Texture2D& ref) |
| { |
| m_context->makeCurrent(*m_surface, *m_surface); |
| EGLImageKHR img = EGL_NO_IMAGE_KHR; |
| switch (operationNdx) |
| { |
| case CREATE_TEXTURE2D_RGB8: img = createTexture2D(ref, GL_TEXTURE_2D, GL_RGB, GL_UNSIGNED_BYTE); break; |
| case CREATE_TEXTURE2D_RGB565: img = createTexture2D(ref, GL_TEXTURE_2D, GL_RGB, GL_UNSIGNED_SHORT_5_6_5); break; |
| case CREATE_TEXTURE2D_RGBA8: img = createTexture2D(ref, GL_TEXTURE_2D, GL_RGBA, GL_UNSIGNED_BYTE); break; |
| case CREATE_TEXTURE2D_RGBA4: img = createTexture2D(ref, GL_TEXTURE_2D, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4); break; |
| case CREATE_TEXTURE2D_RGBA5_A1: img = createTexture2D(ref, GL_TEXTURE_2D, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1); break; |
| |
| case CREATE_CUBE_MAP_POSITIVE_X_RGBA8: img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_RGBA, GL_UNSIGNED_BYTE); break; |
| case CREATE_CUBE_MAP_NEGATIVE_X_RGBA8: img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_RGBA, GL_UNSIGNED_BYTE); break; |
| case CREATE_CUBE_MAP_POSITIVE_Y_RGBA8: img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_RGBA, GL_UNSIGNED_BYTE); break; |
| case CREATE_CUBE_MAP_NEGATIVE_Y_RGBA8: img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_RGBA, GL_UNSIGNED_BYTE); break; |
| case CREATE_CUBE_MAP_POSITIVE_Z_RGBA8: img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_RGBA, GL_UNSIGNED_BYTE); break; |
| case CREATE_CUBE_MAP_NEGATIVE_Z_RGBA8: img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, GL_RGBA, GL_UNSIGNED_BYTE); break; |
| |
| case CREATE_CUBE_MAP_POSITIVE_X_RGB8: img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_RGB, GL_UNSIGNED_BYTE); break; |
| case CREATE_CUBE_MAP_NEGATIVE_X_RGB8: img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_RGB, GL_UNSIGNED_BYTE); break; |
| case CREATE_CUBE_MAP_POSITIVE_Y_RGB8: img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_RGB, GL_UNSIGNED_BYTE); break; |
| case CREATE_CUBE_MAP_NEGATIVE_Y_RGB8: img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_RGB, GL_UNSIGNED_BYTE); break; |
| case CREATE_CUBE_MAP_POSITIVE_Z_RGB8: img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_RGB, GL_UNSIGNED_BYTE); break; |
| case CREATE_CUBE_MAP_NEGATIVE_Z_RGB8: img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, GL_RGB, GL_UNSIGNED_BYTE); break; |
| |
| case CREATE_RENDER_BUFFER_DEPTH16: img = createRenderBuffer(ref, GL_DEPTH_COMPONENT16); break; |
| case CREATE_RENDER_BUFFER_RGBA4: img = createRenderBuffer(ref, GL_RGBA4); break; |
| case CREATE_RENDER_BUFFER_RGB5_A1: img = createRenderBuffer(ref, GL_RGB5_A1); break; |
| case CREATE_RENDER_BUFFER_RGB565: img = createRenderBuffer(ref, GL_RGB565); break; |
| case CREATE_RENDER_BUFFER_STENCIL: img = createRenderBuffer(ref, GL_STENCIL_INDEX8); break; |
| |
| default: |
| DE_ASSERT(false); |
| break; |
| } |
| |
| return img; |
| } |
| |
| namespace |
| { |
| |
| const char* glTargetToString (GLenum target) |
| { |
| switch (target) |
| { |
| case GL_TEXTURE_2D: return "GL_TEXTURE_2D"; |
| break; |
| case GL_TEXTURE_CUBE_MAP_POSITIVE_X: return "GL_TEXTURE_CUBE_MAP_POSITIVE_X"; |
| break; |
| case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: return "GL_TEXTURE_CUBE_MAP_NEGATIVE_X"; |
| break; |
| case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: return "GL_TEXTURE_CUBE_MAP_POSITIVE_Y"; |
| break; |
| case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: return "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y"; |
| break; |
| case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: return "GL_TEXTURE_CUBE_MAP_POSITIVE_Z"; |
| break; |
| case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: return "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z"; |
| break; |
| default: |
| DE_ASSERT(false); |
| break; |
| }; |
| return ""; |
| } |
| |
| const char* glFormatToString (GLenum format) |
| { |
| switch (format) |
| { |
| case GL_RGB: |
| return "GL_RGB"; |
| |
| case GL_RGBA: |
| return "GL_RGBA"; |
| |
| default: |
| DE_ASSERT(false); |
| return ""; |
| } |
| } |
| |
| const char* glTypeToString (GLenum type) |
| { |
| switch (type) |
| { |
| case GL_UNSIGNED_BYTE: |
| return "GL_UNSIGNED_BYTE"; |
| |
| case GL_UNSIGNED_SHORT_5_6_5: |
| return "GL_UNSIGNED_SHORT_5_6_5"; |
| |
| case GL_UNSIGNED_SHORT_4_4_4_4: |
| return "GL_UNSIGNED_SHORT_4_4_4_4"; |
| |
| case GL_UNSIGNED_SHORT_5_5_5_1: |
| return "GL_UNSIGNED_SHORT_5_5_5_1"; |
| |
| default: |
| DE_ASSERT(false); |
| return ""; |
| } |
| } |
| |
| } // anonymous |
| |
| EGLImageKHR GLES2ImageApi::createTexture2D (tcu::Texture2D& reference, GLenum target, GLenum format, GLenum type) |
| { |
| tcu::Texture2D src(glu::mapGLTransferFormat(format, type), 64, 64); |
| src.allocLevel(0); |
| |
| tcu::fillWithComponentGradients(src.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); |
| m_log << tcu::TestLog::Message << "Creating EGLImage from " << glTargetToString(target) << " " << glFormatToString(format) << " " << glTypeToString(type) << " in context: " << m_contextId << tcu::TestLog::EndMessage; |
| |
| deUint32 srcTex = 0; |
| glGenTextures(1, &srcTex); |
| TCU_CHECK(srcTex != 0); |
| if (GL_TEXTURE_2D == target) |
| { |
| GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, srcTex)); |
| GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); |
| GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); |
| GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); |
| GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); |
| GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_2D, 0, format, src.getWidth(), src.getHeight(), 0, format, type, src.getLevel(0).getDataPtr())); |
| } |
| else |
| { |
| GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, srcTex)); |
| GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); |
| GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); |
| GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); |
| GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); |
| |
| // First fill all faces, required by eglCreateImageKHR |
| GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, format, src.getWidth(), src.getHeight(), 0, format, type, 0)); |
| GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, format, src.getWidth(), src.getHeight(), 0, format, type, 0)); |
| GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, format, src.getWidth(), src.getHeight(), 0, format, type, 0)); |
| GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, format, src.getWidth(), src.getHeight(), 0, format, type, 0)); |
| GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, format, src.getWidth(), src.getHeight(), 0, format, type, 0)); |
| GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, format, src.getWidth(), src.getHeight(), 0, format, type, 0)); |
| GLU_CHECK_CALL(glTexImage2D(target, 0, format, src.getWidth(), src.getHeight(), 0, format, type, src.getLevel(0).getDataPtr())); |
| } |
| |
| EGLint attrib[] = { |
| EGL_GL_TEXTURE_LEVEL_KHR, 0, |
| EGL_NONE |
| }; |
| |
| EGLImageKHR img = EGL_NO_IMAGE_KHR; |
| |
| if (GL_TEXTURE_2D == target) |
| { |
| img = m_eglExt.eglCreateImageKHR(m_display.getEGLDisplay(), m_context->getEGLContext(), EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer)(deUintptr)srcTex, attrib); |
| } |
| else |
| { |
| switch (target) |
| { |
| case GL_TEXTURE_CUBE_MAP_POSITIVE_X: img = m_eglExt.eglCreateImageKHR(m_display.getEGLDisplay(), m_context->getEGLContext(), EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR, (EGLClientBuffer)(deUintptr)srcTex, attrib); break; |
| case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: img = m_eglExt.eglCreateImageKHR(m_display.getEGLDisplay(), m_context->getEGLContext(), EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR, (EGLClientBuffer)(deUintptr)srcTex, attrib); break; |
| case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: img = m_eglExt.eglCreateImageKHR(m_display.getEGLDisplay(), m_context->getEGLContext(), EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR, (EGLClientBuffer)(deUintptr)srcTex, attrib); break; |
| case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: img = m_eglExt.eglCreateImageKHR(m_display.getEGLDisplay(), m_context->getEGLContext(), EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR, (EGLClientBuffer)(deUintptr)srcTex, attrib); break; |
| case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: img = m_eglExt.eglCreateImageKHR(m_display.getEGLDisplay(), m_context->getEGLContext(), EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR, (EGLClientBuffer)(deUintptr)srcTex, attrib); break; |
| case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: img = m_eglExt.eglCreateImageKHR(m_display.getEGLDisplay(), m_context->getEGLContext(), EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR, (EGLClientBuffer)(deUintptr)srcTex, attrib); break; |
| |
| default: |
| DE_ASSERT(false); |
| break; |
| } |
| } |
| |
| GLU_CHECK_CALL(glDeleteTextures(1, &srcTex)); |
| TCU_CHECK_EGL_MSG("Failed to create EGLImage"); |
| TCU_CHECK_MSG(img != EGL_NO_IMAGE_KHR, "Failed to create EGLImage, got EGL_NO_IMAGE_KHR"); |
| glBindTexture(GL_TEXTURE_2D, 0); |
| |
| reference = src; |
| |
| return img; |
| } |
| |
| static std::string glRenderbufferTargetToString (GLenum format) |
| { |
| switch (format) |
| { |
| case GL_RGBA4: |
| return "GL_RGBA4"; |
| break; |
| |
| case GL_RGB5_A1: |
| return "GL_RGB5_A1"; |
| break; |
| |
| case GL_RGB565: |
| return "GL_RGB565"; |
| break; |
| |
| case GL_DEPTH_COMPONENT16: |
| return "GL_DEPTH_COMPONENT16"; |
| break; |
| |
| case GL_STENCIL_INDEX8: |
| return "GL_STENCIL_INDEX8"; |
| break; |
| |
| default: |
| DE_ASSERT(false); |
| break; |
| } |
| |
| DE_ASSERT(false); |
| return ""; |
| } |
| |
| EGLImageKHR GLES2ImageApi::createRenderBuffer (tcu::Texture2D& ref, GLenum format) |
| { |
| m_log << tcu::TestLog::Message << "Creating EGLImage from GL_RENDERBUFFER " << glRenderbufferTargetToString(format) << " " << " in context: " << m_contextId << tcu::TestLog::EndMessage; |
| GLuint renderBuffer = 1; |
| |
| GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer)); |
| GLU_CHECK_CALL(glRenderbufferStorage(GL_RENDERBUFFER, format, 64, 64)); |
| |
| GLuint frameBuffer = 1; |
| GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer)); |
| |
| switch (format) |
| { |
| case GL_STENCIL_INDEX8: |
| GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderBuffer)); |
| TCU_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); |
| GLU_CHECK_CALL(glClearStencil(235)); |
| GLU_CHECK_CALL(glClear(GL_STENCIL_BUFFER_BIT)); |
| GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0)); |
| ref = tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::I, tcu::TextureFormat::UNORM_INT8), 64, 64); |
| ref.allocLevel(0); |
| |
| for (int x = 0; x < 64; x++) |
| { |
| for (int y = 0; y < 64; y++) |
| { |
| ref.getLevel(0).setPixel(tcu::IVec4(235, 235, 235, 235), x, y); |
| } |
| } |
| break; |
| |
| case GL_DEPTH_COMPONENT16: |
| GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderBuffer)); |
| TCU_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); |
| GLU_CHECK_CALL(glClearDepthf(0.5f)); |
| GLU_CHECK_CALL(glClear(GL_DEPTH_BUFFER_BIT)); |
| GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0)); |
| ref = tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::I, tcu::TextureFormat::UNORM_INT16), 64, 64); |
| ref.allocLevel(0); |
| |
| for (int x = 0; x < 64; x++) |
| { |
| for (int y = 0; y < 64; y++) |
| { |
| ref.getLevel(0).setPixel(tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f), x, y); |
| } |
| } |
| break; |
| |
| case GL_RGBA4: |
| GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderBuffer)); |
| TCU_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); |
| GLU_CHECK_CALL(glClearColor(0.9f, 0.5f, 0.65f, 1.0f)); |
| GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT)); |
| GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0)); |
| ref = tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_SHORT_4444), 64, 64); |
| ref.allocLevel(0); |
| |
| for (int x = 0; x < 64; x++) |
| { |
| for (int y = 0; y < 64; y++) |
| { |
| ref.getLevel(0).setPixel(tcu::Vec4(0.9f, 0.5f, 0.65f, 1.0f), x, y); |
| } |
| } |
| break; |
| |
| case GL_RGB5_A1: |
| GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderBuffer)); |
| TCU_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); |
| GLU_CHECK_CALL(glClearColor(0.5f, 0.7f, 0.65f, 1.0f)); |
| GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT)); |
| GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0)); |
| ref = tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_SHORT_5551), 64, 64); |
| ref.allocLevel(0); |
| |
| for (int x = 0; x < 64; x++) |
| { |
| for (int y = 0; y < 64; y++) |
| { |
| ref.getLevel(0).setPixel(tcu::Vec4(0.5f, 0.7f, 0.65f, 1.0f), x, y); |
| } |
| } |
| break; |
| |
| case GL_RGB565: |
| GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderBuffer)); |
| TCU_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); |
| GLU_CHECK_CALL(glClearColor(0.2f, 0.5f, 0.65f, 1.0f)); |
| GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT)); |
| GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0)); |
| ref = tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_SHORT_565), 64, 64); |
| ref.allocLevel(0); |
| |
| for (int x = 0; x < 64; x++) |
| { |
| for (int y = 0; y < 64; y++) |
| { |
| ref.getLevel(0).setPixel(tcu::Vec4(0.2f, 0.5f, 0.65f, 1.0f), x, y); |
| } |
| } |
| break; |
| |
| default: |
| DE_ASSERT(false); |
| } |
| |
| GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); |
| GLU_CHECK_CALL(glDeleteFramebuffers(1, &frameBuffer)); |
| |
| EGLint attrib[] = { |
| EGL_NONE |
| }; |
| |
| EGLImageKHR img = m_eglExt.eglCreateImageKHR(m_display.getEGLDisplay(), m_context->getEGLContext(), EGL_GL_RENDERBUFFER_KHR, (EGLClientBuffer)(deUintptr)renderBuffer, attrib); |
| |
| GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderBuffer)); |
| return img; |
| } |
| |
| bool GLES2ImageApi::render (int operationNdx, EGLImageKHR img, const tcu::Texture2D& reference) |
| { |
| m_context->makeCurrent(*m_surface, *m_surface); |
| switch (operationNdx) |
| { |
| case RENDER_TEXTURE2D: |
| return renderTexture2D(img, reference); |
| |
| case RENDER_READ_PIXELS_RENDERBUFFER: |
| return renderReadPixelsRenderBuffer(img, reference); |
| |
| case RENDER_DEPTHBUFFER: |
| return renderDepth(img, reference); |
| |
| case RENDER_TRY_ALL: |
| return renderTryAll(img, reference); |
| |
| default: |
| DE_ASSERT(false); |
| break; |
| }; |
| return false; |
| } |
| |
| bool GLES2ImageApi::renderTexture2D (EGLImageKHR img, const tcu::Texture2D& reference) |
| { |
| glClearColor(0.0, 0.0, 0.0, 0.0); |
| glViewport(0, 0, reference.getWidth(), reference.getHeight()); |
| glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); |
| glDisable(GL_DEPTH_TEST); |
| |
| m_log << tcu::TestLog::Message << "Rendering EGLImage as GL_TEXTURE_2D in context: " << m_contextId << tcu::TestLog::EndMessage; |
| TCU_CHECK(img != EGL_NO_IMAGE_KHR); |
| |
| deUint32 srcTex = 0; |
| glGenTextures(1, &srcTex); |
| TCU_CHECK(srcTex != 0); |
| GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, srcTex)); |
| m_eglExt.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)img); |
| GLenum error = glGetError(); |
| |
| if (error == GL_INVALID_OPERATION) |
| { |
| GLU_CHECK_CALL(glDeleteTextures(1, &srcTex)); |
| throw tcu::NotSupportedError("Creating texture2D from EGLImage type not supported", "glEGLImageTargetTexture2DOES", __FILE__, __LINE__); |
| } |
| |
| TCU_CHECK(error == GL_NONE); |
| |
| TCU_CHECK_EGL_MSG("glEGLImageTargetTexture2DOES() failed"); |
| |
| GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); |
| GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); |
| GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); |
| GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); |
| |
| const char* vertexShader = |
| "attribute highp vec2 a_coord;\n" |
| "varying mediump vec2 v_texCoord;\n" |
| "void main(void) {\n" |
| "\tv_texCoord = vec2((a_coord.x + 1.0) * 0.5, (a_coord.y + 1.0) * 0.5);\n" |
| "\tgl_Position = vec4(a_coord, -0.1, 1.0);\n" |
| "}\n"; |
| |
| const char* fragmentShader = |
| "varying mediump vec2 v_texCoord;\n" |
| "uniform sampler2D u_sampler;\n" |
| "void main(void) {\n" |
| "\tmediump vec4 texColor = texture2D(u_sampler, v_texCoord);\n" |
| "\tgl_FragColor = vec4(texColor);\n" |
| "}"; |
| |
| Program program(vertexShader, fragmentShader); |
| TCU_CHECK(program.isOk()); |
| |
| GLuint glProgram = program.getProgram(); |
| GLU_CHECK_CALL(glUseProgram(glProgram)); |
| |
| GLuint coordLoc = glGetAttribLocation(glProgram, "a_coord"); |
| TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord"); |
| |
| GLuint samplerLoc = glGetUniformLocation(glProgram, "u_sampler"); |
| TCU_CHECK_MSG((int)samplerLoc != (int)-1, "Couldn't find uniform u_sampler"); |
| |
| float coords[] = |
| { |
| -1.0, -1.0, |
| 1.0, -1.0, |
| 1.0, 1.0, |
| |
| 1.0, 1.0, |
| -1.0, 1.0, |
| -1.0, -1.0 |
| }; |
| |
| GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, srcTex)); |
| GLU_CHECK_CALL(glUniform1i(samplerLoc, 0)); |
| GLU_CHECK_CALL(glEnableVertexAttribArray(coordLoc)); |
| GLU_CHECK_CALL(glVertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, coords)); |
| |
| GLU_CHECK_CALL(glDrawArrays(GL_TRIANGLES, 0, 6)); |
| GLU_CHECK_CALL(glDisableVertexAttribArray(coordLoc)); |
| GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, 0)); |
| GLU_CHECK_CALL(glDeleteTextures(1, &srcTex)); |
| |
| tcu::Surface screen(reference.getWidth(), reference.getHeight()); |
| glReadPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()); |
| GLU_CHECK_MSG("glReadPixels()"); |
| |
| tcu::Surface referenceScreen(reference.getWidth(), reference.getHeight()); |
| |
| for (int y = 0; y < referenceScreen.getHeight(); y++) |
| { |
| for (int x = 0; x < referenceScreen.getWidth(); x++) |
| { |
| tcu::Vec4 src = reference.getLevel(0).getPixel(x, y); |
| referenceScreen.setPixel(x, y, tcu::RGBA(src)); |
| } |
| } |
| |
| float threshold = 0.05f; |
| bool match = tcu::fuzzyCompare(m_log, "ComparisonResult", "Image comparison result", referenceScreen, screen, threshold, tcu::COMPARE_LOG_RESULT); |
| |
| return match; |
| } |
| |
| bool GLES2ImageApi::renderDepth (EGLImageKHR img, const tcu::Texture2D& reference) |
| { |
| m_log << tcu::TestLog::Message << "Rendering with depth buffer" << tcu::TestLog::EndMessage; |
| |
| deUint32 framebuffer; |
| glGenFramebuffers(1, &framebuffer); |
| TCU_CHECK(framebuffer != (GLuint)-1); |
| GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)); |
| |
| deUint32 renderbufferColor = 0; |
| glGenRenderbuffers(1, &renderbufferColor); |
| TCU_CHECK(renderbufferColor != (GLuint)-1); |
| GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, renderbufferColor)); |
| GLU_CHECK_CALL(glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, reference.getWidth(), reference.getHeight())); |
| GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, 0)); |
| |
| deUint32 renderbufferDepth = 0; |
| glGenRenderbuffers(1, &renderbufferDepth); |
| TCU_CHECK(renderbufferDepth != (GLuint)-1); |
| GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, renderbufferDepth)); |
| |
| m_eglExt.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, (GLeglImageOES)img); |
| |
| GLenum error = glGetError(); |
| |
| if (error == GL_INVALID_OPERATION) |
| { |
| GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbufferDepth)); |
| GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbufferColor)); |
| throw tcu::NotSupportedError("Creating renderbuffer from EGLImage type not supported", "glEGLImageTargetRenderbufferStorageOES", __FILE__, __LINE__); |
| } |
| |
| TCU_CHECK(error == GL_NONE); |
| |
| TCU_CHECK_EGL_MSG("glEGLImageTargetRenderbufferStorageOES() failed"); |
| |
| GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, renderbufferDepth)); |
| GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbufferDepth)); |
| |
| GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, renderbufferColor)); |
| GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbufferColor)); |
| GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, 0)); |
| |
| GLU_CHECK_CALL(glViewport(0, 0, reference.getWidth(), reference.getHeight())); |
| if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) |
| { |
| GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer)); |
| GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbufferDepth)); |
| GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbufferColor)); |
| throw tcu::NotSupportedError("EGLImage as depth attachment not supported", "", __FILE__, __LINE__); |
| } |
| |
| // Render |
| const char* vertexShader = |
| "attribute highp vec2 a_coord;\n" |
| "uniform highp float u_depth;\n" |
| "void main(void) {\n" |
| "\tgl_Position = vec4(a_coord, u_depth, 1.0);\n" |
| "}\n"; |
| |
| const char* fragmentShader = |
| "uniform mediump vec4 u_color;\n" |
| "void main(void) {\n" |
| "\tgl_FragColor = u_color;\n" |
| "}"; |
| |
| Program program(vertexShader, fragmentShader); |
| TCU_CHECK(program.isOk()); |
| |
| GLuint glProgram = program.getProgram(); |
| GLU_CHECK_CALL(glUseProgram(glProgram)); |
| |
| GLuint coordLoc = glGetAttribLocation(glProgram, "a_coord"); |
| TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord"); |
| |
| GLuint colorLoc = glGetUniformLocation(glProgram, "u_color"); |
| TCU_CHECK_MSG((int)colorLoc != (int)-1, "Couldn't find uniform u_color"); |
| |
| GLuint depthLoc = glGetUniformLocation(glProgram, "u_depth"); |
| TCU_CHECK_MSG((int)depthLoc != (int)-1, "Couldn't find uniform u_depth"); |
| |
| float coords[] = |
| { |
| -1.0, -1.0, |
| 1.0, -1.0, |
| 1.0, 1.0, |
| |
| 1.0, 1.0, |
| -1.0, 1.0, |
| -1.0, -1.0 |
| }; |
| |
| float depthLevels[] = { |
| 0.1f, |
| 0.2f, |
| 0.3f, |
| 0.4f, |
| 0.5f, |
| 0.6f, |
| 0.7f, |
| 0.8f, |
| 0.9f, |
| 1.0f |
| }; |
| |
| tcu::Vec4 depthLevelColors[] = { |
| tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), |
| tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), |
| tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f), |
| tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), |
| tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f), |
| |
| tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f), |
| tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), |
| tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f), |
| tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f), |
| tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f) |
| }; |
| |
| DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(depthLevels) == DE_LENGTH_OF_ARRAY(depthLevelColors)); |
| |
| GLU_CHECK_CALL(glEnableVertexAttribArray(coordLoc)); |
| GLU_CHECK_CALL(glVertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, coords)); |
| |
| GLU_CHECK_CALL(glEnable(GL_DEPTH_TEST)); |
| GLU_CHECK_CALL(glDepthFunc(GL_LESS)); |
| |
| for (int level = 0; level < DE_LENGTH_OF_ARRAY(depthLevels); level++) |
| { |
| tcu::Vec4 color = depthLevelColors[level]; |
| GLU_CHECK_CALL(glUniform4f(colorLoc, color.x(), color.y(), color.z(), color.w())); |
| GLU_CHECK_CALL(glUniform1f(depthLoc, depthLevels[level])); |
| GLU_CHECK_CALL(glDrawArrays(GL_TRIANGLES, 0, 6)); |
| } |
| |
| GLU_CHECK_CALL(glDisable(GL_DEPTH_TEST)); |
| GLU_CHECK_CALL(glDisableVertexAttribArray(coordLoc)); |
| |
| tcu::Surface screen(reference.getWidth(), reference.getHeight()); |
| tcu::Surface referenceScreen(reference.getWidth(), reference.getHeight()); |
| |
| glReadPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()); |
| |
| for (int y = 0; y < reference.getHeight(); y++) |
| { |
| for (int x = 0; x < reference.getWidth(); x++) |
| { |
| tcu::RGBA result; |
| for (int level = 0; level < DE_LENGTH_OF_ARRAY(depthLevels); level++) |
| { |
| tcu::Vec4 src = reference.getLevel(0).getPixel(x, y); |
| |
| if (src.x() < depthLevels[level]) |
| { |
| result = tcu::RGBA((int)(depthLevelColors[level].x() * 255.0f), (int)(depthLevelColors[level].y() * 255.0f), (int)(depthLevelColors[level].z() * 255.0f), (int)(depthLevelColors[level].w() * 255.0f)); |
| } |
| } |
| |
| referenceScreen.setPixel(x, reference.getHeight(), result); |
| } |
| } |
| |
| bool isOk = tcu::pixelThresholdCompare(m_log, "Depth buffer rendering result", "Result from rendering with depth buffer", referenceScreen, screen, tcu::RGBA(1,1,1,1), tcu::COMPARE_LOG_RESULT); |
| |
| GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); |
| GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, 0)); |
| GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbufferDepth)); |
| GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbufferColor)); |
| GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer)); |
| GLU_CHECK_CALL(glFinish()); |
| |
| return isOk; |
| } |
| |
| bool GLES2ImageApi::renderReadPixelsRenderBuffer (EGLImageKHR img, const tcu::Texture2D& reference) |
| { |
| m_log << tcu::TestLog::Message << "Reading with ReadPixels from renderbuffer" << tcu::TestLog::EndMessage; |
| |
| deUint32 framebuffer; |
| glGenFramebuffers(1, &framebuffer); |
| TCU_CHECK(framebuffer != (GLuint)-1); |
| GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)); |
| |
| deUint32 renderbuffer = 0; |
| glGenRenderbuffers(1, &renderbuffer); |
| TCU_CHECK(renderbuffer != (GLuint)-1); |
| GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer)); |
| |
| m_eglExt.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, (GLeglImageOES)img); |
| |
| GLenum error = glGetError(); |
| |
| if (error == GL_INVALID_OPERATION) |
| { |
| GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer)); |
| throw tcu::NotSupportedError("Creating renderbuffer from EGLImage type not supported", "glEGLImageTargetRenderbufferStorageOES", __FILE__, __LINE__); |
| } |
| |
| TCU_CHECK(error == GL_NONE); |
| |
| TCU_CHECK_EGL_MSG("glEGLImageTargetRenderbufferStorageOES() failed"); |
| |
| GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer)); |
| |
| GLU_CHECK_CALL(glViewport(0, 0, reference.getWidth(), reference.getHeight())); |
| if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) |
| { |
| GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer)); |
| GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer)); |
| throw tcu::NotSupportedError("EGLImage as color attachment not supported", "", __FILE__, __LINE__); |
| } |
| |
| tcu::Surface screen(reference.getWidth(), reference.getHeight()); |
| tcu::Surface referenceScreen(reference.getWidth(), reference.getHeight()); |
| |
| glReadPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()); |
| |
| for (int y = 0; y < reference.getHeight(); y++) |
| { |
| for (int x = 0; x < reference.getWidth(); x++) |
| { |
| tcu::Vec4 src = reference.getLevel(0).getPixel(x, y); |
| referenceScreen.setPixel(x, y, tcu::RGBA(src)); |
| } |
| } |
| |
| bool isOk = tcu::pixelThresholdCompare(m_log, "Renderbuffer read", "Result from reading renderbuffer", referenceScreen, screen, tcu::RGBA(1,1,1,1), tcu::COMPARE_LOG_RESULT); |
| |
| GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); |
| GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, 0)); |
| GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer)); |
| GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer)); |
| GLU_CHECK_CALL(glFinish()); |
| |
| return isOk; |
| } |
| |
| bool GLES2ImageApi::renderTryAll (EGLImageKHR img, const tcu::Texture2D& reference) |
| { |
| bool isOk = true; |
| bool foundSupportedRendering = false; |
| |
| try |
| { |
| if (!renderTexture2D(img, reference)) |
| isOk = false; |
| |
| foundSupportedRendering = true; |
| } |
| catch (const tcu::NotSupportedError& error) |
| { |
| m_log << tcu::TestLog::Message << error.what() << tcu::TestLog::EndMessage; |
| } |
| |
| if (!isOk) |
| return false; |
| |
| try |
| { |
| if (!renderReadPixelsRenderBuffer(img, reference)) |
| isOk = false; |
| |
| foundSupportedRendering = true; |
| } |
| catch (const tcu::NotSupportedError& error) |
| { |
| m_log << tcu::TestLog::Message << error.what() << tcu::TestLog::EndMessage; |
| } |
| |
| if (!isOk) |
| return false; |
| |
| try |
| { |
| if (!renderDepth(img, reference)) |
| isOk = false; |
| |
| foundSupportedRendering = true; |
| } |
| catch (const tcu::NotSupportedError& error) |
| { |
| m_log << tcu::TestLog::Message << error.what() << tcu::TestLog::EndMessage; |
| } |
| |
| if (!foundSupportedRendering) |
| throw tcu::NotSupportedError("Rendering not supported", "", __FILE__, __LINE__); |
| |
| return isOk; |
| } |
| |
| bool GLES2ImageApi::renderCubeMap (EGLImageKHR img, const tcu::Surface& reference, GLenum face) |
| { |
| // \note This is not supported by EGLImage |
| DE_ASSERT(false); |
| |
| glClearColor(0.5, 0.5, 0.5, 1.0); |
| glViewport(0, 0, reference.getWidth(), reference.getHeight()); |
| glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); |
| glDisable(GL_DEPTH_TEST); |
| |
| m_log << tcu::TestLog::Message << "Rendering EGLImage as " << glTargetToString(face) << " in context: " << m_contextId << tcu::TestLog::EndMessage; |
| DE_ASSERT(img != EGL_NO_IMAGE_KHR); |
| |
| deUint32 srcTex = 0; |
| glGenTextures(1, &srcTex); |
| DE_ASSERT(srcTex != 0); |
| GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, srcTex)); |
| GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, reference.getWidth(), reference.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)); |
| GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, reference.getWidth(), reference.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)); |
| GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, reference.getWidth(), reference.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)); |
| GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, reference.getWidth(), reference.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)); |
| GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, reference.getWidth(), reference.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)); |
| GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, reference.getWidth(), reference.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)); |
| |
| m_eglExt.glEGLImageTargetTexture2DOES(face, (GLeglImageOES)img); |
| GLenum error = glGetError(); |
| |
| if (error == GL_INVALID_OPERATION) |
| { |
| GLU_CHECK_CALL(glDeleteTextures(1, &srcTex)); |
| throw tcu::NotSupportedError("Creating texture cubemap from EGLImage type not supported", "glEGLImageTargetTexture2DOES", __FILE__, __LINE__); |
| } |
| |
| TCU_CHECK(error == GL_NONE); |
| |
| TCU_CHECK_EGL_MSG("glEGLImageTargetTexture2DOES() failed"); |
| |
| GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); |
| GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); |
| GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); |
| GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); |
| |
| const char* vertexShader = |
| "attribute highp vec3 a_coord;\n" |
| "attribute highp vec3 a_texCoord;\n" |
| "varying mediump vec3 v_texCoord;\n" |
| "void main(void) {\n" |
| "\tv_texCoord = a_texCoord;\n" |
| "\tgl_Position = vec4(a_coord.xy, -0.1, 1.0);\n" |
| "}\n"; |
| |
| const char* fragmentShader = |
| "varying mediump vec3 v_texCoord;\n" |
| "uniform samplerCube u_sampler;\n" |
| "void main(void) {\n" |
| "\tmediump vec4 texColor = textureCube(u_sampler, v_texCoord);\n" |
| "\tgl_FragColor = vec4(texColor.rgb, 1.0);\n" |
| "}"; |
| |
| Program program(vertexShader, fragmentShader); |
| DE_ASSERT(program.isOk()); |
| |
| GLuint glProgram = program.getProgram(); |
| GLU_CHECK_CALL(glUseProgram(glProgram)); |
| |
| GLint coordLoc = glGetAttribLocation(glProgram, "a_coord"); |
| DE_ASSERT(coordLoc != -1); |
| |
| GLint texCoordLoc = glGetAttribLocation(glProgram, "a_texCoord"); |
| DE_ASSERT(texCoordLoc != -1); |
| |
| GLint samplerLoc = glGetUniformLocation(glProgram, "u_sampler"); |
| DE_ASSERT(samplerLoc != -1); |
| |
| float coords[] = |
| { |
| -1.0, -1.0, |
| 1.0, -1.0, |
| 1.0, 1.0, |
| |
| 1.0, 1.0, |
| -1.0, 1.0, |
| -1.0, -1.0, |
| }; |
| |
| float sampleTexCoords[] = |
| { |
| 10.0, -1.0, -1.0, |
| 10.0, 1.0, -1.0, |
| 10.0, 1.0, 1.0, |
| |
| 10.0, 1.0, 1.0, |
| 10.0, -1.0, 1.0, |
| 10.0, -1.0, -1.0, |
| }; |
| |
| vector<float> texCoords; |
| float sign = 0.0f; |
| int dir = -1; |
| |
| switch (face) |
| { |
| case GL_TEXTURE_CUBE_MAP_POSITIVE_X: sign = 1.0; dir = 0; break; |
| case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: sign = -1.0; dir = 0; break; |
| case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: sign = 1.0; dir = 1; break; |
| case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: sign = -1.0; dir = 1; break; |
| case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: sign = 1.0; dir = 2; break; |
| case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: sign = -1.0; dir = 2; break; |
| default: |
| DE_ASSERT(false); |
| } |
| |
| for (int i = 0; i < 6; i++) |
| { |
| texCoords.push_back(sign * sampleTexCoords[i*3 + (dir % 3)]); |
| texCoords.push_back(sampleTexCoords[i*3 + ((dir + 1) % 3)]); |
| texCoords.push_back(sampleTexCoords[i*3 + ((dir + 2) % 3)]); |
| } |
| |
| GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, srcTex)); |
| GLU_CHECK_CALL(glUniform1i(samplerLoc, 0)); |
| GLU_CHECK_CALL(glEnableVertexAttribArray(coordLoc)); |
| GLU_CHECK_CALL(glEnableVertexAttribArray(texCoordLoc)); |
| GLU_CHECK_CALL(glVertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, coords)); |
| GLU_CHECK_CALL(glVertexAttribPointer(texCoordLoc, 3, GL_FLOAT, GL_FALSE, 0, coords)); |
| |
| GLU_CHECK_CALL(glDrawArrays(GL_TRIANGLES, 0, 6)); |
| GLU_CHECK_CALL(glDisableVertexAttribArray(coordLoc)); |
| GLU_CHECK_CALL(glDisableVertexAttribArray(texCoordLoc)); |
| GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, 0)); |
| GLU_CHECK_CALL(glDeleteTextures(1, &srcTex)); |
| |
| tcu::Surface screen(reference.getWidth(), reference.getHeight()); |
| glReadPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()); |
| GLU_CHECK_MSG("glReadPixels()"); |
| |
| float threshold = 0.05f; |
| bool match = tcu::fuzzyCompare(m_log, "ComparisonResult", "Image comparison result", reference, screen, threshold, tcu::COMPARE_LOG_RESULT); |
| |
| return match; |
| } |
| |
| void GLES2ImageApi::modify (int operationNdx, EGLImageKHR img, tcu::Texture2D& reference) |
| { |
| switch (operationNdx) |
| { |
| case MODIFY_TEXSUBIMAGE_RGBA8: |
| modifyTexSubImage(img, reference, GL_RGBA, GL_UNSIGNED_BYTE); |
| break; |
| |
| case MODIFY_TEXSUBIMAGE_RGBA5_A1: |
| modifyTexSubImage(img, reference, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1); |
| break; |
| |
| case MODIFY_TEXSUBIMAGE_RGBA4: |
| modifyTexSubImage(img, reference, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4); |
| break; |
| |
| case MODIFY_TEXSUBIMAGE_RGB8: |
| modifyTexSubImage(img, reference, GL_RGB, GL_UNSIGNED_BYTE); |
| break; |
| |
| case MODIFY_TEXSUBIMAGE_RGB565: |
| modifyTexSubImage(img, reference, GL_RGB, GL_UNSIGNED_SHORT_5_6_5); |
| break; |
| |
| case MODIFY_RENDERBUFFER_CLEAR_COLOR: |
| modifyRenderbufferClearColor(img, reference); |
| break; |
| |
| case MODIFY_RENDERBUFFER_CLEAR_DEPTH: |
| modifyRenderbufferClearDepth(img, reference); |
| break; |
| |
| case MODIFY_RENDERBUFFER_CLEAR_STENCIL: |
| modifyRenderbufferClearStencil(img, reference); |
| break; |
| |
| default: |
| DE_ASSERT(false); |
| break; |
| } |
| } |
| |
| void GLES2ImageApi::modifyTexSubImage (EGLImageKHR img, tcu::Texture2D& reference, GLenum format, GLenum type) |
| { |
| m_log << tcu::TestLog::Message << "Modifying EGLImage with glTexSubImage2D" << tcu::TestLog::EndMessage; |
| |
| deUint32 srcTex = 0; |
| glGenTextures(1, &srcTex); |
| TCU_CHECK(srcTex != 0); |
| GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, srcTex)); |
| |
| m_eglExt.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)img); |
| |
| GLenum error = glGetError(); |
| |
| if (error == GL_INVALID_OPERATION) |
| { |
| GLU_CHECK_CALL(glDeleteTextures(1, &srcTex)); |
| throw tcu::NotSupportedError("Creating texture2D from EGLImage type not supported", "glEGLImageTargetTexture2DOES", __FILE__, __LINE__); |
| } |
| TCU_CHECK(error == GL_NONE); |
| |
| TCU_CHECK_EGL_MSG("glEGLImageTargetTexture2DOES() failed"); |
| |
| int xOffset = 8; |
| int yOffset = 16; |
| |
| tcu::Texture2D src(glu::mapGLTransferFormat(format, type), 16, 16); |
| src.allocLevel(0); |
| tcu::fillWithComponentGradients(src.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); |
| |
| GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, srcTex)); |
| GLU_CHECK_CALL(glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, src.getWidth(), src.getHeight(), format, type, src.getLevel(0).getDataPtr())); |
| |
| for (int x = 0; x < src.getWidth(); x++) |
| { |
| if (x + xOffset >= reference.getWidth()) |
| continue; |
| |
| for (int y = 0; y < src.getHeight(); y++) |
| { |
| if (y + yOffset >= reference.getHeight()) |
| continue; |
| |
| reference.getLevel(0).setPixel(src.getLevel(0).getPixel(x, y), x+xOffset, y+yOffset); |
| } |
| } |
| |
| GLU_CHECK_CALL(glDeleteTextures(1, &srcTex)); |
| GLU_CHECK_CALL(glFinish()); |
| GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, 0)); |
| } |
| |
| void GLES2ImageApi::modifyRenderbufferClearColor (EGLImageKHR img, tcu::Texture2D& reference) |
| { |
| m_log << tcu::TestLog::Message << "Modifying EGLImage with glClear to renderbuffer" << tcu::TestLog::EndMessage; |
| |
| deUint32 framebuffer; |
| glGenFramebuffers(1, &framebuffer); |
| TCU_CHECK(framebuffer != (GLuint)-1); |
| GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)); |
| |
| deUint32 renderbuffer = 0; |
| glGenRenderbuffers(1, &renderbuffer); |
| TCU_CHECK(renderbuffer != (GLuint)-1); |
| GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer)); |
| |
| m_eglExt.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, (GLeglImageOES)img); |
| |
| GLenum error = glGetError(); |
| |
| if (error == GL_INVALID_OPERATION) |
| { |
| GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer)); |
| GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer)); |
| throw tcu::NotSupportedError("Creating renderbuffer from EGLImage type not supported", "glEGLImageTargetRenderbufferStorageOES", __FILE__, __LINE__); |
| } |
| TCU_CHECK(error == GL_NONE); |
| |
| TCU_CHECK_EGL_MSG("glEGLImageTargetRenderbufferStorageOES() failed"); |
| |
| float red = 0.3f; |
| float green = 0.5f; |
| float blue = 0.3f; |
| float alpha = 1.0f; |
| |
| GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer)); |
| |
| GLU_CHECK_CALL(glViewport(0, 0, reference.getWidth(), reference.getHeight())); |
| if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) |
| { |
| GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer)); |
| GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer)); |
| throw tcu::NotSupportedError("EGLImage type as color attachment not supported", "", __FILE__, __LINE__); |
| } |
| |
| GLU_CHECK_CALL(glClearColor(red, green, blue, alpha)); |
| GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT)); |
| |
| for (int x = 0; x < reference.getWidth(); x++) |
| { |
| for (int y = 0; y < reference.getHeight(); y++) |
| { |
| tcu::Vec4 color = tcu::Vec4(red, green, blue, alpha); |
| reference.getLevel(0).setPixel(color, x, y); |
| } |
| } |
| |
| GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); |
| GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, 0)); |
| GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer)); |
| GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer)); |
| GLU_CHECK_CALL(glFinish()); |
| } |
| |
| void GLES2ImageApi::modifyRenderbufferClearDepth (EGLImageKHR img, tcu::Texture2D& reference) |
| { |
| m_log << tcu::TestLog::Message << "Modifying EGLImage with glClear to renderbuffer" << tcu::TestLog::EndMessage; |
| |
| deUint32 framebuffer; |
| glGenFramebuffers(1, &framebuffer); |
| TCU_CHECK(framebuffer != (GLuint)-1); |
| GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)); |
| |
| deUint32 renderbuffer = 0; |
| glGenRenderbuffers(1, &renderbuffer); |
| TCU_CHECK(renderbuffer != 0); |
| GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer)); |
| |
| m_eglExt.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, (GLeglImageOES)img); |
| |
| GLenum error = glGetError(); |
| |
| if (error == GL_INVALID_OPERATION) |
| { |
| GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer)); |
| GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer)); |
| throw tcu::NotSupportedError("Creating renderbuffer from EGLImage type not supported", "glEGLImageTargetRenderbufferStorageOES", __FILE__, __LINE__); |
| } |
| TCU_CHECK(error == GL_NONE); |
| |
| TCU_CHECK_EGL_MSG("glEGLImageTargetRenderbufferStorageOES() failed"); |
| |
| float depth = 0.7f; |
| |
| GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer)); |
| |
| GLU_CHECK_CALL(glViewport(0, 0, reference.getWidth(), reference.getHeight())); |
| if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) |
| { |
| GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer)); |
| GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer)); |
| throw tcu::NotSupportedError("EGLImage type as depth attachment not supported", "", __FILE__, __LINE__); |
| } |
| |
| GLU_CHECK_CALL(glClearDepthf(depth)); |
| GLU_CHECK_CALL(glClear(GL_DEPTH_BUFFER_BIT)); |
| |
| for (int x = 0; x < reference.getWidth(); x++) |
| { |
| for (int y = 0; y < reference.getHeight(); y++) |
| { |
| tcu::Vec4 color = tcu::Vec4(depth, depth, depth, depth); |
| reference.getLevel(0).setPixel(color, x, y); |
| } |
| } |
| |
| GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); |
| GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, 0)); |
| GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer)); |
| GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer)); |
| GLU_CHECK_CALL(glFinish()); |
| } |
| |
| void GLES2ImageApi::modifyRenderbufferClearStencil (EGLImageKHR img, tcu::Texture2D& reference) |
| { |
| m_log << tcu::TestLog::Message << "Modifying EGLImage with glClear to renderbuffer" << tcu::TestLog::EndMessage; |
| |
| deUint32 framebuffer; |
| glGenFramebuffers(1, &framebuffer); |
| TCU_CHECK(framebuffer != (GLuint)-1); |
| GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)); |
| |
| deUint32 renderbuffer = 0; |
| glGenRenderbuffers(1, &renderbuffer); |
| TCU_CHECK(renderbuffer != 0); |
| GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer)); |
| |
| m_eglExt.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, (GLeglImageOES)img); |
| GLenum error = glGetError(); |
| |
| if (error == GL_INVALID_OPERATION) |
| { |
| GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer)); |
| GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer)); |
| throw tcu::NotSupportedError("Creating renderbuffer from EGLImage type not supported", "glEGLImageTargetRenderbufferStorageOES", __FILE__, __LINE__); |
| } |
| TCU_CHECK(error == GL_NONE); |
| |
| TCU_CHECK_EGL_MSG("glEGLImageTargetRenderbufferStorageOES() failed"); |
| |
| int stencilValue = 78; |
| |
| GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuffer)); |
| |
| GLU_CHECK_CALL(glViewport(0, 0, reference.getWidth(), reference.getHeight())); |
| if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) |
| { |
| GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer)); |
| GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer)); |
| throw tcu::NotSupportedError("EGLImage type as stencil attachment not supported", "", __FILE__, __LINE__); |
| } |
| |
| GLU_CHECK_CALL(glClearStencil(stencilValue)); |
| GLU_CHECK_CALL(glClear(GL_STENCIL_BUFFER_BIT)); |
| |
| for (int x = 0; x < reference.getWidth(); x++) |
| { |
| for (int y = 0; y < reference.getHeight(); y++) |
| { |
| tcu::IVec4 color = tcu::IVec4(stencilValue, stencilValue, stencilValue, stencilValue); |
| reference.getLevel(0).setPixel(color, x, y); |
| } |
| } |
| |
| GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); |
| GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, 0)); |
| GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer)); |
| GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer)); |
| GLU_CHECK_CALL(glFinish()); |
| } |
| |
| |
| void GLES2ImageApi::checkRequiredExtensions (set<string>& extensions, TestSpec::Operation::Type type, int operationNdx) |
| { |
| switch (type) |
| { |
| case TestSpec::Operation::TYPE_CREATE: |
| switch (operationNdx) |
| { |
| case CREATE_TEXTURE2D_RGB8: |
| case CREATE_TEXTURE2D_RGB565: |
| case CREATE_TEXTURE2D_RGBA8: |
| case CREATE_TEXTURE2D_RGBA5_A1: |
| case CREATE_TEXTURE2D_RGBA4: |
| extensions.insert("EGL_KHR_gl_texture_2D_image"); |
| break; |
| |
| case CREATE_CUBE_MAP_POSITIVE_X_RGB8: |
| case CREATE_CUBE_MAP_NEGATIVE_X_RGB8: |
| case CREATE_CUBE_MAP_POSITIVE_Y_RGB8: |
| case CREATE_CUBE_MAP_NEGATIVE_Y_RGB8: |
| case CREATE_CUBE_MAP_POSITIVE_Z_RGB8: |
| case CREATE_CUBE_MAP_NEGATIVE_Z_RGB8: |
| case CREATE_CUBE_MAP_POSITIVE_X_RGBA8: |
| case CREATE_CUBE_MAP_NEGATIVE_X_RGBA8: |
| case CREATE_CUBE_MAP_POSITIVE_Y_RGBA8: |
| case CREATE_CUBE_MAP_NEGATIVE_Y_RGBA8: |
| case CREATE_CUBE_MAP_POSITIVE_Z_RGBA8: |
| case CREATE_CUBE_MAP_NEGATIVE_Z_RGBA8: |
| extensions.insert("EGL_KHR_gl_texture_cubemap_image"); |
| break; |
| |
| case CREATE_RENDER_BUFFER_RGBA4: |
| case CREATE_RENDER_BUFFER_RGB5_A1: |
| case CREATE_RENDER_BUFFER_RGB565: |
| case CREATE_RENDER_BUFFER_DEPTH16: |
| case CREATE_RENDER_BUFFER_STENCIL: |
| extensions.insert("EGL_KHR_gl_renderbuffer_image"); |
| break; |
| |
| default: |
| DE_ASSERT(false); |
| } |
| break; |
| |
| case TestSpec::Operation::TYPE_RENDER: |
| switch (operationNdx) |
| { |
| case RENDER_TEXTURE2D: |
| case RENDER_READ_PIXELS_RENDERBUFFER: |
| case RENDER_DEPTHBUFFER: |
| case RENDER_TRY_ALL: |
| extensions.insert("GL_OES_EGL_image"); |
| break; |
| |
| default: |
| DE_ASSERT(false); |
| break; |
| } |
| break; |
| |
| case TestSpec::Operation::TYPE_MODIFY: |
| switch (operationNdx) |
| { |
| case MODIFY_TEXSUBIMAGE_RGB565: |
| case MODIFY_TEXSUBIMAGE_RGB8: |
| case MODIFY_TEXSUBIMAGE_RGBA8: |
| case MODIFY_TEXSUBIMAGE_RGBA5_A1: |
| case MODIFY_TEXSUBIMAGE_RGBA4: |
| case MODIFY_RENDERBUFFER_CLEAR_COLOR: |
| case MODIFY_RENDERBUFFER_CLEAR_DEPTH: |
| case MODIFY_RENDERBUFFER_CLEAR_STENCIL: |
| extensions.insert("GL_OES_EGL_image"); |
| break; |
| |
| default: |
| DE_ASSERT(false); |
| break; |
| }; |
| break; |
| |
| default: |
| DE_ASSERT(false); |
| break; |
| } |
| } |
| |
| class ImageFormatCase : public TestCase |
| { |
| public: |
| ImageFormatCase (EglTestContext& eglTestCtx, const TestSpec& spec); |
| ~ImageFormatCase (void); |
| |
| void init (void); |
| void deinit (void); |
| IterateResult iterate (void); |
| void checkExtensions (void); |
| |
| private: |
| EGLConfig getConfig (void); |
| |
| const TestSpec m_spec; |
| tcu::TestLog& m_log; |
| |
| vector<ImageApi*> m_apiContexts; |
| |
| tcu::egl::Display* m_display; |
| eglu::NativeWindow* m_window; |
| tcu::egl::Surface* m_surface; |
| EGLConfig m_config; |
| int m_curIter; |
| EGLImageKHR m_img; |
| tcu::Texture2D m_refImg; |
| EglExt m_eglExt; |
| }; |
| |
| EGLConfig ImageFormatCase::getConfig (void) |
| { |
| vector<EGLConfig> configs; |
| eglu::FilterList filter; |
| |
| EGLint attribList[] = |
| { |
| EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
| EGL_SURFACE_TYPE, EGL_WINDOW_BIT, |
| EGL_ALPHA_SIZE, 1, |
| EGL_DEPTH_SIZE, 8, |
| EGL_NONE |
| }; |
| m_display->chooseConfig(attribList, configs); |
| |
| return configs[0]; |
| } |
| |
| ImageFormatCase::ImageFormatCase (EglTestContext& eglTestCtx, const TestSpec& spec) |
| : TestCase (eglTestCtx, spec.name.c_str(), spec.desc.c_str()) |
| , m_spec (spec) |
| , m_log (eglTestCtx.getTestContext().getLog()) |
| , m_display (DE_NULL) |
| , m_window (DE_NULL) |
| , m_surface (DE_NULL) |
| , m_config (0) |
| , m_curIter (0) |
| , m_img (EGL_NO_IMAGE_KHR) |
| , m_refImg (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1, 1) |
| { |
| } |
| |
| ImageFormatCase::~ImageFormatCase (void) |
| { |
| deinit(); |
| } |
| |
| void ImageFormatCase::checkExtensions (void) |
| { |
| vector<string> extensions; |
| m_display->getExtensions(extensions); |
| |
| set<string> extSet(extensions.begin(), extensions.end()); |
| |
| const char* glExt = (const char*)glGetString(GL_EXTENSIONS); |
| |
| for (const char* c = glExt; true; c++) |
| { |
| if (*c == '\0') |
| { |
| extSet.insert(string(glExt)); |
| break; |
| } |
| |
| if (*c == ' ') |
| { |
| extSet.insert(string(glExt, c)); |
| glExt = (c+1); |
| } |
| } |
| |
| if (extSet.find("EGL_KHR_image_base") == extSet.end() |
| && extSet.find("EGL_KHR_image") == extSet.end()) |
| { |
| m_log << tcu::TestLog::Message |
| << "EGL_KHR_image and EGL_KHR_image_base not supported." |
| << "One should be supported." |
| << tcu::TestLog::EndMessage; |
| throw tcu::NotSupportedError("Extension not supported", "EGL_KHR_image_base", __FILE__, __LINE__); |
| } |
| |
| set<string> requiredExtensions; |
| for (int operationNdx = 0; operationNdx < (int)m_spec.operations.size(); operationNdx++) |
| m_apiContexts[m_spec.operations[m_curIter].apiIndex]->checkRequiredExtensions(requiredExtensions, m_spec.operations[operationNdx].type, m_spec.operations[operationNdx].operationIndex); |
| |
| std::set<string>::iterator extIter = requiredExtensions.begin(); |
| for (; extIter != requiredExtensions.end(); extIter++) |
| { |
| if (extSet.find(*extIter) == extSet.end()) |
| throw tcu::NotSupportedError("Extension not supported", (*extIter).c_str(), __FILE__, __LINE__); |
| } |
| } |
| |
| void ImageFormatCase::init (void) |
| { |
| m_display = &m_eglTestCtx.getDisplay(); |
| m_config = getConfig(); |
| m_window = m_eglTestCtx.createNativeWindow(m_display->getEGLDisplay(), m_config, DE_NULL, 480, 480, eglu::parseWindowVisibility(m_testCtx.getCommandLine())); |
| m_surface = new tcu::egl::WindowSurface(*m_display, eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *m_window, m_display->getEGLDisplay(), m_config, DE_NULL)); |
| |
| for (int contextNdx = 0; contextNdx < (int)m_spec.contexts.size(); contextNdx++) |
| { |
| ImageApi* api = DE_NULL; |
| switch (m_spec.contexts[contextNdx]) |
| { |
| case TestSpec::API_GLES2: |
| { |
| api = new GLES2ImageApi(contextNdx, m_log, *m_display, m_surface, m_config); |
| break; |
| } |
| |
| default: |
| DE_ASSERT(false); |
| break; |
| } |
| m_apiContexts.push_back(api); |
| } |
| checkExtensions(); |
| } |
| |
| void ImageFormatCase::deinit (void) |
| { |
| for (int contexNdx = 0 ; contexNdx < (int)m_apiContexts.size(); contexNdx++) |
| delete m_apiContexts[contexNdx]; |
| |
| m_apiContexts.clear(); |
| delete m_surface; |
| m_surface = DE_NULL; |
| delete m_window; |
| m_window = DE_NULL; |
| } |
| |
| TestCase::IterateResult ImageFormatCase::iterate (void) |
| { |
| bool isOk = true; |
| |
| switch (m_spec.operations[m_curIter].type) |
| { |
| case TestSpec::Operation::TYPE_CREATE: |
| { |
| // Delete old image if exists |
| if (m_img != EGL_NO_IMAGE_KHR) |
| { |
| m_log << tcu::TestLog::Message << "Destroying old EGLImage" << tcu::TestLog::EndMessage; |
| TCU_CHECK_EGL_CALL(m_eglExt.eglDestroyImageKHR(m_display->getEGLDisplay(), m_img)); |
| |
| m_img = EGL_NO_IMAGE_KHR; |
| } |
| |
| m_img = m_apiContexts[m_spec.operations[m_curIter].apiIndex]->create(m_spec.operations[m_curIter].operationIndex, m_refImg); |
| break; |
| } |
| |
| case TestSpec::Operation::TYPE_RENDER: |
| { |
| DE_ASSERT(m_apiContexts[m_spec.operations[m_curIter].apiIndex]); |
| isOk = m_apiContexts[m_spec.operations[m_curIter].apiIndex]->render(m_spec.operations[m_curIter].operationIndex, m_img, m_refImg); |
| break; |
| } |
| |
| case TestSpec::Operation::TYPE_MODIFY: |
| { |
| m_apiContexts[m_spec.operations[m_curIter].apiIndex]->modify(m_spec.operations[m_curIter].operationIndex, m_img, m_refImg); |
| break; |
| } |
| |
| default: |
| DE_ASSERT(false); |
| break; |
| } |
| |
| if (isOk && ++m_curIter < (int)m_spec.operations.size()) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| return CONTINUE; |
| } |
| else if (!isOk) |
| { |
| if (m_img != EGL_NO_IMAGE_KHR) |
| { |
| m_log << tcu::TestLog::Message << "Destroying EGLImage" << tcu::TestLog::EndMessage; |
| TCU_CHECK_EGL_CALL(m_eglExt.eglDestroyImageKHR(m_display->getEGLDisplay(), m_img)); |
| m_img = EGL_NO_IMAGE_KHR; |
| } |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| return STOP; |
| } |
| else |
| { |
| if (m_img != EGL_NO_IMAGE_KHR) |
| { |
| m_log << tcu::TestLog::Message << "Destroying EGLImage" << tcu::TestLog::EndMessage; |
| TCU_CHECK_EGL_CALL(m_eglExt.eglDestroyImageKHR(m_display->getEGLDisplay(), m_img)); |
| m_img = EGL_NO_IMAGE_KHR; |
| } |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| return STOP; |
| } |
| } |
| |
| SimpleCreationTests::SimpleCreationTests (EglTestContext& eglTestCtx) |
| : TestCaseGroup (eglTestCtx, "create", "EGLImage creation tests") |
| { |
| } |
| |
| #define PUSH_VALUES_TO_VECTOR(type, vector, ...)\ |
| do {\ |
| type array[] = __VA_ARGS__;\ |
| for (int i = 0; i < DE_LENGTH_OF_ARRAY(array); i++)\ |
| {\ |
| vector.push_back(array[i]);\ |
| }\ |
| } while(false); |
| |
| void SimpleCreationTests::init (void) |
| { |
| GLES2ImageApi::Create createOperations[] = { |
| GLES2ImageApi::CREATE_TEXTURE2D_RGB8, |
| GLES2ImageApi::CREATE_TEXTURE2D_RGB565, |
| GLES2ImageApi::CREATE_TEXTURE2D_RGBA8, |
| GLES2ImageApi::CREATE_TEXTURE2D_RGBA5_A1, |
| GLES2ImageApi::CREATE_TEXTURE2D_RGBA4, |
| |
| GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_X_RGBA8, |
| GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_Y_RGBA8, |
| GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_Z_RGBA8, |
| |
| GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_X_RGBA8, |
| GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_Y_RGBA8, |
| GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_Z_RGBA8, |
| |
| GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_X_RGB8, |
| GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_Y_RGB8, |
| GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_Z_RGB8, |
| |
| GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_X_RGB8, |
| GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_Y_RGB8, |
| GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_Z_RGB8, |
| |
| GLES2ImageApi::CREATE_RENDER_BUFFER_RGBA4, |
| GLES2ImageApi::CREATE_RENDER_BUFFER_RGB5_A1, |
| GLES2ImageApi::CREATE_RENDER_BUFFER_RGB565, |
| GLES2ImageApi::CREATE_RENDER_BUFFER_DEPTH16, |
| GLES2ImageApi::CREATE_RENDER_BUFFER_STENCIL |
| }; |
| |
| const char* createOperationsStr[] = { |
| "texture_rgb8", |
| "texture_rgb565", |
| "texture_rgba8", |
| "texture_rgba5_a1", |
| "texture_rgba4", |
| |
| "cubemap_positive_x_rgba", |
| "cubemap_positive_y_rgba", |
| "cubemap_positive_z_rgba", |
| |
| "cubemap_negative_x_rgba", |
| "cubemap_negative_y_rgba", |
| "cubemap_negative_z_rgba", |
| |
| "cubemap_positive_x_rgb", |
| "cubemap_positive_y_rgb", |
| "cubemap_positive_z_rgb", |
| |
| "cubemap_negative_x_rgb", |
| "cubemap_negative_y_rgb", |
| "cubemap_negative_z_rgb", |
| |
| "renderbuffer_rgba4", |
| "renderbuffer_rgb5_a1", |
| "renderbuffer_rgb565", |
| "renderbuffer_depth16", |
| "renderbuffer_stencil" |
| }; |
| |
| GLES2ImageApi::Render renderOperations[] = { |
| GLES2ImageApi::RENDER_TEXTURE2D, |
| GLES2ImageApi::RENDER_READ_PIXELS_RENDERBUFFER, |
| GLES2ImageApi::RENDER_DEPTHBUFFER |
| }; |
| const char* renderOperationsStr[] = { |
| "texture", |
| "read_pixels", |
| "depth_buffer" |
| }; |
| |
| DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(createOperations) == DE_LENGTH_OF_ARRAY(createOperationsStr)); |
| DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(renderOperations) == DE_LENGTH_OF_ARRAY(renderOperationsStr)); |
| |
| for (int createNdx = 0; createNdx < DE_LENGTH_OF_ARRAY(createOperations); createNdx++) |
| { |
| for (int renderNdx = 0; renderNdx < DE_LENGTH_OF_ARRAY(renderOperations); renderNdx++) |
| { |
| TestSpec spec; |
| spec.name = std::string("gles2_") + createOperationsStr[createNdx] + "_" + renderOperationsStr[renderNdx]; |
| spec.desc = spec.name; |
| |
| PUSH_VALUES_TO_VECTOR(TestSpec::ApiContext, spec.contexts, |
| { |
| TestSpec::API_GLES2 |
| }); |
| PUSH_VALUES_TO_VECTOR(TestSpec::Operation, spec.operations, |
| { |
| { TestSpec::API_GLES2, 0, TestSpec::Operation::TYPE_CREATE, createOperations[createNdx] }, |
| { TestSpec::API_GLES2, 0, TestSpec::Operation::TYPE_RENDER, renderOperations[renderNdx] }, |
| }); |
| |
| addChild(new ImageFormatCase(m_eglTestCtx, spec)); |
| } |
| } |
| } |
| |
| MultiContextRenderTests::MultiContextRenderTests (EglTestContext& eglTestCtx) |
| : TestCaseGroup (eglTestCtx, "render_multiple_contexts", "EGLImage render tests on multiple contexts") |
| { |
| } |
| |
| void MultiContextRenderTests::init (void) |
| { |
| GLES2ImageApi::Create createOperations[] = { |
| GLES2ImageApi::CREATE_TEXTURE2D_RGB8, |
| GLES2ImageApi::CREATE_TEXTURE2D_RGB565, |
| GLES2ImageApi::CREATE_TEXTURE2D_RGBA8, |
| GLES2ImageApi::CREATE_TEXTURE2D_RGBA5_A1, |
| GLES2ImageApi::CREATE_TEXTURE2D_RGBA4, |
| |
| GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_X_RGBA8, |
| GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_Y_RGBA8, |
| GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_Z_RGBA8, |
| |
| GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_X_RGBA8, |
| GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_Y_RGBA8, |
| GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_Z_RGBA8, |
| |
| GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_X_RGB8, |
| GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_Y_RGB8, |
| GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_Z_RGB8, |
| |
| GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_X_RGB8, |
| GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_Y_RGB8, |
| GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_Z_RGB8, |
| |
| GLES2ImageApi::CREATE_RENDER_BUFFER_RGBA4, |
| GLES2ImageApi::CREATE_RENDER_BUFFER_RGB5_A1, |
| GLES2ImageApi::CREATE_RENDER_BUFFER_RGB565, |
| GLES2ImageApi::CREATE_RENDER_BUFFER_DEPTH16, |
| GLES2ImageApi::CREATE_RENDER_BUFFER_STENCIL |
| }; |
| |
| const char* createOperationsStr[] = { |
| "texture_rgb8", |
| "texture_rgb565", |
| "texture_rgba8", |
| "texture_rgba5_a1", |
| "texture_rgba4", |
| |
| "cubemap_positive_x_rgba8", |
| "cubemap_positive_y_rgba8", |
| "cubemap_positive_z_rgba8", |
| |
| "cubemap_negative_x_rgba8", |
| "cubemap_negative_y_rgba8", |
| "cubemap_negative_z_rgba8", |
| |
| "cubemap_positive_x_rgb8", |
| "cubemap_positive_y_rgb8", |
| "cubemap_positive_z_rgb8", |
| |
| "cubemap_negative_x_rgb8", |
| "cubemap_negative_y_rgb8", |
| "cubemap_negative_z_rgb8", |
| |
| "renderbuffer_rgba4", |
| "renderbuffer_rgb5_a1", |
| "renderbuffer_rgb565", |
| "renderbuffer_depth16", |
| "renderbuffer_stencil" |
| }; |
| |
| GLES2ImageApi::Render renderOperations[] = { |
| GLES2ImageApi::RENDER_TEXTURE2D, |
| GLES2ImageApi::RENDER_READ_PIXELS_RENDERBUFFER, |
| GLES2ImageApi::RENDER_DEPTHBUFFER |
| }; |
| const char* renderOperationsStr[] = { |
| "texture", |
| "read_pixels", |
| "depth_buffer" |
| }; |
| |
| DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(createOperations) == DE_LENGTH_OF_ARRAY(createOperationsStr)); |
| DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(renderOperations) == DE_LENGTH_OF_ARRAY(renderOperationsStr)); |
| |
| for (int createNdx = 0; createNdx < DE_LENGTH_OF_ARRAY(createOperations); createNdx++) |
| { |
| for (int renderNdx = 0; renderNdx < DE_LENGTH_OF_ARRAY(renderOperations); renderNdx++) |
| { |
| TestSpec spec; |
| spec.name = std::string("gles2_") + createOperationsStr[createNdx] + "_" + renderOperationsStr[renderNdx]; |
| spec.desc = spec.name; |
| |
| PUSH_VALUES_TO_VECTOR(TestSpec::ApiContext, spec.contexts, |
| { |
| TestSpec::API_GLES2, |
| TestSpec::API_GLES2 |
| }); |
| PUSH_VALUES_TO_VECTOR(TestSpec::Operation, spec.operations, |
| { |
| { TestSpec::API_GLES2, 0, TestSpec::Operation::TYPE_CREATE, createOperations[createNdx] }, |
| { TestSpec::API_GLES2, 1, TestSpec::Operation::TYPE_RENDER, renderOperations[renderNdx] }, |
| { TestSpec::API_GLES2, 0, TestSpec::Operation::TYPE_RENDER, renderOperations[renderNdx] }, |
| { TestSpec::API_GLES2, 1, TestSpec::Operation::TYPE_CREATE, createOperations[createNdx] }, |
| { TestSpec::API_GLES2, 1, TestSpec::Operation::TYPE_RENDER, renderOperations[renderNdx] }, |
| { TestSpec::API_GLES2, 0, TestSpec::Operation::TYPE_RENDER, renderOperations[renderNdx] } |
| }); |
| addChild(new ImageFormatCase(m_eglTestCtx, spec)); |
| } |
| } |
| } |
| |
| ModifyTests::ModifyTests (EglTestContext& eglTestCtx) |
| : TestCaseGroup (eglTestCtx, "modify", "EGLImage modifying tests") |
| { |
| } |
| |
| void ModifyTests::init (void) |
| { |
| GLES2ImageApi::Create createOperations[] = { |
| GLES2ImageApi::CREATE_TEXTURE2D_RGB8, |
| GLES2ImageApi::CREATE_TEXTURE2D_RGB565, |
| GLES2ImageApi::CREATE_TEXTURE2D_RGBA8, |
| GLES2ImageApi::CREATE_TEXTURE2D_RGBA5_A1, |
| GLES2ImageApi::CREATE_TEXTURE2D_RGBA4, |
| |
| GLES2ImageApi::CREATE_RENDER_BUFFER_RGBA4, |
| GLES2ImageApi::CREATE_RENDER_BUFFER_RGB5_A1, |
| GLES2ImageApi::CREATE_RENDER_BUFFER_RGB565, |
| GLES2ImageApi::CREATE_RENDER_BUFFER_DEPTH16, |
| GLES2ImageApi::CREATE_RENDER_BUFFER_STENCIL |
| }; |
| |
| const char* createOperationsStr[] = { |
| "tex_rgb8", |
| "tex_rgb565", |
| "tex_rgba8", |
| "tex_rgba5_a1", |
| "tex_rgba4", |
| |
| "renderbuffer_rgba4", |
| "renderbuffer_rgb5_a1", |
| "renderbuffer_rgb565", |
| "renderbuffer_depth16", |
| "renderbuffer_stencil" |
| }; |
| |
| GLES2ImageApi::Modify modifyOperations[] = { |
| GLES2ImageApi::MODIFY_TEXSUBIMAGE_RGB8, |
| GLES2ImageApi::MODIFY_TEXSUBIMAGE_RGB565, |
| GLES2ImageApi::MODIFY_TEXSUBIMAGE_RGBA8, |
| GLES2ImageApi::MODIFY_TEXSUBIMAGE_RGBA5_A1, |
| GLES2ImageApi::MODIFY_TEXSUBIMAGE_RGBA4, |
| |
| GLES2ImageApi::MODIFY_RENDERBUFFER_CLEAR_COLOR, |
| GLES2ImageApi::MODIFY_RENDERBUFFER_CLEAR_DEPTH, |
| GLES2ImageApi::MODIFY_RENDERBUFFER_CLEAR_STENCIL, |
| }; |
| |
| const char* modifyOperationsStr[] = { |
| "tex_subimage_rgb8", |
| "tex_subimage_rgb565", |
| "tex_subimage_rgba8", |
| "tex_subimage_rgba5_a1", |
| "tex_subimage_rgba4", |
| |
| "renderbuffer_clear_color", |
| "renderbuffer_clear_depth", |
| "renderbuffer_clear_stencil", |
| }; |
| |
| DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(modifyOperations) == DE_LENGTH_OF_ARRAY(modifyOperationsStr)); |
| DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(createOperations) == DE_LENGTH_OF_ARRAY(createOperationsStr)); |
| |
| for (int createNdx = 0; createNdx < DE_LENGTH_OF_ARRAY(createOperations); createNdx++) |
| { |
| for (int modifyNdx = 0; modifyNdx < DE_LENGTH_OF_ARRAY(modifyOperations); modifyNdx++) |
| { |
| TestSpec spec; |
| spec.name = "gles2_tex_sub_image"; |
| spec.desc = spec.name; |
| |
| PUSH_VALUES_TO_VECTOR(TestSpec::ApiContext, spec.contexts, |
| { |
| TestSpec::API_GLES2 |
| }); |
| PUSH_VALUES_TO_VECTOR(TestSpec::Operation, spec.operations, |
| { |
| { TestSpec::API_GLES2, 0, TestSpec::Operation::TYPE_CREATE, createOperations[createNdx] }, |
| { TestSpec::API_GLES2, 0, TestSpec::Operation::TYPE_RENDER, GLES2ImageApi::RENDER_TRY_ALL }, |
| { TestSpec::API_GLES2, 0, TestSpec::Operation::TYPE_MODIFY, modifyOperations[modifyNdx] }, |
| { TestSpec::API_GLES2, 0, TestSpec::Operation::TYPE_RENDER, GLES2ImageApi::RENDER_TRY_ALL } |
| }); |
| |
| spec.name = std::string(createOperationsStr[createNdx]) + "_" + modifyOperationsStr[modifyNdx]; |
| addChild(new ImageFormatCase(m_eglTestCtx, spec)); |
| } |
| } |
| } |
| |
| } // Image |
| } // egl |
| } // deqp |