Add yuv420 format to EGL AHB tests
authorAlex Lan <alex.lan@arm.com>
Fri, 20 Aug 2021 10:47:25 +0000 (18:47 +0800)
committerAlex Lan <alex.lan@arm.com>
Tue, 9 Nov 2021 03:29:23 +0000 (11:29 +0800)
Create an external texture with Y8Cb8Cr8_420 buffer format,
Initialize it with glClear, and sample it.

The test's behavior is like this:
1,initialize the external yuv texture with glClear
2,using glReadPixels to store the initial value in reference
3,sample this yuv texture
4,compare the rendering result with reference

New test:
dEQP-EGL.functional.image.create.gles3_android_native_yuv420_yuv_texture

Components: EGL, Framework

Change-Id: Ie4535505ea0d8d384794df77afa6583fe99fb1e2

android/cts/master/egl-master.txt
framework/common/tcuTexture.cpp
framework/common/tcuTexture.hpp
modules/egl/teglAndroidUtil.cpp
modules/egl/teglAndroidUtil.hpp
modules/egl/teglImageFormatTests.cpp
modules/egl/teglImageTests.cpp
modules/egl/teglImageUtil.cpp
modules/egl/teglImageUtil.hpp

index 6d31157..48c1a77 100644 (file)
@@ -1049,6 +1049,7 @@ dEQP-EGL.functional.image.create.gles2_android_native_rgb10a2_read_pixels
 dEQP-EGL.functional.image.create.gles2_android_native_rgba16f_texture
 dEQP-EGL.functional.image.create.gles2_android_native_rgba16f_read_pixels
 dEQP-EGL.functional.image.create.gles2_android_native_s8_stencil_buffer
+dEQP-EGL.functional.image.create.gles3_android_native_yuv420_yuv_texture
 dEQP-EGL.functional.image.create.gles3_android_native_array_rgba4_texture_array
 dEQP-EGL.functional.image.create.gles3_android_native_array_rgb5_a1_texture_array
 dEQP-EGL.functional.image.create.gles3_android_native_array_rgb565_texture_array
index 8c25bb8..869515c 100644 (file)
@@ -3568,25 +3568,28 @@ void Texture1D::allocLevel (int levelNdx)
 
 Texture2D::Texture2D (const TextureFormat& format, int width, int height, bool es2)
        : TextureLevelPyramid   (format, computeMipPyramidLevels(width, height))
-       , m_width                               (width)
-       , m_height                              (height)
-       , m_view                                (getNumLevels(), getLevels(), es2)
+       , m_yuvTextureUsed      (false)
+       , m_width               (width)
+       , m_height              (height)
+       , m_view                (getNumLevels(), getLevels(), es2)
 {
 }
 
 Texture2D::Texture2D (const TextureFormat& format, int width, int height, int mipmaps)
        : TextureLevelPyramid   (format, mipmaps)
-       , m_width                               (width)
-       , m_height                              (height)
-       , m_view                                (getNumLevels(), getLevels())
+       , m_yuvTextureUsed      (false)
+       , m_width               (width)
+       , m_height              (height)
+       , m_view                (getNumLevels(), getLevels())
 {
 }
 
 Texture2D::Texture2D (const Texture2D& other)
        : TextureLevelPyramid   (other)
-       , m_width                               (other.m_width)
-       , m_height                              (other.m_height)
-       , m_view                                (getNumLevels(), getLevels(), other.getView().isES2())
+       , m_yuvTextureUsed      (other.m_yuvTextureUsed)
+       , m_width               (other.m_width)
+       , m_height              (other.m_height)
+       , m_view                (getNumLevels(), getLevels(), other.getView().isES2())
 {
 }
 
@@ -3600,7 +3603,7 @@ Texture2D& Texture2D::operator= (const Texture2D& other)
        m_width         = other.m_width;
        m_height        = other.m_height;
        m_view          = Texture2DView(getNumLevels(), getLevels(), other.getView().isES2());
-
+       m_yuvTextureUsed = other.m_yuvTextureUsed;
        return *this;
 }
 
