Edit

kc3-lang/angle/src/tests/test_utils/MultiviewTest.cpp

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2018-12-02 12:03:33
    Hash : 35cd7332
    Message : Refactor test shader style. This change enforces a lot more consistency. We pass const char * to the Compile functions instead of std::string. Also fixes the indentation of C++11 block comments to be more consistent. Bug: angleproject:2995 Change-Id: Id6e5ea94055d8cbd420df4ea2e81b2d96cb5ce78 Reviewed-on: https://chromium-review.googlesource.com/c/1357103 Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>

  • src/tests/test_utils/MultiviewTest.cpp
  • //
    // Copyright 2018 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    // MultiviewTest:
    //   Implementation of helpers for multiview testing.
    //
    
    #include "test_utils/MultiviewTest.h"
    #include "platform/WorkaroundsD3D.h"
    #include "test_utils/gl_raii.h"
    
    namespace angle
    {
    
    GLuint CreateSimplePassthroughProgram(int numViews)
    {
        const std::string vsSource =
            "#version 300 es\n"
            "#extension GL_OVR_multiview : require\n"
            "layout(num_views = " +
            ToString(numViews) +
            ") in;\n"
            "layout(location=0) in vec2 vPosition;\n"
            "void main()\n"
            "{\n"
            "   gl_PointSize = 1.;\n"
            "   gl_Position = vec4(vPosition.xy, 0.0, 1.0);\n"
            "}\n";
    
        constexpr char kFS[] =
            "#version 300 es\n"
            "#extension GL_OVR_multiview : require\n"
            "precision mediump float;\n"
            "out vec4 col;\n"
            "void main()\n"
            "{\n"
            "   col = vec4(0,1,0,1);\n"
            "}\n";
        return CompileProgram(vsSource.c_str(), kFS);
    }
    
    void CreateMultiviewBackingTextures(GLenum multiviewLayout,
                                        int samples,
                                        int viewWidth,
                                        int height,
                                        int numLayers,
                                        std::vector<GLuint> colorTextures,
                                        GLuint depthTexture,
                                        GLuint depthStencilTexture)
    {
        // The same zero data is used to initialize both color and depth/stencil textures.
        std::vector<GLubyte> textureData;
        textureData.resize(viewWidth * height * numLayers * 4, 0u);
    
        // Multisampling is only supported for layered framebuffers.
        ASSERT((samples == 0) || multiviewLayout == GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE);
    
        // We can't upload data to multisample textures, so we clear them using a temporary framebuffer
        // instead. The current framebuffer binding is stored so we can restore it once we're done with
        // using the temporary framebuffers.
        GLint restoreDrawFramebuffer;
        glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &restoreDrawFramebuffer);
    
        // Create color and depth textures.
        switch (multiviewLayout)
        {
            case GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE:
            {
                int textureWidth = viewWidth * numLayers;
                for (auto colorTexture : colorTextures)
                {
                    glBindTexture(GL_TEXTURE_2D, colorTexture);
                    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, height, 0, GL_RGBA,
                                 GL_UNSIGNED_BYTE, textureData.data());
                    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
                    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
                }
    
                if (depthTexture != 0)
                {
                    glBindTexture(GL_TEXTURE_2D, depthTexture);
                    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, textureWidth, height, 0,
                                 GL_DEPTH_COMPONENT, GL_FLOAT, textureData.data());
                }
                if (depthStencilTexture != 0)
                {
                    glBindTexture(GL_TEXTURE_2D, depthStencilTexture);
                    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, textureWidth, height, 0,
                                 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, textureData.data());
                }
                glBindTexture(GL_TEXTURE_2D, 0);
                break;
            }
            case GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE:
            {
                GLenum texTarget =
                    (samples > 0) ? GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES : GL_TEXTURE_2D_ARRAY;
                for (auto colorTexture : colorTextures)
                {
                    glBindTexture(texTarget, colorTexture);
                    if (samples > 0)
                    {
                        glTexStorage3DMultisampleOES(texTarget, samples, GL_RGBA8, viewWidth, height,
                                                     numLayers, false);
    
                        GLFramebuffer tempFbo;
                        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tempFbo);
                        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
                        for (int layerIndex = 0; layerIndex < numLayers; ++layerIndex)
                        {
                            glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                                      colorTexture, 0, layerIndex);
                            glClear(GL_COLOR_BUFFER_BIT);
                        }
                    }
                    else
                    {
                        glTexImage3D(texTarget, 0, GL_RGBA8, viewWidth, height, numLayers, 0, GL_RGBA,
                                     GL_UNSIGNED_BYTE, textureData.data());
                        glTexParameteri(texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
                        glTexParameteri(texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
                    }
                }
    
                if (depthTexture != 0)
                {
                    glBindTexture(texTarget, depthTexture);
                    if (samples > 0)
                    {
                        glTexStorage3DMultisampleOES(texTarget, samples, GL_DEPTH_COMPONENT32F,
                                                     viewWidth, height, numLayers, false);
    
                        GLFramebuffer tempFbo;
                        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tempFbo);
                        glClearDepthf(0.0f);
                        for (int layerIndex = 0; layerIndex < numLayers; ++layerIndex)
                        {
                            glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                                                      depthTexture, 0, layerIndex);
                            glClear(GL_DEPTH_BUFFER_BIT);
                        }
                    }
                    else
                    {
                        glTexImage3D(texTarget, 0, GL_DEPTH_COMPONENT32F, viewWidth, height, numLayers,
                                     0, GL_DEPTH_COMPONENT, GL_FLOAT, textureData.data());
                    }
                }
                if (depthStencilTexture != 0)
                {
                    glBindTexture(texTarget, depthStencilTexture);
                    if (samples > 0)
                    {
                        glTexStorage3DMultisampleOES(texTarget, samples, GL_DEPTH24_STENCIL8, viewWidth,
                                                     height, numLayers, false);
    
                        GLFramebuffer tempFbo;
                        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tempFbo);
                        glClearDepthf(0.0f);
                        glClearStencil(0);
                        for (int layerIndex = 0; layerIndex < numLayers; ++layerIndex)
                        {
                            glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
                                                      depthTexture, 0, layerIndex);
                            glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
                        }
                    }
                    else
                    {
                        glTexImage3D(texTarget, 0, GL_DEPTH24_STENCIL8, viewWidth, height, numLayers, 0,
                                     GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, textureData.data());
                    }
                }
                glBindTexture(texTarget, 0);
                break;
            }
            default:
                UNREACHABLE();
        }
        ASSERT_GL_NO_ERROR();
    
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, restoreDrawFramebuffer);
    }
    
    void CreateMultiviewBackingTextures(GLenum multiviewLayout,
                                        int samples,
                                        int viewWidth,
                                        int height,
                                        int numLayers,
                                        GLuint colorTexture,
                                        GLuint depthTexture,
                                        GLuint depthStencilTexture)
    {
        ASSERT(colorTexture != 0u);
        std::vector<GLuint> colorTextures(1, colorTexture);
        CreateMultiviewBackingTextures(multiviewLayout, samples, viewWidth, height, numLayers,
                                       colorTextures, depthTexture, depthStencilTexture);
    }
    
    void AttachMultiviewTextures(GLenum target,
                                 GLenum multiviewLayout,
                                 int viewWidth,
                                 int numViews,
                                 int baseViewIndex,
                                 std::vector<GLuint> colorTextures,
                                 GLuint depthTexture,
                                 GLuint depthStencilTexture)
    {
        ASSERT(multiviewLayout == GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE || (baseViewIndex == 0));
        ASSERT(depthTexture == 0u || depthStencilTexture == 0u);
        switch (multiviewLayout)
        {
            case GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE:
            {
                std::vector<GLint> viewportOffsets(numViews * 2);
                for (int i = 0u; i < numViews; ++i)
                {
                    viewportOffsets[i * 2]     = i * viewWidth;
                    viewportOffsets[i * 2 + 1] = 0;
                }
                for (size_t i = 0; i < colorTextures.size(); ++i)
                {
                    GLenum attachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i);
                    glFramebufferTextureMultiviewSideBySideANGLE(target, attachment, colorTextures[i],
                                                                 0, numViews, viewportOffsets.data());
                }
                if (depthTexture)
                {
                    glFramebufferTextureMultiviewSideBySideANGLE(
                        target, GL_DEPTH_ATTACHMENT, depthTexture, 0, numViews, viewportOffsets.data());
                }
                if (depthStencilTexture)
                {
                    glFramebufferTextureMultiviewSideBySideANGLE(target, GL_DEPTH_STENCIL_ATTACHMENT,
                                                                 depthStencilTexture, 0, numViews,
                                                                 viewportOffsets.data());
                }
                break;
            }
            case GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE:
                for (size_t i = 0; i < colorTextures.size(); ++i)
                {
                    GLenum attachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i);
                    glFramebufferTextureMultiviewLayeredANGLE(target, attachment, colorTextures[i], 0,
                                                              baseViewIndex, numViews);
                }
                if (depthTexture)
                {
                    glFramebufferTextureMultiviewLayeredANGLE(target, GL_DEPTH_ATTACHMENT, depthTexture,
                                                              0, baseViewIndex, numViews);
                }
                if (depthStencilTexture)
                {
                    glFramebufferTextureMultiviewLayeredANGLE(target, GL_DEPTH_STENCIL_ATTACHMENT,
                                                              depthStencilTexture, 0, baseViewIndex,
                                                              numViews);
                }
                break;
            default:
                UNREACHABLE();
        }
    }
    
    void AttachMultiviewTextures(GLenum target,
                                 GLenum multiviewLayout,
                                 int viewWidth,
                                 int numViews,
                                 int baseViewIndex,
                                 GLuint colorTexture,
                                 GLuint depthTexture,
                                 GLuint depthStencilTexture)
    {
        ASSERT(colorTexture != 0u);
        std::vector<GLuint> colorTextures(1, colorTexture);
        AttachMultiviewTextures(target, multiviewLayout, viewWidth, numViews, baseViewIndex,
                                colorTextures, depthTexture, depthStencilTexture);
    }
    
    std::ostream &operator<<(std::ostream &os, const MultiviewImplementationParams &params)
    {
        const PlatformParameters &base = static_cast<const PlatformParameters &>(params);
        os << base;
        if (params.mForceUseGeometryShaderOnD3D)
        {
            os << "_force_geom_shader";
        }
        else
        {
            os << "_vertex_shader";
        }
        return os;
    }
    
    MultiviewImplementationParams VertexShaderOpenGL(GLint majorVersion, GLint minorVersion)
    {
        return MultiviewImplementationParams(majorVersion, minorVersion, false, egl_platform::OPENGL());
    }
    
    MultiviewImplementationParams VertexShaderD3D11(GLint majorVersion, GLint minorVersion)
    {
        return MultiviewImplementationParams(majorVersion, minorVersion, false, egl_platform::D3D11());
    }
    
    MultiviewImplementationParams GeomShaderD3D11(GLint majorVersion, GLint minorVersion)
    {
        return MultiviewImplementationParams(majorVersion, minorVersion, true, egl_platform::D3D11());
    }
    
    void MultiviewTest::overrideWorkaroundsD3D(WorkaroundsD3D *workarounds)
    {
        workarounds->selectViewInGeometryShader = GetParam().mForceUseGeometryShaderOnD3D;
    }
    
    }  // namespace angle