xref: /aosp_15_r20/external/angle/src/tests/gl_tests/MultiviewDrawTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2017 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // Multiview draw tests:
7*8975f5c5SAndroid Build Coastguard Worker // Test issuing multiview Draw* commands.
8*8975f5c5SAndroid Build Coastguard Worker //
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #include "platform/autogen/FeaturesD3D_autogen.h"
11*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/MultiviewTest.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
13*8975f5c5SAndroid Build Coastguard Worker 
14*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
15*8975f5c5SAndroid Build Coastguard Worker 
16*8975f5c5SAndroid Build Coastguard Worker namespace
17*8975f5c5SAndroid Build Coastguard Worker {
18*8975f5c5SAndroid Build Coastguard Worker 
ConvertPixelCoordinatesToClipSpace(const std::vector<Vector2I> & pixels,int width,int height)19*8975f5c5SAndroid Build Coastguard Worker std::vector<Vector2> ConvertPixelCoordinatesToClipSpace(const std::vector<Vector2I> &pixels,
20*8975f5c5SAndroid Build Coastguard Worker                                                         int width,
21*8975f5c5SAndroid Build Coastguard Worker                                                         int height)
22*8975f5c5SAndroid Build Coastguard Worker {
23*8975f5c5SAndroid Build Coastguard Worker     std::vector<Vector2> result(pixels.size());
24*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < pixels.size(); ++i)
25*8975f5c5SAndroid Build Coastguard Worker     {
26*8975f5c5SAndroid Build Coastguard Worker         const auto &pixel          = pixels[i];
27*8975f5c5SAndroid Build Coastguard Worker         float pixelCenterRelativeX = (static_cast<float>(pixel.x()) + .5f) / width;
28*8975f5c5SAndroid Build Coastguard Worker         float pixelCenterRelativeY = (static_cast<float>(pixel.y()) + .5f) / height;
29*8975f5c5SAndroid Build Coastguard Worker         float xInClipSpace         = 2.f * pixelCenterRelativeX - 1.f;
30*8975f5c5SAndroid Build Coastguard Worker         float yInClipSpace         = 2.f * pixelCenterRelativeY - 1.f;
31*8975f5c5SAndroid Build Coastguard Worker         result[i]                  = Vector2(xInClipSpace, yInClipSpace);
32*8975f5c5SAndroid Build Coastguard Worker     }
33*8975f5c5SAndroid Build Coastguard Worker     return result;
34*8975f5c5SAndroid Build Coastguard Worker }
35*8975f5c5SAndroid Build Coastguard Worker }  // namespace
36*8975f5c5SAndroid Build Coastguard Worker 
37*8975f5c5SAndroid Build Coastguard Worker struct MultiviewRenderTestParams final : public MultiviewImplementationParams
38*8975f5c5SAndroid Build Coastguard Worker {
MultiviewRenderTestParamsMultiviewRenderTestParams39*8975f5c5SAndroid Build Coastguard Worker     MultiviewRenderTestParams(int samples,
40*8975f5c5SAndroid Build Coastguard Worker                               const MultiviewImplementationParams &implementationParams)
41*8975f5c5SAndroid Build Coastguard Worker         : MultiviewImplementationParams(implementationParams), mSamples(samples)
42*8975f5c5SAndroid Build Coastguard Worker     {}
43*8975f5c5SAndroid Build Coastguard Worker     int mSamples;
44*8975f5c5SAndroid Build Coastguard Worker };
45*8975f5c5SAndroid Build Coastguard Worker 
operator <<(std::ostream & os,const MultiviewRenderTestParams & params)46*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, const MultiviewRenderTestParams &params)
47*8975f5c5SAndroid Build Coastguard Worker {
48*8975f5c5SAndroid Build Coastguard Worker     const MultiviewImplementationParams &base =
49*8975f5c5SAndroid Build Coastguard Worker         static_cast<const MultiviewImplementationParams &>(params);
50*8975f5c5SAndroid Build Coastguard Worker     os << base;
51*8975f5c5SAndroid Build Coastguard Worker     os << "_layered";
52*8975f5c5SAndroid Build Coastguard Worker 
53*8975f5c5SAndroid Build Coastguard Worker     if (params.mSamples > 0)
54*8975f5c5SAndroid Build Coastguard Worker     {
55*8975f5c5SAndroid Build Coastguard Worker         os << "_samples_" << params.mSamples;
56*8975f5c5SAndroid Build Coastguard Worker     }
57*8975f5c5SAndroid Build Coastguard Worker     return os;
58*8975f5c5SAndroid Build Coastguard Worker }
59*8975f5c5SAndroid Build Coastguard Worker 
60*8975f5c5SAndroid Build Coastguard Worker class MultiviewFramebufferTestBase : public MultiviewTestBase,
61*8975f5c5SAndroid Build Coastguard Worker                                      public ::testing::TestWithParam<MultiviewRenderTestParams>
62*8975f5c5SAndroid Build Coastguard Worker {
63*8975f5c5SAndroid Build Coastguard Worker   protected:
MultiviewFramebufferTestBase(const PlatformParameters & params,int samples)64*8975f5c5SAndroid Build Coastguard Worker     MultiviewFramebufferTestBase(const PlatformParameters &params, int samples)
65*8975f5c5SAndroid Build Coastguard Worker         : MultiviewTestBase(params),
66*8975f5c5SAndroid Build Coastguard Worker           mViewWidth(0),
67*8975f5c5SAndroid Build Coastguard Worker           mViewHeight(0),
68*8975f5c5SAndroid Build Coastguard Worker           mNumViews(0),
69*8975f5c5SAndroid Build Coastguard Worker           mColorTexture(0u),
70*8975f5c5SAndroid Build Coastguard Worker           mDepthTexture(0u),
71*8975f5c5SAndroid Build Coastguard Worker           mDrawFramebuffer(0u),
72*8975f5c5SAndroid Build Coastguard Worker           mSamples(samples),
73*8975f5c5SAndroid Build Coastguard Worker           mResolveTexture(0u)
74*8975f5c5SAndroid Build Coastguard Worker     {}
75*8975f5c5SAndroid Build Coastguard Worker 
FramebufferTestSetUp()76*8975f5c5SAndroid Build Coastguard Worker     void FramebufferTestSetUp() { MultiviewTestBase::MultiviewTestBaseSetUp(); }
77*8975f5c5SAndroid Build Coastguard Worker 
FramebufferTestTearDown()78*8975f5c5SAndroid Build Coastguard Worker     void FramebufferTestTearDown()
79*8975f5c5SAndroid Build Coastguard Worker     {
80*8975f5c5SAndroid Build Coastguard Worker         freeFBOs();
81*8975f5c5SAndroid Build Coastguard Worker         MultiviewTestBase::MultiviewTestBaseTearDown();
82*8975f5c5SAndroid Build Coastguard Worker     }
83*8975f5c5SAndroid Build Coastguard Worker 
updateFBOs(int viewWidth,int height,int numViews,int numLayers,int baseViewIndex)84*8975f5c5SAndroid Build Coastguard Worker     void updateFBOs(int viewWidth, int height, int numViews, int numLayers, int baseViewIndex)
85*8975f5c5SAndroid Build Coastguard Worker     {
86*8975f5c5SAndroid Build Coastguard Worker         ASSERT_TRUE(numViews + baseViewIndex <= numLayers);
87*8975f5c5SAndroid Build Coastguard Worker 
88*8975f5c5SAndroid Build Coastguard Worker         freeFBOs();
89*8975f5c5SAndroid Build Coastguard Worker 
90*8975f5c5SAndroid Build Coastguard Worker         mViewWidth  = viewWidth;
91*8975f5c5SAndroid Build Coastguard Worker         mViewHeight = height;
92*8975f5c5SAndroid Build Coastguard Worker         mNumViews   = numViews;
93*8975f5c5SAndroid Build Coastguard Worker 
94*8975f5c5SAndroid Build Coastguard Worker         glGenTextures(1, &mColorTexture);
95*8975f5c5SAndroid Build Coastguard Worker         glGenTextures(1, &mDepthTexture);
96*8975f5c5SAndroid Build Coastguard Worker 
97*8975f5c5SAndroid Build Coastguard Worker         CreateMultiviewBackingTextures(mSamples, viewWidth, height, numLayers, mColorTexture,
98*8975f5c5SAndroid Build Coastguard Worker                                        mDepthTexture, 0u);
99*8975f5c5SAndroid Build Coastguard Worker 
100*8975f5c5SAndroid Build Coastguard Worker         glGenFramebuffers(1, &mDrawFramebuffer);
101*8975f5c5SAndroid Build Coastguard Worker 
102*8975f5c5SAndroid Build Coastguard Worker         // Create draw framebuffer to be used for multiview rendering.
103*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mDrawFramebuffer);
104*8975f5c5SAndroid Build Coastguard Worker         AttachMultiviewTextures(GL_DRAW_FRAMEBUFFER, viewWidth, numViews, baseViewIndex,
105*8975f5c5SAndroid Build Coastguard Worker                                 mColorTexture, mDepthTexture, 0u);
106*8975f5c5SAndroid Build Coastguard Worker 
107*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER));
108*8975f5c5SAndroid Build Coastguard Worker 
109*8975f5c5SAndroid Build Coastguard Worker         // Create read framebuffer to be used to retrieve the pixel information for testing
110*8975f5c5SAndroid Build Coastguard Worker         // purposes.
111*8975f5c5SAndroid Build Coastguard Worker         mReadFramebuffer.resize(numLayers);
112*8975f5c5SAndroid Build Coastguard Worker         glGenFramebuffers(static_cast<GLsizei>(mReadFramebuffer.size()), mReadFramebuffer.data());
113*8975f5c5SAndroid Build Coastguard Worker         for (int i = 0; i < numLayers; ++i)
114*8975f5c5SAndroid Build Coastguard Worker         {
115*8975f5c5SAndroid Build Coastguard Worker             glBindFramebuffer(GL_READ_FRAMEBUFFER, mReadFramebuffer[i]);
116*8975f5c5SAndroid Build Coastguard Worker             glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mColorTexture, 0,
117*8975f5c5SAndroid Build Coastguard Worker                                       i);
118*8975f5c5SAndroid Build Coastguard Worker             ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE,
119*8975f5c5SAndroid Build Coastguard Worker                              glCheckFramebufferStatus(GL_READ_FRAMEBUFFER));
120*8975f5c5SAndroid Build Coastguard Worker         }
121*8975f5c5SAndroid Build Coastguard Worker 
122*8975f5c5SAndroid Build Coastguard Worker         // Clear the buffers.
123*8975f5c5SAndroid Build Coastguard Worker         glViewport(0, 0, viewWidth, height);
124*8975f5c5SAndroid Build Coastguard Worker     }
125*8975f5c5SAndroid Build Coastguard Worker 
updateFBOs(int viewWidth,int height,int numViews)126*8975f5c5SAndroid Build Coastguard Worker     void updateFBOs(int viewWidth, int height, int numViews)
127*8975f5c5SAndroid Build Coastguard Worker     {
128*8975f5c5SAndroid Build Coastguard Worker         updateFBOs(viewWidth, height, numViews, numViews, 0);
129*8975f5c5SAndroid Build Coastguard Worker     }
130*8975f5c5SAndroid Build Coastguard Worker 
bindMemberDrawFramebuffer()131*8975f5c5SAndroid Build Coastguard Worker     void bindMemberDrawFramebuffer() { glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mDrawFramebuffer); }
132*8975f5c5SAndroid Build Coastguard Worker 
133*8975f5c5SAndroid Build Coastguard Worker     // In case we have a multisampled framebuffer, creates and binds a resolve framebuffer as the
134*8975f5c5SAndroid Build Coastguard Worker     // draw framebuffer, and resolves the read framebuffer to it.
resolveMultisampledFBO()135*8975f5c5SAndroid Build Coastguard Worker     void resolveMultisampledFBO()
136*8975f5c5SAndroid Build Coastguard Worker     {
137*8975f5c5SAndroid Build Coastguard Worker         if (mSamples == 0)
138*8975f5c5SAndroid Build Coastguard Worker         {
139*8975f5c5SAndroid Build Coastguard Worker             return;
140*8975f5c5SAndroid Build Coastguard Worker         }
141*8975f5c5SAndroid Build Coastguard Worker         int numLayers = mReadFramebuffer.size();
142*8975f5c5SAndroid Build Coastguard Worker         if (mResolveFramebuffer.empty())
143*8975f5c5SAndroid Build Coastguard Worker         {
144*8975f5c5SAndroid Build Coastguard Worker             ASSERT_TRUE(mResolveTexture == 0u);
145*8975f5c5SAndroid Build Coastguard Worker             glGenTextures(1, &mResolveTexture);
146*8975f5c5SAndroid Build Coastguard Worker             CreateMultiviewBackingTextures(0, mViewWidth, mViewHeight, numLayers, mResolveTexture,
147*8975f5c5SAndroid Build Coastguard Worker                                            0u, 0u);
148*8975f5c5SAndroid Build Coastguard Worker 
149*8975f5c5SAndroid Build Coastguard Worker             mResolveFramebuffer.resize(numLayers);
150*8975f5c5SAndroid Build Coastguard Worker             glGenFramebuffers(static_cast<GLsizei>(mResolveFramebuffer.size()),
151*8975f5c5SAndroid Build Coastguard Worker                               mResolveFramebuffer.data());
152*8975f5c5SAndroid Build Coastguard Worker             for (int i = 0; i < numLayers; ++i)
153*8975f5c5SAndroid Build Coastguard Worker             {
154*8975f5c5SAndroid Build Coastguard Worker                 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mResolveFramebuffer[i]);
155*8975f5c5SAndroid Build Coastguard Worker                 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
156*8975f5c5SAndroid Build Coastguard Worker                                           mResolveTexture, 0, i);
157*8975f5c5SAndroid Build Coastguard Worker                 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE,
158*8975f5c5SAndroid Build Coastguard Worker                                  glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER));
159*8975f5c5SAndroid Build Coastguard Worker             }
160*8975f5c5SAndroid Build Coastguard Worker         }
161*8975f5c5SAndroid Build Coastguard Worker         for (int i = 0; i < numLayers; ++i)
162*8975f5c5SAndroid Build Coastguard Worker         {
163*8975f5c5SAndroid Build Coastguard Worker             glBindFramebuffer(GL_READ_FRAMEBUFFER, mReadFramebuffer[i]);
164*8975f5c5SAndroid Build Coastguard Worker             glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mResolveFramebuffer[i]);
165*8975f5c5SAndroid Build Coastguard Worker             glBlitFramebuffer(0, 0, mViewWidth, mViewHeight, 0, 0, mViewWidth, mViewHeight,
166*8975f5c5SAndroid Build Coastguard Worker                               GL_COLOR_BUFFER_BIT, GL_NEAREST);
167*8975f5c5SAndroid Build Coastguard Worker         }
168*8975f5c5SAndroid Build Coastguard Worker     }
169*8975f5c5SAndroid Build Coastguard Worker 
GetViewColor(int x,int y,int view)170*8975f5c5SAndroid Build Coastguard Worker     GLColor GetViewColor(int x, int y, int view)
171*8975f5c5SAndroid Build Coastguard Worker     {
172*8975f5c5SAndroid Build Coastguard Worker         EXPECT_TRUE(static_cast<size_t>(view) < mReadFramebuffer.size());
173*8975f5c5SAndroid Build Coastguard Worker         if (mSamples > 0)
174*8975f5c5SAndroid Build Coastguard Worker         {
175*8975f5c5SAndroid Build Coastguard Worker             EXPECT_TRUE(static_cast<size_t>(view) < mResolveFramebuffer.size());
176*8975f5c5SAndroid Build Coastguard Worker             glBindFramebuffer(GL_READ_FRAMEBUFFER, mResolveFramebuffer[view]);
177*8975f5c5SAndroid Build Coastguard Worker         }
178*8975f5c5SAndroid Build Coastguard Worker         else
179*8975f5c5SAndroid Build Coastguard Worker         {
180*8975f5c5SAndroid Build Coastguard Worker             glBindFramebuffer(GL_READ_FRAMEBUFFER, mReadFramebuffer[view]);
181*8975f5c5SAndroid Build Coastguard Worker         }
182*8975f5c5SAndroid Build Coastguard Worker         return ReadColor(x, y);
183*8975f5c5SAndroid Build Coastguard Worker     }
184*8975f5c5SAndroid Build Coastguard Worker 
185*8975f5c5SAndroid Build Coastguard Worker     // Requests the OVR_multiview(2) extension and returns true if the operation succeeds.
requestMultiviewExtension(bool requireMultiviewMultisample)186*8975f5c5SAndroid Build Coastguard Worker     bool requestMultiviewExtension(bool requireMultiviewMultisample)
187*8975f5c5SAndroid Build Coastguard Worker     {
188*8975f5c5SAndroid Build Coastguard Worker         if (!EnsureGLExtensionEnabled(extensionName()))
189*8975f5c5SAndroid Build Coastguard Worker         {
190*8975f5c5SAndroid Build Coastguard Worker             std::cout << "Test skipped due to missing " << extensionName() << "." << std::endl;
191*8975f5c5SAndroid Build Coastguard Worker             return false;
192*8975f5c5SAndroid Build Coastguard Worker         }
193*8975f5c5SAndroid Build Coastguard Worker 
194*8975f5c5SAndroid Build Coastguard Worker         if (requireMultiviewMultisample)
195*8975f5c5SAndroid Build Coastguard Worker         {
196*8975f5c5SAndroid Build Coastguard Worker             if (!EnsureGLExtensionEnabled("GL_OES_texture_storage_multisample_2d_array"))
197*8975f5c5SAndroid Build Coastguard Worker             {
198*8975f5c5SAndroid Build Coastguard Worker                 std::cout << "Test skipped due to missing GL_ANGLE_multiview_multisample."
199*8975f5c5SAndroid Build Coastguard Worker                           << std::endl;
200*8975f5c5SAndroid Build Coastguard Worker                 return false;
201*8975f5c5SAndroid Build Coastguard Worker             }
202*8975f5c5SAndroid Build Coastguard Worker 
203*8975f5c5SAndroid Build Coastguard Worker             if (!EnsureGLExtensionEnabled("GL_ANGLE_multiview_multisample"))
204*8975f5c5SAndroid Build Coastguard Worker             {
205*8975f5c5SAndroid Build Coastguard Worker                 std::cout << "Test skipped due to missing GL_ANGLE_multiview_multisample."
206*8975f5c5SAndroid Build Coastguard Worker                           << std::endl;
207*8975f5c5SAndroid Build Coastguard Worker                 return false;
208*8975f5c5SAndroid Build Coastguard Worker             }
209*8975f5c5SAndroid Build Coastguard Worker         }
210*8975f5c5SAndroid Build Coastguard Worker         return true;
211*8975f5c5SAndroid Build Coastguard Worker     }
212*8975f5c5SAndroid Build Coastguard Worker 
requestMultiviewExtension()213*8975f5c5SAndroid Build Coastguard Worker     bool requestMultiviewExtension() { return requestMultiviewExtension(false); }
extensionName()214*8975f5c5SAndroid Build Coastguard Worker     std::string extensionName()
215*8975f5c5SAndroid Build Coastguard Worker     {
216*8975f5c5SAndroid Build Coastguard Worker         switch (GetParam().mMultiviewExtension)
217*8975f5c5SAndroid Build Coastguard Worker         {
218*8975f5c5SAndroid Build Coastguard Worker             case multiview:
219*8975f5c5SAndroid Build Coastguard Worker                 return "GL_OVR_multiview";
220*8975f5c5SAndroid Build Coastguard Worker             case multiview2:
221*8975f5c5SAndroid Build Coastguard Worker                 return "GL_OVR_multiview2";
222*8975f5c5SAndroid Build Coastguard Worker             default:
223*8975f5c5SAndroid Build Coastguard Worker                 // Ignore unknown.
224*8975f5c5SAndroid Build Coastguard Worker                 return "";
225*8975f5c5SAndroid Build Coastguard Worker         }
226*8975f5c5SAndroid Build Coastguard Worker     }
227*8975f5c5SAndroid Build Coastguard Worker 
isMultisampled()228*8975f5c5SAndroid Build Coastguard Worker     bool isMultisampled() { return mSamples > 0; }
229*8975f5c5SAndroid Build Coastguard Worker 
230*8975f5c5SAndroid Build Coastguard Worker     int mViewWidth;
231*8975f5c5SAndroid Build Coastguard Worker     int mViewHeight;
232*8975f5c5SAndroid Build Coastguard Worker     int mNumViews;
233*8975f5c5SAndroid Build Coastguard Worker 
234*8975f5c5SAndroid Build Coastguard Worker     GLuint mColorTexture;
235*8975f5c5SAndroid Build Coastguard Worker     GLuint mDepthTexture;
236*8975f5c5SAndroid Build Coastguard Worker 
237*8975f5c5SAndroid Build Coastguard Worker   private:
238*8975f5c5SAndroid Build Coastguard Worker     GLuint mDrawFramebuffer;
239*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLuint> mReadFramebuffer;
240*8975f5c5SAndroid Build Coastguard Worker     int mSamples;
241*8975f5c5SAndroid Build Coastguard Worker 
242*8975f5c5SAndroid Build Coastguard Worker     // For reading back multisampled framebuffer.
243*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLuint> mResolveFramebuffer;
244*8975f5c5SAndroid Build Coastguard Worker     GLuint mResolveTexture;
245*8975f5c5SAndroid Build Coastguard Worker 
freeFBOs()246*8975f5c5SAndroid Build Coastguard Worker     void freeFBOs()
247*8975f5c5SAndroid Build Coastguard Worker     {
248*8975f5c5SAndroid Build Coastguard Worker         if (mDrawFramebuffer)
249*8975f5c5SAndroid Build Coastguard Worker         {
250*8975f5c5SAndroid Build Coastguard Worker             glDeleteFramebuffers(1, &mDrawFramebuffer);
251*8975f5c5SAndroid Build Coastguard Worker             mDrawFramebuffer = 0;
252*8975f5c5SAndroid Build Coastguard Worker         }
253*8975f5c5SAndroid Build Coastguard Worker         if (!mReadFramebuffer.empty())
254*8975f5c5SAndroid Build Coastguard Worker         {
255*8975f5c5SAndroid Build Coastguard Worker             GLsizei framebufferCount = static_cast<GLsizei>(mReadFramebuffer.size());
256*8975f5c5SAndroid Build Coastguard Worker             glDeleteFramebuffers(framebufferCount, mReadFramebuffer.data());
257*8975f5c5SAndroid Build Coastguard Worker             mReadFramebuffer.clear();
258*8975f5c5SAndroid Build Coastguard Worker         }
259*8975f5c5SAndroid Build Coastguard Worker         if (!mResolveFramebuffer.empty())
260*8975f5c5SAndroid Build Coastguard Worker         {
261*8975f5c5SAndroid Build Coastguard Worker             GLsizei framebufferCount = static_cast<GLsizei>(mResolveFramebuffer.size());
262*8975f5c5SAndroid Build Coastguard Worker             glDeleteFramebuffers(framebufferCount, mResolveFramebuffer.data());
263*8975f5c5SAndroid Build Coastguard Worker             mResolveFramebuffer.clear();
264*8975f5c5SAndroid Build Coastguard Worker         }
265*8975f5c5SAndroid Build Coastguard Worker         if (mDepthTexture)
266*8975f5c5SAndroid Build Coastguard Worker         {
267*8975f5c5SAndroid Build Coastguard Worker             glDeleteTextures(1, &mDepthTexture);
268*8975f5c5SAndroid Build Coastguard Worker             mDepthTexture = 0;
269*8975f5c5SAndroid Build Coastguard Worker         }
270*8975f5c5SAndroid Build Coastguard Worker         if (mColorTexture)
271*8975f5c5SAndroid Build Coastguard Worker         {
272*8975f5c5SAndroid Build Coastguard Worker             glDeleteTextures(1, &mColorTexture);
273*8975f5c5SAndroid Build Coastguard Worker             mColorTexture = 0;
274*8975f5c5SAndroid Build Coastguard Worker         }
275*8975f5c5SAndroid Build Coastguard Worker         if (mResolveTexture)
276*8975f5c5SAndroid Build Coastguard Worker         {
277*8975f5c5SAndroid Build Coastguard Worker             glDeleteTextures(1, &mResolveTexture);
278*8975f5c5SAndroid Build Coastguard Worker             mResolveTexture = 0;
279*8975f5c5SAndroid Build Coastguard Worker         }
280*8975f5c5SAndroid Build Coastguard Worker     }
281*8975f5c5SAndroid Build Coastguard Worker };
282*8975f5c5SAndroid Build Coastguard Worker 
283*8975f5c5SAndroid Build Coastguard Worker class MultiviewRenderTest : public MultiviewFramebufferTestBase
284*8975f5c5SAndroid Build Coastguard Worker {
285*8975f5c5SAndroid Build Coastguard Worker   protected:
MultiviewRenderTest()286*8975f5c5SAndroid Build Coastguard Worker     MultiviewRenderTest() : MultiviewFramebufferTestBase(GetParam(), GetParam().mSamples) {}
287*8975f5c5SAndroid Build Coastguard Worker 
testSetUp()288*8975f5c5SAndroid Build Coastguard Worker     virtual void testSetUp() {}
testTearDown()289*8975f5c5SAndroid Build Coastguard Worker     virtual void testTearDown() {}
290*8975f5c5SAndroid Build Coastguard Worker 
291*8975f5c5SAndroid Build Coastguard Worker   private:
SetUp()292*8975f5c5SAndroid Build Coastguard Worker     void SetUp() override
293*8975f5c5SAndroid Build Coastguard Worker     {
294*8975f5c5SAndroid Build Coastguard Worker         MultiviewFramebufferTestBase::FramebufferTestSetUp();
295*8975f5c5SAndroid Build Coastguard Worker         testSetUp();
296*8975f5c5SAndroid Build Coastguard Worker     }
TearDown()297*8975f5c5SAndroid Build Coastguard Worker     void TearDown() override
298*8975f5c5SAndroid Build Coastguard Worker     {
299*8975f5c5SAndroid Build Coastguard Worker         testTearDown();
300*8975f5c5SAndroid Build Coastguard Worker         MultiviewFramebufferTestBase::FramebufferTestTearDown();
301*8975f5c5SAndroid Build Coastguard Worker     }
302*8975f5c5SAndroid Build Coastguard Worker };
303*8975f5c5SAndroid Build Coastguard Worker 
DualViewVS(ExtensionName multiviewExtension)304*8975f5c5SAndroid Build Coastguard Worker std::string DualViewVS(ExtensionName multiviewExtension)
305*8975f5c5SAndroid Build Coastguard Worker {
306*8975f5c5SAndroid Build Coastguard Worker     std::string ext;
307*8975f5c5SAndroid Build Coastguard Worker     switch (multiviewExtension)
308*8975f5c5SAndroid Build Coastguard Worker     {
309*8975f5c5SAndroid Build Coastguard Worker         case multiview:
310*8975f5c5SAndroid Build Coastguard Worker             ext = "GL_OVR_multiview";
311*8975f5c5SAndroid Build Coastguard Worker             break;
312*8975f5c5SAndroid Build Coastguard Worker         case multiview2:
313*8975f5c5SAndroid Build Coastguard Worker             ext = "GL_OVR_multiview2";
314*8975f5c5SAndroid Build Coastguard Worker             break;
315*8975f5c5SAndroid Build Coastguard Worker     }
316*8975f5c5SAndroid Build Coastguard Worker 
317*8975f5c5SAndroid Build Coastguard Worker     std::string dualViewVSSource =
318*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
319*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
320*8975f5c5SAndroid Build Coastguard Worker         ext +
321*8975f5c5SAndroid Build Coastguard Worker         " : require\n"
322*8975f5c5SAndroid Build Coastguard Worker         "layout(num_views = 2) in;\n"
323*8975f5c5SAndroid Build Coastguard Worker         "in vec4 vPosition;\n"
324*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
325*8975f5c5SAndroid Build Coastguard Worker         "{\n"
326*8975f5c5SAndroid Build Coastguard Worker         "   gl_Position.x = (gl_ViewID_OVR == 0u ? vPosition.x * 0.5 + 0.5 : vPosition.x * 0.5 - "
327*8975f5c5SAndroid Build Coastguard Worker         "0.5);\n"
328*8975f5c5SAndroid Build Coastguard Worker         "   gl_Position.yzw = vPosition.yzw;\n"
329*8975f5c5SAndroid Build Coastguard Worker         "}\n";
330*8975f5c5SAndroid Build Coastguard Worker     return dualViewVSSource;
331*8975f5c5SAndroid Build Coastguard Worker }
332*8975f5c5SAndroid Build Coastguard Worker 
DualViewFS(ExtensionName multiviewExtension)333*8975f5c5SAndroid Build Coastguard Worker std::string DualViewFS(ExtensionName multiviewExtension)
334*8975f5c5SAndroid Build Coastguard Worker {
335*8975f5c5SAndroid Build Coastguard Worker     std::string ext;
336*8975f5c5SAndroid Build Coastguard Worker     switch (multiviewExtension)
337*8975f5c5SAndroid Build Coastguard Worker     {
338*8975f5c5SAndroid Build Coastguard Worker         case multiview:
339*8975f5c5SAndroid Build Coastguard Worker             ext = "GL_OVR_multiview";
340*8975f5c5SAndroid Build Coastguard Worker             break;
341*8975f5c5SAndroid Build Coastguard Worker         case multiview2:
342*8975f5c5SAndroid Build Coastguard Worker             ext = "GL_OVR_multiview2";
343*8975f5c5SAndroid Build Coastguard Worker             break;
344*8975f5c5SAndroid Build Coastguard Worker     }
345*8975f5c5SAndroid Build Coastguard Worker 
346*8975f5c5SAndroid Build Coastguard Worker     std::string dualViewFSSource =
347*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
348*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
349*8975f5c5SAndroid Build Coastguard Worker         ext +
350*8975f5c5SAndroid Build Coastguard Worker         " : require\n"
351*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
352*8975f5c5SAndroid Build Coastguard Worker         "out vec4 col;\n"
353*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
354*8975f5c5SAndroid Build Coastguard Worker         "{\n"
355*8975f5c5SAndroid Build Coastguard Worker         "  col = vec4(0,1,0,1);\n"
356*8975f5c5SAndroid Build Coastguard Worker         "}\n";
357*8975f5c5SAndroid Build Coastguard Worker     return dualViewFSSource;
358*8975f5c5SAndroid Build Coastguard Worker }
359*8975f5c5SAndroid Build Coastguard Worker 
360*8975f5c5SAndroid Build Coastguard Worker class MultiviewRenderDualViewTest : public MultiviewRenderTest
361*8975f5c5SAndroid Build Coastguard Worker {
362*8975f5c5SAndroid Build Coastguard Worker   protected:
MultiviewRenderDualViewTest()363*8975f5c5SAndroid Build Coastguard Worker     MultiviewRenderDualViewTest() : mProgram(0u) {}
364*8975f5c5SAndroid Build Coastguard Worker 
testSetUp()365*8975f5c5SAndroid Build Coastguard Worker     void testSetUp() override
366*8975f5c5SAndroid Build Coastguard Worker     {
367*8975f5c5SAndroid Build Coastguard Worker         if (!requestMultiviewExtension(isMultisampled()))
368*8975f5c5SAndroid Build Coastguard Worker         {
369*8975f5c5SAndroid Build Coastguard Worker             return;
370*8975f5c5SAndroid Build Coastguard Worker         }
371*8975f5c5SAndroid Build Coastguard Worker 
372*8975f5c5SAndroid Build Coastguard Worker         updateFBOs(2, 1, 2);
373*8975f5c5SAndroid Build Coastguard Worker         mProgram = CompileProgram(DualViewVS(GetParam().mMultiviewExtension).c_str(),
374*8975f5c5SAndroid Build Coastguard Worker                                   DualViewFS(GetParam().mMultiviewExtension).c_str());
375*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(mProgram, 0u);
376*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(mProgram);
377*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
378*8975f5c5SAndroid Build Coastguard Worker     }
379*8975f5c5SAndroid Build Coastguard Worker 
testTearDown()380*8975f5c5SAndroid Build Coastguard Worker     void testTearDown() override
381*8975f5c5SAndroid Build Coastguard Worker     {
382*8975f5c5SAndroid Build Coastguard Worker         if (mProgram != 0u)
383*8975f5c5SAndroid Build Coastguard Worker         {
384*8975f5c5SAndroid Build Coastguard Worker             glDeleteProgram(mProgram);
385*8975f5c5SAndroid Build Coastguard Worker             mProgram = 0u;
386*8975f5c5SAndroid Build Coastguard Worker         }
387*8975f5c5SAndroid Build Coastguard Worker     }
388*8975f5c5SAndroid Build Coastguard Worker 
checkOutput()389*8975f5c5SAndroid Build Coastguard Worker     void checkOutput()
390*8975f5c5SAndroid Build Coastguard Worker     {
391*8975f5c5SAndroid Build Coastguard Worker         resolveMultisampledFBO();
392*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(GLColor::transparentBlack, GetViewColor(0, 0, 0));
393*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(GLColor::green, GetViewColor(1, 0, 0));
394*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(GLColor::green, GetViewColor(0, 0, 1));
395*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(GLColor::transparentBlack, GetViewColor(1, 0, 1));
396*8975f5c5SAndroid Build Coastguard Worker     }
397*8975f5c5SAndroid Build Coastguard Worker 
398*8975f5c5SAndroid Build Coastguard Worker     GLuint mProgram;
399*8975f5c5SAndroid Build Coastguard Worker };
400*8975f5c5SAndroid Build Coastguard Worker 
401*8975f5c5SAndroid Build Coastguard Worker class MultiviewRenderDualViewTestNoWebGL : public MultiviewRenderDualViewTest
402*8975f5c5SAndroid Build Coastguard Worker {
403*8975f5c5SAndroid Build Coastguard Worker   protected:
MultiviewRenderDualViewTestNoWebGL()404*8975f5c5SAndroid Build Coastguard Worker     MultiviewRenderDualViewTestNoWebGL() { setWebGLCompatibilityEnabled(false); }
405*8975f5c5SAndroid Build Coastguard Worker };
406*8975f5c5SAndroid Build Coastguard Worker 
407*8975f5c5SAndroid Build Coastguard Worker // Base class for tests that care mostly about draw call validity and not rendering results.
408*8975f5c5SAndroid Build Coastguard Worker class MultiviewDrawValidationTest : public MultiviewTest
409*8975f5c5SAndroid Build Coastguard Worker {
410*8975f5c5SAndroid Build Coastguard Worker   protected:
MultiviewDrawValidationTest()411*8975f5c5SAndroid Build Coastguard Worker     MultiviewDrawValidationTest() : MultiviewTest() {}
412*8975f5c5SAndroid Build Coastguard Worker 
initOnePixelColorTexture2DSingleLayered(GLuint texId)413*8975f5c5SAndroid Build Coastguard Worker     void initOnePixelColorTexture2DSingleLayered(GLuint texId)
414*8975f5c5SAndroid Build Coastguard Worker     {
415*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D_ARRAY, texId);
416*8975f5c5SAndroid Build Coastguard Worker         glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
417*8975f5c5SAndroid Build Coastguard Worker                      nullptr);
418*8975f5c5SAndroid Build Coastguard Worker     }
419*8975f5c5SAndroid Build Coastguard Worker 
initOnePixelColorTexture2DMultiLayered(GLuint texId)420*8975f5c5SAndroid Build Coastguard Worker     void initOnePixelColorTexture2DMultiLayered(GLuint texId)
421*8975f5c5SAndroid Build Coastguard Worker     {
422*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D_ARRAY, texId);
423*8975f5c5SAndroid Build Coastguard Worker         glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
424*8975f5c5SAndroid Build Coastguard Worker                      nullptr);
425*8975f5c5SAndroid Build Coastguard Worker     }
426*8975f5c5SAndroid Build Coastguard Worker 
427*8975f5c5SAndroid Build Coastguard Worker     // This initializes a simple VAO with a valid vertex buffer and index buffer with three
428*8975f5c5SAndroid Build Coastguard Worker     // vertices.
initVAO(GLuint vao,GLuint vertexBuffer,GLuint indexBuffer)429*8975f5c5SAndroid Build Coastguard Worker     void initVAO(GLuint vao, GLuint vertexBuffer, GLuint indexBuffer)
430*8975f5c5SAndroid Build Coastguard Worker     {
431*8975f5c5SAndroid Build Coastguard Worker         glBindVertexArray(vao);
432*8975f5c5SAndroid Build Coastguard Worker 
433*8975f5c5SAndroid Build Coastguard Worker         const float kVertexData[3] = {0.0f};
434*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
435*8975f5c5SAndroid Build Coastguard Worker         glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3u, &kVertexData[0], GL_STATIC_DRAW);
436*8975f5c5SAndroid Build Coastguard Worker 
437*8975f5c5SAndroid Build Coastguard Worker         const unsigned int kIndices[3] = {0u, 1u, 2u};
438*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
439*8975f5c5SAndroid Build Coastguard Worker         glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * 3, &kIndices[0],
440*8975f5c5SAndroid Build Coastguard Worker                      GL_STATIC_DRAW);
441*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
442*8975f5c5SAndroid Build Coastguard Worker     }
443*8975f5c5SAndroid Build Coastguard Worker };
444*8975f5c5SAndroid Build Coastguard Worker 
445*8975f5c5SAndroid Build Coastguard Worker class MultiviewOcclusionQueryTest : public MultiviewRenderTest
446*8975f5c5SAndroid Build Coastguard Worker {
447*8975f5c5SAndroid Build Coastguard Worker   protected:
MultiviewOcclusionQueryTest()448*8975f5c5SAndroid Build Coastguard Worker     MultiviewOcclusionQueryTest() {}
449*8975f5c5SAndroid Build Coastguard Worker 
requestOcclusionQueryExtension()450*8975f5c5SAndroid Build Coastguard Worker     bool requestOcclusionQueryExtension()
451*8975f5c5SAndroid Build Coastguard Worker     {
452*8975f5c5SAndroid Build Coastguard Worker         if (!EnsureGLExtensionEnabled("GL_EXT_occlusion_query_boolean"))
453*8975f5c5SAndroid Build Coastguard Worker         {
454*8975f5c5SAndroid Build Coastguard Worker             std::cout << "Test skipped due to missing GL_EXT_occlusion_query_boolean." << std::endl;
455*8975f5c5SAndroid Build Coastguard Worker             return false;
456*8975f5c5SAndroid Build Coastguard Worker         }
457*8975f5c5SAndroid Build Coastguard Worker         return true;
458*8975f5c5SAndroid Build Coastguard Worker     }
459*8975f5c5SAndroid Build Coastguard Worker 
drawAndRetrieveOcclusionQueryResult(GLuint program)460*8975f5c5SAndroid Build Coastguard Worker     GLuint drawAndRetrieveOcclusionQueryResult(GLuint program)
461*8975f5c5SAndroid Build Coastguard Worker     {
462*8975f5c5SAndroid Build Coastguard Worker         GLQueryEXT query;
463*8975f5c5SAndroid Build Coastguard Worker         glBeginQueryEXT(GL_ANY_SAMPLES_PASSED, query);
464*8975f5c5SAndroid Build Coastguard Worker         drawQuad(program, "vPosition", 0.0f, 1.0f, true);
465*8975f5c5SAndroid Build Coastguard Worker         glEndQueryEXT(GL_ANY_SAMPLES_PASSED);
466*8975f5c5SAndroid Build Coastguard Worker 
467*8975f5c5SAndroid Build Coastguard Worker         GLuint result = GL_TRUE;
468*8975f5c5SAndroid Build Coastguard Worker         glGetQueryObjectuivEXT(query, GL_QUERY_RESULT, &result);
469*8975f5c5SAndroid Build Coastguard Worker         return result;
470*8975f5c5SAndroid Build Coastguard Worker     }
471*8975f5c5SAndroid Build Coastguard Worker };
472*8975f5c5SAndroid Build Coastguard Worker 
473*8975f5c5SAndroid Build Coastguard Worker class MultiviewProgramGenerationTest : public MultiviewTest
474*8975f5c5SAndroid Build Coastguard Worker {
475*8975f5c5SAndroid Build Coastguard Worker   protected:
MultiviewProgramGenerationTest()476*8975f5c5SAndroid Build Coastguard Worker     MultiviewProgramGenerationTest() {}
477*8975f5c5SAndroid Build Coastguard Worker };
478*8975f5c5SAndroid Build Coastguard Worker 
479*8975f5c5SAndroid Build Coastguard Worker class MultiviewRenderPrimitiveTest : public MultiviewRenderTest
480*8975f5c5SAndroid Build Coastguard Worker {
481*8975f5c5SAndroid Build Coastguard Worker   protected:
MultiviewRenderPrimitiveTest()482*8975f5c5SAndroid Build Coastguard Worker     MultiviewRenderPrimitiveTest() : mVBO(0u) {}
483*8975f5c5SAndroid Build Coastguard Worker 
testSetUp()484*8975f5c5SAndroid Build Coastguard Worker     void testSetUp() override { glGenBuffers(1, &mVBO); }
485*8975f5c5SAndroid Build Coastguard Worker 
testTearDown()486*8975f5c5SAndroid Build Coastguard Worker     void testTearDown() override
487*8975f5c5SAndroid Build Coastguard Worker     {
488*8975f5c5SAndroid Build Coastguard Worker         if (mVBO)
489*8975f5c5SAndroid Build Coastguard Worker         {
490*8975f5c5SAndroid Build Coastguard Worker             glDeleteBuffers(1, &mVBO);
491*8975f5c5SAndroid Build Coastguard Worker             mVBO = 0u;
492*8975f5c5SAndroid Build Coastguard Worker         }
493*8975f5c5SAndroid Build Coastguard Worker     }
494*8975f5c5SAndroid Build Coastguard Worker 
setupGeometry(const std::vector<Vector2> & vertexData)495*8975f5c5SAndroid Build Coastguard Worker     void setupGeometry(const std::vector<Vector2> &vertexData)
496*8975f5c5SAndroid Build Coastguard Worker     {
497*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, mVBO);
498*8975f5c5SAndroid Build Coastguard Worker         glBufferData(GL_ARRAY_BUFFER, vertexData.size() * sizeof(Vector2), vertexData.data(),
499*8975f5c5SAndroid Build Coastguard Worker                      GL_STATIC_DRAW);
500*8975f5c5SAndroid Build Coastguard Worker         glEnableVertexAttribArray(0);
501*8975f5c5SAndroid Build Coastguard Worker         glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
502*8975f5c5SAndroid Build Coastguard Worker     }
503*8975f5c5SAndroid Build Coastguard Worker 
checkGreenChannel(const GLubyte expectedGreenChannelData[])504*8975f5c5SAndroid Build Coastguard Worker     void checkGreenChannel(const GLubyte expectedGreenChannelData[])
505*8975f5c5SAndroid Build Coastguard Worker     {
506*8975f5c5SAndroid Build Coastguard Worker         for (int view = 0; view < mNumViews; ++view)
507*8975f5c5SAndroid Build Coastguard Worker         {
508*8975f5c5SAndroid Build Coastguard Worker             for (int w = 0; w < mViewWidth; ++w)
509*8975f5c5SAndroid Build Coastguard Worker             {
510*8975f5c5SAndroid Build Coastguard Worker                 for (int h = 0; h < mViewHeight; ++h)
511*8975f5c5SAndroid Build Coastguard Worker                 {
512*8975f5c5SAndroid Build Coastguard Worker                     size_t flatIndex =
513*8975f5c5SAndroid Build Coastguard Worker                         static_cast<size_t>(view * mViewWidth * mViewHeight + mViewWidth * h + w);
514*8975f5c5SAndroid Build Coastguard Worker                     EXPECT_EQ(GLColor(0, expectedGreenChannelData[flatIndex], 0,
515*8975f5c5SAndroid Build Coastguard Worker                                       expectedGreenChannelData[flatIndex]),
516*8975f5c5SAndroid Build Coastguard Worker                               GetViewColor(w, h, view))
517*8975f5c5SAndroid Build Coastguard Worker                         << "view: " << view << ", w: " << w << ", h: " << h;
518*8975f5c5SAndroid Build Coastguard Worker                 }
519*8975f5c5SAndroid Build Coastguard Worker             }
520*8975f5c5SAndroid Build Coastguard Worker         }
521*8975f5c5SAndroid Build Coastguard Worker     }
522*8975f5c5SAndroid Build Coastguard Worker     GLuint mVBO;
523*8975f5c5SAndroid Build Coastguard Worker };
524*8975f5c5SAndroid Build Coastguard Worker 
525*8975f5c5SAndroid Build Coastguard Worker class MultiviewLayeredRenderTest : public MultiviewFramebufferTestBase
526*8975f5c5SAndroid Build Coastguard Worker {
527*8975f5c5SAndroid Build Coastguard Worker   protected:
MultiviewLayeredRenderTest()528*8975f5c5SAndroid Build Coastguard Worker     MultiviewLayeredRenderTest() : MultiviewFramebufferTestBase(GetParam(), 0) {}
SetUp()529*8975f5c5SAndroid Build Coastguard Worker     void SetUp() final { MultiviewFramebufferTestBase::FramebufferTestSetUp(); }
TearDown()530*8975f5c5SAndroid Build Coastguard Worker     void TearDown() final { MultiviewFramebufferTestBase::FramebufferTestTearDown(); }
531*8975f5c5SAndroid Build Coastguard Worker };
532*8975f5c5SAndroid Build Coastguard Worker 
533*8975f5c5SAndroid Build Coastguard Worker // The test verifies that glDraw*Indirect works for any number of views.
TEST_P(MultiviewDrawValidationTest,IndirectDraw)534*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewDrawValidationTest, IndirectDraw)
535*8975f5c5SAndroid Build Coastguard Worker {
536*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
537*8975f5c5SAndroid Build Coastguard Worker 
538*8975f5c5SAndroid Build Coastguard Worker     const std::string FS =
539*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
540*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
541*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
542*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
543*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
544*8975f5c5SAndroid Build Coastguard Worker         "out vec4 color;\n"
545*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
546*8975f5c5SAndroid Build Coastguard Worker         "{color = vec4(1);}\n";
547*8975f5c5SAndroid Build Coastguard Worker 
548*8975f5c5SAndroid Build Coastguard Worker     GLVertexArray vao;
549*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexBuffer;
550*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indexBuffer;
551*8975f5c5SAndroid Build Coastguard Worker     initVAO(vao, vertexBuffer, indexBuffer);
552*8975f5c5SAndroid Build Coastguard Worker 
553*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
554*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
555*8975f5c5SAndroid Build Coastguard Worker 
556*8975f5c5SAndroid Build Coastguard Worker     GLBuffer commandBuffer;
557*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_DRAW_INDIRECT_BUFFER, commandBuffer);
558*8975f5c5SAndroid Build Coastguard Worker     const GLuint commandData[] = {1u, 1u, 0u, 0u, 0u};
559*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(GLuint) * 5u, &commandData[0], GL_STATIC_DRAW);
560*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
561*8975f5c5SAndroid Build Coastguard Worker 
562*8975f5c5SAndroid Build Coastguard Worker     // Check that no errors are generated with the framebuffer having 2 views.
563*8975f5c5SAndroid Build Coastguard Worker     {
564*8975f5c5SAndroid Build Coastguard Worker         const std::string VS =
565*8975f5c5SAndroid Build Coastguard Worker             "#version 300 es\n"
566*8975f5c5SAndroid Build Coastguard Worker             "#extension " +
567*8975f5c5SAndroid Build Coastguard Worker             extensionName() +
568*8975f5c5SAndroid Build Coastguard Worker             ": require\n"
569*8975f5c5SAndroid Build Coastguard Worker             "layout(num_views = 2) in;\n"
570*8975f5c5SAndroid Build Coastguard Worker             "void main()\n"
571*8975f5c5SAndroid Build Coastguard Worker             "{}\n";
572*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_PROGRAM(program, VS.c_str(), FS.c_str());
573*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(program);
574*8975f5c5SAndroid Build Coastguard Worker 
575*8975f5c5SAndroid Build Coastguard Worker         GLTexture tex2DArray;
576*8975f5c5SAndroid Build Coastguard Worker         initOnePixelColorTexture2DMultiLayered(tex2DArray);
577*8975f5c5SAndroid Build Coastguard Worker 
578*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray, 0, 0, 2);
579*8975f5c5SAndroid Build Coastguard Worker 
580*8975f5c5SAndroid Build Coastguard Worker         glDrawArraysIndirect(GL_TRIANGLES, nullptr);
581*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
582*8975f5c5SAndroid Build Coastguard Worker 
583*8975f5c5SAndroid Build Coastguard Worker         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, nullptr);
584*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
585*8975f5c5SAndroid Build Coastguard Worker     }
586*8975f5c5SAndroid Build Coastguard Worker 
587*8975f5c5SAndroid Build Coastguard Worker     // Check that no errors are generated if the number of views is 1.
588*8975f5c5SAndroid Build Coastguard Worker     {
589*8975f5c5SAndroid Build Coastguard Worker         const std::string VS =
590*8975f5c5SAndroid Build Coastguard Worker             "#version 300 es\n"
591*8975f5c5SAndroid Build Coastguard Worker             "#extension " +
592*8975f5c5SAndroid Build Coastguard Worker             extensionName() +
593*8975f5c5SAndroid Build Coastguard Worker             ": require\n"
594*8975f5c5SAndroid Build Coastguard Worker             "layout(num_views = 1) in;\n"
595*8975f5c5SAndroid Build Coastguard Worker             "void main()\n"
596*8975f5c5SAndroid Build Coastguard Worker             "{}\n";
597*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_PROGRAM(program, VS.c_str(), FS.c_str());
598*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(program);
599*8975f5c5SAndroid Build Coastguard Worker 
600*8975f5c5SAndroid Build Coastguard Worker         GLTexture tex2D;
601*8975f5c5SAndroid Build Coastguard Worker         initOnePixelColorTexture2DSingleLayered(tex2D);
602*8975f5c5SAndroid Build Coastguard Worker 
603*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2D, 0, 0, 1);
604*8975f5c5SAndroid Build Coastguard Worker 
605*8975f5c5SAndroid Build Coastguard Worker         glDrawArraysIndirect(GL_TRIANGLES, nullptr);
606*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
607*8975f5c5SAndroid Build Coastguard Worker 
608*8975f5c5SAndroid Build Coastguard Worker         glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, nullptr);
609*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
610*8975f5c5SAndroid Build Coastguard Worker     }
611*8975f5c5SAndroid Build Coastguard Worker }
612*8975f5c5SAndroid Build Coastguard Worker 
613*8975f5c5SAndroid Build Coastguard Worker // The test verifies that glDraw*:
614*8975f5c5SAndroid Build Coastguard Worker // 1) generates an INVALID_OPERATION error if the number of views in the active draw framebuffer and
615*8975f5c5SAndroid Build Coastguard Worker // program differs.
616*8975f5c5SAndroid Build Coastguard Worker // 2) does not generate any error if the number of views is the same.
TEST_P(MultiviewDrawValidationTest,NumViewsMismatch)617*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewDrawValidationTest, NumViewsMismatch)
618*8975f5c5SAndroid Build Coastguard Worker {
619*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
620*8975f5c5SAndroid Build Coastguard Worker 
621*8975f5c5SAndroid Build Coastguard Worker     const std::string VS =
622*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
623*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
624*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
625*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
626*8975f5c5SAndroid Build Coastguard Worker         "layout(num_views = 2) in;\n"
627*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
628*8975f5c5SAndroid Build Coastguard Worker         "{}\n";
629*8975f5c5SAndroid Build Coastguard Worker     const std::string FS =
630*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
631*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
632*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
633*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
634*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
635*8975f5c5SAndroid Build Coastguard Worker         "out vec4 color;\n"
636*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
637*8975f5c5SAndroid Build Coastguard Worker         "{color = vec4(1);}\n";
638*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, VS.c_str(), FS.c_str());
639*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
640*8975f5c5SAndroid Build Coastguard Worker 
641*8975f5c5SAndroid Build Coastguard Worker     GLVertexArray vao;
642*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexBuffer;
643*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indexBuffer;
644*8975f5c5SAndroid Build Coastguard Worker     initVAO(vao, vertexBuffer, indexBuffer);
645*8975f5c5SAndroid Build Coastguard Worker 
646*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
647*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
648*8975f5c5SAndroid Build Coastguard Worker 
649*8975f5c5SAndroid Build Coastguard Worker     // Check for a GL_INVALID_OPERATION error with the framebuffer and program having different
650*8975f5c5SAndroid Build Coastguard Worker     // number of views.
651*8975f5c5SAndroid Build Coastguard Worker     {
652*8975f5c5SAndroid Build Coastguard Worker         GLTexture tex2D;
653*8975f5c5SAndroid Build Coastguard Worker         initOnePixelColorTexture2DSingleLayered(tex2D);
654*8975f5c5SAndroid Build Coastguard Worker 
655*8975f5c5SAndroid Build Coastguard Worker         // The framebuffer has only 1 view.
656*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2D, 0, 0, 1);
657*8975f5c5SAndroid Build Coastguard Worker 
658*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 0, 3);
659*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
660*8975f5c5SAndroid Build Coastguard Worker 
661*8975f5c5SAndroid Build Coastguard Worker         glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr);
662*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
663*8975f5c5SAndroid Build Coastguard Worker     }
664*8975f5c5SAndroid Build Coastguard Worker 
665*8975f5c5SAndroid Build Coastguard Worker     // Check that no errors are generated if the number of views in both program and draw
666*8975f5c5SAndroid Build Coastguard Worker     // framebuffer matches.
667*8975f5c5SAndroid Build Coastguard Worker     {
668*8975f5c5SAndroid Build Coastguard Worker         GLTexture tex2DArray;
669*8975f5c5SAndroid Build Coastguard Worker         initOnePixelColorTexture2DMultiLayered(tex2DArray);
670*8975f5c5SAndroid Build Coastguard Worker 
671*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray, 0, 0, 2);
672*8975f5c5SAndroid Build Coastguard Worker 
673*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 0, 3);
674*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
675*8975f5c5SAndroid Build Coastguard Worker 
676*8975f5c5SAndroid Build Coastguard Worker         glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr);
677*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
678*8975f5c5SAndroid Build Coastguard Worker     }
679*8975f5c5SAndroid Build Coastguard Worker }
680*8975f5c5SAndroid Build Coastguard Worker 
681*8975f5c5SAndroid Build Coastguard Worker // The test verifies that glDraw* generates an INVALID_OPERATION error if the program does not use
682*8975f5c5SAndroid Build Coastguard Worker // the multiview extension, but the active draw framebuffer has more than one view.
TEST_P(MultiviewDrawValidationTest,NumViewsMismatchForNonMultiviewProgram)683*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewDrawValidationTest, NumViewsMismatchForNonMultiviewProgram)
684*8975f5c5SAndroid Build Coastguard Worker {
685*8975f5c5SAndroid Build Coastguard Worker     if (!requestMultiviewExtension())
686*8975f5c5SAndroid Build Coastguard Worker     {
687*8975f5c5SAndroid Build Coastguard Worker         return;
688*8975f5c5SAndroid Build Coastguard Worker     }
689*8975f5c5SAndroid Build Coastguard Worker 
690*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVS[] =
691*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
692*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
693*8975f5c5SAndroid Build Coastguard Worker         "{}\n";
694*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] =
695*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
696*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
697*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
698*8975f5c5SAndroid Build Coastguard Worker         "{}\n";
699*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(programNoMultiview, kVS, kFS);
700*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(programNoMultiview);
701*8975f5c5SAndroid Build Coastguard Worker 
702*8975f5c5SAndroid Build Coastguard Worker     GLVertexArray vao;
703*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexBuffer;
704*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indexBuffer;
705*8975f5c5SAndroid Build Coastguard Worker     initVAO(vao, vertexBuffer, indexBuffer);
706*8975f5c5SAndroid Build Coastguard Worker 
707*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
708*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
709*8975f5c5SAndroid Build Coastguard Worker 
710*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex2DArray;
711*8975f5c5SAndroid Build Coastguard Worker     initOnePixelColorTexture2DMultiLayered(tex2DArray);
712*8975f5c5SAndroid Build Coastguard Worker 
713*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray, 0, 0, 2);
714*8975f5c5SAndroid Build Coastguard Worker 
715*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLES, 0, 3);
716*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
717*8975f5c5SAndroid Build Coastguard Worker 
718*8975f5c5SAndroid Build Coastguard Worker     glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr);
719*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
720*8975f5c5SAndroid Build Coastguard Worker }
721*8975f5c5SAndroid Build Coastguard Worker 
722*8975f5c5SAndroid Build Coastguard Worker // The test verifies that glDraw*:
723*8975f5c5SAndroid Build Coastguard Worker // 1) generates an INVALID_OPERATION error if the number of views in the active draw framebuffer is
724*8975f5c5SAndroid Build Coastguard Worker // greater than 1 and there is an active not paused transform feedback object.
725*8975f5c5SAndroid Build Coastguard Worker // 2) does not generate any error if the number of views in the draw framebuffer is 1.
TEST_P(MultiviewDrawValidationTest,ActiveTransformFeedback)726*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewDrawValidationTest, ActiveTransformFeedback)
727*8975f5c5SAndroid Build Coastguard Worker {
728*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
729*8975f5c5SAndroid Build Coastguard Worker 
730*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVS[] = R"(#version 300 es
731*8975f5c5SAndroid Build Coastguard Worker out float tfVarying;
732*8975f5c5SAndroid Build Coastguard Worker void main()
733*8975f5c5SAndroid Build Coastguard Worker {
734*8975f5c5SAndroid Build Coastguard Worker     tfVarying = 1.0;
735*8975f5c5SAndroid Build Coastguard Worker })";
736*8975f5c5SAndroid Build Coastguard Worker 
737*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(#version 300 es
738*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
739*8975f5c5SAndroid Build Coastguard Worker void main()
740*8975f5c5SAndroid Build Coastguard Worker {})";
741*8975f5c5SAndroid Build Coastguard Worker 
742*8975f5c5SAndroid Build Coastguard Worker     std::vector<std::string> tfVaryings;
743*8975f5c5SAndroid Build Coastguard Worker     tfVaryings.emplace_back("tfVarying");
744*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(singleViewProgram, kVS, kFS, tfVaryings,
745*8975f5c5SAndroid Build Coastguard Worker                                         GL_SEPARATE_ATTRIBS);
746*8975f5c5SAndroid Build Coastguard Worker 
747*8975f5c5SAndroid Build Coastguard Worker     std::vector<std::string> dualViewTFVaryings;
748*8975f5c5SAndroid Build Coastguard Worker     dualViewTFVaryings.emplace_back("gl_Position");
749*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(dualViewProgram,
750*8975f5c5SAndroid Build Coastguard Worker                                         DualViewVS(GetParam().mMultiviewExtension).c_str(),
751*8975f5c5SAndroid Build Coastguard Worker                                         DualViewFS(GetParam().mMultiviewExtension).c_str(),
752*8975f5c5SAndroid Build Coastguard Worker                                         dualViewTFVaryings, GL_SEPARATE_ATTRIBS);
753*8975f5c5SAndroid Build Coastguard Worker 
754*8975f5c5SAndroid Build Coastguard Worker     GLVertexArray vao;
755*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexBuffer;
756*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indexBuffer;
757*8975f5c5SAndroid Build Coastguard Worker     initVAO(vao, vertexBuffer, indexBuffer);
758*8975f5c5SAndroid Build Coastguard Worker 
759*8975f5c5SAndroid Build Coastguard Worker     GLBuffer tbo;
760*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, tbo);
761*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(float) * 16u, nullptr, GL_STATIC_DRAW);
762*8975f5c5SAndroid Build Coastguard Worker 
763*8975f5c5SAndroid Build Coastguard Worker     GLTransformFeedback transformFeedback;
764*8975f5c5SAndroid Build Coastguard Worker     glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedback);
765*8975f5c5SAndroid Build Coastguard Worker 
766*8975f5c5SAndroid Build Coastguard Worker     glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tbo);
767*8975f5c5SAndroid Build Coastguard Worker 
768*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(dualViewProgram);
769*8975f5c5SAndroid Build Coastguard Worker     glBeginTransformFeedback(GL_TRIANGLES);
770*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
771*8975f5c5SAndroid Build Coastguard Worker 
772*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
773*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
774*8975f5c5SAndroid Build Coastguard Worker 
775*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex2DArray;
776*8975f5c5SAndroid Build Coastguard Worker     initOnePixelColorTexture2DMultiLayered(tex2DArray);
777*8975f5c5SAndroid Build Coastguard Worker 
778*8975f5c5SAndroid Build Coastguard Worker     GLenum bufs[] = {GL_NONE};
779*8975f5c5SAndroid Build Coastguard Worker     glDrawBuffers(1, bufs);
780*8975f5c5SAndroid Build Coastguard Worker 
781*8975f5c5SAndroid Build Coastguard Worker     // Check that drawArrays generates an error when there is an active transform feedback object
782*8975f5c5SAndroid Build Coastguard Worker     // and the number of views in the draw framebuffer is greater than 1.
783*8975f5c5SAndroid Build Coastguard Worker     {
784*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray, 0, 0, 2);
785*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 0, 3);
786*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
787*8975f5c5SAndroid Build Coastguard Worker     }
788*8975f5c5SAndroid Build Coastguard Worker 
789*8975f5c5SAndroid Build Coastguard Worker     glEndTransformFeedback();
790*8975f5c5SAndroid Build Coastguard Worker 
791*8975f5c5SAndroid Build Coastguard Worker     // Ending transform feedback should allow the draw to succeed.
792*8975f5c5SAndroid Build Coastguard Worker     {
793*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 0, 3);
794*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
795*8975f5c5SAndroid Build Coastguard Worker     }
796*8975f5c5SAndroid Build Coastguard Worker 
797*8975f5c5SAndroid Build Coastguard Worker     // A paused transform feedback should not trigger an error.
798*8975f5c5SAndroid Build Coastguard Worker     glBeginTransformFeedback(GL_TRIANGLES);
799*8975f5c5SAndroid Build Coastguard Worker     glPauseTransformFeedback();
800*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
801*8975f5c5SAndroid Build Coastguard Worker 
802*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLES, 0, 3);
803*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
804*8975f5c5SAndroid Build Coastguard Worker 
805*8975f5c5SAndroid Build Coastguard Worker     // Unbind transform feedback - should succeed.
806*8975f5c5SAndroid Build Coastguard Worker     glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
807*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLES, 0, 3);
808*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
809*8975f5c5SAndroid Build Coastguard Worker 
810*8975f5c5SAndroid Build Coastguard Worker     // Rebind paused transform feedback - should succeed.
811*8975f5c5SAndroid Build Coastguard Worker     glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedback);
812*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLES, 0, 3);
813*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
814*8975f5c5SAndroid Build Coastguard Worker 
815*8975f5c5SAndroid Build Coastguard Worker     glResumeTransformFeedback();
816*8975f5c5SAndroid Build Coastguard Worker     glEndTransformFeedback();
817*8975f5c5SAndroid Build Coastguard Worker 
818*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(singleViewProgram);
819*8975f5c5SAndroid Build Coastguard Worker     glBeginTransformFeedback(GL_TRIANGLES);
820*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
821*8975f5c5SAndroid Build Coastguard Worker 
822*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex2D;
823*8975f5c5SAndroid Build Coastguard Worker     initOnePixelColorTexture2DSingleLayered(tex2D);
824*8975f5c5SAndroid Build Coastguard Worker 
825*8975f5c5SAndroid Build Coastguard Worker     // Check that drawArrays does not generate an error when the number of views in the draw
826*8975f5c5SAndroid Build Coastguard Worker     // framebuffer is 1.
827*8975f5c5SAndroid Build Coastguard Worker     {
828*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2D, 0, 0, 1);
829*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 0, 3);
830*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
831*8975f5c5SAndroid Build Coastguard Worker     }
832*8975f5c5SAndroid Build Coastguard Worker 
833*8975f5c5SAndroid Build Coastguard Worker     glEndTransformFeedback();
834*8975f5c5SAndroid Build Coastguard Worker }
835*8975f5c5SAndroid Build Coastguard Worker 
836*8975f5c5SAndroid Build Coastguard Worker // The test verifies that glDraw*:
837*8975f5c5SAndroid Build Coastguard Worker // 1) generates an INVALID_OPERATION error if the number of views in the active draw framebuffer is
838*8975f5c5SAndroid Build Coastguard Worker // greater than 1 and there is an active query for target GL_TIME_ELAPSED_EXT.
839*8975f5c5SAndroid Build Coastguard Worker // 2) does not generate any error if the number of views in the draw framebuffer is 1.
TEST_P(MultiviewDrawValidationTest,ActiveTimeElapsedQuery)840*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewDrawValidationTest, ActiveTimeElapsedQuery)
841*8975f5c5SAndroid Build Coastguard Worker {
842*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
843*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_disjoint_timer_query"));
844*8975f5c5SAndroid Build Coastguard Worker 
845*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(dualViewProgram, DualViewVS(GetParam().mMultiviewExtension).c_str(),
846*8975f5c5SAndroid Build Coastguard Worker                      DualViewFS(GetParam().mMultiviewExtension).c_str());
847*8975f5c5SAndroid Build Coastguard Worker 
848*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVS[] =
849*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
850*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
851*8975f5c5SAndroid Build Coastguard Worker         "{}\n";
852*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] =
853*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
854*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
855*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
856*8975f5c5SAndroid Build Coastguard Worker         "{}\n";
857*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(singleViewProgram, kVS, kFS);
858*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(singleViewProgram);
859*8975f5c5SAndroid Build Coastguard Worker 
860*8975f5c5SAndroid Build Coastguard Worker     GLVertexArray vao;
861*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexBuffer;
862*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indexBuffer;
863*8975f5c5SAndroid Build Coastguard Worker     initVAO(vao, vertexBuffer, indexBuffer);
864*8975f5c5SAndroid Build Coastguard Worker 
865*8975f5c5SAndroid Build Coastguard Worker     GLuint query = 0u;
866*8975f5c5SAndroid Build Coastguard Worker     glGenQueriesEXT(1, &query);
867*8975f5c5SAndroid Build Coastguard Worker     glBeginQueryEXT(GL_TIME_ELAPSED_EXT, query);
868*8975f5c5SAndroid Build Coastguard Worker 
869*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
870*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
871*8975f5c5SAndroid Build Coastguard Worker 
872*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex2DArr;
873*8975f5c5SAndroid Build Coastguard Worker     initOnePixelColorTexture2DMultiLayered(tex2DArr);
874*8975f5c5SAndroid Build Coastguard Worker 
875*8975f5c5SAndroid Build Coastguard Worker     GLenum bufs[] = {GL_NONE};
876*8975f5c5SAndroid Build Coastguard Worker     glDrawBuffers(1, bufs);
877*8975f5c5SAndroid Build Coastguard Worker 
878*8975f5c5SAndroid Build Coastguard Worker     // Check first case.
879*8975f5c5SAndroid Build Coastguard Worker     {
880*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(dualViewProgram);
881*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArr, 0, 0, 2);
882*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
883*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
884*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 0, 3);
885*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
886*8975f5c5SAndroid Build Coastguard Worker     }
887*8975f5c5SAndroid Build Coastguard Worker 
888*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex2D;
889*8975f5c5SAndroid Build Coastguard Worker     initOnePixelColorTexture2DSingleLayered(tex2D);
890*8975f5c5SAndroid Build Coastguard Worker 
891*8975f5c5SAndroid Build Coastguard Worker     // Check second case.
892*8975f5c5SAndroid Build Coastguard Worker     {
893*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(singleViewProgram);
894*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2D, 0, 0, 1);
895*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
896*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
897*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 0, 3);
898*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
899*8975f5c5SAndroid Build Coastguard Worker     }
900*8975f5c5SAndroid Build Coastguard Worker 
901*8975f5c5SAndroid Build Coastguard Worker     glEndQueryEXT(GL_TIME_ELAPSED_EXT);
902*8975f5c5SAndroid Build Coastguard Worker     glDeleteQueries(1, &query);
903*8975f5c5SAndroid Build Coastguard Worker 
904*8975f5c5SAndroid Build Coastguard Worker     // Check starting a query after a successful draw.
905*8975f5c5SAndroid Build Coastguard Worker     {
906*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(dualViewProgram);
907*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArr, 0, 0, 2);
908*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
909*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
910*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 0, 3);
911*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
912*8975f5c5SAndroid Build Coastguard Worker 
913*8975f5c5SAndroid Build Coastguard Worker         glGenQueriesEXT(1, &query);
914*8975f5c5SAndroid Build Coastguard Worker         glBeginQueryEXT(GL_TIME_ELAPSED_EXT, query);
915*8975f5c5SAndroid Build Coastguard Worker 
916*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 0, 3);
917*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
918*8975f5c5SAndroid Build Coastguard Worker 
919*8975f5c5SAndroid Build Coastguard Worker         glEndQueryEXT(GL_TIME_ELAPSED_EXT);
920*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 0, 3);
921*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
922*8975f5c5SAndroid Build Coastguard Worker 
923*8975f5c5SAndroid Build Coastguard Worker         glDeleteQueries(1, &query);
924*8975f5c5SAndroid Build Coastguard Worker     }
925*8975f5c5SAndroid Build Coastguard Worker }
926*8975f5c5SAndroid Build Coastguard Worker 
927*8975f5c5SAndroid Build Coastguard Worker // The test checks that glDrawArrays can be used to render into two views.
TEST_P(MultiviewRenderDualViewTest,DrawArrays)928*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewRenderDualViewTest, DrawArrays)
929*8975f5c5SAndroid Build Coastguard Worker {
930*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!requestMultiviewExtension(isMultisampled()));
931*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
932*8975f5c5SAndroid Build Coastguard Worker 
933*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, "vPosition", 0.0f, 1.0f, true);
934*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
935*8975f5c5SAndroid Build Coastguard Worker 
936*8975f5c5SAndroid Build Coastguard Worker     checkOutput();
937*8975f5c5SAndroid Build Coastguard Worker }
938*8975f5c5SAndroid Build Coastguard Worker 
939*8975f5c5SAndroid Build Coastguard Worker // The test checks that glDrawArrays can be used to render into two views, after the program
940*8975f5c5SAndroid Build Coastguard Worker // executable has been installed and the program relinked (with a failing link, and using a
941*8975f5c5SAndroid Build Coastguard Worker // different number of views).
TEST_P(MultiviewRenderDualViewTestNoWebGL,DrawArraysAfterFailedRelink)942*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewRenderDualViewTestNoWebGL, DrawArraysAfterFailedRelink)
943*8975f5c5SAndroid Build Coastguard Worker {
944*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!requestMultiviewExtension(isMultisampled()));
945*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D());
946*8975f5c5SAndroid Build Coastguard Worker 
947*8975f5c5SAndroid Build Coastguard Worker     std::string ext =
948*8975f5c5SAndroid Build Coastguard Worker         GetParam().mMultiviewExtension == multiview ? "GL_OVR_multiview" : "GL_OVR_multiview2";
949*8975f5c5SAndroid Build Coastguard Worker 
950*8975f5c5SAndroid Build Coastguard Worker     const std::string kVS = R"(#version 300 es
951*8975f5c5SAndroid Build Coastguard Worker #extension )" + ext + R"( : require
952*8975f5c5SAndroid Build Coastguard Worker layout(num_views = 2) in;
953*8975f5c5SAndroid Build Coastguard Worker void main()
954*8975f5c5SAndroid Build Coastguard Worker {
955*8975f5c5SAndroid Build Coastguard Worker     vec2 pos = vec2(0.0);
956*8975f5c5SAndroid Build Coastguard Worker     switch (gl_VertexID) {
957*8975f5c5SAndroid Build Coastguard Worker         case 0: pos = vec2(-1.0, -1.0); break;
958*8975f5c5SAndroid Build Coastguard Worker         case 1: pos = vec2(1.0, -1.0); break;
959*8975f5c5SAndroid Build Coastguard Worker         case 2: pos = vec2(-1.0, 1.0); break;
960*8975f5c5SAndroid Build Coastguard Worker         case 3: pos = vec2(1.0, 1.0); break;
961*8975f5c5SAndroid Build Coastguard Worker     };
962*8975f5c5SAndroid Build Coastguard Worker     pos.x = gl_ViewID_OVR == 0u ? pos.x * 0.5 + 0.5 : pos.x * 0.5 - 0.5;
963*8975f5c5SAndroid Build Coastguard Worker     gl_Position = vec4(pos, 0.0, 1.0);
964*8975f5c5SAndroid Build Coastguard Worker })";
965*8975f5c5SAndroid Build Coastguard Worker 
966*8975f5c5SAndroid Build Coastguard Worker     const std::string kFS = R"(#version 300 es
967*8975f5c5SAndroid Build Coastguard Worker #extension )" + ext + R"( : require
968*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
969*8975f5c5SAndroid Build Coastguard Worker out vec4 col;
970*8975f5c5SAndroid Build Coastguard Worker void main()
971*8975f5c5SAndroid Build Coastguard Worker {
972*8975f5c5SAndroid Build Coastguard Worker     col = vec4(0, 1, 0, 1);
973*8975f5c5SAndroid Build Coastguard Worker })";
974*8975f5c5SAndroid Build Coastguard Worker 
975*8975f5c5SAndroid Build Coastguard Worker     const std::string kBadVS = R"(#version 300 es
976*8975f5c5SAndroid Build Coastguard Worker #extension )" + ext + R"( : require
977*8975f5c5SAndroid Build Coastguard Worker layout(num_views = 4) in;
978*8975f5c5SAndroid Build Coastguard Worker out vec4 linkError;
979*8975f5c5SAndroid Build Coastguard Worker void main()
980*8975f5c5SAndroid Build Coastguard Worker {
981*8975f5c5SAndroid Build Coastguard Worker     vec2 pos = vec2(0.0);
982*8975f5c5SAndroid Build Coastguard Worker     switch (gl_VertexID) {
983*8975f5c5SAndroid Build Coastguard Worker         case 0: pos = vec2(-1.0, -1.0); break;
984*8975f5c5SAndroid Build Coastguard Worker         case 1: pos = vec2(1.0, -1.0); break;
985*8975f5c5SAndroid Build Coastguard Worker         case 2: pos = vec2(-1.0, 1.0); break;
986*8975f5c5SAndroid Build Coastguard Worker         case 3: pos = vec2(1.0, 1.0); break;
987*8975f5c5SAndroid Build Coastguard Worker     };
988*8975f5c5SAndroid Build Coastguard Worker     pos.x = gl_ViewID_OVR == 0u ? pos.x * 0.5 + 0.5 : pos.x * 0.5 - 0.5;
989*8975f5c5SAndroid Build Coastguard Worker     gl_Position = vec4(pos, 0.0, 1.0);
990*8975f5c5SAndroid Build Coastguard Worker     linkError = vec4(0);
991*8975f5c5SAndroid Build Coastguard Worker })";
992*8975f5c5SAndroid Build Coastguard Worker 
993*8975f5c5SAndroid Build Coastguard Worker     const std::string kBadFS = R"(#version 300 es
994*8975f5c5SAndroid Build Coastguard Worker #extension )" + ext + R"( : require
995*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
996*8975f5c5SAndroid Build Coastguard Worker flat in uvec4 linkError;
997*8975f5c5SAndroid Build Coastguard Worker out vec4 col;
998*8975f5c5SAndroid Build Coastguard Worker void main()
999*8975f5c5SAndroid Build Coastguard Worker {
1000*8975f5c5SAndroid Build Coastguard Worker     col = vec4(linkError);
1001*8975f5c5SAndroid Build Coastguard Worker })";
1002*8975f5c5SAndroid Build Coastguard Worker 
1003*8975f5c5SAndroid Build Coastguard Worker     // First, create a good program
1004*8975f5c5SAndroid Build Coastguard Worker     GLuint program = glCreateProgram();
1005*8975f5c5SAndroid Build Coastguard Worker     GLuint vs      = CompileShader(GL_VERTEX_SHADER, kVS.c_str());
1006*8975f5c5SAndroid Build Coastguard Worker     GLuint fs      = CompileShader(GL_FRAGMENT_SHADER, kFS.c_str());
1007*8975f5c5SAndroid Build Coastguard Worker 
1008*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, vs);
1009*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, fs);
1010*8975f5c5SAndroid Build Coastguard Worker 
1011*8975f5c5SAndroid Build Coastguard Worker     glLinkProgram(program);
1012*8975f5c5SAndroid Build Coastguard Worker     CheckLinkStatusAndReturnProgram(program, true);
1013*8975f5c5SAndroid Build Coastguard Worker 
1014*8975f5c5SAndroid Build Coastguard Worker     // Detach the shaders for the sake of DrawArraysAfterFailedRelink
1015*8975f5c5SAndroid Build Coastguard Worker     glDetachShader(program, vs);
1016*8975f5c5SAndroid Build Coastguard Worker     glDetachShader(program, fs);
1017*8975f5c5SAndroid Build Coastguard Worker 
1018*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(vs);
1019*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(fs);
1020*8975f5c5SAndroid Build Coastguard Worker 
1021*8975f5c5SAndroid Build Coastguard Worker     // Install the executable
1022*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1023*8975f5c5SAndroid Build Coastguard Worker 
1024*8975f5c5SAndroid Build Coastguard Worker     // Relink the program but in an erroneous way
1025*8975f5c5SAndroid Build Coastguard Worker     GLuint badVs = CompileShader(GL_VERTEX_SHADER, kBadVS.c_str());
1026*8975f5c5SAndroid Build Coastguard Worker     GLuint badFs = CompileShader(GL_FRAGMENT_SHADER, kBadFS.c_str());
1027*8975f5c5SAndroid Build Coastguard Worker 
1028*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, badVs);
1029*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, badFs);
1030*8975f5c5SAndroid Build Coastguard Worker 
1031*8975f5c5SAndroid Build Coastguard Worker     glLinkProgram(program);
1032*8975f5c5SAndroid Build Coastguard Worker 
1033*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(badVs);
1034*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(badFs);
1035*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1036*8975f5c5SAndroid Build Coastguard Worker 
1037*8975f5c5SAndroid Build Coastguard Worker     // Issue a draw and make sure everything works.
1038*8975f5c5SAndroid Build Coastguard Worker     glClearColor(0, 0, 0, 0);
1039*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
1040*8975f5c5SAndroid Build Coastguard Worker     // drawQuad(mProgram, "vPosition", 0.0f, 1.0f, true);
1041*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1042*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1043*8975f5c5SAndroid Build Coastguard Worker 
1044*8975f5c5SAndroid Build Coastguard Worker     checkOutput();
1045*8975f5c5SAndroid Build Coastguard Worker 
1046*8975f5c5SAndroid Build Coastguard Worker     glDeleteProgram(program);
1047*8975f5c5SAndroid Build Coastguard Worker }
1048*8975f5c5SAndroid Build Coastguard Worker 
1049*8975f5c5SAndroid Build Coastguard Worker // The test checks that glDrawElements can be used to render into two views.
TEST_P(MultiviewRenderDualViewTest,DrawElements)1050*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewRenderDualViewTest, DrawElements)
1051*8975f5c5SAndroid Build Coastguard Worker {
1052*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!requestMultiviewExtension(isMultisampled()));
1053*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
1054*8975f5c5SAndroid Build Coastguard Worker 
1055*8975f5c5SAndroid Build Coastguard Worker     drawIndexedQuad(mProgram, "vPosition", 0.0f, 1.0f, true);
1056*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1057*8975f5c5SAndroid Build Coastguard Worker 
1058*8975f5c5SAndroid Build Coastguard Worker     checkOutput();
1059*8975f5c5SAndroid Build Coastguard Worker }
1060*8975f5c5SAndroid Build Coastguard Worker 
1061*8975f5c5SAndroid Build Coastguard Worker // The test checks that glDrawRangeElements can be used to render into two views.
TEST_P(MultiviewRenderDualViewTest,DrawRangeElements)1062*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewRenderDualViewTest, DrawRangeElements)
1063*8975f5c5SAndroid Build Coastguard Worker {
1064*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!requestMultiviewExtension(isMultisampled()));
1065*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
1066*8975f5c5SAndroid Build Coastguard Worker 
1067*8975f5c5SAndroid Build Coastguard Worker     drawIndexedQuad(mProgram, "vPosition", 0.0f, 1.0f, true, true);
1068*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1069*8975f5c5SAndroid Build Coastguard Worker 
1070*8975f5c5SAndroid Build Coastguard Worker     checkOutput();
1071*8975f5c5SAndroid Build Coastguard Worker }
1072*8975f5c5SAndroid Build Coastguard Worker 
1073*8975f5c5SAndroid Build Coastguard Worker // The test checks that glDrawArrays can be used to render into four views.
TEST_P(MultiviewRenderTest,DrawArraysFourViews)1074*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewRenderTest, DrawArraysFourViews)
1075*8975f5c5SAndroid Build Coastguard Worker {
1076*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!requestMultiviewExtension(isMultisampled()));
1077*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
1078*8975f5c5SAndroid Build Coastguard Worker 
1079*8975f5c5SAndroid Build Coastguard Worker     const std::string VS =
1080*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1081*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1082*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1083*8975f5c5SAndroid Build Coastguard Worker         " : require\n"
1084*8975f5c5SAndroid Build Coastguard Worker         "layout(num_views = 4) in;\n"
1085*8975f5c5SAndroid Build Coastguard Worker         "in vec4 vPosition;\n"
1086*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1087*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1088*8975f5c5SAndroid Build Coastguard Worker         "   if (gl_ViewID_OVR == 0u) {\n"
1089*8975f5c5SAndroid Build Coastguard Worker         "       gl_Position.x = vPosition.x*0.25 - 0.75;\n"
1090*8975f5c5SAndroid Build Coastguard Worker         "   } else if (gl_ViewID_OVR == 1u) {\n"
1091*8975f5c5SAndroid Build Coastguard Worker         "       gl_Position.x = vPosition.x*0.25 - 0.25;\n"
1092*8975f5c5SAndroid Build Coastguard Worker         "   } else if (gl_ViewID_OVR == 2u) {\n"
1093*8975f5c5SAndroid Build Coastguard Worker         "       gl_Position.x = vPosition.x*0.25 + 0.25;\n"
1094*8975f5c5SAndroid Build Coastguard Worker         "   } else {\n"
1095*8975f5c5SAndroid Build Coastguard Worker         "       gl_Position.x = vPosition.x*0.25 + 0.75;\n"
1096*8975f5c5SAndroid Build Coastguard Worker         "   }"
1097*8975f5c5SAndroid Build Coastguard Worker         "   gl_Position.yzw = vPosition.yzw;\n"
1098*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1099*8975f5c5SAndroid Build Coastguard Worker 
1100*8975f5c5SAndroid Build Coastguard Worker     const std::string FS =
1101*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1102*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1103*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1104*8975f5c5SAndroid Build Coastguard Worker         " : require\n"
1105*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
1106*8975f5c5SAndroid Build Coastguard Worker         "out vec4 col;\n"
1107*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1108*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1109*8975f5c5SAndroid Build Coastguard Worker         "    col = vec4(0,1,0,1);\n"
1110*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1111*8975f5c5SAndroid Build Coastguard Worker 
1112*8975f5c5SAndroid Build Coastguard Worker     updateFBOs(4, 1, 4);
1113*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, VS.c_str(), FS.c_str());
1114*8975f5c5SAndroid Build Coastguard Worker 
1115*8975f5c5SAndroid Build Coastguard Worker     drawQuad(program, "vPosition", 0.0f, 1.0f, true);
1116*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1117*8975f5c5SAndroid Build Coastguard Worker 
1118*8975f5c5SAndroid Build Coastguard Worker     resolveMultisampledFBO();
1119*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < 4; ++i)
1120*8975f5c5SAndroid Build Coastguard Worker     {
1121*8975f5c5SAndroid Build Coastguard Worker         for (int j = 0; j < 4; ++j)
1122*8975f5c5SAndroid Build Coastguard Worker         {
1123*8975f5c5SAndroid Build Coastguard Worker             if (i == j)
1124*8975f5c5SAndroid Build Coastguard Worker             {
1125*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_EQ(GLColor::green, GetViewColor(j, 0, i));
1126*8975f5c5SAndroid Build Coastguard Worker             }
1127*8975f5c5SAndroid Build Coastguard Worker             else
1128*8975f5c5SAndroid Build Coastguard Worker             {
1129*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_EQ(GLColor::transparentBlack, GetViewColor(j, 0, i));
1130*8975f5c5SAndroid Build Coastguard Worker             }
1131*8975f5c5SAndroid Build Coastguard Worker         }
1132*8975f5c5SAndroid Build Coastguard Worker     }
1133*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1134*8975f5c5SAndroid Build Coastguard Worker }
1135*8975f5c5SAndroid Build Coastguard Worker 
1136*8975f5c5SAndroid Build Coastguard Worker // The test checks that glDrawArraysInstanced can be used to render into two views.
TEST_P(MultiviewRenderTest,DrawArraysInstanced)1137*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewRenderTest, DrawArraysInstanced)
1138*8975f5c5SAndroid Build Coastguard Worker {
1139*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!requestMultiviewExtension(isMultisampled()));
1140*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
1141*8975f5c5SAndroid Build Coastguard Worker 
1142*8975f5c5SAndroid Build Coastguard Worker     const std::string VS =
1143*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1144*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1145*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1146*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
1147*8975f5c5SAndroid Build Coastguard Worker         "layout(num_views = 2) in;\n"
1148*8975f5c5SAndroid Build Coastguard Worker         "in vec4 vPosition;\n"
1149*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1150*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1151*8975f5c5SAndroid Build Coastguard Worker         "       vec4 p = vPosition;\n"
1152*8975f5c5SAndroid Build Coastguard Worker         "       if (gl_InstanceID == 1){\n"
1153*8975f5c5SAndroid Build Coastguard Worker         "               p.y = p.y * 0.5 + 0.5;\n"
1154*8975f5c5SAndroid Build Coastguard Worker         "       } else {\n"
1155*8975f5c5SAndroid Build Coastguard Worker         "               p.y = p.y * 0.5 - 0.5;\n"
1156*8975f5c5SAndroid Build Coastguard Worker         "       }\n"
1157*8975f5c5SAndroid Build Coastguard Worker         "       gl_Position.x = (gl_ViewID_OVR == 0u ? p.x * 0.5 + 0.5 : p.x * 0.5 - 0.5);\n"
1158*8975f5c5SAndroid Build Coastguard Worker         "       gl_Position.yzw = p.yzw;\n"
1159*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1160*8975f5c5SAndroid Build Coastguard Worker 
1161*8975f5c5SAndroid Build Coastguard Worker     const std::string FS =
1162*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1163*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1164*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1165*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
1166*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
1167*8975f5c5SAndroid Build Coastguard Worker         "out vec4 col;\n"
1168*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1169*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1170*8975f5c5SAndroid Build Coastguard Worker         "    col = vec4(0,1,0,1);\n"
1171*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1172*8975f5c5SAndroid Build Coastguard Worker 
1173*8975f5c5SAndroid Build Coastguard Worker     const int kViewWidth  = 2;
1174*8975f5c5SAndroid Build Coastguard Worker     const int kViewHeight = 2;
1175*8975f5c5SAndroid Build Coastguard Worker     const int kNumViews   = 2;
1176*8975f5c5SAndroid Build Coastguard Worker     updateFBOs(kViewWidth, kViewHeight, kNumViews);
1177*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, VS.c_str(), FS.c_str());
1178*8975f5c5SAndroid Build Coastguard Worker 
1179*8975f5c5SAndroid Build Coastguard Worker     drawQuadInstanced(program, "vPosition", 0.0f, 1.0f, true, 2u);
1180*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1181*8975f5c5SAndroid Build Coastguard Worker 
1182*8975f5c5SAndroid Build Coastguard Worker     resolveMultisampledFBO();
1183*8975f5c5SAndroid Build Coastguard Worker 
1184*8975f5c5SAndroid Build Coastguard Worker     const GLubyte expectedGreenChannel[kNumViews][kViewHeight][kViewWidth] = {{{0, 255}, {0, 255}},
1185*8975f5c5SAndroid Build Coastguard Worker                                                                               {{255, 0}, {255, 0}}};
1186*8975f5c5SAndroid Build Coastguard Worker 
1187*8975f5c5SAndroid Build Coastguard Worker     for (int view = 0; view < 2; ++view)
1188*8975f5c5SAndroid Build Coastguard Worker     {
1189*8975f5c5SAndroid Build Coastguard Worker         for (int y = 0; y < 2; ++y)
1190*8975f5c5SAndroid Build Coastguard Worker         {
1191*8975f5c5SAndroid Build Coastguard Worker             for (int x = 0; x < 2; ++x)
1192*8975f5c5SAndroid Build Coastguard Worker             {
1193*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_EQ(GLColor(0, expectedGreenChannel[view][y][x], 0,
1194*8975f5c5SAndroid Build Coastguard Worker                                   expectedGreenChannel[view][y][x]),
1195*8975f5c5SAndroid Build Coastguard Worker                           GetViewColor(x, y, view));
1196*8975f5c5SAndroid Build Coastguard Worker             }
1197*8975f5c5SAndroid Build Coastguard Worker         }
1198*8975f5c5SAndroid Build Coastguard Worker     }
1199*8975f5c5SAndroid Build Coastguard Worker }
1200*8975f5c5SAndroid Build Coastguard Worker 
1201*8975f5c5SAndroid Build Coastguard Worker // The test verifies that the attribute divisor is correctly adjusted when drawing with a multi-view
1202*8975f5c5SAndroid Build Coastguard Worker // program. The test draws 4 instances of a quad each of which covers a single pixel. The x and y
1203*8975f5c5SAndroid Build Coastguard Worker // offset of each quad are passed as separate attributes which are indexed based on the
1204*8975f5c5SAndroid Build Coastguard Worker // corresponding attribute divisors. A divisor of 1 is used for the y offset to have all quads
1205*8975f5c5SAndroid Build Coastguard Worker // drawn vertically next to each other. A divisor of 3 is used for the x offset to have the last
1206*8975f5c5SAndroid Build Coastguard Worker // quad offsetted by one pixel to the right. Note that the number of views is divisible by 1, but
1207*8975f5c5SAndroid Build Coastguard Worker // not by 3.
TEST_P(MultiviewRenderTest,AttribDivisor)1208*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewRenderTest, AttribDivisor)
1209*8975f5c5SAndroid Build Coastguard Worker {
1210*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!requestMultiviewExtension(isMultisampled()));
1211*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
1212*8975f5c5SAndroid Build Coastguard Worker 
1213*8975f5c5SAndroid Build Coastguard Worker     // Looks like an incorrect D3D debug layer message is generated on Windows AMD and NVIDIA.
1214*8975f5c5SAndroid Build Coastguard Worker     // May be specific to Windows 7 / Windows Server 2008. http://anglebug.com/42261480
1215*8975f5c5SAndroid Build Coastguard Worker     if (IsWindows() && IsD3D11())
1216*8975f5c5SAndroid Build Coastguard Worker     {
1217*8975f5c5SAndroid Build Coastguard Worker         ignoreD3D11SDKLayersWarnings();
1218*8975f5c5SAndroid Build Coastguard Worker     }
1219*8975f5c5SAndroid Build Coastguard Worker 
1220*8975f5c5SAndroid Build Coastguard Worker     const std::string VS =
1221*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1222*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1223*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1224*8975f5c5SAndroid Build Coastguard Worker         " : require\n"
1225*8975f5c5SAndroid Build Coastguard Worker         "layout(num_views = 2) in;\n"
1226*8975f5c5SAndroid Build Coastguard Worker         "in vec3 vPosition;\n"
1227*8975f5c5SAndroid Build Coastguard Worker         "in float offsetX;\n"
1228*8975f5c5SAndroid Build Coastguard Worker         "in float offsetY;\n"
1229*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1230*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1231*8975f5c5SAndroid Build Coastguard Worker         "       vec4 p = vec4(vPosition, 1.);\n"
1232*8975f5c5SAndroid Build Coastguard Worker         "       p.xy = p.xy * 0.25 - vec2(0.75) + vec2(offsetX, offsetY);\n"
1233*8975f5c5SAndroid Build Coastguard Worker         "       gl_Position.x = (gl_ViewID_OVR == 0u ? p.x : p.x + 1.0);\n"
1234*8975f5c5SAndroid Build Coastguard Worker         "       gl_Position.yzw = p.yzw;\n"
1235*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1236*8975f5c5SAndroid Build Coastguard Worker 
1237*8975f5c5SAndroid Build Coastguard Worker     const std::string FS =
1238*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1239*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1240*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1241*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
1242*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
1243*8975f5c5SAndroid Build Coastguard Worker         "out vec4 col;\n"
1244*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1245*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1246*8975f5c5SAndroid Build Coastguard Worker         "    col = vec4(0,1,0,1);\n"
1247*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1248*8975f5c5SAndroid Build Coastguard Worker 
1249*8975f5c5SAndroid Build Coastguard Worker     const int kViewWidth  = 4;
1250*8975f5c5SAndroid Build Coastguard Worker     const int kViewHeight = 4;
1251*8975f5c5SAndroid Build Coastguard Worker     const int kNumViews   = 2;
1252*8975f5c5SAndroid Build Coastguard Worker     updateFBOs(kViewWidth, kViewHeight, kNumViews);
1253*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, VS.c_str(), FS.c_str());
1254*8975f5c5SAndroid Build Coastguard Worker 
1255*8975f5c5SAndroid Build Coastguard Worker     GLBuffer xOffsetVBO;
1256*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, xOffsetVBO);
1257*8975f5c5SAndroid Build Coastguard Worker     const GLfloat xOffsetData[4] = {0.0f, 0.5f, 1.0f, 1.0f};
1258*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 4, xOffsetData, GL_STATIC_DRAW);
1259*8975f5c5SAndroid Build Coastguard Worker     GLint xOffsetLoc = glGetAttribLocation(program, "offsetX");
1260*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(xOffsetLoc, 1, GL_FLOAT, GL_FALSE, 0, 0);
1261*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribDivisor(xOffsetLoc, 3);
1262*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(xOffsetLoc);
1263*8975f5c5SAndroid Build Coastguard Worker 
1264*8975f5c5SAndroid Build Coastguard Worker     GLBuffer yOffsetVBO;
1265*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, yOffsetVBO);
1266*8975f5c5SAndroid Build Coastguard Worker     const GLfloat yOffsetData[4] = {0.0f, 0.5f, 1.0f, 1.5f};
1267*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 4, yOffsetData, GL_STATIC_DRAW);
1268*8975f5c5SAndroid Build Coastguard Worker     GLint yOffsetLoc = glGetAttribLocation(program, "offsetY");
1269*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribDivisor(yOffsetLoc, 1);
1270*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(yOffsetLoc, 1, GL_FLOAT, GL_FALSE, 0, 0);
1271*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(yOffsetLoc);
1272*8975f5c5SAndroid Build Coastguard Worker 
1273*8975f5c5SAndroid Build Coastguard Worker     drawQuadInstanced(program, "vPosition", 0.0f, 1.0f, true, 4u);
1274*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1275*8975f5c5SAndroid Build Coastguard Worker 
1276*8975f5c5SAndroid Build Coastguard Worker     resolveMultisampledFBO();
1277*8975f5c5SAndroid Build Coastguard Worker 
1278*8975f5c5SAndroid Build Coastguard Worker     const GLubyte expectedGreenChannel[kNumViews][kViewHeight][kViewWidth] = {
1279*8975f5c5SAndroid Build Coastguard Worker         {{255, 0, 0, 0}, {255, 0, 0, 0}, {255, 0, 0, 0}, {0, 255, 0, 0}},
1280*8975f5c5SAndroid Build Coastguard Worker         {{0, 0, 255, 0}, {0, 0, 255, 0}, {0, 0, 255, 0}, {0, 0, 0, 255}}};
1281*8975f5c5SAndroid Build Coastguard Worker     for (int view = 0; view < 2; ++view)
1282*8975f5c5SAndroid Build Coastguard Worker     {
1283*8975f5c5SAndroid Build Coastguard Worker         for (int row = 0; row < 4; ++row)
1284*8975f5c5SAndroid Build Coastguard Worker         {
1285*8975f5c5SAndroid Build Coastguard Worker             for (int col = 0; col < 4; ++col)
1286*8975f5c5SAndroid Build Coastguard Worker             {
1287*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_EQ(GLColor(0, expectedGreenChannel[view][row][col], 0,
1288*8975f5c5SAndroid Build Coastguard Worker                                   expectedGreenChannel[view][row][col]),
1289*8975f5c5SAndroid Build Coastguard Worker                           GetViewColor(col, row, view));
1290*8975f5c5SAndroid Build Coastguard Worker             }
1291*8975f5c5SAndroid Build Coastguard Worker         }
1292*8975f5c5SAndroid Build Coastguard Worker     }
1293*8975f5c5SAndroid Build Coastguard Worker }
1294*8975f5c5SAndroid Build Coastguard Worker 
1295*8975f5c5SAndroid Build Coastguard Worker // Test that different sequences of vertexAttribDivisor, useProgram and bindVertexArray in a
1296*8975f5c5SAndroid Build Coastguard Worker // multi-view context propagate the correct divisor to the driver.
TEST_P(MultiviewRenderTest,DivisorOrderOfOperation)1297*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewRenderTest, DivisorOrderOfOperation)
1298*8975f5c5SAndroid Build Coastguard Worker {
1299*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!requestMultiviewExtension(isMultisampled()));
1300*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
1301*8975f5c5SAndroid Build Coastguard Worker 
1302*8975f5c5SAndroid Build Coastguard Worker     updateFBOs(1, 1, 2);
1303*8975f5c5SAndroid Build Coastguard Worker 
1304*8975f5c5SAndroid Build Coastguard Worker     // Create multiview program.
1305*8975f5c5SAndroid Build Coastguard Worker     const std::string VS =
1306*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1307*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1308*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1309*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
1310*8975f5c5SAndroid Build Coastguard Worker         "layout(num_views = 2) in;\n"
1311*8975f5c5SAndroid Build Coastguard Worker         "layout(location = 0) in vec2 vPosition;\n"
1312*8975f5c5SAndroid Build Coastguard Worker         "layout(location = 1) in float offsetX;\n"
1313*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1314*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1315*8975f5c5SAndroid Build Coastguard Worker         "       vec4 p = vec4(vPosition, 0.0, 1.0);\n"
1316*8975f5c5SAndroid Build Coastguard Worker         "       p.x += offsetX;\n"
1317*8975f5c5SAndroid Build Coastguard Worker         "       gl_Position = p;\n"
1318*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1319*8975f5c5SAndroid Build Coastguard Worker 
1320*8975f5c5SAndroid Build Coastguard Worker     const std::string FS =
1321*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1322*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1323*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1324*8975f5c5SAndroid Build Coastguard Worker         " : require\n"
1325*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
1326*8975f5c5SAndroid Build Coastguard Worker         "out vec4 col;\n"
1327*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1328*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1329*8975f5c5SAndroid Build Coastguard Worker         "    col = vec4(0,1,0,1);\n"
1330*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1331*8975f5c5SAndroid Build Coastguard Worker 
1332*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, VS.c_str(), FS.c_str());
1333*8975f5c5SAndroid Build Coastguard Worker 
1334*8975f5c5SAndroid Build Coastguard Worker     constexpr char kStubVS[] =
1335*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1336*8975f5c5SAndroid Build Coastguard Worker         "layout(location = 0) in vec2 vPosition;\n"
1337*8975f5c5SAndroid Build Coastguard Worker         "layout(location = 1) in float offsetX;\n"
1338*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1339*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1340*8975f5c5SAndroid Build Coastguard Worker         "       gl_Position = vec4(vPosition, 0.0, 1.0);\n"
1341*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1342*8975f5c5SAndroid Build Coastguard Worker 
1343*8975f5c5SAndroid Build Coastguard Worker     constexpr char kStubFS[] =
1344*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1345*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
1346*8975f5c5SAndroid Build Coastguard Worker         "out vec4 col;\n"
1347*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1348*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1349*8975f5c5SAndroid Build Coastguard Worker         "    col = vec4(0,0,0,1);\n"
1350*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1351*8975f5c5SAndroid Build Coastguard Worker 
1352*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(stubProgram, kStubVS, kStubFS);
1353*8975f5c5SAndroid Build Coastguard Worker 
1354*8975f5c5SAndroid Build Coastguard Worker     GLBuffer xOffsetVBO;
1355*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, xOffsetVBO);
1356*8975f5c5SAndroid Build Coastguard Worker     const GLfloat xOffsetData[12] = {0.0f, 4.0f, 4.0f, 4.0f, 4.0f, 4.0f,
1357*8975f5c5SAndroid Build Coastguard Worker                                      4.0f, 4.0f, 4.0f, 4.0f, 4.0f, 4.0f};
1358*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 12, xOffsetData, GL_STATIC_DRAW);
1359*8975f5c5SAndroid Build Coastguard Worker 
1360*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexVBO;
1361*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, vertexVBO);
1362*8975f5c5SAndroid Build Coastguard Worker     Vector2 kQuadVertices[6] = {Vector2(-1.f, -1.f), Vector2(1.f, -1.f), Vector2(1.f, 1.f),
1363*8975f5c5SAndroid Build Coastguard Worker                                 Vector2(-1.f, -1.f), Vector2(1.f, 1.f),  Vector2(-1.f, 1.f)};
1364*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices, GL_STATIC_DRAW);
1365*8975f5c5SAndroid Build Coastguard Worker 
1366*8975f5c5SAndroid Build Coastguard Worker     GLVertexArray vao[2];
1367*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0u; i < 2u; ++i)
1368*8975f5c5SAndroid Build Coastguard Worker     {
1369*8975f5c5SAndroid Build Coastguard Worker         glBindVertexArray(vao[i]);
1370*8975f5c5SAndroid Build Coastguard Worker 
1371*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, vertexVBO);
1372*8975f5c5SAndroid Build Coastguard Worker         glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
1373*8975f5c5SAndroid Build Coastguard Worker         glEnableVertexAttribArray(0);
1374*8975f5c5SAndroid Build Coastguard Worker 
1375*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, xOffsetVBO);
1376*8975f5c5SAndroid Build Coastguard Worker         glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, 0);
1377*8975f5c5SAndroid Build Coastguard Worker         glEnableVertexAttribArray(1);
1378*8975f5c5SAndroid Build Coastguard Worker     }
1379*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1380*8975f5c5SAndroid Build Coastguard Worker 
1381*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, 1, 1);
1382*8975f5c5SAndroid Build Coastguard Worker     glScissor(0, 0, 1, 1);
1383*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_SCISSOR_TEST);
1384*8975f5c5SAndroid Build Coastguard Worker     glClearColor(0, 0, 0, 1);
1385*8975f5c5SAndroid Build Coastguard Worker 
1386*8975f5c5SAndroid Build Coastguard Worker     // Clear the buffers, propagate divisor to the driver, bind the vao and keep it active.
1387*8975f5c5SAndroid Build Coastguard Worker     // It is necessary to call draw, so that the divisor is propagated and to guarantee that dirty
1388*8975f5c5SAndroid Build Coastguard Worker     // bits are cleared.
1389*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(stubProgram);
1390*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1391*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1392*8975f5c5SAndroid Build Coastguard Worker     glBindVertexArray(vao[0]);
1393*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribDivisor(1, 0);
1394*8975f5c5SAndroid Build Coastguard Worker     glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 1);
1395*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
1396*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1397*8975f5c5SAndroid Build Coastguard Worker 
1398*8975f5c5SAndroid Build Coastguard Worker     // Check that vertexAttribDivisor uses the number of views to update the divisor.
1399*8975f5c5SAndroid Build Coastguard Worker     bindMemberDrawFramebuffer();
1400*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1401*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1402*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribDivisor(1, 1);
1403*8975f5c5SAndroid Build Coastguard Worker     glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 1);
1404*8975f5c5SAndroid Build Coastguard Worker 
1405*8975f5c5SAndroid Build Coastguard Worker     resolveMultisampledFBO();
1406*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(GLColor::green, GetViewColor(0, 0, 0));
1407*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(GLColor::green, GetViewColor(0, 0, 1));
1408*8975f5c5SAndroid Build Coastguard Worker 
1409*8975f5c5SAndroid Build Coastguard Worker     // Clear the buffers and propagate divisor to the driver.
1410*8975f5c5SAndroid Build Coastguard Worker     // We keep the vao active and propagate the divisor to guarantee that there are no unresolved
1411*8975f5c5SAndroid Build Coastguard Worker     // dirty bits when useProgram is called.
1412*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(stubProgram);
1413*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1414*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1415*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribDivisor(1, 1);
1416*8975f5c5SAndroid Build Coastguard Worker     glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 1);
1417*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
1418*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1419*8975f5c5SAndroid Build Coastguard Worker 
1420*8975f5c5SAndroid Build Coastguard Worker     // Check that useProgram uses the number of views to update the divisor.
1421*8975f5c5SAndroid Build Coastguard Worker     bindMemberDrawFramebuffer();
1422*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1423*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1424*8975f5c5SAndroid Build Coastguard Worker     glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 1);
1425*8975f5c5SAndroid Build Coastguard Worker 
1426*8975f5c5SAndroid Build Coastguard Worker     resolveMultisampledFBO();
1427*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(GLColor::green, GetViewColor(0, 0, 0));
1428*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(GLColor::green, GetViewColor(0, 0, 1));
1429*8975f5c5SAndroid Build Coastguard Worker 
1430*8975f5c5SAndroid Build Coastguard Worker     // We go through similar steps as before.
1431*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(stubProgram);
1432*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1433*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1434*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribDivisor(1, 1);
1435*8975f5c5SAndroid Build Coastguard Worker     glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 1);
1436*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(0);
1437*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1438*8975f5c5SAndroid Build Coastguard Worker 
1439*8975f5c5SAndroid Build Coastguard Worker     // Check that bindVertexArray uses the number of views to update the divisor.
1440*8975f5c5SAndroid Build Coastguard Worker     {
1441*8975f5c5SAndroid Build Coastguard Worker         // Call useProgram with vao[1] being active to guarantee that useProgram will adjust the
1442*8975f5c5SAndroid Build Coastguard Worker         // divisor for vao[1] only.
1443*8975f5c5SAndroid Build Coastguard Worker         bindMemberDrawFramebuffer();
1444*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1445*8975f5c5SAndroid Build Coastguard Worker         glBindVertexArray(vao[1]);
1446*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(program);
1447*8975f5c5SAndroid Build Coastguard Worker         glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 1);
1448*8975f5c5SAndroid Build Coastguard Worker         glBindVertexArray(0);
1449*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1450*8975f5c5SAndroid Build Coastguard Worker     }
1451*8975f5c5SAndroid Build Coastguard Worker     // Bind vao[0] after useProgram is called to ensure that bindVertexArray is the call which
1452*8975f5c5SAndroid Build Coastguard Worker     // adjusts the divisor.
1453*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1454*8975f5c5SAndroid Build Coastguard Worker     glBindVertexArray(vao[0]);
1455*8975f5c5SAndroid Build Coastguard Worker     glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 1);
1456*8975f5c5SAndroid Build Coastguard Worker 
1457*8975f5c5SAndroid Build Coastguard Worker     resolveMultisampledFBO();
1458*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(GLColor::green, GetViewColor(0, 0, 0));
1459*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(GLColor::green, GetViewColor(0, 0, 1));
1460*8975f5c5SAndroid Build Coastguard Worker }
1461*8975f5c5SAndroid Build Coastguard Worker 
1462*8975f5c5SAndroid Build Coastguard Worker // Test that no fragments pass the occlusion query for a multi-view vertex shader which always
1463*8975f5c5SAndroid Build Coastguard Worker // transforms geometry to be outside of the clip region.
TEST_P(MultiviewOcclusionQueryTest,OcclusionQueryNothingVisible)1464*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewOcclusionQueryTest, OcclusionQueryNothingVisible)
1465*8975f5c5SAndroid Build Coastguard Worker {
1466*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
1467*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!requestOcclusionQueryExtension());
1468*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
1469*8975f5c5SAndroid Build Coastguard Worker 
1470*8975f5c5SAndroid Build Coastguard Worker     const std::string VS =
1471*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1472*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1473*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1474*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
1475*8975f5c5SAndroid Build Coastguard Worker         "layout(num_views = 2) in;\n"
1476*8975f5c5SAndroid Build Coastguard Worker         "in vec3 vPosition;\n"
1477*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1478*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1479*8975f5c5SAndroid Build Coastguard Worker         "       gl_Position.x = 2.0;\n"
1480*8975f5c5SAndroid Build Coastguard Worker         "       gl_Position.yzw = vec3(vPosition.yz, 1.);\n"
1481*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1482*8975f5c5SAndroid Build Coastguard Worker 
1483*8975f5c5SAndroid Build Coastguard Worker     const std::string FS =
1484*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1485*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1486*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1487*8975f5c5SAndroid Build Coastguard Worker         " : require\n"
1488*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
1489*8975f5c5SAndroid Build Coastguard Worker         "out vec4 col;\n"
1490*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1491*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1492*8975f5c5SAndroid Build Coastguard Worker         "    col = vec4(1,0,0,0);\n"
1493*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1494*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, VS.c_str(), FS.c_str());
1495*8975f5c5SAndroid Build Coastguard Worker     updateFBOs(1, 1, 2);
1496*8975f5c5SAndroid Build Coastguard Worker 
1497*8975f5c5SAndroid Build Coastguard Worker     GLuint result = drawAndRetrieveOcclusionQueryResult(program);
1498*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1499*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FALSE(result);
1500*8975f5c5SAndroid Build Coastguard Worker }
1501*8975f5c5SAndroid Build Coastguard Worker 
1502*8975f5c5SAndroid Build Coastguard Worker // Test that there are fragments passing the occlusion query if only view 0 can produce
1503*8975f5c5SAndroid Build Coastguard Worker // output.
TEST_P(MultiviewOcclusionQueryTest,OcclusionQueryOnlyLeftVisible)1504*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewOcclusionQueryTest, OcclusionQueryOnlyLeftVisible)
1505*8975f5c5SAndroid Build Coastguard Worker {
1506*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
1507*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!requestOcclusionQueryExtension());
1508*8975f5c5SAndroid Build Coastguard Worker 
1509*8975f5c5SAndroid Build Coastguard Worker     const std::string VS =
1510*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1511*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1512*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1513*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
1514*8975f5c5SAndroid Build Coastguard Worker         "layout(num_views = 2) in;\n"
1515*8975f5c5SAndroid Build Coastguard Worker         "in vec3 vPosition;\n"
1516*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1517*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1518*8975f5c5SAndroid Build Coastguard Worker         "       gl_Position.x = gl_ViewID_OVR == 0u ? vPosition.x : 2.0;\n"
1519*8975f5c5SAndroid Build Coastguard Worker         "       gl_Position.yzw = vec3(vPosition.yz, 1.);\n"
1520*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1521*8975f5c5SAndroid Build Coastguard Worker 
1522*8975f5c5SAndroid Build Coastguard Worker     const std::string FS =
1523*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1524*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1525*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1526*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
1527*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
1528*8975f5c5SAndroid Build Coastguard Worker         "out vec4 col;\n"
1529*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1530*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1531*8975f5c5SAndroid Build Coastguard Worker         "    col = vec4(1,0,0,0);\n"
1532*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1533*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, VS.c_str(), FS.c_str());
1534*8975f5c5SAndroid Build Coastguard Worker     updateFBOs(1, 1, 2);
1535*8975f5c5SAndroid Build Coastguard Worker 
1536*8975f5c5SAndroid Build Coastguard Worker     GLuint result = drawAndRetrieveOcclusionQueryResult(program);
1537*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1538*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_TRUE(result);
1539*8975f5c5SAndroid Build Coastguard Worker }
1540*8975f5c5SAndroid Build Coastguard Worker 
1541*8975f5c5SAndroid Build Coastguard Worker // Test that there are fragments passing the occlusion query if only view 1 can produce
1542*8975f5c5SAndroid Build Coastguard Worker // output.
TEST_P(MultiviewOcclusionQueryTest,OcclusionQueryOnlyRightVisible)1543*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewOcclusionQueryTest, OcclusionQueryOnlyRightVisible)
1544*8975f5c5SAndroid Build Coastguard Worker {
1545*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!requestMultiviewExtension());
1546*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!requestOcclusionQueryExtension());
1547*8975f5c5SAndroid Build Coastguard Worker 
1548*8975f5c5SAndroid Build Coastguard Worker     const std::string VS =
1549*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1550*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1551*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1552*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
1553*8975f5c5SAndroid Build Coastguard Worker         "layout(num_views = 2) in;\n"
1554*8975f5c5SAndroid Build Coastguard Worker         "in vec3 vPosition;\n"
1555*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1556*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1557*8975f5c5SAndroid Build Coastguard Worker         "       gl_Position.x = gl_ViewID_OVR == 1u ? vPosition.x : 2.0;\n"
1558*8975f5c5SAndroid Build Coastguard Worker         "       gl_Position.yzw = vec3(vPosition.yz, 1.);\n"
1559*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1560*8975f5c5SAndroid Build Coastguard Worker 
1561*8975f5c5SAndroid Build Coastguard Worker     const std::string FS =
1562*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1563*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1564*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1565*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
1566*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
1567*8975f5c5SAndroid Build Coastguard Worker         "out vec4 col;\n"
1568*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1569*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1570*8975f5c5SAndroid Build Coastguard Worker         "    col = vec4(1,0,0,0);\n"
1571*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1572*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, VS.c_str(), FS.c_str());
1573*8975f5c5SAndroid Build Coastguard Worker     updateFBOs(1, 1, 2);
1574*8975f5c5SAndroid Build Coastguard Worker 
1575*8975f5c5SAndroid Build Coastguard Worker     GLuint result = drawAndRetrieveOcclusionQueryResult(program);
1576*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1577*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_TRUE(result);
1578*8975f5c5SAndroid Build Coastguard Worker }
1579*8975f5c5SAndroid Build Coastguard Worker 
1580*8975f5c5SAndroid Build Coastguard Worker // Test that a simple multi-view program which doesn't use gl_ViewID_OVR in neither VS nor FS
1581*8975f5c5SAndroid Build Coastguard Worker // compiles and links without an error.
TEST_P(MultiviewProgramGenerationTest,SimpleProgram)1582*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewProgramGenerationTest, SimpleProgram)
1583*8975f5c5SAndroid Build Coastguard Worker {
1584*8975f5c5SAndroid Build Coastguard Worker     if (!requestMultiviewExtension())
1585*8975f5c5SAndroid Build Coastguard Worker     {
1586*8975f5c5SAndroid Build Coastguard Worker         return;
1587*8975f5c5SAndroid Build Coastguard Worker     }
1588*8975f5c5SAndroid Build Coastguard Worker 
1589*8975f5c5SAndroid Build Coastguard Worker     const std::string VS =
1590*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1591*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1592*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1593*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
1594*8975f5c5SAndroid Build Coastguard Worker         "layout(num_views = 2) in;\n"
1595*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1596*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1597*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1598*8975f5c5SAndroid Build Coastguard Worker 
1599*8975f5c5SAndroid Build Coastguard Worker     const std::string FS =
1600*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1601*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1602*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1603*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
1604*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
1605*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1606*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1607*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1608*8975f5c5SAndroid Build Coastguard Worker 
1609*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, VS.c_str(), FS.c_str());
1610*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1611*8975f5c5SAndroid Build Coastguard Worker 
1612*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1613*8975f5c5SAndroid Build Coastguard Worker }
1614*8975f5c5SAndroid Build Coastguard Worker 
1615*8975f5c5SAndroid Build Coastguard Worker // Test that a simple multi-view program which uses gl_ViewID_OVR only in VS compiles and links
1616*8975f5c5SAndroid Build Coastguard Worker // without an error.
TEST_P(MultiviewProgramGenerationTest,UseViewIDInVertexShader)1617*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewProgramGenerationTest, UseViewIDInVertexShader)
1618*8975f5c5SAndroid Build Coastguard Worker {
1619*8975f5c5SAndroid Build Coastguard Worker     if (!requestMultiviewExtension())
1620*8975f5c5SAndroid Build Coastguard Worker     {
1621*8975f5c5SAndroid Build Coastguard Worker         return;
1622*8975f5c5SAndroid Build Coastguard Worker     }
1623*8975f5c5SAndroid Build Coastguard Worker 
1624*8975f5c5SAndroid Build Coastguard Worker     const std::string VS =
1625*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1626*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1627*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1628*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
1629*8975f5c5SAndroid Build Coastguard Worker         "layout(num_views = 2) in;\n"
1630*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1631*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1632*8975f5c5SAndroid Build Coastguard Worker         "   if (gl_ViewID_OVR == 0u) {\n"
1633*8975f5c5SAndroid Build Coastguard Worker         "       gl_Position = vec4(1,0,0,1);\n"
1634*8975f5c5SAndroid Build Coastguard Worker         "   } else {\n"
1635*8975f5c5SAndroid Build Coastguard Worker         "       gl_Position = vec4(-1,0,0,1);\n"
1636*8975f5c5SAndroid Build Coastguard Worker         "   }\n"
1637*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1638*8975f5c5SAndroid Build Coastguard Worker 
1639*8975f5c5SAndroid Build Coastguard Worker     const std::string FS =
1640*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1641*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1642*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1643*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
1644*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
1645*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1646*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1647*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1648*8975f5c5SAndroid Build Coastguard Worker 
1649*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, VS.c_str(), FS.c_str());
1650*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1651*8975f5c5SAndroid Build Coastguard Worker 
1652*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1653*8975f5c5SAndroid Build Coastguard Worker }
1654*8975f5c5SAndroid Build Coastguard Worker 
1655*8975f5c5SAndroid Build Coastguard Worker // Test that a simple multi-view program which uses gl_ViewID_OVR only in FS compiles and links
1656*8975f5c5SAndroid Build Coastguard Worker // without an error.
TEST_P(MultiviewProgramGenerationTest,UseViewIDInFragmentShader)1657*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewProgramGenerationTest, UseViewIDInFragmentShader)
1658*8975f5c5SAndroid Build Coastguard Worker {
1659*8975f5c5SAndroid Build Coastguard Worker     if (!requestMultiviewExtension())
1660*8975f5c5SAndroid Build Coastguard Worker     {
1661*8975f5c5SAndroid Build Coastguard Worker         return;
1662*8975f5c5SAndroid Build Coastguard Worker     }
1663*8975f5c5SAndroid Build Coastguard Worker 
1664*8975f5c5SAndroid Build Coastguard Worker     const std::string VS =
1665*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1666*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1667*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1668*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
1669*8975f5c5SAndroid Build Coastguard Worker         "layout(num_views = 2) in;\n"
1670*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1671*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1672*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1673*8975f5c5SAndroid Build Coastguard Worker 
1674*8975f5c5SAndroid Build Coastguard Worker     const std::string FS =
1675*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1676*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1677*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1678*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
1679*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
1680*8975f5c5SAndroid Build Coastguard Worker         "out vec4 col;\n"
1681*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1682*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1683*8975f5c5SAndroid Build Coastguard Worker         "   if (gl_ViewID_OVR == 0u) {\n"
1684*8975f5c5SAndroid Build Coastguard Worker         "       col = vec4(1,0,0,1);\n"
1685*8975f5c5SAndroid Build Coastguard Worker         "   } else {\n"
1686*8975f5c5SAndroid Build Coastguard Worker         "       col = vec4(-1,0,0,1);\n"
1687*8975f5c5SAndroid Build Coastguard Worker         "   }\n"
1688*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1689*8975f5c5SAndroid Build Coastguard Worker 
1690*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, VS.c_str(), FS.c_str());
1691*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1692*8975f5c5SAndroid Build Coastguard Worker 
1693*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1694*8975f5c5SAndroid Build Coastguard Worker }
1695*8975f5c5SAndroid Build Coastguard Worker 
1696*8975f5c5SAndroid Build Coastguard Worker // The test checks that GL_POINTS is correctly rendered.
TEST_P(MultiviewRenderPrimitiveTest,Points)1697*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewRenderPrimitiveTest, Points)
1698*8975f5c5SAndroid Build Coastguard Worker {
1699*8975f5c5SAndroid Build Coastguard Worker     if (!requestMultiviewExtension())
1700*8975f5c5SAndroid Build Coastguard Worker     {
1701*8975f5c5SAndroid Build Coastguard Worker         return;
1702*8975f5c5SAndroid Build Coastguard Worker     }
1703*8975f5c5SAndroid Build Coastguard Worker 
1704*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
1705*8975f5c5SAndroid Build Coastguard Worker 
1706*8975f5c5SAndroid Build Coastguard Worker     const std::string VS =
1707*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1708*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1709*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1710*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
1711*8975f5c5SAndroid Build Coastguard Worker         "layout(num_views = 2) in;\n"
1712*8975f5c5SAndroid Build Coastguard Worker         "layout(location=0) in vec2 vPosition;\n"
1713*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1714*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1715*8975f5c5SAndroid Build Coastguard Worker         "   gl_PointSize = 1.0;\n"
1716*8975f5c5SAndroid Build Coastguard Worker         "   gl_Position = vec4(vPosition.xy, 0.0, 1.0);\n"
1717*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1718*8975f5c5SAndroid Build Coastguard Worker 
1719*8975f5c5SAndroid Build Coastguard Worker     const std::string FS =
1720*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1721*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1722*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1723*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
1724*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
1725*8975f5c5SAndroid Build Coastguard Worker         "out vec4 col;\n"
1726*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1727*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1728*8975f5c5SAndroid Build Coastguard Worker         "   col = vec4(0,1,0,1);\n"
1729*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1730*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, VS.c_str(), FS.c_str());
1731*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1732*8975f5c5SAndroid Build Coastguard Worker 
1733*8975f5c5SAndroid Build Coastguard Worker     const int kViewWidth  = 4;
1734*8975f5c5SAndroid Build Coastguard Worker     const int kViewHeight = 2;
1735*8975f5c5SAndroid Build Coastguard Worker     const int kNumViews   = 2;
1736*8975f5c5SAndroid Build Coastguard Worker     updateFBOs(kViewWidth, kViewHeight, kNumViews);
1737*8975f5c5SAndroid Build Coastguard Worker 
1738*8975f5c5SAndroid Build Coastguard Worker     std::vector<Vector2I> windowCoordinates = {Vector2I(0, 0), Vector2I(3, 1)};
1739*8975f5c5SAndroid Build Coastguard Worker     std::vector<Vector2> vertexDataInClipSpace =
1740*8975f5c5SAndroid Build Coastguard Worker         ConvertPixelCoordinatesToClipSpace(windowCoordinates, 4, 2);
1741*8975f5c5SAndroid Build Coastguard Worker     setupGeometry(vertexDataInClipSpace);
1742*8975f5c5SAndroid Build Coastguard Worker 
1743*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_POINTS, 0, 2);
1744*8975f5c5SAndroid Build Coastguard Worker 
1745*8975f5c5SAndroid Build Coastguard Worker     const GLubyte expectedGreenChannelData[kNumViews][kViewHeight][kViewWidth] = {
1746*8975f5c5SAndroid Build Coastguard Worker         {{255, 0, 0, 0}, {0, 0, 0, 255}}, {{255, 0, 0, 0}, {0, 0, 0, 255}}};
1747*8975f5c5SAndroid Build Coastguard Worker     checkGreenChannel(expectedGreenChannelData[0][0]);
1748*8975f5c5SAndroid Build Coastguard Worker }
1749*8975f5c5SAndroid Build Coastguard Worker 
1750*8975f5c5SAndroid Build Coastguard Worker // The test checks that GL_LINES is correctly rendered.
1751*8975f5c5SAndroid Build Coastguard Worker // The behavior of this test is not guaranteed by the spec:
1752*8975f5c5SAndroid Build Coastguard Worker // OpenGL ES 3.0.5 (November 3, 2016), Section 3.5.1 Basic Line Segment Rasterization:
1753*8975f5c5SAndroid Build Coastguard Worker // "The coordinates of a fragment produced by the algorithm may not deviate by more than one unit in
1754*8975f5c5SAndroid Build Coastguard Worker // either x or y window coordinates from a corresponding fragment produced by the diamond-exit
1755*8975f5c5SAndroid Build Coastguard Worker // rule."
TEST_P(MultiviewRenderPrimitiveTest,Lines)1756*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewRenderPrimitiveTest, Lines)
1757*8975f5c5SAndroid Build Coastguard Worker {
1758*8975f5c5SAndroid Build Coastguard Worker     if (!requestMultiviewExtension())
1759*8975f5c5SAndroid Build Coastguard Worker     {
1760*8975f5c5SAndroid Build Coastguard Worker         return;
1761*8975f5c5SAndroid Build Coastguard Worker     }
1762*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
1763*8975f5c5SAndroid Build Coastguard Worker 
1764*8975f5c5SAndroid Build Coastguard Worker     GLuint program = CreateSimplePassthroughProgram(2, GetParam().mMultiviewExtension);
1765*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(program, 0u);
1766*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1767*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1768*8975f5c5SAndroid Build Coastguard Worker 
1769*8975f5c5SAndroid Build Coastguard Worker     const int kViewWidth  = 4;
1770*8975f5c5SAndroid Build Coastguard Worker     const int kViewHeight = 2;
1771*8975f5c5SAndroid Build Coastguard Worker     const int kNumViews   = 2;
1772*8975f5c5SAndroid Build Coastguard Worker     updateFBOs(kViewWidth, kViewHeight, kNumViews);
1773*8975f5c5SAndroid Build Coastguard Worker 
1774*8975f5c5SAndroid Build Coastguard Worker     std::vector<Vector2I> windowCoordinates = {Vector2I(0, 0), Vector2I(4, 0)};
1775*8975f5c5SAndroid Build Coastguard Worker     std::vector<Vector2> vertexDataInClipSpace =
1776*8975f5c5SAndroid Build Coastguard Worker         ConvertPixelCoordinatesToClipSpace(windowCoordinates, 4, 2);
1777*8975f5c5SAndroid Build Coastguard Worker     setupGeometry(vertexDataInClipSpace);
1778*8975f5c5SAndroid Build Coastguard Worker 
1779*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_LINES, 0, 2);
1780*8975f5c5SAndroid Build Coastguard Worker 
1781*8975f5c5SAndroid Build Coastguard Worker     const GLubyte expectedGreenChannelData[kNumViews][kViewHeight][kViewWidth] = {
1782*8975f5c5SAndroid Build Coastguard Worker         {{255, 255, 255, 255}, {0, 0, 0, 0}}, {{255, 255, 255, 255}, {0, 0, 0, 0}}};
1783*8975f5c5SAndroid Build Coastguard Worker     checkGreenChannel(expectedGreenChannelData[0][0]);
1784*8975f5c5SAndroid Build Coastguard Worker 
1785*8975f5c5SAndroid Build Coastguard Worker     glDeleteProgram(program);
1786*8975f5c5SAndroid Build Coastguard Worker }
1787*8975f5c5SAndroid Build Coastguard Worker 
1788*8975f5c5SAndroid Build Coastguard Worker // The test checks that GL_LINE_STRIP is correctly rendered.
1789*8975f5c5SAndroid Build Coastguard Worker // The behavior of this test is not guaranteed by the spec:
1790*8975f5c5SAndroid Build Coastguard Worker // OpenGL ES 3.0.5 (November 3, 2016), Section 3.5.1 Basic Line Segment Rasterization:
1791*8975f5c5SAndroid Build Coastguard Worker // "The coordinates of a fragment produced by the algorithm may not deviate by more than one unit in
1792*8975f5c5SAndroid Build Coastguard Worker // either x or y window coordinates from a corresponding fragment produced by the diamond-exit
1793*8975f5c5SAndroid Build Coastguard Worker // rule."
TEST_P(MultiviewRenderPrimitiveTest,LineStrip)1794*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewRenderPrimitiveTest, LineStrip)
1795*8975f5c5SAndroid Build Coastguard Worker {
1796*8975f5c5SAndroid Build Coastguard Worker     if (!requestMultiviewExtension())
1797*8975f5c5SAndroid Build Coastguard Worker     {
1798*8975f5c5SAndroid Build Coastguard Worker         return;
1799*8975f5c5SAndroid Build Coastguard Worker     }
1800*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
1801*8975f5c5SAndroid Build Coastguard Worker 
1802*8975f5c5SAndroid Build Coastguard Worker     GLuint program = CreateSimplePassthroughProgram(2, GetParam().mMultiviewExtension);
1803*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(program, 0u);
1804*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1805*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1806*8975f5c5SAndroid Build Coastguard Worker 
1807*8975f5c5SAndroid Build Coastguard Worker     const int kViewWidth  = 4;
1808*8975f5c5SAndroid Build Coastguard Worker     const int kViewHeight = 2;
1809*8975f5c5SAndroid Build Coastguard Worker     const int kNumViews   = 2;
1810*8975f5c5SAndroid Build Coastguard Worker     updateFBOs(kViewWidth, kViewHeight, kNumViews);
1811*8975f5c5SAndroid Build Coastguard Worker 
1812*8975f5c5SAndroid Build Coastguard Worker     std::vector<Vector2I> windowCoordinates = {Vector2I(0, 0), Vector2I(3, 0), Vector2I(3, 2)};
1813*8975f5c5SAndroid Build Coastguard Worker     std::vector<Vector2> vertexDataInClipSpace =
1814*8975f5c5SAndroid Build Coastguard Worker         ConvertPixelCoordinatesToClipSpace(windowCoordinates, 4, 2);
1815*8975f5c5SAndroid Build Coastguard Worker     setupGeometry(vertexDataInClipSpace);
1816*8975f5c5SAndroid Build Coastguard Worker 
1817*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_LINE_STRIP, 0, 3);
1818*8975f5c5SAndroid Build Coastguard Worker 
1819*8975f5c5SAndroid Build Coastguard Worker     const GLubyte expectedGreenChannelData[kNumViews][kViewHeight][kViewWidth] = {
1820*8975f5c5SAndroid Build Coastguard Worker         {{255, 255, 255, 255}, {0, 0, 0, 255}}, {{255, 255, 255, 255}, {0, 0, 0, 255}}};
1821*8975f5c5SAndroid Build Coastguard Worker     checkGreenChannel(expectedGreenChannelData[0][0]);
1822*8975f5c5SAndroid Build Coastguard Worker 
1823*8975f5c5SAndroid Build Coastguard Worker     glDeleteProgram(program);
1824*8975f5c5SAndroid Build Coastguard Worker }
1825*8975f5c5SAndroid Build Coastguard Worker 
1826*8975f5c5SAndroid Build Coastguard Worker // The test checks that GL_LINE_LOOP is correctly rendered.
1827*8975f5c5SAndroid Build Coastguard Worker // The behavior of this test is not guaranteed by the spec:
1828*8975f5c5SAndroid Build Coastguard Worker // OpenGL ES 3.0.5 (November 3, 2016), Section 3.5.1 Basic Line Segment Rasterization:
1829*8975f5c5SAndroid Build Coastguard Worker // "The coordinates of a fragment produced by the algorithm may not deviate by more than one unit in
1830*8975f5c5SAndroid Build Coastguard Worker // either x or y window coordinates from a corresponding fragment produced by the diamond-exit
1831*8975f5c5SAndroid Build Coastguard Worker // rule."
TEST_P(MultiviewRenderPrimitiveTest,LineLoop)1832*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewRenderPrimitiveTest, LineLoop)
1833*8975f5c5SAndroid Build Coastguard Worker {
1834*8975f5c5SAndroid Build Coastguard Worker     if (!requestMultiviewExtension())
1835*8975f5c5SAndroid Build Coastguard Worker     {
1836*8975f5c5SAndroid Build Coastguard Worker         return;
1837*8975f5c5SAndroid Build Coastguard Worker     }
1838*8975f5c5SAndroid Build Coastguard Worker     // Only this subtest fails on intel-hd-630-ubuntu-stable. Driver bug?
1839*8975f5c5SAndroid Build Coastguard Worker     // https://anglebug.com/42262137
1840*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGL());
1841*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
1842*8975f5c5SAndroid Build Coastguard Worker 
1843*8975f5c5SAndroid Build Coastguard Worker     GLuint program = CreateSimplePassthroughProgram(2, GetParam().mMultiviewExtension);
1844*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(program, 0u);
1845*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1846*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1847*8975f5c5SAndroid Build Coastguard Worker 
1848*8975f5c5SAndroid Build Coastguard Worker     const int kViewWidth  = 4;
1849*8975f5c5SAndroid Build Coastguard Worker     const int kViewHeight = 4;
1850*8975f5c5SAndroid Build Coastguard Worker     const int kNumViews   = 2;
1851*8975f5c5SAndroid Build Coastguard Worker     updateFBOs(kViewWidth, kViewHeight, kNumViews);
1852*8975f5c5SAndroid Build Coastguard Worker 
1853*8975f5c5SAndroid Build Coastguard Worker     std::vector<Vector2I> windowCoordinates = {Vector2I(0, 0), Vector2I(3, 0), Vector2I(3, 3),
1854*8975f5c5SAndroid Build Coastguard Worker                                                Vector2I(0, 3)};
1855*8975f5c5SAndroid Build Coastguard Worker     std::vector<Vector2> vertexDataInClipSpace =
1856*8975f5c5SAndroid Build Coastguard Worker         ConvertPixelCoordinatesToClipSpace(windowCoordinates, 4, 4);
1857*8975f5c5SAndroid Build Coastguard Worker     setupGeometry(vertexDataInClipSpace);
1858*8975f5c5SAndroid Build Coastguard Worker 
1859*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_LINE_LOOP, 0, 4);
1860*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1861*8975f5c5SAndroid Build Coastguard Worker 
1862*8975f5c5SAndroid Build Coastguard Worker     const GLubyte expectedGreenChannelData[kNumViews][kViewHeight][kViewWidth] = {
1863*8975f5c5SAndroid Build Coastguard Worker         {{255, 255, 255, 255}, {255, 0, 0, 255}, {255, 0, 0, 255}, {255, 255, 255, 255}},
1864*8975f5c5SAndroid Build Coastguard Worker         {{255, 255, 255, 255}, {255, 0, 0, 255}, {255, 0, 0, 255}, {255, 255, 255, 255}}};
1865*8975f5c5SAndroid Build Coastguard Worker     checkGreenChannel(expectedGreenChannelData[0][0]);
1866*8975f5c5SAndroid Build Coastguard Worker 
1867*8975f5c5SAndroid Build Coastguard Worker     glDeleteProgram(program);
1868*8975f5c5SAndroid Build Coastguard Worker }
1869*8975f5c5SAndroid Build Coastguard Worker 
1870*8975f5c5SAndroid Build Coastguard Worker // The test checks that GL_TRIANGLE_STRIP is correctly rendered.
TEST_P(MultiviewRenderPrimitiveTest,TriangleStrip)1871*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewRenderPrimitiveTest, TriangleStrip)
1872*8975f5c5SAndroid Build Coastguard Worker {
1873*8975f5c5SAndroid Build Coastguard Worker     if (!requestMultiviewExtension())
1874*8975f5c5SAndroid Build Coastguard Worker     {
1875*8975f5c5SAndroid Build Coastguard Worker         return;
1876*8975f5c5SAndroid Build Coastguard Worker     }
1877*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
1878*8975f5c5SAndroid Build Coastguard Worker 
1879*8975f5c5SAndroid Build Coastguard Worker     GLuint program = CreateSimplePassthroughProgram(2, GetParam().mMultiviewExtension);
1880*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(program, 0u);
1881*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1882*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1883*8975f5c5SAndroid Build Coastguard Worker 
1884*8975f5c5SAndroid Build Coastguard Worker     std::vector<Vector2> vertexDataInClipSpace = {Vector2(1.0f, 0.0f), Vector2(0.0f, 0.0f),
1885*8975f5c5SAndroid Build Coastguard Worker                                                   Vector2(1.0f, 1.0f), Vector2(0.0f, 1.0f)};
1886*8975f5c5SAndroid Build Coastguard Worker     setupGeometry(vertexDataInClipSpace);
1887*8975f5c5SAndroid Build Coastguard Worker 
1888*8975f5c5SAndroid Build Coastguard Worker     const int kViewWidth  = 2;
1889*8975f5c5SAndroid Build Coastguard Worker     const int kViewHeight = 2;
1890*8975f5c5SAndroid Build Coastguard Worker     const int kNumViews   = 2;
1891*8975f5c5SAndroid Build Coastguard Worker     updateFBOs(kViewWidth, kViewHeight, kNumViews);
1892*8975f5c5SAndroid Build Coastguard Worker 
1893*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1894*8975f5c5SAndroid Build Coastguard Worker 
1895*8975f5c5SAndroid Build Coastguard Worker     const GLubyte expectedGreenChannelData[kNumViews][kViewHeight][kViewWidth] = {
1896*8975f5c5SAndroid Build Coastguard Worker         {{0, 0}, {0, 255}}, {{0, 0}, {0, 255}}};
1897*8975f5c5SAndroid Build Coastguard Worker     checkGreenChannel(expectedGreenChannelData[0][0]);
1898*8975f5c5SAndroid Build Coastguard Worker 
1899*8975f5c5SAndroid Build Coastguard Worker     glDeleteProgram(program);
1900*8975f5c5SAndroid Build Coastguard Worker }
1901*8975f5c5SAndroid Build Coastguard Worker 
1902*8975f5c5SAndroid Build Coastguard Worker // The test checks that GL_TRIANGLE_FAN is correctly rendered.
TEST_P(MultiviewRenderPrimitiveTest,TriangleFan)1903*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewRenderPrimitiveTest, TriangleFan)
1904*8975f5c5SAndroid Build Coastguard Worker {
1905*8975f5c5SAndroid Build Coastguard Worker     if (!requestMultiviewExtension())
1906*8975f5c5SAndroid Build Coastguard Worker     {
1907*8975f5c5SAndroid Build Coastguard Worker         return;
1908*8975f5c5SAndroid Build Coastguard Worker     }
1909*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
1910*8975f5c5SAndroid Build Coastguard Worker 
1911*8975f5c5SAndroid Build Coastguard Worker     GLuint program = CreateSimplePassthroughProgram(2, GetParam().mMultiviewExtension);
1912*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(program, 0u);
1913*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1914*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1915*8975f5c5SAndroid Build Coastguard Worker 
1916*8975f5c5SAndroid Build Coastguard Worker     std::vector<Vector2> vertexDataInClipSpace = {Vector2(0.0f, 0.0f), Vector2(0.0f, 1.0f),
1917*8975f5c5SAndroid Build Coastguard Worker                                                   Vector2(1.0f, 1.0f), Vector2(1.0f, 0.0f)};
1918*8975f5c5SAndroid Build Coastguard Worker     setupGeometry(vertexDataInClipSpace);
1919*8975f5c5SAndroid Build Coastguard Worker 
1920*8975f5c5SAndroid Build Coastguard Worker     const int kViewWidth  = 2;
1921*8975f5c5SAndroid Build Coastguard Worker     const int kViewHeight = 2;
1922*8975f5c5SAndroid Build Coastguard Worker     const int kNumViews   = 2;
1923*8975f5c5SAndroid Build Coastguard Worker     updateFBOs(kViewWidth, kViewHeight, kNumViews);
1924*8975f5c5SAndroid Build Coastguard Worker 
1925*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1926*8975f5c5SAndroid Build Coastguard Worker 
1927*8975f5c5SAndroid Build Coastguard Worker     const GLubyte expectedGreenChannelData[kNumViews][kViewHeight][kViewWidth] = {
1928*8975f5c5SAndroid Build Coastguard Worker         {{0, 0}, {0, 255}}, {{0, 0}, {0, 255}}};
1929*8975f5c5SAndroid Build Coastguard Worker     checkGreenChannel(expectedGreenChannelData[0][0]);
1930*8975f5c5SAndroid Build Coastguard Worker 
1931*8975f5c5SAndroid Build Coastguard Worker     glDeleteProgram(program);
1932*8975f5c5SAndroid Build Coastguard Worker }
1933*8975f5c5SAndroid Build Coastguard Worker 
1934*8975f5c5SAndroid Build Coastguard Worker // Verify that re-linking a program adjusts the attribute divisor.
1935*8975f5c5SAndroid Build Coastguard Worker // The test uses instacing to draw for each view a strips of two red quads and two blue quads next
1936*8975f5c5SAndroid Build Coastguard Worker // to each other. The quads' position and color depend on the corresponding attribute divisors.
TEST_P(MultiviewRenderTest,ProgramRelinkUpdatesAttribDivisor)1937*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewRenderTest, ProgramRelinkUpdatesAttribDivisor)
1938*8975f5c5SAndroid Build Coastguard Worker {
1939*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
1940*8975f5c5SAndroid Build Coastguard Worker     if (!requestMultiviewExtension(isMultisampled()))
1941*8975f5c5SAndroid Build Coastguard Worker     {
1942*8975f5c5SAndroid Build Coastguard Worker         return;
1943*8975f5c5SAndroid Build Coastguard Worker     }
1944*8975f5c5SAndroid Build Coastguard Worker 
1945*8975f5c5SAndroid Build Coastguard Worker     // Looks like an incorrect D3D debug layer message is generated on Windows AMD and NVIDIA.
1946*8975f5c5SAndroid Build Coastguard Worker     // May be specific to Windows 7 / Windows Server 2008. http://anglebug.com/42261480
1947*8975f5c5SAndroid Build Coastguard Worker     if (IsWindows() && IsD3D11())
1948*8975f5c5SAndroid Build Coastguard Worker     {
1949*8975f5c5SAndroid Build Coastguard Worker         ignoreD3D11SDKLayersWarnings();
1950*8975f5c5SAndroid Build Coastguard Worker     }
1951*8975f5c5SAndroid Build Coastguard Worker 
1952*8975f5c5SAndroid Build Coastguard Worker     const int kViewWidth  = 4;
1953*8975f5c5SAndroid Build Coastguard Worker     const int kViewHeight = 1;
1954*8975f5c5SAndroid Build Coastguard Worker     const int kNumViews   = 2;
1955*8975f5c5SAndroid Build Coastguard Worker 
1956*8975f5c5SAndroid Build Coastguard Worker     const std::string FS =
1957*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
1958*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
1959*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
1960*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
1961*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
1962*8975f5c5SAndroid Build Coastguard Worker         "in vec4 oColor;\n"
1963*8975f5c5SAndroid Build Coastguard Worker         "out vec4 col;\n"
1964*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
1965*8975f5c5SAndroid Build Coastguard Worker         "{\n"
1966*8975f5c5SAndroid Build Coastguard Worker         "    col = oColor;\n"
1967*8975f5c5SAndroid Build Coastguard Worker         "}\n";
1968*8975f5c5SAndroid Build Coastguard Worker 
1969*8975f5c5SAndroid Build Coastguard Worker     auto generateVertexShaderSource = [](int numViews, std::string extensionName) -> std::string {
1970*8975f5c5SAndroid Build Coastguard Worker         std::string source =
1971*8975f5c5SAndroid Build Coastguard Worker             "#version 300 es\n"
1972*8975f5c5SAndroid Build Coastguard Worker             "#extension " +
1973*8975f5c5SAndroid Build Coastguard Worker             extensionName +
1974*8975f5c5SAndroid Build Coastguard Worker             ": require\n"
1975*8975f5c5SAndroid Build Coastguard Worker             "layout(num_views = " +
1976*8975f5c5SAndroid Build Coastguard Worker             ToString(numViews) +
1977*8975f5c5SAndroid Build Coastguard Worker             ") in;\n"
1978*8975f5c5SAndroid Build Coastguard Worker             "in vec3 vPosition;\n"
1979*8975f5c5SAndroid Build Coastguard Worker             "in float vOffsetX;\n"
1980*8975f5c5SAndroid Build Coastguard Worker             "in vec4 vColor;\n"
1981*8975f5c5SAndroid Build Coastguard Worker             "out vec4 oColor;\n"
1982*8975f5c5SAndroid Build Coastguard Worker             "void main()\n"
1983*8975f5c5SAndroid Build Coastguard Worker             "{\n"
1984*8975f5c5SAndroid Build Coastguard Worker             "       vec4 p = vec4(vPosition, 1.);\n"
1985*8975f5c5SAndroid Build Coastguard Worker             "       p.x = p.x * 0.25 - 0.75 + vOffsetX;\n"
1986*8975f5c5SAndroid Build Coastguard Worker             "       oColor = vColor;\n"
1987*8975f5c5SAndroid Build Coastguard Worker             "       gl_Position = p;\n"
1988*8975f5c5SAndroid Build Coastguard Worker             "}\n";
1989*8975f5c5SAndroid Build Coastguard Worker         return source;
1990*8975f5c5SAndroid Build Coastguard Worker     };
1991*8975f5c5SAndroid Build Coastguard Worker 
1992*8975f5c5SAndroid Build Coastguard Worker     std::string vsSource = generateVertexShaderSource(kNumViews, extensionName());
1993*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, vsSource.c_str(), FS.c_str());
1994*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1995*8975f5c5SAndroid Build Coastguard Worker 
1996*8975f5c5SAndroid Build Coastguard Worker     GLint positionLoc;
1997*8975f5c5SAndroid Build Coastguard Worker     GLBuffer xOffsetVBO;
1998*8975f5c5SAndroid Build Coastguard Worker     GLint xOffsetLoc;
1999*8975f5c5SAndroid Build Coastguard Worker     GLBuffer colorVBO;
2000*8975f5c5SAndroid Build Coastguard Worker     GLint colorLoc;
2001*8975f5c5SAndroid Build Coastguard Worker 
2002*8975f5c5SAndroid Build Coastguard Worker     {
2003*8975f5c5SAndroid Build Coastguard Worker         // Initialize buffers and setup attributes.
2004*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, xOffsetVBO);
2005*8975f5c5SAndroid Build Coastguard Worker         const GLfloat kXOffsetData[4] = {0.0f, 0.5f, 1.0f, 1.5f};
2006*8975f5c5SAndroid Build Coastguard Worker         glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 4, kXOffsetData, GL_STATIC_DRAW);
2007*8975f5c5SAndroid Build Coastguard Worker         xOffsetLoc = glGetAttribLocation(program, "vOffsetX");
2008*8975f5c5SAndroid Build Coastguard Worker         glVertexAttribPointer(xOffsetLoc, 1, GL_FLOAT, GL_FALSE, 0, 0);
2009*8975f5c5SAndroid Build Coastguard Worker         glVertexAttribDivisor(xOffsetLoc, 1);
2010*8975f5c5SAndroid Build Coastguard Worker         glEnableVertexAttribArray(xOffsetLoc);
2011*8975f5c5SAndroid Build Coastguard Worker 
2012*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, colorVBO);
2013*8975f5c5SAndroid Build Coastguard Worker         const GLColor kColors[2] = {GLColor::red, GLColor::blue};
2014*8975f5c5SAndroid Build Coastguard Worker         glBufferData(GL_ARRAY_BUFFER, sizeof(GLColor) * 2, kColors, GL_STATIC_DRAW);
2015*8975f5c5SAndroid Build Coastguard Worker         colorLoc = glGetAttribLocation(program, "vColor");
2016*8975f5c5SAndroid Build Coastguard Worker         glVertexAttribDivisor(colorLoc, 2);
2017*8975f5c5SAndroid Build Coastguard Worker         glVertexAttribPointer(colorLoc, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0);
2018*8975f5c5SAndroid Build Coastguard Worker         glEnableVertexAttribArray(colorLoc);
2019*8975f5c5SAndroid Build Coastguard Worker 
2020*8975f5c5SAndroid Build Coastguard Worker         positionLoc = glGetAttribLocation(program, "vPosition");
2021*8975f5c5SAndroid Build Coastguard Worker     }
2022*8975f5c5SAndroid Build Coastguard Worker 
2023*8975f5c5SAndroid Build Coastguard Worker     {
2024*8975f5c5SAndroid Build Coastguard Worker         updateFBOs(kViewWidth, kViewHeight, kNumViews);
2025*8975f5c5SAndroid Build Coastguard Worker 
2026*8975f5c5SAndroid Build Coastguard Worker         drawQuadInstanced(program, "vPosition", 0.0f, 1.0f, true, 4u);
2027*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2028*8975f5c5SAndroid Build Coastguard Worker 
2029*8975f5c5SAndroid Build Coastguard Worker         resolveMultisampledFBO();
2030*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(GLColor::red, GetViewColor(0, 0, 0));
2031*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(GLColor::red, GetViewColor(1, 0, 0));
2032*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(GLColor::blue, GetViewColor(2, 0, 0));
2033*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(GLColor::blue, GetViewColor(3, 0, 0));
2034*8975f5c5SAndroid Build Coastguard Worker     }
2035*8975f5c5SAndroid Build Coastguard Worker 
2036*8975f5c5SAndroid Build Coastguard Worker     {
2037*8975f5c5SAndroid Build Coastguard Worker         const int kNewNumViews = 3;
2038*8975f5c5SAndroid Build Coastguard Worker         vsSource               = generateVertexShaderSource(kNewNumViews, extensionName());
2039*8975f5c5SAndroid Build Coastguard Worker         updateFBOs(kViewWidth, kViewHeight, kNewNumViews);
2040*8975f5c5SAndroid Build Coastguard Worker 
2041*8975f5c5SAndroid Build Coastguard Worker         GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource.c_str());
2042*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(0u, vs);
2043*8975f5c5SAndroid Build Coastguard Worker         GLuint fs = CompileShader(GL_FRAGMENT_SHADER, FS.c_str());
2044*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(0u, fs);
2045*8975f5c5SAndroid Build Coastguard Worker 
2046*8975f5c5SAndroid Build Coastguard Worker         GLint numAttachedShaders = 0;
2047*8975f5c5SAndroid Build Coastguard Worker         glGetProgramiv(program, GL_ATTACHED_SHADERS, &numAttachedShaders);
2048*8975f5c5SAndroid Build Coastguard Worker 
2049*8975f5c5SAndroid Build Coastguard Worker         GLuint attachedShaders[2] = {0u};
2050*8975f5c5SAndroid Build Coastguard Worker         glGetAttachedShaders(program, numAttachedShaders, nullptr, attachedShaders);
2051*8975f5c5SAndroid Build Coastguard Worker         for (int i = 0; i < 2; ++i)
2052*8975f5c5SAndroid Build Coastguard Worker         {
2053*8975f5c5SAndroid Build Coastguard Worker             glDetachShader(program, attachedShaders[i]);
2054*8975f5c5SAndroid Build Coastguard Worker         }
2055*8975f5c5SAndroid Build Coastguard Worker 
2056*8975f5c5SAndroid Build Coastguard Worker         glAttachShader(program, vs);
2057*8975f5c5SAndroid Build Coastguard Worker         glDeleteShader(vs);
2058*8975f5c5SAndroid Build Coastguard Worker 
2059*8975f5c5SAndroid Build Coastguard Worker         glAttachShader(program, fs);
2060*8975f5c5SAndroid Build Coastguard Worker         glDeleteShader(fs);
2061*8975f5c5SAndroid Build Coastguard Worker 
2062*8975f5c5SAndroid Build Coastguard Worker         glBindAttribLocation(program, positionLoc, "vPosition");
2063*8975f5c5SAndroid Build Coastguard Worker         glBindAttribLocation(program, xOffsetLoc, "vOffsetX");
2064*8975f5c5SAndroid Build Coastguard Worker         glBindAttribLocation(program, colorLoc, "vColor");
2065*8975f5c5SAndroid Build Coastguard Worker 
2066*8975f5c5SAndroid Build Coastguard Worker         glLinkProgram(program);
2067*8975f5c5SAndroid Build Coastguard Worker 
2068*8975f5c5SAndroid Build Coastguard Worker         drawQuadInstanced(program, "vPosition", 0.0f, 1.0f, true, 4u);
2069*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2070*8975f5c5SAndroid Build Coastguard Worker 
2071*8975f5c5SAndroid Build Coastguard Worker         resolveMultisampledFBO();
2072*8975f5c5SAndroid Build Coastguard Worker         for (int i = 0; i < kNewNumViews; ++i)
2073*8975f5c5SAndroid Build Coastguard Worker         {
2074*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(GLColor::red, GetViewColor(0, 0, i));
2075*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(GLColor::red, GetViewColor(1, 0, i));
2076*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(GLColor::blue, GetViewColor(2, 0, i));
2077*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(GLColor::blue, GetViewColor(3, 0, i));
2078*8975f5c5SAndroid Build Coastguard Worker         }
2079*8975f5c5SAndroid Build Coastguard Worker     }
2080*8975f5c5SAndroid Build Coastguard Worker }
2081*8975f5c5SAndroid Build Coastguard Worker 
2082*8975f5c5SAndroid Build Coastguard Worker // Test that useProgram applies the number of views in computing the final value of the attribute
2083*8975f5c5SAndroid Build Coastguard Worker // divisor.
TEST_P(MultiviewRenderTest,DivisorUpdatedOnProgramChange)2084*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewRenderTest, DivisorUpdatedOnProgramChange)
2085*8975f5c5SAndroid Build Coastguard Worker {
2086*8975f5c5SAndroid Build Coastguard Worker     if (!requestMultiviewExtension(isMultisampled()))
2087*8975f5c5SAndroid Build Coastguard Worker     {
2088*8975f5c5SAndroid Build Coastguard Worker         return;
2089*8975f5c5SAndroid Build Coastguard Worker     }
2090*8975f5c5SAndroid Build Coastguard Worker 
2091*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
2092*8975f5c5SAndroid Build Coastguard Worker 
2093*8975f5c5SAndroid Build Coastguard Worker     // Looks like an incorrect D3D debug layer message is generated on Windows / AMD.
2094*8975f5c5SAndroid Build Coastguard Worker     // May be specific to Windows 7 / Windows Server 2008. http://anglebug.com/42261480
2095*8975f5c5SAndroid Build Coastguard Worker     if (IsWindows() && IsD3D11())
2096*8975f5c5SAndroid Build Coastguard Worker     {
2097*8975f5c5SAndroid Build Coastguard Worker         ignoreD3D11SDKLayersWarnings();
2098*8975f5c5SAndroid Build Coastguard Worker     }
2099*8975f5c5SAndroid Build Coastguard Worker 
2100*8975f5c5SAndroid Build Coastguard Worker     GLVertexArray vao;
2101*8975f5c5SAndroid Build Coastguard Worker     glBindVertexArray(vao);
2102*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vbo;
2103*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, vbo);
2104*8975f5c5SAndroid Build Coastguard Worker     std::vector<Vector2I> windowCoordinates = {Vector2I(0, 0), Vector2I(1, 0), Vector2I(2, 0),
2105*8975f5c5SAndroid Build Coastguard Worker                                                Vector2I(3, 0)};
2106*8975f5c5SAndroid Build Coastguard Worker     std::vector<Vector2> vertexDataInClipSpace =
2107*8975f5c5SAndroid Build Coastguard Worker         ConvertPixelCoordinatesToClipSpace(windowCoordinates, 4, 1);
2108*8975f5c5SAndroid Build Coastguard Worker     // Fill with x positions so that the resulting clip space coordinate fails the clip test.
2109*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, sizeof(Vector2) * vertexDataInClipSpace.size(),
2110*8975f5c5SAndroid Build Coastguard Worker                  vertexDataInClipSpace.data(), GL_STATIC_DRAW);
2111*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(0);
2112*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(0, 2, GL_FLOAT, 0, 0, nullptr);
2113*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribDivisor(0, 1);
2114*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
2115*8975f5c5SAndroid Build Coastguard Worker 
2116*8975f5c5SAndroid Build Coastguard Worker     // Create a program and fbo with N views and draw N instances of a point horizontally.
2117*8975f5c5SAndroid Build Coastguard Worker     for (int numViews = 2; numViews <= 4; ++numViews)
2118*8975f5c5SAndroid Build Coastguard Worker     {
2119*8975f5c5SAndroid Build Coastguard Worker         updateFBOs(4, 1, numViews);
2120*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2121*8975f5c5SAndroid Build Coastguard Worker 
2122*8975f5c5SAndroid Build Coastguard Worker         GLuint program = CreateSimplePassthroughProgram(numViews, GetParam().mMultiviewExtension);
2123*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(program, 0u);
2124*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(program);
2125*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2126*8975f5c5SAndroid Build Coastguard Worker 
2127*8975f5c5SAndroid Build Coastguard Worker         glDrawArraysInstanced(GL_POINTS, 0, 1, numViews);
2128*8975f5c5SAndroid Build Coastguard Worker 
2129*8975f5c5SAndroid Build Coastguard Worker         resolveMultisampledFBO();
2130*8975f5c5SAndroid Build Coastguard Worker         for (int view = 0; view < numViews; ++view)
2131*8975f5c5SAndroid Build Coastguard Worker         {
2132*8975f5c5SAndroid Build Coastguard Worker             for (int j = 0; j < numViews; ++j)
2133*8975f5c5SAndroid Build Coastguard Worker             {
2134*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_EQ(GLColor::green, GetViewColor(j, 0, view));
2135*8975f5c5SAndroid Build Coastguard Worker             }
2136*8975f5c5SAndroid Build Coastguard Worker             for (int j = numViews; j < 4; ++j)
2137*8975f5c5SAndroid Build Coastguard Worker             {
2138*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_EQ(GLColor::transparentBlack, GetViewColor(j, 0, view));
2139*8975f5c5SAndroid Build Coastguard Worker             }
2140*8975f5c5SAndroid Build Coastguard Worker         }
2141*8975f5c5SAndroid Build Coastguard Worker 
2142*8975f5c5SAndroid Build Coastguard Worker         glDeleteProgram(program);
2143*8975f5c5SAndroid Build Coastguard Worker     }
2144*8975f5c5SAndroid Build Coastguard Worker }
2145*8975f5c5SAndroid Build Coastguard Worker 
2146*8975f5c5SAndroid Build Coastguard Worker // The test checks that gl_ViewID_OVR is correctly propagated to the fragment shader.
TEST_P(MultiviewRenderTest,SelectColorBasedOnViewIDOVR)2147*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewRenderTest, SelectColorBasedOnViewIDOVR)
2148*8975f5c5SAndroid Build Coastguard Worker {
2149*8975f5c5SAndroid Build Coastguard Worker     if (!requestMultiviewExtension(isMultisampled()))
2150*8975f5c5SAndroid Build Coastguard Worker     {
2151*8975f5c5SAndroid Build Coastguard Worker         return;
2152*8975f5c5SAndroid Build Coastguard Worker     }
2153*8975f5c5SAndroid Build Coastguard Worker 
2154*8975f5c5SAndroid Build Coastguard Worker     const std::string VS =
2155*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
2156*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
2157*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
2158*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
2159*8975f5c5SAndroid Build Coastguard Worker         "layout(num_views = 3) in;\n"
2160*8975f5c5SAndroid Build Coastguard Worker         "in vec3 vPosition;\n"
2161*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
2162*8975f5c5SAndroid Build Coastguard Worker         "{\n"
2163*8975f5c5SAndroid Build Coastguard Worker         "   gl_Position = vec4(vPosition, 1.);\n"
2164*8975f5c5SAndroid Build Coastguard Worker         "}\n";
2165*8975f5c5SAndroid Build Coastguard Worker 
2166*8975f5c5SAndroid Build Coastguard Worker     const std::string FS =
2167*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
2168*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
2169*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
2170*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
2171*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
2172*8975f5c5SAndroid Build Coastguard Worker         "out vec4 col;\n"
2173*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
2174*8975f5c5SAndroid Build Coastguard Worker         "{\n"
2175*8975f5c5SAndroid Build Coastguard Worker         "    if (gl_ViewID_OVR == 0u) {\n"
2176*8975f5c5SAndroid Build Coastguard Worker         "       col = vec4(1,0,0,1);\n"
2177*8975f5c5SAndroid Build Coastguard Worker         "    } else if (gl_ViewID_OVR == 1u) {\n"
2178*8975f5c5SAndroid Build Coastguard Worker         "       col = vec4(0,1,0,1);\n"
2179*8975f5c5SAndroid Build Coastguard Worker         "    } else if (gl_ViewID_OVR == 2u) {\n"
2180*8975f5c5SAndroid Build Coastguard Worker         "       col = vec4(0,0,1,1);\n"
2181*8975f5c5SAndroid Build Coastguard Worker         "    } else {\n"
2182*8975f5c5SAndroid Build Coastguard Worker         "       col = vec4(0,0,0,0);\n"
2183*8975f5c5SAndroid Build Coastguard Worker         "    }\n"
2184*8975f5c5SAndroid Build Coastguard Worker         "}\n";
2185*8975f5c5SAndroid Build Coastguard Worker 
2186*8975f5c5SAndroid Build Coastguard Worker     updateFBOs(1, 1, 3);
2187*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, VS.c_str(), FS.c_str());
2188*8975f5c5SAndroid Build Coastguard Worker 
2189*8975f5c5SAndroid Build Coastguard Worker     drawQuad(program, "vPosition", 0.0f, 1.0f, true);
2190*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
2191*8975f5c5SAndroid Build Coastguard Worker 
2192*8975f5c5SAndroid Build Coastguard Worker     resolveMultisampledFBO();
2193*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(GLColor::red, GetViewColor(0, 0, 0));
2194*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(GLColor::green, GetViewColor(0, 0, 1));
2195*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(GLColor::blue, GetViewColor(0, 0, 2));
2196*8975f5c5SAndroid Build Coastguard Worker }
2197*8975f5c5SAndroid Build Coastguard Worker 
2198*8975f5c5SAndroid Build Coastguard Worker // The test checks that the inactive layers of a 2D texture array are not written to by a
2199*8975f5c5SAndroid Build Coastguard Worker // multi-view program.
TEST_P(MultiviewLayeredRenderTest,RenderToSubrangeOfLayers)2200*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewLayeredRenderTest, RenderToSubrangeOfLayers)
2201*8975f5c5SAndroid Build Coastguard Worker {
2202*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
2203*8975f5c5SAndroid Build Coastguard Worker     if (!requestMultiviewExtension())
2204*8975f5c5SAndroid Build Coastguard Worker     {
2205*8975f5c5SAndroid Build Coastguard Worker         return;
2206*8975f5c5SAndroid Build Coastguard Worker     }
2207*8975f5c5SAndroid Build Coastguard Worker 
2208*8975f5c5SAndroid Build Coastguard Worker     const std::string VS =
2209*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
2210*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
2211*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
2212*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
2213*8975f5c5SAndroid Build Coastguard Worker         "layout(num_views = 2) in;\n"
2214*8975f5c5SAndroid Build Coastguard Worker         "in vec3 vPosition;\n"
2215*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
2216*8975f5c5SAndroid Build Coastguard Worker         "{\n"
2217*8975f5c5SAndroid Build Coastguard Worker         "   gl_Position = vec4(vPosition, 1.);\n"
2218*8975f5c5SAndroid Build Coastguard Worker         "}\n";
2219*8975f5c5SAndroid Build Coastguard Worker 
2220*8975f5c5SAndroid Build Coastguard Worker     const std::string FS =
2221*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
2222*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
2223*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
2224*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
2225*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
2226*8975f5c5SAndroid Build Coastguard Worker         "out vec4 col;\n"
2227*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
2228*8975f5c5SAndroid Build Coastguard Worker         "{\n"
2229*8975f5c5SAndroid Build Coastguard Worker         "     col = vec4(0,1,0,1);\n"
2230*8975f5c5SAndroid Build Coastguard Worker         "}\n";
2231*8975f5c5SAndroid Build Coastguard Worker 
2232*8975f5c5SAndroid Build Coastguard Worker     updateFBOs(1, 1, 2, 4, 1);
2233*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, VS.c_str(), FS.c_str());
2234*8975f5c5SAndroid Build Coastguard Worker 
2235*8975f5c5SAndroid Build Coastguard Worker     drawQuad(program, "vPosition", 0.0f, 1.0f, true);
2236*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
2237*8975f5c5SAndroid Build Coastguard Worker 
2238*8975f5c5SAndroid Build Coastguard Worker     resolveMultisampledFBO();
2239*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(GLColor::transparentBlack, GetViewColor(0, 0, 0));
2240*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(GLColor::green, GetViewColor(0, 0, 1));
2241*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(GLColor::green, GetViewColor(0, 0, 2));
2242*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(GLColor::transparentBlack, GetViewColor(0, 0, 3));
2243*8975f5c5SAndroid Build Coastguard Worker }
2244*8975f5c5SAndroid Build Coastguard Worker 
2245*8975f5c5SAndroid Build Coastguard Worker // The D3D11 renderer uses a GS whenever the varyings are flat interpolated which can cause
2246*8975f5c5SAndroid Build Coastguard Worker // potential bugs if the view is selected in the VS. The test contains a program in which the
2247*8975f5c5SAndroid Build Coastguard Worker // gl_InstanceID is passed as a flat varying to the fragment shader where it is used to discard the
2248*8975f5c5SAndroid Build Coastguard Worker // fragment if its value is negative. The gl_InstanceID should never be negative and that branch is
2249*8975f5c5SAndroid Build Coastguard Worker // never taken. One quad is drawn and the color is selected based on the ViewID - red for view 0 and
2250*8975f5c5SAndroid Build Coastguard Worker // green for view 1.
TEST_P(MultiviewRenderTest,FlatInterpolation)2251*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewRenderTest, FlatInterpolation)
2252*8975f5c5SAndroid Build Coastguard Worker {
2253*8975f5c5SAndroid Build Coastguard Worker     if (!requestMultiviewExtension(isMultisampled()))
2254*8975f5c5SAndroid Build Coastguard Worker     {
2255*8975f5c5SAndroid Build Coastguard Worker         return;
2256*8975f5c5SAndroid Build Coastguard Worker     }
2257*8975f5c5SAndroid Build Coastguard Worker 
2258*8975f5c5SAndroid Build Coastguard Worker     const std::string VS =
2259*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
2260*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
2261*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
2262*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
2263*8975f5c5SAndroid Build Coastguard Worker         "layout(num_views = 2) in;\n"
2264*8975f5c5SAndroid Build Coastguard Worker         "in vec3 vPosition;\n"
2265*8975f5c5SAndroid Build Coastguard Worker         "flat out int oInstanceID;\n"
2266*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
2267*8975f5c5SAndroid Build Coastguard Worker         "{\n"
2268*8975f5c5SAndroid Build Coastguard Worker         "   gl_Position = vec4(vPosition, 1.);\n"
2269*8975f5c5SAndroid Build Coastguard Worker         "   oInstanceID = gl_InstanceID;\n"
2270*8975f5c5SAndroid Build Coastguard Worker         "}\n";
2271*8975f5c5SAndroid Build Coastguard Worker 
2272*8975f5c5SAndroid Build Coastguard Worker     const std::string FS =
2273*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
2274*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
2275*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
2276*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
2277*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
2278*8975f5c5SAndroid Build Coastguard Worker         "flat in int oInstanceID;\n"
2279*8975f5c5SAndroid Build Coastguard Worker         "out vec4 col;\n"
2280*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
2281*8975f5c5SAndroid Build Coastguard Worker         "{\n"
2282*8975f5c5SAndroid Build Coastguard Worker         "    if (oInstanceID < 0) {\n"
2283*8975f5c5SAndroid Build Coastguard Worker         "       discard;\n"
2284*8975f5c5SAndroid Build Coastguard Worker         "    }\n"
2285*8975f5c5SAndroid Build Coastguard Worker         "    if (gl_ViewID_OVR == 0u) {\n"
2286*8975f5c5SAndroid Build Coastguard Worker         "       col = vec4(1,0,0,1);\n"
2287*8975f5c5SAndroid Build Coastguard Worker         "    } else {\n"
2288*8975f5c5SAndroid Build Coastguard Worker         "       col = vec4(0,1,0,1);\n"
2289*8975f5c5SAndroid Build Coastguard Worker         "    }\n"
2290*8975f5c5SAndroid Build Coastguard Worker         "}\n";
2291*8975f5c5SAndroid Build Coastguard Worker 
2292*8975f5c5SAndroid Build Coastguard Worker     updateFBOs(1, 1, 2);
2293*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, VS.c_str(), FS.c_str());
2294*8975f5c5SAndroid Build Coastguard Worker 
2295*8975f5c5SAndroid Build Coastguard Worker     drawQuad(program, "vPosition", 0.0f, 1.0f, true);
2296*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
2297*8975f5c5SAndroid Build Coastguard Worker 
2298*8975f5c5SAndroid Build Coastguard Worker     resolveMultisampledFBO();
2299*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(GLColor::red, GetViewColor(0, 0, 0));
2300*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(GLColor::green, GetViewColor(0, 0, 1));
2301*8975f5c5SAndroid Build Coastguard Worker }
2302*8975f5c5SAndroid Build Coastguard Worker 
2303*8975f5c5SAndroid Build Coastguard Worker // This test assigns gl_ViewID_OVR to a flat int varying and then sets the color based on that
2304*8975f5c5SAndroid Build Coastguard Worker // varying in the fragment shader.
TEST_P(MultiviewRenderTest,FlatInterpolation2)2305*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewRenderTest, FlatInterpolation2)
2306*8975f5c5SAndroid Build Coastguard Worker {
2307*8975f5c5SAndroid Build Coastguard Worker     if (!requestMultiviewExtension(isMultisampled()))
2308*8975f5c5SAndroid Build Coastguard Worker     {
2309*8975f5c5SAndroid Build Coastguard Worker         return;
2310*8975f5c5SAndroid Build Coastguard Worker     }
2311*8975f5c5SAndroid Build Coastguard Worker 
2312*8975f5c5SAndroid Build Coastguard Worker     const std::string VS =
2313*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
2314*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
2315*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
2316*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
2317*8975f5c5SAndroid Build Coastguard Worker         "layout(num_views = 2) in;\n"
2318*8975f5c5SAndroid Build Coastguard Worker         "in vec3 vPosition;\n"
2319*8975f5c5SAndroid Build Coastguard Worker         "flat out int flatVarying;\n"
2320*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
2321*8975f5c5SAndroid Build Coastguard Worker         "{\n"
2322*8975f5c5SAndroid Build Coastguard Worker         "   gl_Position = vec4(vPosition, 1.);\n"
2323*8975f5c5SAndroid Build Coastguard Worker         "   flatVarying = int(gl_ViewID_OVR);\n"
2324*8975f5c5SAndroid Build Coastguard Worker         "}\n";
2325*8975f5c5SAndroid Build Coastguard Worker 
2326*8975f5c5SAndroid Build Coastguard Worker     const std::string FS =
2327*8975f5c5SAndroid Build Coastguard Worker         "#version 300 es\n"
2328*8975f5c5SAndroid Build Coastguard Worker         "#extension " +
2329*8975f5c5SAndroid Build Coastguard Worker         extensionName() +
2330*8975f5c5SAndroid Build Coastguard Worker         ": require\n"
2331*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
2332*8975f5c5SAndroid Build Coastguard Worker         "flat in int flatVarying;\n"
2333*8975f5c5SAndroid Build Coastguard Worker         "out vec4 col;\n"
2334*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
2335*8975f5c5SAndroid Build Coastguard Worker         "{\n"
2336*8975f5c5SAndroid Build Coastguard Worker         "    if (flatVarying == 0) {\n"
2337*8975f5c5SAndroid Build Coastguard Worker         "       col = vec4(1,0,0,1);\n"
2338*8975f5c5SAndroid Build Coastguard Worker         "    } else {\n"
2339*8975f5c5SAndroid Build Coastguard Worker         "       col = vec4(0,1,0,1);\n"
2340*8975f5c5SAndroid Build Coastguard Worker         "    }\n"
2341*8975f5c5SAndroid Build Coastguard Worker         "}\n";
2342*8975f5c5SAndroid Build Coastguard Worker 
2343*8975f5c5SAndroid Build Coastguard Worker     updateFBOs(1, 1, 2);
2344*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, VS.c_str(), FS.c_str());
2345*8975f5c5SAndroid Build Coastguard Worker 
2346*8975f5c5SAndroid Build Coastguard Worker     drawQuad(program, "vPosition", 0.0f, 1.0f, true);
2347*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
2348*8975f5c5SAndroid Build Coastguard Worker 
2349*8975f5c5SAndroid Build Coastguard Worker     resolveMultisampledFBO();
2350*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(GLColor::red, GetViewColor(0, 0, 0));
2351*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(GLColor::green, GetViewColor(0, 0, 1));
2352*8975f5c5SAndroid Build Coastguard Worker }
2353*8975f5c5SAndroid Build Coastguard Worker 
2354*8975f5c5SAndroid Build Coastguard Worker // Test that shader caching maintains the num_views value used in GL_OVR_multiview between shader
2355*8975f5c5SAndroid Build Coastguard Worker // compilations.
TEST_P(MultiviewRenderTest,ShaderCacheVertexWithOVRMultiview)2356*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultiviewRenderTest, ShaderCacheVertexWithOVRMultiview)
2357*8975f5c5SAndroid Build Coastguard Worker {
2358*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsVulkan());
2359*8975f5c5SAndroid Build Coastguard Worker     if (!requestMultiviewExtension(true))
2360*8975f5c5SAndroid Build Coastguard Worker     {
2361*8975f5c5SAndroid Build Coastguard Worker         return;
2362*8975f5c5SAndroid Build Coastguard Worker     }
2363*8975f5c5SAndroid Build Coastguard Worker 
2364*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVS[] = R"(#version 300 es
2365*8975f5c5SAndroid Build Coastguard Worker #extension GL_OVR_multiview : enable
2366*8975f5c5SAndroid Build Coastguard Worker 
2367*8975f5c5SAndroid Build Coastguard Worker layout (num_views = 2) in;
2368*8975f5c5SAndroid Build Coastguard Worker 
2369*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
2370*8975f5c5SAndroid Build Coastguard Worker 
2371*8975f5c5SAndroid Build Coastguard Worker layout (location = 0) in vec4 a_position;
2372*8975f5c5SAndroid Build Coastguard Worker 
2373*8975f5c5SAndroid Build Coastguard Worker out float redValue;
2374*8975f5c5SAndroid Build Coastguard Worker out float greenValue;
2375*8975f5c5SAndroid Build Coastguard Worker 
2376*8975f5c5SAndroid Build Coastguard Worker void main() {
2377*8975f5c5SAndroid Build Coastguard Worker     gl_Position = a_position;
2378*8975f5c5SAndroid Build Coastguard Worker     if (gl_ViewID_OVR == uint(0))
2379*8975f5c5SAndroid Build Coastguard Worker     {
2380*8975f5c5SAndroid Build Coastguard Worker         redValue = 1.;
2381*8975f5c5SAndroid Build Coastguard Worker         greenValue = 0.;
2382*8975f5c5SAndroid Build Coastguard Worker     }
2383*8975f5c5SAndroid Build Coastguard Worker     else
2384*8975f5c5SAndroid Build Coastguard Worker     {
2385*8975f5c5SAndroid Build Coastguard Worker         redValue = 0.;
2386*8975f5c5SAndroid Build Coastguard Worker         greenValue = 1.;
2387*8975f5c5SAndroid Build Coastguard Worker     }
2388*8975f5c5SAndroid Build Coastguard Worker })";
2389*8975f5c5SAndroid Build Coastguard Worker 
2390*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(#version 300 es
2391*8975f5c5SAndroid Build Coastguard Worker 
2392*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
2393*8975f5c5SAndroid Build Coastguard Worker 
2394*8975f5c5SAndroid Build Coastguard Worker in float redValue;
2395*8975f5c5SAndroid Build Coastguard Worker in float greenValue;
2396*8975f5c5SAndroid Build Coastguard Worker 
2397*8975f5c5SAndroid Build Coastguard Worker out vec4 fragColor;
2398*8975f5c5SAndroid Build Coastguard Worker 
2399*8975f5c5SAndroid Build Coastguard Worker void main()
2400*8975f5c5SAndroid Build Coastguard Worker {
2401*8975f5c5SAndroid Build Coastguard Worker     fragColor = vec4(redValue, greenValue, 0., 1.);
2402*8975f5c5SAndroid Build Coastguard Worker })";
2403*8975f5c5SAndroid Build Coastguard Worker 
2404*8975f5c5SAndroid Build Coastguard Worker     // Only use a single 1x1 FBO
2405*8975f5c5SAndroid Build Coastguard Worker     updateFBOs(1, 1, 2);
2406*8975f5c5SAndroid Build Coastguard Worker 
2407*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(unusedProgram, kVS, kFS);
2408*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
2409*8975f5c5SAndroid Build Coastguard Worker     // Delete the shader and recompile to fetch from cache.
2410*8975f5c5SAndroid Build Coastguard Worker     glDeleteProgram(unusedProgram);
2411*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, kVS, kFS);
2412*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
2413*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
2414*8975f5c5SAndroid Build Coastguard Worker 
2415*8975f5c5SAndroid Build Coastguard Worker     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f, 1.0f, true);
2416*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
2417*8975f5c5SAndroid Build Coastguard Worker 
2418*8975f5c5SAndroid Build Coastguard Worker     resolveMultisampledFBO();
2419*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(GLColor::red, GetViewColor(0, 0, 0));
2420*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(GLColor::green, GetViewColor(0, 0, 1));
2421*8975f5c5SAndroid Build Coastguard Worker }
2422*8975f5c5SAndroid Build Coastguard Worker 
VertexShaderOpenGL(ExtensionName multiviewExtension)2423*8975f5c5SAndroid Build Coastguard Worker MultiviewRenderTestParams VertexShaderOpenGL(ExtensionName multiviewExtension)
2424*8975f5c5SAndroid Build Coastguard Worker {
2425*8975f5c5SAndroid Build Coastguard Worker     return MultiviewRenderTestParams(0, VertexShaderOpenGL(3, 0, multiviewExtension));
2426*8975f5c5SAndroid Build Coastguard Worker }
2427*8975f5c5SAndroid Build Coastguard Worker 
VertexShaderVulkan(ExtensionName multiviewExtension)2428*8975f5c5SAndroid Build Coastguard Worker MultiviewRenderTestParams VertexShaderVulkan(ExtensionName multiviewExtension)
2429*8975f5c5SAndroid Build Coastguard Worker {
2430*8975f5c5SAndroid Build Coastguard Worker     return MultiviewRenderTestParams(0, VertexShaderVulkan(3, 0, multiviewExtension));
2431*8975f5c5SAndroid Build Coastguard Worker }
2432*8975f5c5SAndroid Build Coastguard Worker 
GeomShaderD3D11(ExtensionName multiviewExtension)2433*8975f5c5SAndroid Build Coastguard Worker MultiviewRenderTestParams GeomShaderD3D11(ExtensionName multiviewExtension)
2434*8975f5c5SAndroid Build Coastguard Worker {
2435*8975f5c5SAndroid Build Coastguard Worker     return MultiviewRenderTestParams(0, GeomShaderD3D11(3, 0, multiviewExtension));
2436*8975f5c5SAndroid Build Coastguard Worker }
2437*8975f5c5SAndroid Build Coastguard Worker 
VertexShaderD3D11(ExtensionName multiviewExtension)2438*8975f5c5SAndroid Build Coastguard Worker MultiviewRenderTestParams VertexShaderD3D11(ExtensionName multiviewExtension)
2439*8975f5c5SAndroid Build Coastguard Worker {
2440*8975f5c5SAndroid Build Coastguard Worker     return MultiviewRenderTestParams(0, VertexShaderD3D11(3, 0, multiviewExtension));
2441*8975f5c5SAndroid Build Coastguard Worker }
2442*8975f5c5SAndroid Build Coastguard Worker 
MultisampledVertexShaderOpenGL(ExtensionName multiviewExtension)2443*8975f5c5SAndroid Build Coastguard Worker MultiviewRenderTestParams MultisampledVertexShaderOpenGL(ExtensionName multiviewExtension)
2444*8975f5c5SAndroid Build Coastguard Worker {
2445*8975f5c5SAndroid Build Coastguard Worker     return MultiviewRenderTestParams(2, VertexShaderOpenGL(3, 1, multiviewExtension));
2446*8975f5c5SAndroid Build Coastguard Worker }
2447*8975f5c5SAndroid Build Coastguard Worker 
MultisampledVertexShaderVulkan(ExtensionName multiviewExtension)2448*8975f5c5SAndroid Build Coastguard Worker MultiviewRenderTestParams MultisampledVertexShaderVulkan(ExtensionName multiviewExtension)
2449*8975f5c5SAndroid Build Coastguard Worker {
2450*8975f5c5SAndroid Build Coastguard Worker     return MultiviewRenderTestParams(2, VertexShaderVulkan(3, 1, multiviewExtension));
2451*8975f5c5SAndroid Build Coastguard Worker }
2452*8975f5c5SAndroid Build Coastguard Worker 
MultisampledVertexShaderD3D11(ExtensionName multiviewExtension)2453*8975f5c5SAndroid Build Coastguard Worker MultiviewRenderTestParams MultisampledVertexShaderD3D11(ExtensionName multiviewExtension)
2454*8975f5c5SAndroid Build Coastguard Worker {
2455*8975f5c5SAndroid Build Coastguard Worker     return MultiviewRenderTestParams(2, VertexShaderD3D11(3, 1, multiviewExtension));
2456*8975f5c5SAndroid Build Coastguard Worker }
2457*8975f5c5SAndroid Build Coastguard Worker 
2458*8975f5c5SAndroid Build Coastguard Worker #define ALL_VERTEX_SHADER_CONFIGS(minor)                         \
2459*8975f5c5SAndroid Build Coastguard Worker     VertexShaderOpenGL(3, minor, ExtensionName::multiview),      \
2460*8975f5c5SAndroid Build Coastguard Worker         VertexShaderVulkan(3, minor, ExtensionName::multiview),  \
2461*8975f5c5SAndroid Build Coastguard Worker         VertexShaderD3D11(3, minor, ExtensionName::multiview),   \
2462*8975f5c5SAndroid Build Coastguard Worker         VertexShaderOpenGL(3, minor, ExtensionName::multiview2), \
2463*8975f5c5SAndroid Build Coastguard Worker         VertexShaderVulkan(3, minor, ExtensionName::multiview2), \
2464*8975f5c5SAndroid Build Coastguard Worker         VertexShaderD3D11(3, minor, ExtensionName::multiview2)
2465*8975f5c5SAndroid Build Coastguard Worker 
2466*8975f5c5SAndroid Build Coastguard Worker #define ALL_SINGLESAMPLE_CONFIGS()                                                              \
2467*8975f5c5SAndroid Build Coastguard Worker     VertexShaderOpenGL(ExtensionName::multiview), VertexShaderVulkan(ExtensionName::multiview), \
2468*8975f5c5SAndroid Build Coastguard Worker         VertexShaderD3D11(ExtensionName::multiview), GeomShaderD3D11(ExtensionName::multiview), \
2469*8975f5c5SAndroid Build Coastguard Worker         VertexShaderOpenGL(ExtensionName::multiview2),                                          \
2470*8975f5c5SAndroid Build Coastguard Worker         VertexShaderVulkan(ExtensionName::multiview2),                                          \
2471*8975f5c5SAndroid Build Coastguard Worker         VertexShaderD3D11(ExtensionName::multiview2), GeomShaderD3D11(ExtensionName::multiview2)
2472*8975f5c5SAndroid Build Coastguard Worker 
2473*8975f5c5SAndroid Build Coastguard Worker #define ALL_MULTISAMPLE_CONFIGS()                                  \
2474*8975f5c5SAndroid Build Coastguard Worker     MultisampledVertexShaderOpenGL(ExtensionName::multiview),      \
2475*8975f5c5SAndroid Build Coastguard Worker         MultisampledVertexShaderVulkan(ExtensionName::multiview),  \
2476*8975f5c5SAndroid Build Coastguard Worker         MultisampledVertexShaderD3D11(ExtensionName::multiview),   \
2477*8975f5c5SAndroid Build Coastguard Worker         MultisampledVertexShaderOpenGL(ExtensionName::multiview2), \
2478*8975f5c5SAndroid Build Coastguard Worker         MultisampledVertexShaderVulkan(ExtensionName::multiview2), \
2479*8975f5c5SAndroid Build Coastguard Worker         MultisampledVertexShaderD3D11(ExtensionName::multiview2)
2480*8975f5c5SAndroid Build Coastguard Worker 
2481*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MultiviewDrawValidationTest);
2482*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST(MultiviewDrawValidationTest, ALL_VERTEX_SHADER_CONFIGS(1));
2483*8975f5c5SAndroid Build Coastguard Worker 
2484*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MultiviewRenderDualViewTest);
2485*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST(MultiviewRenderDualViewTest,
2486*8975f5c5SAndroid Build Coastguard Worker                        ALL_SINGLESAMPLE_CONFIGS(),
2487*8975f5c5SAndroid Build Coastguard Worker                        ALL_MULTISAMPLE_CONFIGS());
2488*8975f5c5SAndroid Build Coastguard Worker 
2489*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MultiviewRenderDualViewTestNoWebGL);
2490*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST(MultiviewRenderDualViewTestNoWebGL,
2491*8975f5c5SAndroid Build Coastguard Worker                        ALL_SINGLESAMPLE_CONFIGS(),
2492*8975f5c5SAndroid Build Coastguard Worker                        ALL_MULTISAMPLE_CONFIGS());
2493*8975f5c5SAndroid Build Coastguard Worker 
2494*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MultiviewRenderTest);
2495*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST(MultiviewRenderTest, ALL_SINGLESAMPLE_CONFIGS(), ALL_MULTISAMPLE_CONFIGS());
2496*8975f5c5SAndroid Build Coastguard Worker 
2497*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MultiviewOcclusionQueryTest);
2498*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST(MultiviewOcclusionQueryTest, ALL_SINGLESAMPLE_CONFIGS());
2499*8975f5c5SAndroid Build Coastguard Worker 
2500*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MultiviewProgramGenerationTest);
2501*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST(MultiviewProgramGenerationTest,
2502*8975f5c5SAndroid Build Coastguard Worker                        ALL_VERTEX_SHADER_CONFIGS(0),
2503*8975f5c5SAndroid Build Coastguard Worker                        GeomShaderD3D11(3, 0, ExtensionName::multiview),
2504*8975f5c5SAndroid Build Coastguard Worker                        GeomShaderD3D11(3, 0, ExtensionName::multiview2));
2505*8975f5c5SAndroid Build Coastguard Worker 
2506*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MultiviewRenderPrimitiveTest);
2507*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST(MultiviewRenderPrimitiveTest, ALL_SINGLESAMPLE_CONFIGS());
2508*8975f5c5SAndroid Build Coastguard Worker 
2509*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MultiviewLayeredRenderTest);
2510*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST(MultiviewLayeredRenderTest, ALL_SINGLESAMPLE_CONFIGS());
2511