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