Hash :
48969c95
Author :
Date :
2024-05-31T16:34:07
GL: Implement QCOM_tiled_rendering Bug: angleproject:343900918 Change-Id: I01612e11795d7aa8ee20f6e9bd5ef62fe40e2910 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5588630 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
//
// Copyright 2024 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.
//
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
namespace angle
{
class TiledRenderingTest : public ANGLETest<>
{
protected:
TiledRenderingTest()
{
setWindowWidth(128);
setWindowHeight(128);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
}
};
// Validate that the extension entry points generate errors when the extension is not available.
TEST_P(TiledRenderingTest, ExtensionDisabled)
{
ANGLE_SKIP_TEST_IF(IsGLExtensionEnabled("GL_QCOM_tiled_rendering"));
glStartTilingQCOM(0, 0, 1, 1, GL_COLOR_BUFFER_BIT0_QCOM);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
glEndTilingQCOM(GL_COLOR_BUFFER_BIT0_QCOM);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
// Test that tiled rendering can be stared and stopped. Verify that only pixels in bounds are
// written.
TEST_P(TiledRenderingTest, BasicUsage)
{
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_tiled_rendering"));
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Blue());
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glStartTilingQCOM(10, 12, 15, 17, GL_COLOR_BUFFER_BIT0_QCOM);
drawQuad(program, essl1_shaders::PositionAttrib(), 0);
glEndTilingQCOM(GL_COLOR_BUFFER_BIT0_QCOM);
const int w = getWindowWidth();
const int h = getWindowHeight();
EXPECT_PIXEL_RECT_EQ(10, 12, 15, 17, GLColor::blue);
EXPECT_PIXEL_RECT_EQ(0, 0, w, 12, GLColor::transparentBlack);
EXPECT_PIXEL_RECT_EQ(0, 12 + 17, w, h - 12 - 17, GLColor::transparentBlack);
EXPECT_PIXEL_RECT_EQ(0, 0, 10, h, GLColor::transparentBlack);
EXPECT_PIXEL_RECT_EQ(10 + 15, 0, w - 10 - 15, h, GLColor::transparentBlack);
}
// Test that changing the framebuffer implicitly ends tiled rendering.
TEST_P(TiledRenderingTest, ImplicitEnd)
{
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_tiled_rendering"));
GLTexture tex1;
glBindTexture(GL_TEXTURE_2D, tex1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
GLFramebuffer fbo1;
glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex1, 0);
GLTexture tex2;
glBindTexture(GL_TEXTURE_2D, tex2);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
GLFramebuffer fbo2;
glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2, 0);
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Blue());
glClearColor(0, 0, 0, 0);
glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
glClear(GL_COLOR_BUFFER_BIT);
glStartTilingQCOM(0, 0, 8, 8, GL_COLOR_BUFFER_BIT0_QCOM);
EXPECT_GL_NO_ERROR();
drawQuad(program, essl1_shaders::PositionAttrib(), 0);
// Switch framebuffer bindings. Tiling is implicitly ended and start can be called again without
// errors.
glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
glClear(GL_COLOR_BUFFER_BIT);
glStartTilingQCOM(8, 8, 8, 8, GL_COLOR_BUFFER_BIT0_QCOM);
EXPECT_GL_NO_ERROR();
drawQuad(program, essl1_shaders::PositionAttrib(), 0);
glEndTilingQCOM(GL_COLOR_BUFFER_BIT0_QCOM);
// Test that the correct tiling regions were used
glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
EXPECT_PIXEL_COLOR_EQ(4, 4, GLColor::blue);
glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
EXPECT_PIXEL_COLOR_EQ(12, 12, GLColor::blue);
// Qualcomm drivers do not implicitly end tiling when changing the texture bound to the
// framebuffer so ANGLE inherits this behaviour. Validate that tiling is not ended.
glBindTexture(GL_TEXTURE_2D, tex1);
glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
glClear(GL_COLOR_BUFFER_BIT);
glStartTilingQCOM(4, 4, 4, 4, GL_COLOR_BUFFER_BIT0_QCOM);
EXPECT_GL_NO_ERROR();
drawQuad(program, essl1_shaders::PositionAttrib(), 0);
// Redefine to 8x8 with red data
std::vector<GLColor> redData(8 * 8, GLColor::red);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, redData.data());
// If tiling is still continuing from before, should only draw to [4, 4] to (8, 8)
drawQuad(program, essl1_shaders::PositionAttrib(), 0);
glStartTilingQCOM(4, 4, 4, 4, GL_COLOR_BUFFER_BIT0_QCOM);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
glEndTilingQCOM(GL_COLOR_BUFFER_BIT0_QCOM);
EXPECT_GL_NO_ERROR();
EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::red);
EXPECT_PIXEL_RECT_EQ(4, 4, 4, 4, GLColor::blue);
}
// Test that the only written areas are the intersection of scissor and tiled rendering area
TEST_P(TiledRenderingTest, Scissor)
{
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_tiled_rendering"));
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Blue());
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_SCISSOR_TEST);
glScissor(0, 0, 12, 12);
glStartTilingQCOM(8, 8, 8, 8, GL_COLOR_BUFFER_BIT0_QCOM);
// Scissor and tile intersect from [8, 8] to [12, 12]
drawQuad(program, essl1_shaders::PositionAttrib(), 0);
glEndTilingQCOM(GL_COLOR_BUFFER_BIT0_QCOM);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
EXPECT_PIXEL_COLOR_EQ(6, 6, GLColor::transparentBlack);
EXPECT_PIXEL_RECT_EQ(8, 8, 4, 4, GLColor::blue);
EXPECT_PIXEL_COLOR_EQ(14, 14, GLColor::transparentBlack);
EXPECT_PIXEL_COLOR_EQ(18, 18, GLColor::transparentBlack);
}
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(TiledRenderingTest);
} // namespace angle