index 15d4fc5..f1c95b1 100644 (file)
@@ -626,25 +626,25 @@ private:
 class Texture2D : private TextureLevelPyramid
 {
 public:
-                                                                       Texture2D                       (const TextureFormat& format, int width, int height, bool es2 = false);
-                                                                       Texture2D                       (const TextureFormat& format, int width, int height, int mipmaps);
-                                                                       Texture2D                       (const Texture2D& other);
-                                                                       ~Texture2D                      (void);
+                                               Texture2D               (const TextureFormat& format, int width, int height, bool es2 = false);
+                                               Texture2D               (const TextureFormat& format, int width, int height, int mipmaps);
+                                               Texture2D               (const Texture2D& other);
+                                               ~Texture2D              (void);
 
-       int                                                             getWidth                        (void) const    { return m_width;       }
-       int                                                             getHeight                       (void) const    { return m_height;      }
-       const Texture2DView&                    getView                         (void) const    { return m_view;        }
-
-       void                                                    allocLevel                      (int levelNdx);
+       int                                     getWidth                (void) const    { return m_width;       }
+       int                                     getHeight               (void) const    { return m_height;      }
+       const Texture2DView&                    getView                 (void) const    { return m_view;        }
+       bool                                    isYUVTextureUsed        (void) const    { return m_yuvTextureUsed;}
+       void                                    allocLevel              (int levelNdx);
 
        // Sampling
-       Vec4                                                    sample                          (const Sampler& sampler, float s, float t, float lod) const;
-       Vec4                                                    sampleOffset            (const Sampler& sampler, float s, float t, float lod, const IVec2& offset) const;
-       float                                                   sampleCompare           (const Sampler& sampler, float ref, float s, float t, float lod) const;
-       float                                                   sampleCompareOffset     (const Sampler& sampler, float ref, float s, float t, float lod, const IVec2& offset) const;
+       Vec4                                    sample                  (const Sampler& sampler, float s, float t, float lod) const;
+       Vec4                                    sampleOffset            (const Sampler& sampler, float s, float t, float lod, const IVec2& offset) const;
+       float                                   sampleCompare           (const Sampler& sampler, float ref, float s, float t, float lod) const;
+       float                                   sampleCompareOffset     (const Sampler& sampler, float ref, float s, float t, float lod, const IVec2& offset) const;
 
-       Vec4                                                    gatherOffsets           (const Sampler& sampler, float s, float t, int componentNdx, const IVec2 (&offsets)[4]) const;
-       Vec4                                                    gatherOffsetsCompare(const Sampler& sampler, float ref, float s, float t, const IVec2 (&offsets)[4]) const;
+       Vec4                                    gatherOffsets           (const Sampler& sampler, float s, float t, int componentNdx, const IVec2 (&offsets)[4]) const;
+       Vec4                                    gatherOffsetsCompare    (const Sampler& sampler, float ref, float s, float t, const IVec2 (&offsets)[4]) const;
 
        using TextureLevelPyramid::getFormat;
        using TextureLevelPyramid::getNumLevels;
@@ -653,13 +653,14 @@ public:
        using TextureLevelPyramid::isLevelEmpty;
 
        Texture2D&                                              operator=                       (const Texture2D& other);
-
+       //whether this is a yuv format texture tests
+       bool                                                    m_yuvTextureUsed;
        operator Texture2DView (void) const { return m_view; }
 
 private:
-       int                                                             m_width;
-       int                                                             m_height;
-       Texture2DView                                   m_view;
+       int                                                     m_width;
+       int                                                     m_height;
+       Texture2DView                                           m_view;
 } DE_WARN_UNUSED_TYPE;
 
 inline Vec4 Texture2D::sample (const Sampler& sampler, float s, float t, float lod) const
index bea9de2..5e0b456 100644 (file)
@@ -48,10 +48,10 @@ using namespace eglw;
 
 #if (DE_OS != DE_OS_ANDROID)
 
-MovePtr<ImageSource> createAndroidNativeImageSource    (GLenum format, deUint32 numLayers)
+MovePtr<ImageSource> createAndroidNativeImageSource    (GLenum format, deUint32 numLayers, bool isYUV)
 {
        DE_UNREF(numLayers);
-       return createUnsupportedImageSource("Not Android platform", format);
+       return createUnsupportedImageSource("Not Android platform", format, isYUV);
 }
 
 #else // DE_OS == DE_OS_ANDROID
