Edit

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

Branch :

  • Show log

    Commit

  • Author : Shahbaz Youssefi
    Date : 2021-06-15 17:37:45
    Hash : 5b314268
    Message : Vulkan: Support OVR_multiview and OVR_multiview2 Multiview is supported in Vulkan simply by specifying the number of views in the render pass, and creating the appropriate image views. A number of changes to the way image views and render targets are stored are made to support those that don't cover the entire range of layers. One particular detail that is not implemented in this change is the use of queries in combination with multiview. Vulkan specifies that N queries are actually produced (N being the number of views) which must be summed by the application, but this is not currently done. Bug: angleproject:6048 Change-Id: I1d4a9894c232d3a93d7a97c9fa0eedc334e57469 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2967625 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Charlie Lao <cclao@google.com>

  • 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/FeaturesD3D.h"
    #include "test_utils/gl_raii.h"
    
    namespace angle
    {
    
    GLuint CreateSimplePassthroughProgram(int numViews, ExtensionName multiviewExtension)
    {
        std::string ext;
        switch (multiviewExtension)
        {
            case multiview:
                ext = "GL_OVR_multiview";
                break;
            case multiview2:
                ext = "GL_OVR_multiview2";
                break;
            default:
                // Unknown extension.
                break;
        }
    
        const std::string vsSource =
            "#version 300 es\n"
            "#extension " +
            ext +
            " : 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";
    
        const std::string fsSource =
            "#version 300 es\n"
            "#extension " +
            ext +
            " : 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(), fsSource.c_str());
    }
    
    void CreateMultiviewBackingTextures(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);
    
        // 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.
        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);
        ASSERT_GL_NO_ERROR();
    
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, restoreDrawFramebuffer);
    }
    
    void CreateMultiviewBackingTextures(int samples,
                                        int viewWidth,
                                        int height,
                                        int numLayers,
                                        GLuint colorTexture,
                                        GLuint depthTexture,
                                        GLuint depthStencilTexture)
    {
        ASSERT_TRUE(colorTexture != 0u);
        std::vector<GLuint> colorTextures(1, colorTexture);
        CreateMultiviewBackingTextures(samples, viewWidth, height, numLayers, colorTextures,
                                       depthTexture, depthStencilTexture);
    }
    
    void AttachMultiviewTextures(GLenum target,
                                 int viewWidth,
                                 int numViews,
                                 int baseViewIndex,
                                 std::vector<GLuint> colorTextures,
                                 GLuint depthTexture,
                                 GLuint depthStencilTexture)
    {
        ASSERT_TRUE(depthTexture == 0u || depthStencilTexture == 0u);
        for (size_t i = 0; i < colorTextures.size(); ++i)
        {
            GLenum attachment = static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i);
            glFramebufferTextureMultiviewOVR(target, attachment, colorTextures[i], 0, baseViewIndex,
                                             numViews);
        }
        if (depthTexture)
        {
            glFramebufferTextureMultiviewOVR(target, GL_DEPTH_ATTACHMENT, depthTexture, 0,
                                             baseViewIndex, numViews);
        }
        if (depthStencilTexture)
        {
            glFramebufferTextureMultiviewOVR(target, GL_DEPTH_STENCIL_ATTACHMENT, depthStencilTexture,
                                             0, baseViewIndex, numViews);
        }
    }
    
    void AttachMultiviewTextures(GLenum target,
                                 int viewWidth,
                                 int numViews,
                                 int baseViewIndex,
                                 GLuint colorTexture,
                                 GLuint depthTexture,
                                 GLuint depthStencilTexture)
    {
        ASSERT_TRUE(colorTexture != 0u);
        std::vector<GLuint> colorTextures(1, colorTexture);
        AttachMultiviewTextures(target, 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";
        }
        if (params.mMultiviewExtension)
        {
            os << "_multiview";
        }
        else
        {
            os << "_multiview2";
        }
        return os;
    }
    
    MultiviewImplementationParams VertexShaderOpenGL(GLint majorVersion,
                                                     GLint minorVersion,
                                                     ExtensionName multiviewExtension)
    {
        return MultiviewImplementationParams(majorVersion, minorVersion, false, egl_platform::OPENGL(),
                                             multiviewExtension);
    }
    
    MultiviewImplementationParams VertexShaderVulkan(GLint majorVersion,
                                                     GLint minorVersion,
                                                     ExtensionName multiviewExtension)
    {
        return MultiviewImplementationParams(majorVersion, minorVersion, false, egl_platform::VULKAN(),
                                             multiviewExtension);
    }
    
    MultiviewImplementationParams VertexShaderD3D11(GLint majorVersion,
                                                    GLint minorVersion,
                                                    ExtensionName multiviewExtension)
    {
        return MultiviewImplementationParams(majorVersion, minorVersion, false, egl_platform::D3D11(),
                                             multiviewExtension);
    }
    
    MultiviewImplementationParams GeomShaderD3D11(GLint majorVersion,
                                                  GLint minorVersion,
                                                  ExtensionName multiviewExtension)
    {
        return MultiviewImplementationParams(majorVersion, minorVersion, true, egl_platform::D3D11(),
                                             multiviewExtension);
    }
    
    void MultiviewTest::overrideWorkaroundsD3D(FeaturesD3D *features)
    {
        features->overrideFeatures({"select_view_in_geometry_shader"},
                                   GetParam().mForceUseGeometryShaderOnD3D);
    }
    
    }  // namespace angle