xref: /aosp_15_r20/external/angle/src/tests/egl_tests/EGLStreamTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2016 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 // EGLStreamTest:
7*8975f5c5SAndroid Build Coastguard Worker //   Tests pertaining to egl::Stream.
8*8975f5c5SAndroid Build Coastguard Worker //
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #include <gtest/gtest.h>
11*8975f5c5SAndroid Build Coastguard Worker 
12*8975f5c5SAndroid Build Coastguard Worker #include <d3d11.h>
13*8975f5c5SAndroid Build Coastguard Worker #include <vector>
14*8975f5c5SAndroid Build Coastguard Worker 
15*8975f5c5SAndroid Build Coastguard Worker #include "media/yuvtest.inl"
16*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "util/EGLWindow.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "util/OSWindow.h"
20*8975f5c5SAndroid Build Coastguard Worker 
21*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
22*8975f5c5SAndroid Build Coastguard Worker 
23*8975f5c5SAndroid Build Coastguard Worker namespace
24*8975f5c5SAndroid Build Coastguard Worker {
25*8975f5c5SAndroid Build Coastguard Worker 
CheckTextureSupport(ID3D11Device * device,DXGI_FORMAT format)26*8975f5c5SAndroid Build Coastguard Worker bool CheckTextureSupport(ID3D11Device *device, DXGI_FORMAT format)
27*8975f5c5SAndroid Build Coastguard Worker {
28*8975f5c5SAndroid Build Coastguard Worker     HRESULT result;
29*8975f5c5SAndroid Build Coastguard Worker     UINT formatSupport;
30*8975f5c5SAndroid Build Coastguard Worker     result = device->CheckFormatSupport(DXGI_FORMAT_NV12, &formatSupport);
31*8975f5c5SAndroid Build Coastguard Worker     if (result == E_FAIL)
32*8975f5c5SAndroid Build Coastguard Worker     {
33*8975f5c5SAndroid Build Coastguard Worker         return false;
34*8975f5c5SAndroid Build Coastguard Worker     }
35*8975f5c5SAndroid Build Coastguard Worker     return (formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0;
36*8975f5c5SAndroid Build Coastguard Worker }
37*8975f5c5SAndroid Build Coastguard Worker 
CheckNV12TextureSupport(ID3D11Device * device)38*8975f5c5SAndroid Build Coastguard Worker bool CheckNV12TextureSupport(ID3D11Device *device)
39*8975f5c5SAndroid Build Coastguard Worker {
40*8975f5c5SAndroid Build Coastguard Worker     return CheckTextureSupport(device, DXGI_FORMAT_NV12);
41*8975f5c5SAndroid Build Coastguard Worker }
42*8975f5c5SAndroid Build Coastguard Worker 
CheckP010TextureSupport(ID3D11Device * device)43*8975f5c5SAndroid Build Coastguard Worker bool CheckP010TextureSupport(ID3D11Device *device)
44*8975f5c5SAndroid Build Coastguard Worker {
45*8975f5c5SAndroid Build Coastguard Worker     return CheckTextureSupport(device, DXGI_FORMAT_P010);
46*8975f5c5SAndroid Build Coastguard Worker }
47*8975f5c5SAndroid Build Coastguard Worker 
48*8975f5c5SAndroid Build Coastguard Worker class EGLStreamTest : public ANGLETest<>
49*8975f5c5SAndroid Build Coastguard Worker {
50*8975f5c5SAndroid Build Coastguard Worker   protected:
EGLStreamTest()51*8975f5c5SAndroid Build Coastguard Worker     EGLStreamTest()
52*8975f5c5SAndroid Build Coastguard Worker     {
53*8975f5c5SAndroid Build Coastguard Worker         setWindowWidth(128);
54*8975f5c5SAndroid Build Coastguard Worker         setWindowHeight(128);
55*8975f5c5SAndroid Build Coastguard Worker         setConfigRedBits(8);
56*8975f5c5SAndroid Build Coastguard Worker         setConfigGreenBits(8);
57*8975f5c5SAndroid Build Coastguard Worker         setConfigBlueBits(8);
58*8975f5c5SAndroid Build Coastguard Worker         setConfigAlphaBits(8);
59*8975f5c5SAndroid Build Coastguard Worker         setConfigDepthBits(24);
60*8975f5c5SAndroid Build Coastguard Worker     }
61*8975f5c5SAndroid Build Coastguard Worker };
62*8975f5c5SAndroid Build Coastguard Worker 
63*8975f5c5SAndroid Build Coastguard Worker // Tests validation of the stream API
TEST_P(EGLStreamTest,StreamValidationTest)64*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLStreamTest, StreamValidationTest)
65*8975f5c5SAndroid Build Coastguard Worker {
66*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window            = getEGLWindow();
67*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display           = window->getDisplay();
68*8975f5c5SAndroid Build Coastguard Worker     const char *extensionsString = eglQueryString(display, EGL_EXTENSIONS);
69*8975f5c5SAndroid Build Coastguard Worker     if (strstr(extensionsString, "EGL_KHR_stream") == nullptr)
70*8975f5c5SAndroid Build Coastguard Worker     {
71*8975f5c5SAndroid Build Coastguard Worker         std::cout << "Stream extension not supported" << std::endl;
72*8975f5c5SAndroid Build Coastguard Worker         return;
73*8975f5c5SAndroid Build Coastguard Worker     }
74*8975f5c5SAndroid Build Coastguard Worker 
75*8975f5c5SAndroid Build Coastguard Worker     const EGLint streamAttributesBad[] = {
76*8975f5c5SAndroid Build Coastguard Worker         EGL_STREAM_STATE_KHR,
77*8975f5c5SAndroid Build Coastguard Worker         0,
78*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
79*8975f5c5SAndroid Build Coastguard Worker         EGL_PRODUCER_FRAME_KHR,
80*8975f5c5SAndroid Build Coastguard Worker         0,
81*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
82*8975f5c5SAndroid Build Coastguard Worker         EGL_CONSUMER_FRAME_KHR,
83*8975f5c5SAndroid Build Coastguard Worker         0,
84*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
85*8975f5c5SAndroid Build Coastguard Worker         EGL_CONSUMER_LATENCY_USEC_KHR,
86*8975f5c5SAndroid Build Coastguard Worker         -1,
87*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
88*8975f5c5SAndroid Build Coastguard Worker         EGL_RED_SIZE,
89*8975f5c5SAndroid Build Coastguard Worker         EGL_DONT_CARE,
90*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
91*8975f5c5SAndroid Build Coastguard Worker     };
92*8975f5c5SAndroid Build Coastguard Worker 
93*8975f5c5SAndroid Build Coastguard Worker     // Validate create stream attributes
94*8975f5c5SAndroid Build Coastguard Worker     EGLStreamKHR stream = eglCreateStreamKHR(display, &streamAttributesBad[0]);
95*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_ERROR(EGL_BAD_ACCESS);
96*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(EGL_NO_STREAM_KHR, stream);
97*8975f5c5SAndroid Build Coastguard Worker 
98*8975f5c5SAndroid Build Coastguard Worker     stream = eglCreateStreamKHR(display, &streamAttributesBad[3]);
99*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_ERROR(EGL_BAD_ACCESS);
100*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(EGL_NO_STREAM_KHR, stream);
101*8975f5c5SAndroid Build Coastguard Worker 
102*8975f5c5SAndroid Build Coastguard Worker     stream = eglCreateStreamKHR(display, &streamAttributesBad[6]);
103*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_ERROR(EGL_BAD_ACCESS);
104*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(EGL_NO_STREAM_KHR, stream);
105*8975f5c5SAndroid Build Coastguard Worker 
106*8975f5c5SAndroid Build Coastguard Worker     stream = eglCreateStreamKHR(display, &streamAttributesBad[9]);
107*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_ERROR(EGL_BAD_PARAMETER);
108*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(EGL_NO_STREAM_KHR, stream);
109*8975f5c5SAndroid Build Coastguard Worker 
110*8975f5c5SAndroid Build Coastguard Worker     stream = eglCreateStreamKHR(display, &streamAttributesBad[12]);
111*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
112*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(EGL_NO_STREAM_KHR, stream);
113*8975f5c5SAndroid Build Coastguard Worker 
114*8975f5c5SAndroid Build Coastguard Worker     const EGLint streamAttributes[] = {
115*8975f5c5SAndroid Build Coastguard Worker         EGL_CONSUMER_LATENCY_USEC_KHR,
116*8975f5c5SAndroid Build Coastguard Worker         0,
117*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
118*8975f5c5SAndroid Build Coastguard Worker     };
119*8975f5c5SAndroid Build Coastguard Worker 
120*8975f5c5SAndroid Build Coastguard Worker     stream = eglCreateStreamKHR(EGL_NO_DISPLAY, streamAttributes);
121*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_ERROR(EGL_BAD_DISPLAY);
122*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(EGL_NO_STREAM_KHR, stream);
123*8975f5c5SAndroid Build Coastguard Worker 
124*8975f5c5SAndroid Build Coastguard Worker     // Create an actual stream
125*8975f5c5SAndroid Build Coastguard Worker     stream = eglCreateStreamKHR(display, streamAttributes);
126*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
127*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(EGL_NO_STREAM_KHR, stream);
128*8975f5c5SAndroid Build Coastguard Worker 
129*8975f5c5SAndroid Build Coastguard Worker     // Assert it is in the created state
130*8975f5c5SAndroid Build Coastguard Worker     EGLint state;
131*8975f5c5SAndroid Build Coastguard Worker     eglQueryStreamKHR(display, stream, EGL_STREAM_STATE_KHR, &state);
132*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
133*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(EGL_STREAM_STATE_CREATED_KHR, state);
134*8975f5c5SAndroid Build Coastguard Worker 
135*8975f5c5SAndroid Build Coastguard Worker     // Test getting and setting the latency
136*8975f5c5SAndroid Build Coastguard Worker     EGLint latency = 10;
137*8975f5c5SAndroid Build Coastguard Worker     eglStreamAttribKHR(display, stream, EGL_CONSUMER_LATENCY_USEC_KHR, latency);
138*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
139*8975f5c5SAndroid Build Coastguard Worker     eglQueryStreamKHR(display, stream, EGL_CONSUMER_LATENCY_USEC_KHR, &latency);
140*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
141*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(10, latency);
142*8975f5c5SAndroid Build Coastguard Worker     eglStreamAttribKHR(display, stream, EGL_CONSUMER_LATENCY_USEC_KHR, -1);
143*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_ERROR(EGL_BAD_PARAMETER);
144*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(10, latency);
145*8975f5c5SAndroid Build Coastguard Worker 
146*8975f5c5SAndroid Build Coastguard Worker     // Test the 64-bit queries
147*8975f5c5SAndroid Build Coastguard Worker     EGLuint64KHR value;
148*8975f5c5SAndroid Build Coastguard Worker     eglQueryStreamu64KHR(display, stream, EGL_CONSUMER_FRAME_KHR, &value);
149*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
150*8975f5c5SAndroid Build Coastguard Worker     eglQueryStreamu64KHR(display, stream, EGL_PRODUCER_FRAME_KHR, &value);
151*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
152*8975f5c5SAndroid Build Coastguard Worker 
153*8975f5c5SAndroid Build Coastguard Worker     // Destroy the stream
154*8975f5c5SAndroid Build Coastguard Worker     eglDestroyStreamKHR(display, stream);
155*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
156*8975f5c5SAndroid Build Coastguard Worker }
157*8975f5c5SAndroid Build Coastguard Worker 
158*8975f5c5SAndroid Build Coastguard Worker // Tests validation of stream consumer gltexture API
TEST_P(EGLStreamTest,StreamConsumerGLTextureValidationTest)159*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLStreamTest, StreamConsumerGLTextureValidationTest)
160*8975f5c5SAndroid Build Coastguard Worker {
161*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window            = getEGLWindow();
162*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display           = window->getDisplay();
163*8975f5c5SAndroid Build Coastguard Worker     const char *extensionsString = eglQueryString(display, EGL_EXTENSIONS);
164*8975f5c5SAndroid Build Coastguard Worker     if (strstr(extensionsString, "EGL_KHR_stream_consumer_gltexture") == nullptr)
165*8975f5c5SAndroid Build Coastguard Worker     {
166*8975f5c5SAndroid Build Coastguard Worker         std::cout << "Stream consumer gltexture extension not supported" << std::endl;
167*8975f5c5SAndroid Build Coastguard Worker         return;
168*8975f5c5SAndroid Build Coastguard Worker     }
169*8975f5c5SAndroid Build Coastguard Worker 
170*8975f5c5SAndroid Build Coastguard Worker     const EGLint streamAttributes[] = {
171*8975f5c5SAndroid Build Coastguard Worker         EGL_CONSUMER_LATENCY_USEC_KHR, 0, EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, 0, EGL_NONE,
172*8975f5c5SAndroid Build Coastguard Worker     };
173*8975f5c5SAndroid Build Coastguard Worker 
174*8975f5c5SAndroid Build Coastguard Worker     EGLStreamKHR stream = eglCreateStreamKHR(display, streamAttributes);
175*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
176*8975f5c5SAndroid Build Coastguard Worker 
177*8975f5c5SAndroid Build Coastguard Worker     EGLBoolean result = eglStreamConsumerGLTextureExternalKHR(display, stream);
178*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_FALSE(result);
179*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_ERROR(EGL_BAD_ACCESS);
180*8975f5c5SAndroid Build Coastguard Worker 
181*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
182*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex);
183*8975f5c5SAndroid Build Coastguard Worker     result = eglStreamConsumerGLTextureExternalKHR(display, stream);
184*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_TRUE(result);
185*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
186*8975f5c5SAndroid Build Coastguard Worker 
187*8975f5c5SAndroid Build Coastguard Worker     EGLint state;
188*8975f5c5SAndroid Build Coastguard Worker     eglQueryStreamKHR(display, stream, EGL_STREAM_STATE_KHR, &state);
189*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
190*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(EGL_STREAM_STATE_CONNECTING_KHR, state);
191*8975f5c5SAndroid Build Coastguard Worker 
192*8975f5c5SAndroid Build Coastguard Worker     eglDestroyStreamKHR(display, stream);
193*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
194*8975f5c5SAndroid Build Coastguard Worker }
195*8975f5c5SAndroid Build Coastguard Worker 
196*8975f5c5SAndroid Build Coastguard Worker // Tests validation of stream consumer gltexture yuv API
TEST_P(EGLStreamTest,StreamConsumerGLTextureYUVValidationTest)197*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLStreamTest, StreamConsumerGLTextureYUVValidationTest)
198*8975f5c5SAndroid Build Coastguard Worker {
199*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window            = getEGLWindow();
200*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display           = window->getDisplay();
201*8975f5c5SAndroid Build Coastguard Worker     const char *extensionsString = eglQueryString(display, EGL_EXTENSIONS);
202*8975f5c5SAndroid Build Coastguard Worker     if (strstr(extensionsString, "EGL_NV_stream_consumer_gltexture_yuv") == nullptr)
203*8975f5c5SAndroid Build Coastguard Worker     {
204*8975f5c5SAndroid Build Coastguard Worker         std::cout << "Stream consumer gltexture yuv extension not supported" << std::endl;
205*8975f5c5SAndroid Build Coastguard Worker         return;
206*8975f5c5SAndroid Build Coastguard Worker     }
207*8975f5c5SAndroid Build Coastguard Worker 
208*8975f5c5SAndroid Build Coastguard Worker     const EGLint streamAttributes[] = {
209*8975f5c5SAndroid Build Coastguard Worker         EGL_CONSUMER_LATENCY_USEC_KHR, 0, EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, 0, EGL_NONE,
210*8975f5c5SAndroid Build Coastguard Worker     };
211*8975f5c5SAndroid Build Coastguard Worker 
212*8975f5c5SAndroid Build Coastguard Worker     EGLStreamKHR stream = eglCreateStreamKHR(display, streamAttributes);
213*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
214*8975f5c5SAndroid Build Coastguard Worker 
215*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib consumerAttributesBad[] = {
216*8975f5c5SAndroid Build Coastguard Worker         EGL_COLOR_BUFFER_TYPE,
217*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_BUFFER_EXT,  // 0
218*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_NUMBER_OF_PLANES_EXT,
219*8975f5c5SAndroid Build Coastguard Worker         0,
220*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
221*8975f5c5SAndroid Build Coastguard Worker         EGL_COLOR_BUFFER_TYPE,
222*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_BUFFER_EXT,  // 5
223*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_NUMBER_OF_PLANES_EXT,
224*8975f5c5SAndroid Build Coastguard Worker         1,
225*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
226*8975f5c5SAndroid Build Coastguard Worker         EGL_COLOR_BUFFER_TYPE,
227*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_BUFFER_EXT,  // 10
228*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_NUMBER_OF_PLANES_EXT,
229*8975f5c5SAndroid Build Coastguard Worker         1,
230*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_PLANE0_TEXTURE_UNIT_NV,
231*8975f5c5SAndroid Build Coastguard Worker         9999,
232*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
233*8975f5c5SAndroid Build Coastguard Worker         EGL_COLOR_BUFFER_TYPE,
234*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_BUFFER_EXT,  // 17
235*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_NUMBER_OF_PLANES_EXT,
236*8975f5c5SAndroid Build Coastguard Worker         1,
237*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_PLANE0_TEXTURE_UNIT_NV,
238*8975f5c5SAndroid Build Coastguard Worker         0,
239*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_PLANE1_TEXTURE_UNIT_NV,
240*8975f5c5SAndroid Build Coastguard Worker         1,
241*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
242*8975f5c5SAndroid Build Coastguard Worker         EGL_COLOR_BUFFER_TYPE,
243*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_BUFFER_EXT,  // 26
244*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_NUMBER_OF_PLANES_EXT,
245*8975f5c5SAndroid Build Coastguard Worker         2,
246*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_PLANE0_TEXTURE_UNIT_NV,
247*8975f5c5SAndroid Build Coastguard Worker         0,
248*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_PLANE1_TEXTURE_UNIT_NV,
249*8975f5c5SAndroid Build Coastguard Worker         0,
250*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
251*8975f5c5SAndroid Build Coastguard Worker     };
252*8975f5c5SAndroid Build Coastguard Worker 
253*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib consumerAttributes[] = {
254*8975f5c5SAndroid Build Coastguard Worker         EGL_COLOR_BUFFER_TYPE,
255*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_BUFFER_EXT,
256*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_NUMBER_OF_PLANES_EXT,
257*8975f5c5SAndroid Build Coastguard Worker         2,
258*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_PLANE0_TEXTURE_UNIT_NV,
259*8975f5c5SAndroid Build Coastguard Worker         0,
260*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_PLANE1_TEXTURE_UNIT_NV,
261*8975f5c5SAndroid Build Coastguard Worker         1,
262*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
263*8975f5c5SAndroid Build Coastguard Worker     };
264*8975f5c5SAndroid Build Coastguard Worker 
265*8975f5c5SAndroid Build Coastguard Worker     EGLBoolean result =
266*8975f5c5SAndroid Build Coastguard Worker         eglStreamConsumerGLTextureExternalAttribsNV(display, stream, &consumerAttributesBad[0]);
267*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_FALSE(result);
268*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_ERROR(EGL_BAD_MATCH);
269*8975f5c5SAndroid Build Coastguard Worker 
270*8975f5c5SAndroid Build Coastguard Worker     result =
271*8975f5c5SAndroid Build Coastguard Worker         eglStreamConsumerGLTextureExternalAttribsNV(display, stream, &consumerAttributesBad[5]);
272*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_FALSE(result);
273*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_ERROR(EGL_BAD_MATCH);
274*8975f5c5SAndroid Build Coastguard Worker 
275*8975f5c5SAndroid Build Coastguard Worker     result =
276*8975f5c5SAndroid Build Coastguard Worker         eglStreamConsumerGLTextureExternalAttribsNV(display, stream, &consumerAttributesBad[10]);
277*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_FALSE(result);
278*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_ERROR(EGL_BAD_ACCESS);
279*8975f5c5SAndroid Build Coastguard Worker 
280*8975f5c5SAndroid Build Coastguard Worker     result =
281*8975f5c5SAndroid Build Coastguard Worker         eglStreamConsumerGLTextureExternalAttribsNV(display, stream, &consumerAttributesBad[17]);
282*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_FALSE(result);
283*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_ERROR(EGL_BAD_MATCH);
284*8975f5c5SAndroid Build Coastguard Worker 
285*8975f5c5SAndroid Build Coastguard Worker     result = eglStreamConsumerGLTextureExternalAttribsNV(display, stream, consumerAttributes);
286*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_FALSE(result);
287*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_ERROR(EGL_BAD_ACCESS);
288*8975f5c5SAndroid Build Coastguard Worker 
289*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex[2];
290*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE0);
291*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex[0]);
292*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE1);
293*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex[1]);
294*8975f5c5SAndroid Build Coastguard Worker 
295*8975f5c5SAndroid Build Coastguard Worker     result =
296*8975f5c5SAndroid Build Coastguard Worker         eglStreamConsumerGLTextureExternalAttribsNV(display, stream, &consumerAttributesBad[26]);
297*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_FALSE(result);
298*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_ERROR(EGL_BAD_ACCESS);
299*8975f5c5SAndroid Build Coastguard Worker 
300*8975f5c5SAndroid Build Coastguard Worker     result = eglStreamConsumerGLTextureExternalAttribsNV(display, stream, consumerAttributes);
301*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_TRUE(result);
302*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
303*8975f5c5SAndroid Build Coastguard Worker 
304*8975f5c5SAndroid Build Coastguard Worker     EGLint state;
305*8975f5c5SAndroid Build Coastguard Worker     eglQueryStreamKHR(display, stream, EGL_STREAM_STATE_KHR, &state);
306*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
307*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(EGL_STREAM_STATE_CONNECTING_KHR, state);
308*8975f5c5SAndroid Build Coastguard Worker 
309*8975f5c5SAndroid Build Coastguard Worker     eglDestroyStreamKHR(display, stream);
310*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
311*8975f5c5SAndroid Build Coastguard Worker }
312*8975f5c5SAndroid Build Coastguard Worker 
313*8975f5c5SAndroid Build Coastguard Worker // Tests that deleting a texture invalidates the associated stream
TEST_P(EGLStreamTest,StreamConsumerGLTextureYUVDeletionTest)314*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLStreamTest, StreamConsumerGLTextureYUVDeletionTest)
315*8975f5c5SAndroid Build Coastguard Worker {
316*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window            = getEGLWindow();
317*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display           = window->getDisplay();
318*8975f5c5SAndroid Build Coastguard Worker     const char *extensionsString = eglQueryString(display, EGL_EXTENSIONS);
319*8975f5c5SAndroid Build Coastguard Worker     if (strstr(extensionsString, "EGL_ANGLE_stream_producer_d3d_texture") == nullptr)
320*8975f5c5SAndroid Build Coastguard Worker     {
321*8975f5c5SAndroid Build Coastguard Worker         std::cout << "Stream producer d3d texture not supported" << std::endl;
322*8975f5c5SAndroid Build Coastguard Worker         return;
323*8975f5c5SAndroid Build Coastguard Worker     }
324*8975f5c5SAndroid Build Coastguard Worker 
325*8975f5c5SAndroid Build Coastguard Worker     const EGLint streamAttributes[] = {
326*8975f5c5SAndroid Build Coastguard Worker         EGL_CONSUMER_LATENCY_USEC_KHR, 0, EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, 0, EGL_NONE,
327*8975f5c5SAndroid Build Coastguard Worker     };
328*8975f5c5SAndroid Build Coastguard Worker 
329*8975f5c5SAndroid Build Coastguard Worker     EGLStreamKHR stream = eglCreateStreamKHR(display, streamAttributes);
330*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
331*8975f5c5SAndroid Build Coastguard Worker 
332*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib consumerAttributes[] = {
333*8975f5c5SAndroid Build Coastguard Worker         EGL_COLOR_BUFFER_TYPE,
334*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_BUFFER_EXT,
335*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_NUMBER_OF_PLANES_EXT,
336*8975f5c5SAndroid Build Coastguard Worker         2,
337*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_PLANE0_TEXTURE_UNIT_NV,
338*8975f5c5SAndroid Build Coastguard Worker         0,
339*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_PLANE1_TEXTURE_UNIT_NV,
340*8975f5c5SAndroid Build Coastguard Worker         1,
341*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
342*8975f5c5SAndroid Build Coastguard Worker     };
343*8975f5c5SAndroid Build Coastguard Worker 
344*8975f5c5SAndroid Build Coastguard Worker     // Note: The purpose of this test means that we can't use the RAII GLTexture class
345*8975f5c5SAndroid Build Coastguard Worker     GLuint tex[2];
346*8975f5c5SAndroid Build Coastguard Worker     glGenTextures(2, tex);
347*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE0);
348*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex[0]);
349*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE1);
350*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex[1]);
351*8975f5c5SAndroid Build Coastguard Worker 
352*8975f5c5SAndroid Build Coastguard Worker     EGLBoolean result =
353*8975f5c5SAndroid Build Coastguard Worker         eglStreamConsumerGLTextureExternalAttribsNV(display, stream, consumerAttributes);
354*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_TRUE(result);
355*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
356*8975f5c5SAndroid Build Coastguard Worker 
357*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib producerAttributes[] = {
358*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
359*8975f5c5SAndroid Build Coastguard Worker     };
360*8975f5c5SAndroid Build Coastguard Worker 
361*8975f5c5SAndroid Build Coastguard Worker     result = eglCreateStreamProducerD3DTextureANGLE(display, stream, producerAttributes);
362*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_TRUE(result);
363*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
364*8975f5c5SAndroid Build Coastguard Worker 
365*8975f5c5SAndroid Build Coastguard Worker     EGLint state;
366*8975f5c5SAndroid Build Coastguard Worker     eglQueryStreamKHR(display, stream, EGL_STREAM_STATE_KHR, &state);
367*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
368*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(EGL_STREAM_STATE_EMPTY_KHR, state);
369*8975f5c5SAndroid Build Coastguard Worker 
370*8975f5c5SAndroid Build Coastguard Worker     // Delete the first texture, which should be enough to invalidate the stream
371*8975f5c5SAndroid Build Coastguard Worker     glDeleteTextures(1, tex);
372*8975f5c5SAndroid Build Coastguard Worker 
373*8975f5c5SAndroid Build Coastguard Worker     eglQueryStreamKHR(display, stream, EGL_STREAM_STATE_KHR, &state);
374*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
375*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(EGL_STREAM_STATE_DISCONNECTED_KHR, state);
376*8975f5c5SAndroid Build Coastguard Worker 
377*8975f5c5SAndroid Build Coastguard Worker     eglDestroyStreamKHR(display, stream);
378*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
379*8975f5c5SAndroid Build Coastguard Worker }
380*8975f5c5SAndroid Build Coastguard Worker 
381*8975f5c5SAndroid Build Coastguard Worker class D3D11TextureStreamSamplingTest : public ANGLETest<>
382*8975f5c5SAndroid Build Coastguard Worker {
383*8975f5c5SAndroid Build Coastguard Worker   protected:
testSetUp()384*8975f5c5SAndroid Build Coastguard Worker     void testSetUp() override
385*8975f5c5SAndroid Build Coastguard Worker     {
386*8975f5c5SAndroid Build Coastguard Worker         EGLWindow *window = getEGLWindow();
387*8975f5c5SAndroid Build Coastguard Worker         mDisplay          = window->getDisplay();
388*8975f5c5SAndroid Build Coastguard Worker         if (!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_ANGLE_stream_producer_d3d_texture"))
389*8975f5c5SAndroid Build Coastguard Worker         {
390*8975f5c5SAndroid Build Coastguard Worker             std::cout << "Stream producer d3d texture not supported" << std::endl;
391*8975f5c5SAndroid Build Coastguard Worker             return;
392*8975f5c5SAndroid Build Coastguard Worker         }
393*8975f5c5SAndroid Build Coastguard Worker 
394*8975f5c5SAndroid Build Coastguard Worker         glGenRenderbuffers(1, &mRB);
395*8975f5c5SAndroid Build Coastguard Worker         glBindRenderbuffer(GL_RENDERBUFFER, mRB);
396*8975f5c5SAndroid Build Coastguard Worker         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 2, 2);
397*8975f5c5SAndroid Build Coastguard Worker         glBindRenderbuffer(GL_RENDERBUFFER, 0);
398*8975f5c5SAndroid Build Coastguard Worker 
399*8975f5c5SAndroid Build Coastguard Worker         glGenFramebuffers(1, &mFB);
400*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, mFB);
401*8975f5c5SAndroid Build Coastguard Worker         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mRB);
402*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
403*8975f5c5SAndroid Build Coastguard Worker 
404*8975f5c5SAndroid Build Coastguard Worker         glViewport(0, 0, 2, 2);
405*8975f5c5SAndroid Build Coastguard Worker         glClearColor(1, 0, 0, 1);
406*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
407*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
408*8975f5c5SAndroid Build Coastguard Worker 
409*8975f5c5SAndroid Build Coastguard Worker         uint32_t pixel;
410*8975f5c5SAndroid Build Coastguard Worker         glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
411*8975f5c5SAndroid Build Coastguard Worker         ASSERT_EQ(pixel, 0xff0000ff);
412*8975f5c5SAndroid Build Coastguard Worker 
413*8975f5c5SAndroid Build Coastguard Worker         mStream = eglCreateStreamKHR(mDisplay, nullptr);
414*8975f5c5SAndroid Build Coastguard Worker         ASSERT_EGL_SUCCESS();
415*8975f5c5SAndroid Build Coastguard Worker 
416*8975f5c5SAndroid Build Coastguard Worker         EGLDeviceEXT eglDevice;
417*8975f5c5SAndroid Build Coastguard Worker         eglQueryDisplayAttribEXT(mDisplay, EGL_DEVICE_EXT, (EGLAttrib *)&eglDevice);
418*8975f5c5SAndroid Build Coastguard Worker         eglQueryDeviceAttribEXT(eglDevice, EGL_D3D11_DEVICE_ANGLE, (EGLAttrib *)&mD3D);
419*8975f5c5SAndroid Build Coastguard Worker     }
420*8975f5c5SAndroid Build Coastguard Worker 
testTearDown()421*8975f5c5SAndroid Build Coastguard Worker     void testTearDown() override
422*8975f5c5SAndroid Build Coastguard Worker     {
423*8975f5c5SAndroid Build Coastguard Worker         EGLBoolean result = eglDestroyStreamKHR(mDisplay, mStream);
424*8975f5c5SAndroid Build Coastguard Worker         ASSERT_EGL_TRUE(result);
425*8975f5c5SAndroid Build Coastguard Worker         ASSERT_EGL_SUCCESS();
426*8975f5c5SAndroid Build Coastguard Worker 
427*8975f5c5SAndroid Build Coastguard Worker         glDeleteRenderbuffers(1, &mRB);
428*8975f5c5SAndroid Build Coastguard Worker         glDeleteFramebuffers(1, &mFB);
429*8975f5c5SAndroid Build Coastguard Worker     }
430*8975f5c5SAndroid Build Coastguard Worker 
431*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay mDisplay  = 0;
432*8975f5c5SAndroid Build Coastguard Worker     EGLStreamKHR mStream = 0;
433*8975f5c5SAndroid Build Coastguard Worker     GLuint mRB           = 0;
434*8975f5c5SAndroid Build Coastguard Worker     GLuint mFB           = 0;
435*8975f5c5SAndroid Build Coastguard Worker     ID3D11Device *mD3D;
436*8975f5c5SAndroid Build Coastguard Worker };
437*8975f5c5SAndroid Build Coastguard Worker 
438*8975f5c5SAndroid Build Coastguard Worker // Test RGBA texture sampling via EGLStreams
TEST_P(D3D11TextureStreamSamplingTest,RGBA)439*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3D11TextureStreamSamplingTest, RGBA)
440*8975f5c5SAndroid Build Coastguard Worker {
441*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
442*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
443*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(
444*8975f5c5SAndroid Build Coastguard Worker         !IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_stream_producer_d3d_texture"));
445*8975f5c5SAndroid Build Coastguard Worker 
446*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVertShader[] = R"(
447*8975f5c5SAndroid Build Coastguard Worker         attribute vec4 aPos;
448*8975f5c5SAndroid Build Coastguard Worker         varying vec2 vTexCoord;
449*8975f5c5SAndroid Build Coastguard Worker         void main()
450*8975f5c5SAndroid Build Coastguard Worker         {
451*8975f5c5SAndroid Build Coastguard Worker             gl_Position = aPos;
452*8975f5c5SAndroid Build Coastguard Worker             vTexCoord = gl_Position.xy * 0.5 + 0.5;
453*8975f5c5SAndroid Build Coastguard Worker         }
454*8975f5c5SAndroid Build Coastguard Worker     )";
455*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFragShader[] = R"(
456*8975f5c5SAndroid Build Coastguard Worker         #extension GL_NV_EGL_stream_consumer_external : require
457*8975f5c5SAndroid Build Coastguard Worker         precision mediump float;
458*8975f5c5SAndroid Build Coastguard Worker         uniform samplerExternalOES uTex;
459*8975f5c5SAndroid Build Coastguard Worker         varying vec2 vTexCoord;
460*8975f5c5SAndroid Build Coastguard Worker         void main()
461*8975f5c5SAndroid Build Coastguard Worker         {
462*8975f5c5SAndroid Build Coastguard Worker             gl_FragColor = texture2D(uTex, vTexCoord);
463*8975f5c5SAndroid Build Coastguard Worker         }
464*8975f5c5SAndroid Build Coastguard Worker     )";
465*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(prog, kVertShader, kFragShader);
466*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(prog);
467*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(glGetUniformLocation(prog, "uTex"), 0);
468*8975f5c5SAndroid Build Coastguard Worker 
469*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
470*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE0);
471*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex);
472*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
473*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
474*8975f5c5SAndroid Build Coastguard Worker 
475*8975f5c5SAndroid Build Coastguard Worker     EGLBoolean result = eglStreamConsumerGLTextureExternalAttribsNV(mDisplay, mStream, nullptr);
476*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_TRUE(result);
477*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
478*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE3);  // Set to an unused slot to ensure StreamConsumer picked up
479*8975f5c5SAndroid Build Coastguard Worker                                    // the current slot.
480*8975f5c5SAndroid Build Coastguard Worker 
481*8975f5c5SAndroid Build Coastguard Worker     result = eglCreateStreamProducerD3DTextureANGLE(mDisplay, mStream, nullptr);
482*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_TRUE(result);
483*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
484*8975f5c5SAndroid Build Coastguard Worker 
485*8975f5c5SAndroid Build Coastguard Worker     // Create and post the d3d11 texture
486*8975f5c5SAndroid Build Coastguard Worker 
487*8975f5c5SAndroid Build Coastguard Worker     D3D11_TEXTURE2D_DESC desc = {};
488*8975f5c5SAndroid Build Coastguard Worker     desc.Width                = 1;
489*8975f5c5SAndroid Build Coastguard Worker     desc.Height               = 1;
490*8975f5c5SAndroid Build Coastguard Worker     desc.Format               = DXGI_FORMAT_R8G8B8A8_UNORM;
491*8975f5c5SAndroid Build Coastguard Worker     desc.MipLevels            = 1;
492*8975f5c5SAndroid Build Coastguard Worker     desc.ArraySize            = 1;
493*8975f5c5SAndroid Build Coastguard Worker     desc.SampleDesc.Count     = 1;
494*8975f5c5SAndroid Build Coastguard Worker     desc.Usage                = D3D11_USAGE_DEFAULT;
495*8975f5c5SAndroid Build Coastguard Worker     desc.BindFlags            = D3D11_BIND_SHADER_RESOURCE;
496*8975f5c5SAndroid Build Coastguard Worker 
497*8975f5c5SAndroid Build Coastguard Worker     constexpr uint8_t texData[] = {0x10, 0x20, 0x30, 0x40};
498*8975f5c5SAndroid Build Coastguard Worker     D3D11_SUBRESOURCE_DATA subres;
499*8975f5c5SAndroid Build Coastguard Worker     subres.pSysMem     = texData;
500*8975f5c5SAndroid Build Coastguard Worker     subres.SysMemPitch = 4;
501*8975f5c5SAndroid Build Coastguard Worker 
502*8975f5c5SAndroid Build Coastguard Worker     ID3D11Texture2D *texture = nullptr;
503*8975f5c5SAndroid Build Coastguard Worker     (void)mD3D->CreateTexture2D(&desc, &subres, &texture);
504*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(nullptr, texture);
505*8975f5c5SAndroid Build Coastguard Worker 
506*8975f5c5SAndroid Build Coastguard Worker     result = eglStreamPostD3DTextureANGLE(mDisplay, mStream, (void *)texture, nullptr);
507*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_TRUE(result);
508*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
509*8975f5c5SAndroid Build Coastguard Worker 
510*8975f5c5SAndroid Build Coastguard Worker     // Sample and test
511*8975f5c5SAndroid Build Coastguard Worker 
512*8975f5c5SAndroid Build Coastguard Worker     result = eglStreamConsumerAcquireKHR(mDisplay, mStream);
513*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_TRUE(result);
514*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
515*8975f5c5SAndroid Build Coastguard Worker 
516*8975f5c5SAndroid Build Coastguard Worker     drawQuad(prog, "aPos", 0.0);
517*8975f5c5SAndroid Build Coastguard Worker 
518*8975f5c5SAndroid Build Coastguard Worker     uint32_t pixel;
519*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
520*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
521*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(pixel, static_cast<uint32_t>(0x40302010));
522*8975f5c5SAndroid Build Coastguard Worker 
523*8975f5c5SAndroid Build Coastguard Worker     result = eglStreamConsumerReleaseKHR(mDisplay, mStream);
524*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_TRUE(result);
525*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
526*8975f5c5SAndroid Build Coastguard Worker }
527*8975f5c5SAndroid Build Coastguard Worker 
528*8975f5c5SAndroid Build Coastguard Worker // Test NV12 texture sampling via EGLStreams
TEST_P(D3D11TextureStreamSamplingTest,NV12)529*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3D11TextureStreamSamplingTest, NV12)
530*8975f5c5SAndroid Build Coastguard Worker {
531*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
532*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
533*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(
534*8975f5c5SAndroid Build Coastguard Worker         !IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_stream_producer_d3d_texture"));
535*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!CheckNV12TextureSupport(mD3D));
536*8975f5c5SAndroid Build Coastguard Worker 
537*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVertShader[] = R"(
538*8975f5c5SAndroid Build Coastguard Worker         attribute vec4 aPos;
539*8975f5c5SAndroid Build Coastguard Worker         varying vec2 vTexCoord;
540*8975f5c5SAndroid Build Coastguard Worker         void main()
541*8975f5c5SAndroid Build Coastguard Worker         {
542*8975f5c5SAndroid Build Coastguard Worker             gl_Position = aPos;
543*8975f5c5SAndroid Build Coastguard Worker             vTexCoord = gl_Position.xy * 0.5 + 0.5;
544*8975f5c5SAndroid Build Coastguard Worker         }
545*8975f5c5SAndroid Build Coastguard Worker     )";
546*8975f5c5SAndroid Build Coastguard Worker     const char kFragShader[]     = R"(
547*8975f5c5SAndroid Build Coastguard Worker         #extension GL_NV_EGL_stream_consumer_external : require
548*8975f5c5SAndroid Build Coastguard Worker         precision mediump float;
549*8975f5c5SAndroid Build Coastguard Worker         uniform samplerExternalOES uTexY;
550*8975f5c5SAndroid Build Coastguard Worker         uniform samplerExternalOES uTexUV;
551*8975f5c5SAndroid Build Coastguard Worker         varying vec2 vTexCoord;
552*8975f5c5SAndroid Build Coastguard Worker         void main()
553*8975f5c5SAndroid Build Coastguard Worker         {
554*8975f5c5SAndroid Build Coastguard Worker             gl_FragColor.r = texture2D(uTexY, vTexCoord).r;
555*8975f5c5SAndroid Build Coastguard Worker             gl_FragColor.gb = texture2D(uTexUV, vTexCoord).rg;
556*8975f5c5SAndroid Build Coastguard Worker             gl_FragColor.a = 1.0;
557*8975f5c5SAndroid Build Coastguard Worker         }
558*8975f5c5SAndroid Build Coastguard Worker     )";
559*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(prog, kVertShader, kFragShader);
560*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(prog);
561*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(glGetUniformLocation(prog, "uTexY"), 0);
562*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(glGetUniformLocation(prog, "uTexUV"), 1);
563*8975f5c5SAndroid Build Coastguard Worker 
564*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
565*8975f5c5SAndroid Build Coastguard Worker 
566*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex[2];
567*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE0);
568*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex[0]);
569*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
570*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
571*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE1);
572*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex[1]);
573*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
574*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
575*8975f5c5SAndroid Build Coastguard Worker 
576*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE3);  // Set to an unused slot to ensure StreamConsumer picks up
577*8975f5c5SAndroid Build Coastguard Worker                                    // the current slot.
578*8975f5c5SAndroid Build Coastguard Worker     constexpr EGLAttrib consumerAttributes[] = {
579*8975f5c5SAndroid Build Coastguard Worker         EGL_COLOR_BUFFER_TYPE,
580*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_BUFFER_EXT,
581*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_NUMBER_OF_PLANES_EXT,
582*8975f5c5SAndroid Build Coastguard Worker         2,
583*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_PLANE0_TEXTURE_UNIT_NV,
584*8975f5c5SAndroid Build Coastguard Worker         0,
585*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_PLANE1_TEXTURE_UNIT_NV,
586*8975f5c5SAndroid Build Coastguard Worker         1,
587*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
588*8975f5c5SAndroid Build Coastguard Worker     };
589*8975f5c5SAndroid Build Coastguard Worker     EGLBoolean result = eglStreamConsumerGLTextureExternalAttribsNV(
590*8975f5c5SAndroid Build Coastguard Worker         mDisplay, mStream, const_cast<EGLAttrib *>(consumerAttributes));
591*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_TRUE(result);
592*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
593*8975f5c5SAndroid Build Coastguard Worker 
594*8975f5c5SAndroid Build Coastguard Worker     result = eglCreateStreamProducerD3DTextureANGLE(mDisplay, mStream, nullptr);
595*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_TRUE(result);
596*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
597*8975f5c5SAndroid Build Coastguard Worker 
598*8975f5c5SAndroid Build Coastguard Worker     // Create and post the d3d11 texture
599*8975f5c5SAndroid Build Coastguard Worker 
600*8975f5c5SAndroid Build Coastguard Worker     D3D11_TEXTURE2D_DESC desc = {};
601*8975f5c5SAndroid Build Coastguard Worker     desc.Width                = 2;
602*8975f5c5SAndroid Build Coastguard Worker     desc.Height               = 2;
603*8975f5c5SAndroid Build Coastguard Worker     desc.Format               = DXGI_FORMAT_NV12;
604*8975f5c5SAndroid Build Coastguard Worker     desc.MipLevels            = 1;
605*8975f5c5SAndroid Build Coastguard Worker     desc.ArraySize            = 1;
606*8975f5c5SAndroid Build Coastguard Worker     desc.SampleDesc.Count     = 1;
607*8975f5c5SAndroid Build Coastguard Worker     desc.Usage                = D3D11_USAGE_DEFAULT;
608*8975f5c5SAndroid Build Coastguard Worker     desc.BindFlags            = D3D11_BIND_SHADER_RESOURCE;
609*8975f5c5SAndroid Build Coastguard Worker 
610*8975f5c5SAndroid Build Coastguard Worker     /* DXGI_FORMAT_NV12:
611*8975f5c5SAndroid Build Coastguard Worker      * Width and height must be even.
612*8975f5c5SAndroid Build Coastguard Worker      * Direct3D 11 staging resources and initData parameters for this format use
613*8975f5c5SAndroid Build Coastguard Worker      * (rowPitch * (height + (height / 2))) bytes.
614*8975f5c5SAndroid Build Coastguard Worker      * The first (SysMemPitch * height) bytes are the Y plane, the remaining
615*8975f5c5SAndroid Build Coastguard Worker      * (SysMemPitch * (height / 2)) bytes are the UV plane.
616*8975f5c5SAndroid Build Coastguard Worker      */
617*8975f5c5SAndroid Build Coastguard Worker     constexpr uint8_t texData[] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60};
618*8975f5c5SAndroid Build Coastguard Worker     D3D11_SUBRESOURCE_DATA subres;
619*8975f5c5SAndroid Build Coastguard Worker     subres.pSysMem     = texData;
620*8975f5c5SAndroid Build Coastguard Worker     subres.SysMemPitch = 2;
621*8975f5c5SAndroid Build Coastguard Worker 
622*8975f5c5SAndroid Build Coastguard Worker     ID3D11Texture2D *texture = nullptr;
623*8975f5c5SAndroid Build Coastguard Worker     (void)mD3D->CreateTexture2D(&desc, &subres, &texture);
624*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(nullptr, texture);
625*8975f5c5SAndroid Build Coastguard Worker 
626*8975f5c5SAndroid Build Coastguard Worker     result = eglStreamPostD3DTextureANGLE(mDisplay, mStream, (void *)texture, nullptr);
627*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_TRUE(result);
628*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
629*8975f5c5SAndroid Build Coastguard Worker 
630*8975f5c5SAndroid Build Coastguard Worker     // Sample and test
631*8975f5c5SAndroid Build Coastguard Worker 
632*8975f5c5SAndroid Build Coastguard Worker     result = eglStreamConsumerAcquireKHR(mDisplay, mStream);
633*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_TRUE(result);
634*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
635*8975f5c5SAndroid Build Coastguard Worker 
636*8975f5c5SAndroid Build Coastguard Worker     drawQuad(prog, "aPos", 0.0);
637*8975f5c5SAndroid Build Coastguard Worker     uint32_t pixel;
638*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
639*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(pixel, 0xff605010);
640*8975f5c5SAndroid Build Coastguard Worker 
641*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(1, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
642*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(pixel, 0xff605020);
643*8975f5c5SAndroid Build Coastguard Worker 
644*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
645*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(pixel, 0xff605030);
646*8975f5c5SAndroid Build Coastguard Worker 
647*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
648*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(pixel, 0xff605040);
649*8975f5c5SAndroid Build Coastguard Worker 
650*8975f5c5SAndroid Build Coastguard Worker     result = eglStreamConsumerReleaseKHR(mDisplay, mStream);
651*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_TRUE(result);
652*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
653*8975f5c5SAndroid Build Coastguard Worker }
654*8975f5c5SAndroid Build Coastguard Worker 
655*8975f5c5SAndroid Build Coastguard Worker // End2end test for rendering an NV12 texture. Renders a YUV quad, reads back the RGB values, and
656*8975f5c5SAndroid Build Coastguard Worker // ensures they are correct
TEST_P(EGLStreamTest,StreamProducerTextureNV12End2End)657*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLStreamTest, StreamProducerTextureNV12End2End)
658*8975f5c5SAndroid Build Coastguard Worker {
659*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
660*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
661*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(
662*8975f5c5SAndroid Build Coastguard Worker         !IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_stream_producer_d3d_texture"));
663*8975f5c5SAndroid Build Coastguard Worker 
664*8975f5c5SAndroid Build Coastguard Worker     bool useESSL3Shaders =
665*8975f5c5SAndroid Build Coastguard Worker         getClientMajorVersion() >= 3 && IsGLExtensionEnabled("GL_OES_EGL_image_external_essl3");
666*8975f5c5SAndroid Build Coastguard Worker 
667*8975f5c5SAndroid Build Coastguard Worker     // yuv to rgb conversion shader using Microsoft's given conversion formulas
668*8975f5c5SAndroid Build Coastguard Worker     const char *yuvVS = nullptr;
669*8975f5c5SAndroid Build Coastguard Worker     const char *yuvPS = nullptr;
670*8975f5c5SAndroid Build Coastguard Worker     if (useESSL3Shaders)
671*8975f5c5SAndroid Build Coastguard Worker     {
672*8975f5c5SAndroid Build Coastguard Worker         yuvVS =
673*8975f5c5SAndroid Build Coastguard Worker             "#version 300 es\n"
674*8975f5c5SAndroid Build Coastguard Worker             "in highp vec4 position;\n"
675*8975f5c5SAndroid Build Coastguard Worker             "out vec2 texcoord;\n"
676*8975f5c5SAndroid Build Coastguard Worker             "void main(void)\n"
677*8975f5c5SAndroid Build Coastguard Worker             "{\n"
678*8975f5c5SAndroid Build Coastguard Worker             "    gl_Position = position;\n"
679*8975f5c5SAndroid Build Coastguard Worker             "    texcoord = (position.xy * 0.5) + 0.5;\n"
680*8975f5c5SAndroid Build Coastguard Worker             "    texcoord.y = 1.0 - texcoord.y;\n"
681*8975f5c5SAndroid Build Coastguard Worker             "}\n";
682*8975f5c5SAndroid Build Coastguard Worker         yuvPS =
683*8975f5c5SAndroid Build Coastguard Worker             "#version 300 es\n"
684*8975f5c5SAndroid Build Coastguard Worker             "#extension GL_OES_EGL_image_external_essl3 : require\n"
685*8975f5c5SAndroid Build Coastguard Worker             "#extension GL_NV_EGL_stream_consumer_external : require\n"
686*8975f5c5SAndroid Build Coastguard Worker             "precision highp float;\n"
687*8975f5c5SAndroid Build Coastguard Worker             "in vec2 texcoord;\n"
688*8975f5c5SAndroid Build Coastguard Worker             "out vec4 color;\n"
689*8975f5c5SAndroid Build Coastguard Worker             "uniform samplerExternalOES y;\n"
690*8975f5c5SAndroid Build Coastguard Worker             "uniform samplerExternalOES uv\n;"
691*8975f5c5SAndroid Build Coastguard Worker             "void main(void)\n"
692*8975f5c5SAndroid Build Coastguard Worker             "{\n"
693*8975f5c5SAndroid Build Coastguard Worker             "    float c = texture(y, texcoord).r - (16.0 / 256.0);\n"
694*8975f5c5SAndroid Build Coastguard Worker             "    float d = texture(uv, texcoord).r - 0.5;\n"
695*8975f5c5SAndroid Build Coastguard Worker             "    float e = texture(uv, texcoord).g - 0.5;\n"
696*8975f5c5SAndroid Build Coastguard Worker             "    float r = 1.164383 * c + 1.596027 * e;\n"
697*8975f5c5SAndroid Build Coastguard Worker             "    float g = 1.164383 * c - 0.391762 * d - 0.812968 * e;\n"
698*8975f5c5SAndroid Build Coastguard Worker             "    float b = 1.164383 * c + 2.017232 * d;\n"
699*8975f5c5SAndroid Build Coastguard Worker             "    color = vec4(r, g, b, 1.0);\n"
700*8975f5c5SAndroid Build Coastguard Worker             "}\n";
701*8975f5c5SAndroid Build Coastguard Worker     }
702*8975f5c5SAndroid Build Coastguard Worker     else
703*8975f5c5SAndroid Build Coastguard Worker     {
704*8975f5c5SAndroid Build Coastguard Worker         yuvVS =
705*8975f5c5SAndroid Build Coastguard Worker             "attribute highp vec4 position;\n"
706*8975f5c5SAndroid Build Coastguard Worker             "varying vec2 texcoord;\n"
707*8975f5c5SAndroid Build Coastguard Worker             "void main(void)\n"
708*8975f5c5SAndroid Build Coastguard Worker             "{\n"
709*8975f5c5SAndroid Build Coastguard Worker             "    gl_Position = position;\n"
710*8975f5c5SAndroid Build Coastguard Worker             "    texcoord = (position.xy * 0.5) + 0.5;\n"
711*8975f5c5SAndroid Build Coastguard Worker             "    texcoord.y = 1.0 - texcoord.y;\n"
712*8975f5c5SAndroid Build Coastguard Worker             "}\n";
713*8975f5c5SAndroid Build Coastguard Worker 
714*8975f5c5SAndroid Build Coastguard Worker         yuvPS =
715*8975f5c5SAndroid Build Coastguard Worker             "#extension GL_NV_EGL_stream_consumer_external : require\n"
716*8975f5c5SAndroid Build Coastguard Worker             "precision highp float;\n"
717*8975f5c5SAndroid Build Coastguard Worker             "varying vec2 texcoord;\n"
718*8975f5c5SAndroid Build Coastguard Worker             "uniform samplerExternalOES y;\n"
719*8975f5c5SAndroid Build Coastguard Worker             "uniform samplerExternalOES uv\n;"
720*8975f5c5SAndroid Build Coastguard Worker             "void main(void)\n"
721*8975f5c5SAndroid Build Coastguard Worker             "{\n"
722*8975f5c5SAndroid Build Coastguard Worker             "    float c = texture2D(y, texcoord).r - (16.0 / 256.0);\n"
723*8975f5c5SAndroid Build Coastguard Worker             "    float d = texture2D(uv, texcoord).r - 0.5;\n"
724*8975f5c5SAndroid Build Coastguard Worker             "    float e = texture2D(uv, texcoord).g - 0.5;\n"
725*8975f5c5SAndroid Build Coastguard Worker             "    float r = 1.164383 * c + 1.596027 * e;\n"
726*8975f5c5SAndroid Build Coastguard Worker             "    float g = 1.164383 * c - 0.391762 * d - 0.812968 * e;\n"
727*8975f5c5SAndroid Build Coastguard Worker             "    float b = 1.164383 * c + 2.017232 * d;\n"
728*8975f5c5SAndroid Build Coastguard Worker             "    gl_FragColor = vec4(r, g, b, 1.0);\n"
729*8975f5c5SAndroid Build Coastguard Worker             "}\n";
730*8975f5c5SAndroid Build Coastguard Worker     }
731*8975f5c5SAndroid Build Coastguard Worker 
732*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, yuvVS, yuvPS);
733*8975f5c5SAndroid Build Coastguard Worker     GLuint yUniform  = glGetUniformLocation(program, "y");
734*8975f5c5SAndroid Build Coastguard Worker     GLuint uvUniform = glGetUniformLocation(program, "uv");
735*8975f5c5SAndroid Build Coastguard Worker 
736*8975f5c5SAndroid Build Coastguard Worker     // Fetch the D3D11 device
737*8975f5c5SAndroid Build Coastguard Worker     EGLDeviceEXT eglDevice;
738*8975f5c5SAndroid Build Coastguard Worker     eglQueryDisplayAttribEXT(display, EGL_DEVICE_EXT, (EGLAttrib *)&eglDevice);
739*8975f5c5SAndroid Build Coastguard Worker     ID3D11Device *device;
740*8975f5c5SAndroid Build Coastguard Worker     eglQueryDeviceAttribEXT(eglDevice, EGL_D3D11_DEVICE_ANGLE, (EGLAttrib *)&device);
741*8975f5c5SAndroid Build Coastguard Worker 
742*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!CheckNV12TextureSupport(device));
743*8975f5c5SAndroid Build Coastguard Worker 
744*8975f5c5SAndroid Build Coastguard Worker     // Create the NV12 D3D11 texture
745*8975f5c5SAndroid Build Coastguard Worker     D3D11_TEXTURE2D_DESC desc;
746*8975f5c5SAndroid Build Coastguard Worker     desc.Width              = yuvtest_width;
747*8975f5c5SAndroid Build Coastguard Worker     desc.Height             = yuvtest_height;
748*8975f5c5SAndroid Build Coastguard Worker     desc.Format             = DXGI_FORMAT_NV12;
749*8975f5c5SAndroid Build Coastguard Worker     desc.MipLevels          = 1;
750*8975f5c5SAndroid Build Coastguard Worker     desc.ArraySize          = 1;
751*8975f5c5SAndroid Build Coastguard Worker     desc.SampleDesc.Count   = 1;
752*8975f5c5SAndroid Build Coastguard Worker     desc.SampleDesc.Quality = 0;
753*8975f5c5SAndroid Build Coastguard Worker     desc.Usage              = D3D11_USAGE_DEFAULT;
754*8975f5c5SAndroid Build Coastguard Worker     desc.BindFlags          = D3D11_BIND_SHADER_RESOURCE;
755*8975f5c5SAndroid Build Coastguard Worker     desc.CPUAccessFlags     = 0;
756*8975f5c5SAndroid Build Coastguard Worker     desc.MiscFlags          = 0;
757*8975f5c5SAndroid Build Coastguard Worker 
758*8975f5c5SAndroid Build Coastguard Worker     D3D11_SUBRESOURCE_DATA subres;
759*8975f5c5SAndroid Build Coastguard Worker     subres.pSysMem          = yuvtest_data;
760*8975f5c5SAndroid Build Coastguard Worker     subres.SysMemPitch      = yuvtest_width;
761*8975f5c5SAndroid Build Coastguard Worker     subres.SysMemSlicePitch = yuvtest_width * yuvtest_height * 3 / 2;
762*8975f5c5SAndroid Build Coastguard Worker 
763*8975f5c5SAndroid Build Coastguard Worker     ID3D11Texture2D *texture = nullptr;
764*8975f5c5SAndroid Build Coastguard Worker     (void)device->CreateTexture2D(&desc, &subres, &texture);
765*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(nullptr, texture);
766*8975f5c5SAndroid Build Coastguard Worker 
767*8975f5c5SAndroid Build Coastguard Worker     // Create the stream
768*8975f5c5SAndroid Build Coastguard Worker     const EGLint streamAttributes[] = {
769*8975f5c5SAndroid Build Coastguard Worker         EGL_CONSUMER_LATENCY_USEC_KHR, 0, EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, 0, EGL_NONE,
770*8975f5c5SAndroid Build Coastguard Worker     };
771*8975f5c5SAndroid Build Coastguard Worker 
772*8975f5c5SAndroid Build Coastguard Worker     EGLStreamKHR stream = eglCreateStreamKHR(display, streamAttributes);
773*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
774*8975f5c5SAndroid Build Coastguard Worker 
775*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib consumerAttributes[] = {
776*8975f5c5SAndroid Build Coastguard Worker         EGL_COLOR_BUFFER_TYPE,
777*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_BUFFER_EXT,
778*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_NUMBER_OF_PLANES_EXT,
779*8975f5c5SAndroid Build Coastguard Worker         2,
780*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_PLANE0_TEXTURE_UNIT_NV,
781*8975f5c5SAndroid Build Coastguard Worker         0,
782*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_PLANE1_TEXTURE_UNIT_NV,
783*8975f5c5SAndroid Build Coastguard Worker         1,
784*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
785*8975f5c5SAndroid Build Coastguard Worker     };
786*8975f5c5SAndroid Build Coastguard Worker 
787*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex[2];
788*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE0);
789*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex[0]);
790*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
791*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
792*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE1);
793*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex[1]);
794*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
795*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
796*8975f5c5SAndroid Build Coastguard Worker 
797*8975f5c5SAndroid Build Coastguard Worker     EGLBoolean result =
798*8975f5c5SAndroid Build Coastguard Worker         eglStreamConsumerGLTextureExternalAttribsNV(display, stream, consumerAttributes);
799*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_TRUE(result);
800*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
801*8975f5c5SAndroid Build Coastguard Worker 
802*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib producerAttributes[] = {
803*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
804*8975f5c5SAndroid Build Coastguard Worker     };
805*8975f5c5SAndroid Build Coastguard Worker 
806*8975f5c5SAndroid Build Coastguard Worker     result = eglCreateStreamProducerD3DTextureANGLE(display, stream, producerAttributes);
807*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_TRUE(result);
808*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
809*8975f5c5SAndroid Build Coastguard Worker 
810*8975f5c5SAndroid Build Coastguard Worker     // Insert the frame
811*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib frameAttributes[] = {
812*8975f5c5SAndroid Build Coastguard Worker         EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE,
813*8975f5c5SAndroid Build Coastguard Worker         0,
814*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
815*8975f5c5SAndroid Build Coastguard Worker     };
816*8975f5c5SAndroid Build Coastguard Worker     result = eglStreamPostD3DTextureANGLE(display, stream, (void *)texture, frameAttributes);
817*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_TRUE(result);
818*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
819*8975f5c5SAndroid Build Coastguard Worker 
820*8975f5c5SAndroid Build Coastguard Worker     EGLint state;
821*8975f5c5SAndroid Build Coastguard Worker     eglQueryStreamKHR(display, stream, EGL_STREAM_STATE_KHR, &state);
822*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
823*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR, state);
824*8975f5c5SAndroid Build Coastguard Worker 
825*8975f5c5SAndroid Build Coastguard Worker     eglStreamConsumerAcquireKHR(display, stream);
826*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
827*8975f5c5SAndroid Build Coastguard Worker 
828*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
829*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(yUniform, 0);
830*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(uvUniform, 1);
831*8975f5c5SAndroid Build Coastguard Worker     drawQuad(program, "position", 0.0f);
832*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
833*8975f5c5SAndroid Build Coastguard Worker 
834*8975f5c5SAndroid Build Coastguard Worker     eglStreamConsumerReleaseKHR(display, stream);
835*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
836*8975f5c5SAndroid Build Coastguard Worker 
837*8975f5c5SAndroid Build Coastguard Worker     eglSwapBuffers(display, window->getSurface());
838*8975f5c5SAndroid Build Coastguard Worker     SafeRelease(texture);
839*8975f5c5SAndroid Build Coastguard Worker }
840*8975f5c5SAndroid Build Coastguard Worker 
841*8975f5c5SAndroid Build Coastguard Worker // Test P010 texture sampling via EGLStreams
TEST_P(D3D11TextureStreamSamplingTest,P010)842*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3D11TextureStreamSamplingTest, P010)
843*8975f5c5SAndroid Build Coastguard Worker {
844*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
845*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
846*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(
847*8975f5c5SAndroid Build Coastguard Worker         !IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_stream_producer_d3d_texture"));
848*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!CheckP010TextureSupport(mD3D));
849*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
850*8975f5c5SAndroid Build Coastguard Worker 
851*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVertShader[] = R"(
852*8975f5c5SAndroid Build Coastguard Worker attribute vec4 aPos;
853*8975f5c5SAndroid Build Coastguard Worker varying vec2 vTexCoord;
854*8975f5c5SAndroid Build Coastguard Worker void main()
855*8975f5c5SAndroid Build Coastguard Worker {
856*8975f5c5SAndroid Build Coastguard Worker     gl_Position = aPos;
857*8975f5c5SAndroid Build Coastguard Worker     vTexCoord = gl_Position.xy * 0.5 + 0.5;
858*8975f5c5SAndroid Build Coastguard Worker })";
859*8975f5c5SAndroid Build Coastguard Worker 
860*8975f5c5SAndroid Build Coastguard Worker     const char kFragShader[] = R"(
861*8975f5c5SAndroid Build Coastguard Worker #extension GL_NV_EGL_stream_consumer_external : require
862*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
863*8975f5c5SAndroid Build Coastguard Worker uniform samplerExternalOES uTexY;
864*8975f5c5SAndroid Build Coastguard Worker uniform samplerExternalOES uTexUV;
865*8975f5c5SAndroid Build Coastguard Worker varying vec2 vTexCoord;
866*8975f5c5SAndroid Build Coastguard Worker void main()
867*8975f5c5SAndroid Build Coastguard Worker {
868*8975f5c5SAndroid Build Coastguard Worker     gl_FragColor.r = texture2D(uTexY, vTexCoord).r;
869*8975f5c5SAndroid Build Coastguard Worker     gl_FragColor.gb = texture2D(uTexUV, vTexCoord).rg;
870*8975f5c5SAndroid Build Coastguard Worker     gl_FragColor.a = 1.0;
871*8975f5c5SAndroid Build Coastguard Worker })";
872*8975f5c5SAndroid Build Coastguard Worker 
873*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(prog, kVertShader, kFragShader);
874*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(prog);
875*8975f5c5SAndroid Build Coastguard Worker     GLint location = glGetUniformLocation(prog, "uTexY");
876*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(location, -1);
877*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(location, 0);
878*8975f5c5SAndroid Build Coastguard Worker     location = glGetUniformLocation(prog, "uTexUV");
879*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(location, -1);
880*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(location, 1);
881*8975f5c5SAndroid Build Coastguard Worker 
882*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
883*8975f5c5SAndroid Build Coastguard Worker 
884*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex[2];
885*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE0);
886*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex[0]);
887*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
888*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
889*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE1);
890*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex[1]);
891*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
892*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
893*8975f5c5SAndroid Build Coastguard Worker 
894*8975f5c5SAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE3);  // Set to an unused slot to ensure StreamConsumer picks up
895*8975f5c5SAndroid Build Coastguard Worker                                    // the current slot.
896*8975f5c5SAndroid Build Coastguard Worker     constexpr EGLAttrib consumerAttributes[] = {
897*8975f5c5SAndroid Build Coastguard Worker         EGL_COLOR_BUFFER_TYPE,
898*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_BUFFER_EXT,
899*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_NUMBER_OF_PLANES_EXT,
900*8975f5c5SAndroid Build Coastguard Worker         2,
901*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_PLANE0_TEXTURE_UNIT_NV,
902*8975f5c5SAndroid Build Coastguard Worker         0,
903*8975f5c5SAndroid Build Coastguard Worker         EGL_YUV_PLANE1_TEXTURE_UNIT_NV,
904*8975f5c5SAndroid Build Coastguard Worker         1,
905*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,
906*8975f5c5SAndroid Build Coastguard Worker     };
907*8975f5c5SAndroid Build Coastguard Worker     EGLBoolean result = eglStreamConsumerGLTextureExternalAttribsNV(
908*8975f5c5SAndroid Build Coastguard Worker         mDisplay, mStream, const_cast<EGLAttrib *>(consumerAttributes));
909*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_TRUE(result);
910*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
911*8975f5c5SAndroid Build Coastguard Worker 
912*8975f5c5SAndroid Build Coastguard Worker     result = eglCreateStreamProducerD3DTextureANGLE(mDisplay, mStream, nullptr);
913*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_TRUE(result);
914*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
915*8975f5c5SAndroid Build Coastguard Worker 
916*8975f5c5SAndroid Build Coastguard Worker     // Create and post the d3d11 texture
917*8975f5c5SAndroid Build Coastguard Worker 
918*8975f5c5SAndroid Build Coastguard Worker     D3D11_TEXTURE2D_DESC desc = {};
919*8975f5c5SAndroid Build Coastguard Worker     desc.Width                = 2;
920*8975f5c5SAndroid Build Coastguard Worker     desc.Height               = 2;
921*8975f5c5SAndroid Build Coastguard Worker     desc.Format               = DXGI_FORMAT_P010;
922*8975f5c5SAndroid Build Coastguard Worker     desc.MipLevels            = 1;
923*8975f5c5SAndroid Build Coastguard Worker     desc.ArraySize            = 1;
924*8975f5c5SAndroid Build Coastguard Worker     desc.SampleDesc.Count     = 1;
925*8975f5c5SAndroid Build Coastguard Worker     desc.Usage                = D3D11_USAGE_DEFAULT;
926*8975f5c5SAndroid Build Coastguard Worker     desc.BindFlags            = D3D11_BIND_SHADER_RESOURCE;
927*8975f5c5SAndroid Build Coastguard Worker 
928*8975f5c5SAndroid Build Coastguard Worker     // DXGI_FORMAT_P010:
929*8975f5c5SAndroid Build Coastguard Worker     // Width and height must be even.
930*8975f5c5SAndroid Build Coastguard Worker     // Direct3D 11 staging resources and initData parameters for this format use
931*8975f5c5SAndroid Build Coastguard Worker     // (rowPitch * (height + (height / 2))) bytes.
932*8975f5c5SAndroid Build Coastguard Worker     // The first (SysMemPitch * height) bytes are the Y plane, the remaining
933*8975f5c5SAndroid Build Coastguard Worker     // (SysMemPitch * (height / 2)) bytes are the UV plane.
934*8975f5c5SAndroid Build Coastguard Worker     constexpr uint16_t texData[] = {0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000};
935*8975f5c5SAndroid Build Coastguard Worker     D3D11_SUBRESOURCE_DATA subres;
936*8975f5c5SAndroid Build Coastguard Worker     subres.pSysMem     = texData;
937*8975f5c5SAndroid Build Coastguard Worker     subres.SysMemPitch = 4;
938*8975f5c5SAndroid Build Coastguard Worker 
939*8975f5c5SAndroid Build Coastguard Worker     ID3D11Texture2D *texture = nullptr;
940*8975f5c5SAndroid Build Coastguard Worker     (void)mD3D->CreateTexture2D(&desc, &subres, &texture);
941*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(nullptr, texture);
942*8975f5c5SAndroid Build Coastguard Worker 
943*8975f5c5SAndroid Build Coastguard Worker     result = eglStreamPostD3DTextureANGLE(mDisplay, mStream, (void *)texture, nullptr);
944*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_TRUE(result);
945*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
946*8975f5c5SAndroid Build Coastguard Worker 
947*8975f5c5SAndroid Build Coastguard Worker     // Sample and test
948*8975f5c5SAndroid Build Coastguard Worker 
949*8975f5c5SAndroid Build Coastguard Worker     result = eglStreamConsumerAcquireKHR(mDisplay, mStream);
950*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_TRUE(result);
951*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
952*8975f5c5SAndroid Build Coastguard Worker 
953*8975f5c5SAndroid Build Coastguard Worker     drawQuad(prog, "aPos", 0.0);
954*8975f5c5SAndroid Build Coastguard Worker     uint32_t pixel;
955*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
956*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(pixel, 0xff605010);
957*8975f5c5SAndroid Build Coastguard Worker 
958*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(1, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
959*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(pixel, 0xff605020);
960*8975f5c5SAndroid Build Coastguard Worker 
961*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
962*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(pixel, 0xff605030);
963*8975f5c5SAndroid Build Coastguard Worker 
964*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
965*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(pixel, 0xff605040);
966*8975f5c5SAndroid Build Coastguard Worker 
967*8975f5c5SAndroid Build Coastguard Worker     result = eglStreamConsumerReleaseKHR(mDisplay, mStream);
968*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_TRUE(result);
969*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
970*8975f5c5SAndroid Build Coastguard Worker }
971*8975f5c5SAndroid Build Coastguard Worker 
972*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST(EGLStreamTest,
973*8975f5c5SAndroid Build Coastguard Worker                        ES2_D3D9(),
974*8975f5c5SAndroid Build Coastguard Worker                        ES2_D3D11(),
975*8975f5c5SAndroid Build Coastguard Worker                        ES3_D3D11(),
976*8975f5c5SAndroid Build Coastguard Worker                        ES2_OPENGL(),
977*8975f5c5SAndroid Build Coastguard Worker                        ES3_OPENGL(),
978*8975f5c5SAndroid Build Coastguard Worker                        ES2_VULKAN());
979*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST(D3D11TextureStreamSamplingTest, ES2_D3D11(), ES3_D3D11(), ES31_D3D11());
980*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
981