@@ -62,10 +62,10 @@ MovePtr<ImageSource> createAndroidNativeImageSource (GLenum format, deUint32 num
 
 #if !defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
 
-MovePtr<ImageSource> createAndroidNativeImageSource    (GLenum format, deUint32 numLayers)
+MovePtr<ImageSource> createAndroidNativeImageSource    (GLenum format, deUint32 numLayers, bool isYUV)
 {
        DE_UNREF(numLayers);
-       return createUnsupportedImageSource("AHB API not supported", format);
+       return createUnsupportedImageSource("AHB API not supported", format, isYUV);
 }
 
 #else // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
@@ -163,11 +163,11 @@ AHardwareBuffer_Format getPixelFormat (GLenum format)
 class AndroidNativeClientBuffer : public ClientBuffer
 {
 public:
-                                                       AndroidNativeClientBuffer       (const Library& egl, GLenum format, deUint32 numLayers);
-                                                       ~AndroidNativeClientBuffer      (void);
-       EGLClientBuffer                 get                                                     (void) const;
-       void                                    lock                                            (void** data);
-       void                                    unlock                                          (void);
+                                               AndroidNativeClientBuffer       (const Library& egl, GLenum format, deUint32 numLayers, bool isYUV);
+                                               ~AndroidNativeClientBuffer      (void);
+       EGLClientBuffer         get                                                     (void) const;
+       void                            lock                                            (void** data);
+       void                            unlock                                          (void);
        AHardwareBuffer_Desc    describe                                        (void);
 
 private:
@@ -175,7 +175,7 @@ private:
        AHardwareBuffer*                m_hardwareBuffer;
 };
 
-AndroidNativeClientBuffer::AndroidNativeClientBuffer (const Library& egl, GLenum format, deUint32 numLayers)
+AndroidNativeClientBuffer::AndroidNativeClientBuffer (const Library& egl, GLenum format, deUint32 numLayers, bool isYUV)
        : m_egl(egl)
 {
        deInt32 sdkVersion = androidGetSdkVersion();
@@ -193,7 +193,7 @@ AndroidNativeClientBuffer::AndroidNativeClientBuffer (const Library& egl, GLenum
                64u,
                64u,
                numLayers,
-               getPixelFormat(format),
+               isYUV ? AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420 : getPixelFormat(format),
                AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN    |
                AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY  |
                AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
@@ -246,16 +246,17 @@ AHardwareBuffer_Desc AndroidNativeClientBuffer::describe (void)
 class AndroidNativeImageSource : public ImageSource
 {
 public:
-                                                       AndroidNativeImageSource        (GLenum format, deUint32 numLayers) : m_format(format), m_numLayers(numLayers) {}
+                                                       AndroidNativeImageSource        (GLenum format, deUint32 numLayers, bool isYUV) : m_format(format), m_numLayers(numLayers), m_isY8Cb8Cr8_420(isYUV) {}
                                                        ~AndroidNativeImageSource       (void);
        MovePtr<ClientBuffer>   createBuffer                            (const Library& egl, const glw::Functions&, Texture2D*) const;
        string                                  getRequiredExtension            (void) const { return "EGL_ANDROID_get_native_client_buffer"; }
        EGLImageKHR                             createImage                                     (const Library& egl, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const;
        GLenum                                  getEffectiveFormat                      (void) const { return m_format; }
-
+       bool                                    isYUVFormatImage                        (void) const { return m_isY8Cb8Cr8_420; }
 protected:
        GLenum                                  m_format;
        deUint32                                m_numLayers;
+       bool                                    m_isY8Cb8Cr8_420;
 };
 
 AndroidNativeImageSource::~AndroidNativeImageSource (void)
@@ -264,7 +265,7 @@ AndroidNativeImageSource::~AndroidNativeImageSource (void)
 
 MovePtr<ClientBuffer> AndroidNativeImageSource::createBuffer (const Library& egl, const glw::Functions&, Texture2D* ref) const
 {
-       MovePtr<AndroidNativeClientBuffer> buffer (new AndroidNativeClientBuffer(egl, m_format, m_numLayers));
+       MovePtr<AndroidNativeClientBuffer> buffer (new AndroidNativeClientBuffer(egl, m_format, m_numLayers, m_isY8Cb8Cr8_420));
 
        if (ref != DE_NULL)
        {
@@ -272,6 +273,7 @@ MovePtr<ClientBuffer> AndroidNativeImageSource::createBuffer (const Library& egl
                void*                           bufferData      = DE_NULL;
 
                *ref = Texture2D(texFormat, 64, 64);
+               ref->m_yuvTextureUsed = m_isY8Cb8Cr8_420;
                ref->allocLevel(0);
                tcu::fillWithComponentGradients(ref->getLevel(0),
                                                                                tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
@@ -279,7 +281,9 @@ MovePtr<ClientBuffer> AndroidNativeImageSource::createBuffer (const Library& egl
 
                // AHB doesn't allow locking a layered image. In that case the data
                // will be initialized later using OpenGL API.
-               if (m_numLayers == 1u)
+               // YUV format texture will be initialized by glClear.
+
+               if (m_numLayers == 1u && !m_isY8Cb8Cr8_420)
                {
                        buffer->lock(&bufferData);
                        {
@@ -307,15 +311,15 @@ EGLImageKHR AndroidNativeImageSource::createImage (const Library& egl, EGLDispla
 
 } // anonymous
 
-MovePtr<ImageSource> createAndroidNativeImageSource    (GLenum format, deUint32 numLayers)
+MovePtr<ImageSource> createAndroidNativeImageSource    (GLenum format, deUint32 numLayers, bool isYUV)
 {
        try
        {
-               return MovePtr<ImageSource>(new AndroidNativeImageSource(format, numLayers));
+               return MovePtr<ImageSource>(new AndroidNativeImageSource(format, numLayers, isYUV));
        }
        catch (const std::runtime_error& exc)
        {
-               return createUnsupportedImageSource(string("Android native buffers unsupported: ") + exc.what(), format);
+               return createUnsupportedImageSource(string("Android native buffers unsupported: ") + exc.what(), format, isYUV);
        }
 }
 
index 4b56a1b..ba85570 100644 (file)
@@ -32,7 +32,7 @@ namespace egl
 namespace Image
 {
 
-de::MovePtr<ImageSource> createAndroidNativeImageSource                (glw::GLenum format, deUint32 numLayers);
+de::MovePtr<ImageSource> createAndroidNativeImageSource                (glw::GLenum format, deUint32 numLayers, bool isYUV);
 
 } // Image
 } // egl
index e13ccc7..218eaf2 100644 (file)
@@ -188,7 +188,7 @@ public:
                bool                                    invokeGLES                              (GLESImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const;
                deUint32                                getNumLayers                    (void) const { return m_numLayers; }
                glw::GLenum                             getEffectiveFormat              (void) const { return m_imgSource->getEffectiveFormat(); }
-
+               bool                                    isYUVFormatImage                (void) const { return m_imgSource->isYUVFormatImage(); }
        private:
                UniquePtr<ImageSource>  m_imgSource;
                deUint32                                m_numLayers;
@@ -227,7 +227,12 @@ public:
                        bool    invokeGLES                              (GLESImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const override;
                        string  getRequiredExtension    (void) const override { return "GL_OES_EGL_image_external"; }
        };
-
+       class RenderYUVTexture                  : public Render
+       {
+               public:
+                       bool    invokeGLES                              (GLESImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const override;
+                       string  getRequiredExtension    (void) const override { return "GL_EXT_YUV_target"; }
+       };
        class Modify : public GLESAction
        {
        public:
@@ -688,6 +693,116 @@ bool GLESImageApi::RenderExternalTexture::invokeGLES (GLESImageApi& api, MovePtr
        return match;
 }
 
+bool GLESImageApi::RenderYUVTexture::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
+{
+       const glw::Functions&   gl              = api.m_gl;
+       tcu::TestLog&                   log             = api.getLog();
+       Texture                                 srcTex  (gl);
+
+       DE_ASSERT(reference.isYUVTextureUsed());
+
+       gl.clearColor(0.0, 0.0, 0.0, 0.0);
+       gl.viewport(0, 0, reference.getWidth(), reference.getHeight());
+       gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+       gl.disable(GL_DEPTH_TEST);
+
+       log << tcu::TestLog::Message << "Rendering EGLImage as GL_TEXTURE_EXTERNAL_OES in context: " << api.m_contextId << tcu::TestLog::EndMessage;
+       TCU_CHECK(**img != EGL_NO_IMAGE_KHR);
+       GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, *srcTex));
+       imageTargetExternalTexture(api.m_egl, gl, **img);
+       {
+               /* init YUV texture with glClear, clear color value in YUV color space */
+               glu::Framebuffer                fbo(gl);
+               GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *fbo));
+               GLU_CHECK_GLW_CALL(gl, framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,  GL_TEXTURE_EXTERNAL_OES,*srcTex, 0));
+               const tcu::Vec4 colorValues[] =
+               {
+                       tcu::Vec4(0.9f, 0.5f, 0.65f, 1.0f),
+                       tcu::Vec4(0.5f, 0.7f, 0.65f, 1.0f),
+                       tcu::Vec4(0.2f, 0.5f, 0.65f, 1.0f),
+                       tcu::Vec4(0.3f, 0.1f, 0.5f, 1.0f),
+                       tcu::Vec4(0.8f, 0.2f, 0.3f, 1.0f),
+                       tcu::Vec4(0.9f, 0.4f, 0.8f, 1.0f),
+               };
+               tcu::clear(reference.getLevel(0), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
+               GLU_CHECK_GLW_CALL(gl, enable(GL_SCISSOR_TEST));
+               for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorValues); ++ndx)
+               {
+                       const tcu::IVec2        size    = tcu::IVec2((int)((float)(DE_LENGTH_OF_ARRAY(colorValues) - ndx) * ((float)reference.getWidth() / float(DE_LENGTH_OF_ARRAY(colorValues)))),
+                                                                                                       (int)((float)(DE_LENGTH_OF_ARRAY(colorValues) - ndx) * ((float)reference.getHeight() / float(DE_LENGTH_OF_ARRAY(colorValues)))));
+
+                       if (size.x() == 0 || size.y() == 0)
+                               break;
+                       GLU_CHECK_GLW_CALL(gl, scissor(0, 0, size.x(), size.y()));
+
+                       GLU_CHECK_GLW_CALL(gl, clearColor(colorValues[ndx].x(), colorValues[ndx].y(), colorValues[ndx].z(), colorValues[ndx].w()));
+                       GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT));
+                       GLU_CHECK_GLW_CALL(gl, finish());
+                       char tmp[4]={"0"};
+                       GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)tmp));
+                       tcu::clear(tcu::getSubregion(reference.getLevel(0), 0, 0, size.x(), size.y()), tcu::Vec4(tmp[0]/(255.0f), tmp[1]/(255.0f), tmp[2]/(255.0f), tmp[3]/(255.0f)));
+               }
+               GLU_CHECK_GLW_CALL(gl, disable(GL_SCISSOR_TEST));
+               GLU_CHECK_GLW_CALL(gl, framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES, 0, 0));
+               GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
+               GLU_CHECK_GLW_CALL(gl, finish());
+       }
+
+       GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
+       GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
+       GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
+       GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
+
+       const char* const 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* const fragmentShader =
+               "#extension GL_OES_EGL_image_external : require\n"
+               "varying mediump vec2 v_texCoord;\n"
+               "uniform samplerExternalOES u_sampler;\n"
+               "void main(void) {\n"
+               "\tmediump vec4 texColor = texture2D(u_sampler, v_texCoord);\n"
+               "\tgl_FragColor = vec4(texColor);\n"
+               "}";
+
+       Program program(gl, vertexShader, fragmentShader);
+       TCU_CHECK(program.isOk());
+
+       GLuint glProgram = program.getProgram();
+       GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
+
+       GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
+       TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
+
+       GLuint samplerLoc = gl.getUniformLocation(glProgram, "u_sampler");
+       TCU_CHECK_MSG((int)samplerLoc != (int)-1, "Couldn't find uniform u_sampler");
+
+       GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, *srcTex));
+       GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc, 0));
+       GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
+       GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
+
+       GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
+       GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
+       GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, 0));
+
+       tcu::Surface refSurface (reference.getWidth(), reference.getHeight());
+       tcu::Surface screen             (reference.getWidth(), reference.getHeight());
+       GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()));
+
+       tcu::copy(refSurface.getAccess(), reference.getLevel(0));
+
+       float   threshold       = 0.05f;
+       bool    match           = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refSurface, screen, threshold, tcu::COMPARE_LOG_RESULT);
+
+       return match;
+}
+
 bool GLESImageApi::RenderExternalTextureSamplerArray::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
 {
        const glw::Functions&   gl              = api.m_gl;
@@ -1461,7 +1576,7 @@ protected:
 
        void                    addCreateTexture                                (const string& name, EGLenum source, GLenum internalFormat, GLenum format, GLenum type);
        void                    addCreateRenderbuffer                   (const string& name, GLenum format);
-       void                    addCreateAndroidNative                  (const string& name, GLenum format);
+       void                    addCreateAndroidNative                  (const string& name, GLenum format, bool isYUV);
        void                    addCreateAndroidNativeArray             (const string& name, GLenum format, deUint32 numLayers);
        void                    addCreateTexture2DActions               (const string& prefix);
        void                    addCreateTextureCubemapActions  (const string& suffix, GLenum internalFormat, GLenum format, GLenum type);
@@ -1481,14 +1596,14 @@ void ImageTests::addCreateRenderbuffer (const string& name, GLenum format)
        m_createActions.add(name, MovePtr<Action>(new GLESImageApi::Create(createRenderbufferImageSource(format))));
 }
 
