Hash :
89c88559
Author :
Date :
2020-06-20T11:13:57
Add end2end test for readonly feedbackloop Bug: angleproject:4778 Test: ./angle_end2end_tests --gtest_filter=ReadOnlyFeedbackLoopTest* Change-Id: I1c2500395d261c1686e5d325aad173462311c8c3 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2252543 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Mohan Maiya <m.maiya@samsung.com>
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
//
// Copyright 2020 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.
//
// Test that invokes a usecase where there is a feedback loop but the framebuffer
// depth attachment is only read from
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
using namespace angle;
class ReadOnlyFeedbackLoopTest : public ANGLETest
{
protected:
ReadOnlyFeedbackLoopTest()
{
setWindowWidth(256);
setWindowHeight(256);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
}
void testSetUp() override
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepthf(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthRangef(-1.0f, 1.0f);
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
ASSERT_GL_NO_ERROR();
}
};
// Fill out a depth texture to specific values and use it both as a sampler and a depth texture
// with depth write disabled. This is to test a "read-only feedback loop" that needs to be
// supported to match industry standard.
TEST_P(ReadOnlyFeedbackLoopTest, DepthFeedbackLoop)
{
// TODO - Add support for readonly feedback loops (http://anglebug.com/4778)
ANGLE_SKIP_TEST_IF(true);
const GLuint width = getWindowWidth();
const GLuint height = getWindowHeight();
GLTexture colorTex;
GLTexture depthTex;
GLTexture finalTex;
GLFramebuffer gbufferFbo;
GLFramebuffer finalFbo;
ANGLE_GL_PROGRAM(colorFillProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
ANGLE_GL_PROGRAM(textureFillProgram, essl1_shaders::vs::Texture2D(),
essl1_shaders::fs::Texture2D());
glBindTexture(GL_TEXTURE_2D, colorTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
EXPECT_GL_NO_ERROR();
glBindTexture(GL_TEXTURE_2D, depthTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT,
GL_UNSIGNED_INT, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
EXPECT_GL_NO_ERROR();
glBindFramebuffer(GL_FRAMEBUFFER, gbufferFbo);
EXPECT_GL_NO_ERROR();
// Attach a color and depth texture to the FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
EXPECT_GL_NO_ERROR();
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTex, 0);
EXPECT_GL_NO_ERROR();
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
// Set the color texture to blue and depth texture to 1.0f
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
glClearDepthf(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
ASSERT_GL_NO_ERROR();
// Enable Depth test with passing always to write depth.
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDepthFunc(GL_ALWAYS);
// Fill the middle of the depth texture with 0.0f. while the border remains 1.0f as
// previously cleared.
const GLfloat depthValue = 0.0f;
drawQuad(colorFillProgram, essl1_shaders::PositionAttrib(), depthValue, 0.6f);
EXPECT_GL_NO_ERROR();
glBindTexture(GL_TEXTURE_2D, finalTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
EXPECT_GL_NO_ERROR();
glBindFramebuffer(GL_FRAMEBUFFER, finalFbo);
EXPECT_GL_NO_ERROR();
// Enable Depth test without depth write.
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glDepthFunc(GL_GREATER);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, finalTex, 0);
EXPECT_GL_NO_ERROR();
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTex, 0);
EXPECT_GL_NO_ERROR();
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, depthTex);
// Fill finalTex with values read from depthTex. This should work even though depthTex
// is also bound as the depth attachment, because depth write is disabled.
// The write to finalTex only succeeds for the middle region due to depth test.
drawQuad(textureFillProgram, essl1_shaders::PositionAttrib(), 0.7f, 1.0f);
// Copy finalTex to default framebuffer for verification. Depth values written in the first
// draw call are expected in the middle, while the clear value in the clear before the
// second draw call are expected at the border.
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glBindTexture(GL_TEXTURE_2D, finalTex);
drawQuad(textureFillProgram, essl1_shaders::PositionAttrib(), 0.0f, 1.0f);
EXPECT_GL_NO_ERROR();
GLint depthColorValue = (depthValue)*128 + 128;
EXPECT_EQ(depthColorValue, angle::ReadColor(width / 2, height / 2).R);
EXPECT_PIXEL_EQ(0, 0, 0, 0, 255, 255);
}
// Instantiate the test for ES2 and ES3.
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ReadOnlyFeedbackLoopTest);