-void ImageTests::addCreateAndroidNative (const string& name, GLenum format)
+void ImageTests::addCreateAndroidNative (const string& name, GLenum format, bool isYUV = false)
 {
-       m_createActions.add(name, MovePtr<Action>(new GLESImageApi::Create(createAndroidNativeImageSource(format, 1u))));
+       m_createActions.add(name, MovePtr<Action>(new GLESImageApi::Create(createAndroidNativeImageSource(format, 1u, isYUV))));
 }
 
 void ImageTests::addCreateAndroidNativeArray (const string& name, GLenum format, deUint32 numLayers)
 {
-       m_createActions.add(name, MovePtr<Action>(new GLESImageApi::Create(createAndroidNativeImageSource(format, numLayers), numLayers)));
+       m_createActions.add(name, MovePtr<Action>(new GLESImageApi::Create(createAndroidNativeImageSource(format, numLayers, false), numLayers)));
 }
 
 void ImageTests::addCreateTexture2DActions (const string& prefix)
@@ -1534,6 +1649,7 @@ void ImageTests::addCreateAndroidNativeActions (void)
        addCreateAndroidNative("android_native_rgb10a2",        GL_RGB10_A2);
        addCreateAndroidNative("android_native_rgba16f",        GL_RGBA16F);
        addCreateAndroidNative("android_native_s8",                     GL_STENCIL_INDEX8);
+       addCreateAndroidNative("android_native_yuv420",         GL_RGBA8, true);
 
        addCreateAndroidNativeArray("android_native_array_rgba4",       GL_RGBA4,       4u);
        addCreateAndroidNativeArray("android_native_array_rgb5_a1",     GL_RGB5_A1,     4u);
@@ -1559,6 +1675,7 @@ void RenderTests::addRenderActions (void)
        m_renderActions.add("read_pixels",              MovePtr<Action>(new GLESImageApi::RenderReadPixelsRenderbuffer()));
        m_renderActions.add("depth_buffer",             MovePtr<Action>(new GLESImageApi::RenderDepthbuffer()));
        m_renderActions.add("stencil_buffer",   MovePtr<Action>(new GLESImageApi::RenderStencilbuffer()));
+       m_renderActions.add("yuv_texture",              MovePtr<Action>(new GLESImageApi::RenderYUVTexture()));
 }
 
 class SimpleCreationTests : public RenderTests
@@ -1636,51 +1753,67 @@ bool isCompatibleCreateAndRenderActions (const Action& create, const Action& ren
 {
        if (const GLESImageApi::Create* glesCreate = dynamic_cast<const GLESImageApi::Create*>(&create))
        {
-               const GLenum createFormat = glesCreate->getEffectiveFormat();
-
-               if (dynamic_cast<const GLESImageApi::RenderTexture2DArray*>(&render))
-               {
-                       // Makes sense only for texture arrays.
-                       if (glesCreate->getNumLayers() <= 1u)
-                               return false;
-               }
-               else if (glesCreate->getNumLayers() != 1u)
+               bool  yuvFormatTest = glesCreate->isYUVFormatImage();
+               // this path only for none-yuv format tests
+               if(!yuvFormatTest)
                {
-                       // Skip other render actions for texture arrays.
-                       return false;
-               }
+                   const GLenum createFormat = glesCreate->getEffectiveFormat();
 
-               if (dynamic_cast<const GLESImageApi::RenderTexture2D*>(&render))
-               {
-                       // GLES does not have depth or stencil textures
-                       if (isDepthFormat(createFormat) || isStencilFormat(createFormat))
+                       if (dynamic_cast<const GLESImageApi::RenderTexture2DArray*>(&render))
+                       {
+                               // Makes sense only for texture arrays.
+                               if (glesCreate->getNumLayers() <= 1u)
+                                       return false;
+                       }
+                       else if (glesCreate->getNumLayers() != 1u)
+                       {
+                               // Skip other render actions for texture arrays.
                                return false;
-               }
+                       }
 
-               if (dynamic_cast<const GLESImageApi::RenderReadPixelsRenderbuffer*>(&render))
-               {
-                       // GLES does not support readPixels for depth or stencil.
-                       if (isDepthFormat(createFormat) || isStencilFormat(createFormat))
-                               return false;
-               }
+                       if (dynamic_cast<const GLESImageApi::RenderTexture2D*>(&render))
+                       {
+                               // GLES does not have depth or stencil textures
+                               if (isDepthFormat(createFormat) || isStencilFormat(createFormat))
+                                       return false;
+                       }
 
-               if (dynamic_cast<const GLESImageApi::RenderDepthbuffer*>(&render))
-               {
-                       // Copying non-depth data to depth renderbuffer and expecting meaningful
-                       // results just doesn't make any sense.
-                       if (!isDepthFormat(createFormat))
+                       if (dynamic_cast<const GLESImageApi::RenderReadPixelsRenderbuffer*>(&render))
+                       {
+                               // GLES does not support readPixels for depth or stencil.
+                               if (isDepthFormat(createFormat) || isStencilFormat(createFormat))
+                                       return false;
+                       }
+
+                       if (dynamic_cast<const GLESImageApi::RenderDepthbuffer*>(&render))
+                       {
+                               // Copying non-depth data to depth renderbuffer and expecting meaningful
+                               // results just doesn't make any sense.
+                               if (!isDepthFormat(createFormat))
+                                       return false;
+                       }
+
+                       if (dynamic_cast<const GLESImageApi::RenderStencilbuffer*>(&render))
+                       {
+                               // Copying non-stencil data to stencil renderbuffer and expecting meaningful
+                               // results just doesn't make any sense.
+                               if (!isStencilFormat(createFormat))
+                                       return false;
+                       }
+
+                       if (dynamic_cast<const GLESImageApi::RenderYUVTexture*>(&render))
+                       {
+                               // In yuv path rendering with non-yuv format native buffer and expecting meaningful
+                               // results just doesn't make any sense
                                return false;
-               }
+                       }
 
-               if (dynamic_cast<const GLESImageApi::RenderStencilbuffer*>(&render))
+                       return true;
+               }
+               else if (dynamic_cast<const GLESImageApi::RenderYUVTexture*>(&render))
                {
-                       // Copying non-stencil data to stencil renderbuffer and expecting meaningful
-                       // results just doesn't make any sense.
-                       if (!isStencilFormat(createFormat))
-                               return false;
+                       return true;
                }
-
-               return true;
        }
        else
                DE_ASSERT(false);
@@ -1709,7 +1842,8 @@ void SimpleCreationTests::init (void)
                        if (!isCompatibleCreateAndRenderActions(*createAction.action, *renderAction.action))
                                continue;
 
-                       if (dynamic_cast<const GLESImageApi::RenderTexture2DArray*>(renderAction.action.get()))
+                       if (dynamic_cast<const GLESImageApi::RenderTexture2DArray*>(renderAction.action.get()) ||
+                               dynamic_cast<const GLESImageApi::RenderYUVTexture*>(renderAction.action.get()))
                        {
                                // Texture array tests require GLES3.
                                spec.name = std::string("gles3_") + createAction.label + "_" + renderAction.label;
@@ -1824,6 +1958,9 @@ bool isCompatibleCreateAndModifyActions (const Action& create, const Action& mod
                // No modify tests for texture arrays.
                if (glesCreate->getNumLayers() > 1u)
                        return false;
+               // No modify tests for yuv format image.
+               if (glesCreate->isYUVFormatImage())
+                       return false;
 
                const GLenum createFormat = glesCreate->getEffectiveFormat();
 
index 275ab35..a9c6e5e 100644 (file)
@@ -391,7 +391,7 @@ public:
 
                        case EGL_NATIVE_BUFFER_ANDROID:
                                DE_ASSERT(format == 0u && type == 0u);
-                               return createAndroidNativeImageSource(internalFormat, 1u);
+                               return createAndroidNativeImageSource(internalFormat, 1u, false);
 
                        default:
                                DE_FATAL("Impossible");
index b423cb4..cede60f 100644 (file)
@@ -518,16 +518,16 @@ MovePtr<ClientBuffer> RenderbufferImageSource::createBuffer (const eglw::Library
 class UnsupportedImageSource : public ImageSource
 {
 public:
-                                                       UnsupportedImageSource  (const string& message, GLenum format) : m_message(message), m_format(format) {}
+                                                       UnsupportedImageSource  (const string& message, GLenum format, bool isYUV) : m_message(message), m_format(format), m_isY8Cb8Cr8_420(isYUV) {}
        string                                  getRequiredExtension    (void) const { fail(); return ""; }
        MovePtr<ClientBuffer>   createBuffer                    (const eglw::Library& egl, const glw::Functions&, tcu::Texture2D*) const { DE_UNREF(egl); fail(); return de::MovePtr<ClientBuffer>(); }
        EGLImageKHR                             createImage                             (const Library& egl, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const;
        GLenum                                  getEffectiveFormat              (void) const { return m_format; }
-
+       bool                                    isYUVFormatImage                (void) const {return m_isY8Cb8Cr8_420;};
 private:
        const string                    m_message;
        GLenum                                  m_format;
-
+       bool                                    m_isY8Cb8Cr8_420;
        void                                    fail                                    (void) const { TCU_THROW(NotSupportedError, m_message.c_str()); }
 };
 
@@ -550,9 +550,9 @@ MovePtr<ImageSource> createRenderbufferImageSource (GLenum format)
        return MovePtr<ImageSource>(new RenderbufferImageSource(format));
 }
 
-MovePtr<ImageSource> createUnsupportedImageSource (const string& message, GLenum format)
+MovePtr<ImageSource> createUnsupportedImageSource (const string& message, GLenum format, bool isYUV)
 {
-       return MovePtr<ImageSource>(new UnsupportedImageSource(message, format));
+       return MovePtr<ImageSource>(new UnsupportedImageSource(message, format, isYUV));
 }
 
 } // Image
index 2d63df7..58c9240 100644 (file)
@@ -75,11 +75,12 @@ public:
        virtual de::MovePtr<ClientBuffer>       createBuffer            (const eglw::Library& egl, const glw::Functions& gl, tcu::Texture2D* reference = DE_NULL) const = 0;
        virtual eglw::EGLImageKHR                       createImage                     (const eglw::Library& egl, eglw::EGLDisplay dpy, eglw::EGLContext ctx, eglw::EGLClientBuffer clientBuffer) const = 0;
        virtual glw::GLenum                                     getEffectiveFormat      (void) const = 0;
+       virtual bool                                            isYUVFormatImage        (void) const {return false;};
 };
 
 de::MovePtr<ImageSource> createTextureImageSource                      (eglw::EGLenum source, glw::GLenum internalFormat, glw::GLenum format, glw::GLenum type, bool useTexLevel0 = false);
 de::MovePtr<ImageSource> createRenderbufferImageSource         (glw::GLenum format);
-de::MovePtr<ImageSource> createUnsupportedImageSource          (const std::string& message, glw::GLenum format);
+de::MovePtr<ImageSource> createUnsupportedImageSource          (const std::string& message, glw::GLenum format, bool isYUV);
 
 } // Image
 } // egl