xref: /aosp_15_r20/external/angle/src/tests/gl_tests/D3DTextureTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2015 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 // D3DTextureTest:
7*8975f5c5SAndroid Build Coastguard Worker //   Tests of the EGL_ANGLE_d3d_texture_client_buffer extension
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
10*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
11*8975f5c5SAndroid Build Coastguard Worker 
12*8975f5c5SAndroid Build Coastguard Worker #include <d3d11.h>
13*8975f5c5SAndroid Build Coastguard Worker #include <d3d9.h>
14*8975f5c5SAndroid Build Coastguard Worker #include <dxgiformat.h>
15*8975f5c5SAndroid Build Coastguard Worker #include <windows.h>
16*8975f5c5SAndroid Build Coastguard Worker #include <wrl/client.h>
17*8975f5c5SAndroid Build Coastguard Worker 
18*8975f5c5SAndroid Build Coastguard Worker #include "util/EGLWindow.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "util/com_utils.h"
20*8975f5c5SAndroid Build Coastguard Worker 
21*8975f5c5SAndroid Build Coastguard Worker namespace angle
22*8975f5c5SAndroid Build Coastguard Worker {
23*8975f5c5SAndroid Build Coastguard Worker 
24*8975f5c5SAndroid Build Coastguard Worker class D3DTextureTest : public ANGLETest<>
25*8975f5c5SAndroid Build Coastguard Worker {
26*8975f5c5SAndroid Build Coastguard Worker   protected:
D3DTextureTest()27*8975f5c5SAndroid Build Coastguard Worker     D3DTextureTest()
28*8975f5c5SAndroid Build Coastguard Worker     {
29*8975f5c5SAndroid Build Coastguard Worker         setWindowWidth(128);
30*8975f5c5SAndroid Build Coastguard Worker         setWindowHeight(128);
31*8975f5c5SAndroid Build Coastguard Worker         setConfigRedBits(8);
32*8975f5c5SAndroid Build Coastguard Worker         setConfigGreenBits(8);
33*8975f5c5SAndroid Build Coastguard Worker         setConfigBlueBits(8);
34*8975f5c5SAndroid Build Coastguard Worker         setConfigAlphaBits(8);
35*8975f5c5SAndroid Build Coastguard Worker         setConfigDepthBits(24);
36*8975f5c5SAndroid Build Coastguard Worker         setConfigStencilBits(8);
37*8975f5c5SAndroid Build Coastguard Worker     }
38*8975f5c5SAndroid Build Coastguard Worker 
testSetUp()39*8975f5c5SAndroid Build Coastguard Worker     void testSetUp() override
40*8975f5c5SAndroid Build Coastguard Worker     {
41*8975f5c5SAndroid Build Coastguard Worker         constexpr char kVS[] =
42*8975f5c5SAndroid Build Coastguard Worker             R"(precision highp float;
43*8975f5c5SAndroid Build Coastguard Worker             attribute vec4 position;
44*8975f5c5SAndroid Build Coastguard Worker             varying vec2 texcoord;
45*8975f5c5SAndroid Build Coastguard Worker 
46*8975f5c5SAndroid Build Coastguard Worker             void main()
47*8975f5c5SAndroid Build Coastguard Worker             {
48*8975f5c5SAndroid Build Coastguard Worker                 gl_Position = position;
49*8975f5c5SAndroid Build Coastguard Worker                 texcoord = (position.xy * 0.5) + 0.5;
50*8975f5c5SAndroid Build Coastguard Worker                 texcoord.y = 1.0 - texcoord.y;
51*8975f5c5SAndroid Build Coastguard Worker             })";
52*8975f5c5SAndroid Build Coastguard Worker 
53*8975f5c5SAndroid Build Coastguard Worker         constexpr char kTextureFS[] =
54*8975f5c5SAndroid Build Coastguard Worker             R"(precision highp float;
55*8975f5c5SAndroid Build Coastguard Worker             uniform sampler2D tex;
56*8975f5c5SAndroid Build Coastguard Worker             varying vec2 texcoord;
57*8975f5c5SAndroid Build Coastguard Worker 
58*8975f5c5SAndroid Build Coastguard Worker             void main()
59*8975f5c5SAndroid Build Coastguard Worker             {
60*8975f5c5SAndroid Build Coastguard Worker                 gl_FragColor = texture2D(tex, texcoord);
61*8975f5c5SAndroid Build Coastguard Worker             })";
62*8975f5c5SAndroid Build Coastguard Worker 
63*8975f5c5SAndroid Build Coastguard Worker         constexpr char kTextureFSNoSampling[] =
64*8975f5c5SAndroid Build Coastguard Worker             R"(precision highp float;
65*8975f5c5SAndroid Build Coastguard Worker 
66*8975f5c5SAndroid Build Coastguard Worker             void main()
67*8975f5c5SAndroid Build Coastguard Worker             {
68*8975f5c5SAndroid Build Coastguard Worker                 gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
69*8975f5c5SAndroid Build Coastguard Worker             })";
70*8975f5c5SAndroid Build Coastguard Worker 
71*8975f5c5SAndroid Build Coastguard Worker         mTextureProgram = CompileProgram(kVS, kTextureFS);
72*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(0u, mTextureProgram) << "shader compilation failed.";
73*8975f5c5SAndroid Build Coastguard Worker 
74*8975f5c5SAndroid Build Coastguard Worker         mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex");
75*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(-1, mTextureUniformLocation);
76*8975f5c5SAndroid Build Coastguard Worker 
77*8975f5c5SAndroid Build Coastguard Worker         mTextureProgramNoSampling = CompileProgram(kVS, kTextureFSNoSampling);
78*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(0u, mTextureProgramNoSampling) << "shader compilation failed.";
79*8975f5c5SAndroid Build Coastguard Worker 
80*8975f5c5SAndroid Build Coastguard Worker         mD3D11Module = LoadLibrary(TEXT("d3d11.dll"));
81*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(nullptr, mD3D11Module);
82*8975f5c5SAndroid Build Coastguard Worker 
83*8975f5c5SAndroid Build Coastguard Worker         PFN_D3D11_CREATE_DEVICE createDeviceFunc = reinterpret_cast<PFN_D3D11_CREATE_DEVICE>(
84*8975f5c5SAndroid Build Coastguard Worker             GetProcAddress(mD3D11Module, "D3D11CreateDevice"));
85*8975f5c5SAndroid Build Coastguard Worker 
86*8975f5c5SAndroid Build Coastguard Worker         EGLWindow *window   = getEGLWindow();
87*8975f5c5SAndroid Build Coastguard Worker         EGLDisplay display  = window->getDisplay();
88*8975f5c5SAndroid Build Coastguard Worker         EGLDeviceEXT device = EGL_NO_DEVICE_EXT;
89*8975f5c5SAndroid Build Coastguard Worker         if (IsEGLClientExtensionEnabled("EGL_EXT_device_query"))
90*8975f5c5SAndroid Build Coastguard Worker         {
91*8975f5c5SAndroid Build Coastguard Worker             EGLAttrib result = 0;
92*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EGL_TRUE(eglQueryDisplayAttribEXT(display, EGL_DEVICE_EXT, &result));
93*8975f5c5SAndroid Build Coastguard Worker             device = reinterpret_cast<EGLDeviceEXT>(result);
94*8975f5c5SAndroid Build Coastguard Worker         }
95*8975f5c5SAndroid Build Coastguard Worker 
96*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(EGL_NO_DEVICE_EXT, device);
97*8975f5c5SAndroid Build Coastguard Worker 
98*8975f5c5SAndroid Build Coastguard Worker         if (IsEGLDeviceExtensionEnabled(device, "EGL_ANGLE_device_d3d"))
99*8975f5c5SAndroid Build Coastguard Worker         {
100*8975f5c5SAndroid Build Coastguard Worker             EGLAttrib result = 0;
101*8975f5c5SAndroid Build Coastguard Worker             if (eglQueryDeviceAttribEXT(device, EGL_D3D11_DEVICE_ANGLE, &result))
102*8975f5c5SAndroid Build Coastguard Worker             {
103*8975f5c5SAndroid Build Coastguard Worker                 mD3D11Device = reinterpret_cast<ID3D11Device *>(result);
104*8975f5c5SAndroid Build Coastguard Worker                 mD3D11Device->AddRef();
105*8975f5c5SAndroid Build Coastguard Worker             }
106*8975f5c5SAndroid Build Coastguard Worker             else if (eglQueryDeviceAttribEXT(device, EGL_D3D9_DEVICE_ANGLE, &result))
107*8975f5c5SAndroid Build Coastguard Worker             {
108*8975f5c5SAndroid Build Coastguard Worker                 mD3D9Device = reinterpret_cast<IDirect3DDevice9 *>(result);
109*8975f5c5SAndroid Build Coastguard Worker                 mD3D9Device->AddRef();
110*8975f5c5SAndroid Build Coastguard Worker             }
111*8975f5c5SAndroid Build Coastguard Worker         }
112*8975f5c5SAndroid Build Coastguard Worker         else
113*8975f5c5SAndroid Build Coastguard Worker         {
114*8975f5c5SAndroid Build Coastguard Worker             ASSERT_TRUE(
115*8975f5c5SAndroid Build Coastguard Worker                 SUCCEEDED(createDeviceFunc(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr,
116*8975f5c5SAndroid Build Coastguard Worker                                            0, D3D11_SDK_VERSION, &mD3D11Device, nullptr, nullptr)));
117*8975f5c5SAndroid Build Coastguard Worker         }
118*8975f5c5SAndroid Build Coastguard Worker     }
119*8975f5c5SAndroid Build Coastguard Worker 
testTearDown()120*8975f5c5SAndroid Build Coastguard Worker     void testTearDown() override
121*8975f5c5SAndroid Build Coastguard Worker     {
122*8975f5c5SAndroid Build Coastguard Worker         glDeleteProgram(mTextureProgram);
123*8975f5c5SAndroid Build Coastguard Worker         glDeleteProgram(mTextureProgramNoSampling);
124*8975f5c5SAndroid Build Coastguard Worker 
125*8975f5c5SAndroid Build Coastguard Worker         if (mD3D11Device)
126*8975f5c5SAndroid Build Coastguard Worker         {
127*8975f5c5SAndroid Build Coastguard Worker             mD3D11Device->Release();
128*8975f5c5SAndroid Build Coastguard Worker             mD3D11Device = nullptr;
129*8975f5c5SAndroid Build Coastguard Worker         }
130*8975f5c5SAndroid Build Coastguard Worker 
131*8975f5c5SAndroid Build Coastguard Worker         FreeLibrary(mD3D11Module);
132*8975f5c5SAndroid Build Coastguard Worker         mD3D11Module = nullptr;
133*8975f5c5SAndroid Build Coastguard Worker 
134*8975f5c5SAndroid Build Coastguard Worker         if (mD3D9Device)
135*8975f5c5SAndroid Build Coastguard Worker         {
136*8975f5c5SAndroid Build Coastguard Worker             mD3D9Device->Release();
137*8975f5c5SAndroid Build Coastguard Worker             mD3D9Device = nullptr;
138*8975f5c5SAndroid Build Coastguard Worker         }
139*8975f5c5SAndroid Build Coastguard Worker     }
140*8975f5c5SAndroid Build Coastguard Worker 
createD3D11PBuffer(size_t width,size_t height,UINT sampleCount,UINT sampleQuality,UINT bindFlags,DXGI_FORMAT format,const EGLint * attribs)141*8975f5c5SAndroid Build Coastguard Worker     EGLSurface createD3D11PBuffer(size_t width,
142*8975f5c5SAndroid Build Coastguard Worker                                   size_t height,
143*8975f5c5SAndroid Build Coastguard Worker                                   UINT sampleCount,
144*8975f5c5SAndroid Build Coastguard Worker                                   UINT sampleQuality,
145*8975f5c5SAndroid Build Coastguard Worker                                   UINT bindFlags,
146*8975f5c5SAndroid Build Coastguard Worker                                   DXGI_FORMAT format,
147*8975f5c5SAndroid Build Coastguard Worker                                   const EGLint *attribs)
148*8975f5c5SAndroid Build Coastguard Worker     {
149*8975f5c5SAndroid Build Coastguard Worker         EGLWindow *window  = getEGLWindow();
150*8975f5c5SAndroid Build Coastguard Worker         EGLDisplay display = window->getDisplay();
151*8975f5c5SAndroid Build Coastguard Worker         EGLConfig config   = window->getConfig();
152*8975f5c5SAndroid Build Coastguard Worker 
153*8975f5c5SAndroid Build Coastguard Worker         EXPECT_TRUE(mD3D11Device != nullptr);
154*8975f5c5SAndroid Build Coastguard Worker         ID3D11Texture2D *texture = nullptr;
155*8975f5c5SAndroid Build Coastguard Worker         CD3D11_TEXTURE2D_DESC desc(format, static_cast<UINT>(width), static_cast<UINT>(height), 1,
156*8975f5c5SAndroid Build Coastguard Worker                                    1, bindFlags);
157*8975f5c5SAndroid Build Coastguard Worker         desc.SampleDesc.Count   = sampleCount;
158*8975f5c5SAndroid Build Coastguard Worker         desc.SampleDesc.Quality = sampleQuality;
159*8975f5c5SAndroid Build Coastguard Worker         EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &texture)));
160*8975f5c5SAndroid Build Coastguard Worker 
161*8975f5c5SAndroid Build Coastguard Worker         EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(display, EGL_D3D_TEXTURE_ANGLE,
162*8975f5c5SAndroid Build Coastguard Worker                                                               texture, config, attribs);
163*8975f5c5SAndroid Build Coastguard Worker 
164*8975f5c5SAndroid Build Coastguard Worker         texture->Release();
165*8975f5c5SAndroid Build Coastguard Worker 
166*8975f5c5SAndroid Build Coastguard Worker         return pbuffer;
167*8975f5c5SAndroid Build Coastguard Worker     }
168*8975f5c5SAndroid Build Coastguard Worker 
createD3D11PBuffer(size_t width,size_t height,EGLint eglTextureFormat,EGLint eglTextureTarget,UINT sampleCount,UINT sampleQuality,UINT bindFlags,DXGI_FORMAT format)169*8975f5c5SAndroid Build Coastguard Worker     EGLSurface createD3D11PBuffer(size_t width,
170*8975f5c5SAndroid Build Coastguard Worker                                   size_t height,
171*8975f5c5SAndroid Build Coastguard Worker                                   EGLint eglTextureFormat,
172*8975f5c5SAndroid Build Coastguard Worker                                   EGLint eglTextureTarget,
173*8975f5c5SAndroid Build Coastguard Worker                                   UINT sampleCount,
174*8975f5c5SAndroid Build Coastguard Worker                                   UINT sampleQuality,
175*8975f5c5SAndroid Build Coastguard Worker                                   UINT bindFlags,
176*8975f5c5SAndroid Build Coastguard Worker                                   DXGI_FORMAT format)
177*8975f5c5SAndroid Build Coastguard Worker     {
178*8975f5c5SAndroid Build Coastguard Worker         EGLint attribs[] = {
179*8975f5c5SAndroid Build Coastguard Worker             EGL_TEXTURE_FORMAT, eglTextureFormat, EGL_TEXTURE_TARGET,
180*8975f5c5SAndroid Build Coastguard Worker             eglTextureTarget,   EGL_NONE,         EGL_NONE,
181*8975f5c5SAndroid Build Coastguard Worker         };
182*8975f5c5SAndroid Build Coastguard Worker         return createD3D11PBuffer(width, height, sampleCount, sampleQuality, bindFlags, format,
183*8975f5c5SAndroid Build Coastguard Worker                                   attribs);
184*8975f5c5SAndroid Build Coastguard Worker     }
185*8975f5c5SAndroid Build Coastguard Worker 
createPBuffer(size_t width,size_t height,EGLint eglTextureFormat,EGLint eglTextureTarget,UINT sampleCount,UINT sampleQuality)186*8975f5c5SAndroid Build Coastguard Worker     EGLSurface createPBuffer(size_t width,
187*8975f5c5SAndroid Build Coastguard Worker                              size_t height,
188*8975f5c5SAndroid Build Coastguard Worker                              EGLint eglTextureFormat,
189*8975f5c5SAndroid Build Coastguard Worker                              EGLint eglTextureTarget,
190*8975f5c5SAndroid Build Coastguard Worker                              UINT sampleCount,
191*8975f5c5SAndroid Build Coastguard Worker                              UINT sampleQuality)
192*8975f5c5SAndroid Build Coastguard Worker     {
193*8975f5c5SAndroid Build Coastguard Worker         if (mD3D11Device)
194*8975f5c5SAndroid Build Coastguard Worker         {
195*8975f5c5SAndroid Build Coastguard Worker             return createD3D11PBuffer(
196*8975f5c5SAndroid Build Coastguard Worker                 width, height, eglTextureFormat, eglTextureTarget, sampleCount, sampleQuality,
197*8975f5c5SAndroid Build Coastguard Worker                 D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, DXGI_FORMAT_R8G8B8A8_UNORM);
198*8975f5c5SAndroid Build Coastguard Worker         }
199*8975f5c5SAndroid Build Coastguard Worker 
200*8975f5c5SAndroid Build Coastguard Worker         if (mD3D9Device)
201*8975f5c5SAndroid Build Coastguard Worker         {
202*8975f5c5SAndroid Build Coastguard Worker             EGLWindow *window  = getEGLWindow();
203*8975f5c5SAndroid Build Coastguard Worker             EGLDisplay display = window->getDisplay();
204*8975f5c5SAndroid Build Coastguard Worker             EGLConfig config   = window->getConfig();
205*8975f5c5SAndroid Build Coastguard Worker 
206*8975f5c5SAndroid Build Coastguard Worker             EGLint attribs[] = {
207*8975f5c5SAndroid Build Coastguard Worker                 EGL_TEXTURE_FORMAT, eglTextureFormat, EGL_TEXTURE_TARGET,
208*8975f5c5SAndroid Build Coastguard Worker                 eglTextureTarget,   EGL_NONE,         EGL_NONE,
209*8975f5c5SAndroid Build Coastguard Worker             };
210*8975f5c5SAndroid Build Coastguard Worker 
211*8975f5c5SAndroid Build Coastguard Worker             // Multisampled textures are not supported on D3D9.
212*8975f5c5SAndroid Build Coastguard Worker             EXPECT_TRUE(sampleCount <= 1);
213*8975f5c5SAndroid Build Coastguard Worker             EXPECT_TRUE(sampleQuality == 0);
214*8975f5c5SAndroid Build Coastguard Worker 
215*8975f5c5SAndroid Build Coastguard Worker             IDirect3DTexture9 *texture = nullptr;
216*8975f5c5SAndroid Build Coastguard Worker             EXPECT_TRUE(SUCCEEDED(mD3D9Device->CreateTexture(
217*8975f5c5SAndroid Build Coastguard Worker                 static_cast<UINT>(width), static_cast<UINT>(height), 1, D3DUSAGE_RENDERTARGET,
218*8975f5c5SAndroid Build Coastguard Worker                 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, nullptr)));
219*8975f5c5SAndroid Build Coastguard Worker 
220*8975f5c5SAndroid Build Coastguard Worker             EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(display, EGL_D3D_TEXTURE_ANGLE,
221*8975f5c5SAndroid Build Coastguard Worker                                                                   texture, config, attribs);
222*8975f5c5SAndroid Build Coastguard Worker 
223*8975f5c5SAndroid Build Coastguard Worker             texture->Release();
224*8975f5c5SAndroid Build Coastguard Worker 
225*8975f5c5SAndroid Build Coastguard Worker             return pbuffer;
226*8975f5c5SAndroid Build Coastguard Worker         }
227*8975f5c5SAndroid Build Coastguard Worker         else
228*8975f5c5SAndroid Build Coastguard Worker         {
229*8975f5c5SAndroid Build Coastguard Worker             return EGL_NO_SURFACE;
230*8975f5c5SAndroid Build Coastguard Worker         }
231*8975f5c5SAndroid Build Coastguard Worker     }
232*8975f5c5SAndroid Build Coastguard Worker 
valid() const233*8975f5c5SAndroid Build Coastguard Worker     bool valid() const
234*8975f5c5SAndroid Build Coastguard Worker     {
235*8975f5c5SAndroid Build Coastguard Worker         EGLWindow *window  = getEGLWindow();
236*8975f5c5SAndroid Build Coastguard Worker         EGLDisplay display = window->getDisplay();
237*8975f5c5SAndroid Build Coastguard Worker         if (!IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_d3d_texture_client_buffer"))
238*8975f5c5SAndroid Build Coastguard Worker         {
239*8975f5c5SAndroid Build Coastguard Worker             std::cout << "Test skipped due to missing EGL_ANGLE_d3d_texture_client_buffer"
240*8975f5c5SAndroid Build Coastguard Worker                       << std::endl;
241*8975f5c5SAndroid Build Coastguard Worker             return false;
242*8975f5c5SAndroid Build Coastguard Worker         }
243*8975f5c5SAndroid Build Coastguard Worker 
244*8975f5c5SAndroid Build Coastguard Worker         if (!mD3D11Device && !mD3D9Device)
245*8975f5c5SAndroid Build Coastguard Worker         {
246*8975f5c5SAndroid Build Coastguard Worker             std::cout << "Test skipped due to no D3D devices being available." << std::endl;
247*8975f5c5SAndroid Build Coastguard Worker             return false;
248*8975f5c5SAndroid Build Coastguard Worker         }
249*8975f5c5SAndroid Build Coastguard Worker 
250*8975f5c5SAndroid Build Coastguard Worker         if (IsWindows() && IsAMD() && IsOpenGL())
251*8975f5c5SAndroid Build Coastguard Worker         {
252*8975f5c5SAndroid Build Coastguard Worker             std::cout << "Test skipped on Windows AMD OpenGL." << std::endl;
253*8975f5c5SAndroid Build Coastguard Worker             return false;
254*8975f5c5SAndroid Build Coastguard Worker         }
255*8975f5c5SAndroid Build Coastguard Worker 
256*8975f5c5SAndroid Build Coastguard Worker         if (IsWindows() && IsIntel() && IsOpenGL())
257*8975f5c5SAndroid Build Coastguard Worker         {
258*8975f5c5SAndroid Build Coastguard Worker             std::cout << "Test skipped on Windows Intel OpenGL." << std::endl;
259*8975f5c5SAndroid Build Coastguard Worker             return false;
260*8975f5c5SAndroid Build Coastguard Worker         }
261*8975f5c5SAndroid Build Coastguard Worker         return true;
262*8975f5c5SAndroid Build Coastguard Worker     }
263*8975f5c5SAndroid Build Coastguard Worker 
testTextureSamplesAs50PercentGreen(GLuint texture)264*8975f5c5SAndroid Build Coastguard Worker     void testTextureSamplesAs50PercentGreen(GLuint texture)
265*8975f5c5SAndroid Build Coastguard Worker     {
266*8975f5c5SAndroid Build Coastguard Worker         GLFramebuffer scratchFbo;
267*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, scratchFbo);
268*8975f5c5SAndroid Build Coastguard Worker         GLTexture scratchTexture;
269*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, scratchTexture);
270*8975f5c5SAndroid Build Coastguard Worker         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
271*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, scratchTexture,
272*8975f5c5SAndroid Build Coastguard Worker                                0);
273*8975f5c5SAndroid Build Coastguard Worker 
274*8975f5c5SAndroid Build Coastguard Worker         glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
275*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
276*8975f5c5SAndroid Build Coastguard Worker 
277*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(mTextureProgram);
278*8975f5c5SAndroid Build Coastguard Worker         glUniform1i(mTextureUniformLocation, 0);
279*8975f5c5SAndroid Build Coastguard Worker         glActiveTexture(GL_TEXTURE0);
280*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, texture);
281*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
282*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
283*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
284*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
285*8975f5c5SAndroid Build Coastguard Worker 
286*8975f5c5SAndroid Build Coastguard Worker         drawQuad(mTextureProgram, "position", 0.5f);
287*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
288*8975f5c5SAndroid Build Coastguard Worker 
289*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0u, 127u, 0u, 255u), 2);
290*8975f5c5SAndroid Build Coastguard Worker     }
291*8975f5c5SAndroid Build Coastguard Worker 
292*8975f5c5SAndroid Build Coastguard Worker     GLuint mTextureProgram;
293*8975f5c5SAndroid Build Coastguard Worker     GLuint mTextureProgramNoSampling;
294*8975f5c5SAndroid Build Coastguard Worker     GLint mTextureUniformLocation;
295*8975f5c5SAndroid Build Coastguard Worker 
296*8975f5c5SAndroid Build Coastguard Worker     HMODULE mD3D11Module       = nullptr;
297*8975f5c5SAndroid Build Coastguard Worker     ID3D11Device *mD3D11Device = nullptr;
298*8975f5c5SAndroid Build Coastguard Worker 
299*8975f5c5SAndroid Build Coastguard Worker     IDirect3DDevice9 *mD3D9Device = nullptr;
300*8975f5c5SAndroid Build Coastguard Worker };
301*8975f5c5SAndroid Build Coastguard Worker 
302*8975f5c5SAndroid Build Coastguard Worker // Test creating pbuffer from textures with several different DXGI formats.
TEST_P(D3DTextureTest,TestD3D11SupportedFormatsSurface)303*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureTest, TestD3D11SupportedFormatsSurface)
304*8975f5c5SAndroid Build Coastguard Worker {
305*8975f5c5SAndroid Build Coastguard Worker     bool srgbSupported = IsGLExtensionEnabled("GL_EXT_sRGB") || getClientMajorVersion() == 3;
306*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!valid() || !mD3D11Device || !srgbSupported);
307*8975f5c5SAndroid Build Coastguard Worker 
308*8975f5c5SAndroid Build Coastguard Worker     const DXGI_FORMAT formats[] = {DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
309*8975f5c5SAndroid Build Coastguard Worker                                    DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM_SRGB};
310*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < 4; ++i)
311*8975f5c5SAndroid Build Coastguard Worker     {
312*8975f5c5SAndroid Build Coastguard Worker         if (formats[i] == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB)
313*8975f5c5SAndroid Build Coastguard Worker         {
314*8975f5c5SAndroid Build Coastguard Worker             if (IsOpenGL())
315*8975f5c5SAndroid Build Coastguard Worker             {
316*8975f5c5SAndroid Build Coastguard Worker                 // This generates an invalid format error when calling wglDXRegisterObjectNV().
317*8975f5c5SAndroid Build Coastguard Worker                 // Reproducible at least on NVIDIA driver 390.65 on Windows 10.
318*8975f5c5SAndroid Build Coastguard Worker                 std::cout << "DXGI_FORMAT_B8G8R8A8_UNORM_SRGB subtest skipped: IsOpenGL().\n";
319*8975f5c5SAndroid Build Coastguard Worker                 continue;
320*8975f5c5SAndroid Build Coastguard Worker             }
321*8975f5c5SAndroid Build Coastguard Worker         }
322*8975f5c5SAndroid Build Coastguard Worker 
323*8975f5c5SAndroid Build Coastguard Worker         EGLSurface pbuffer = createD3D11PBuffer(32, 32, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D, 1, 0,
324*8975f5c5SAndroid Build Coastguard Worker                                                 D3D11_BIND_RENDER_TARGET, formats[i]);
325*8975f5c5SAndroid Build Coastguard Worker         ASSERT_EGL_SUCCESS();
326*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(EGL_NO_SURFACE, pbuffer);
327*8975f5c5SAndroid Build Coastguard Worker 
328*8975f5c5SAndroid Build Coastguard Worker         EGLWindow *window  = getEGLWindow();
329*8975f5c5SAndroid Build Coastguard Worker         EGLDisplay display = window->getDisplay();
330*8975f5c5SAndroid Build Coastguard Worker 
331*8975f5c5SAndroid Build Coastguard Worker         EGLint colorspace = EGL_NONE;
332*8975f5c5SAndroid Build Coastguard Worker         eglQuerySurface(display, pbuffer, EGL_GL_COLORSPACE, &colorspace);
333*8975f5c5SAndroid Build Coastguard Worker 
334*8975f5c5SAndroid Build Coastguard Worker         if (formats[i] == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB ||
335*8975f5c5SAndroid Build Coastguard Worker             formats[i] == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB)
336*8975f5c5SAndroid Build Coastguard Worker         {
337*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(EGL_GL_COLORSPACE_SRGB, colorspace);
338*8975f5c5SAndroid Build Coastguard Worker         }
339*8975f5c5SAndroid Build Coastguard Worker         else
340*8975f5c5SAndroid Build Coastguard Worker         {
341*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(EGL_GL_COLORSPACE_LINEAR, colorspace);
342*8975f5c5SAndroid Build Coastguard Worker         }
343*8975f5c5SAndroid Build Coastguard Worker 
344*8975f5c5SAndroid Build Coastguard Worker         eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
345*8975f5c5SAndroid Build Coastguard Worker         ASSERT_EGL_SUCCESS();
346*8975f5c5SAndroid Build Coastguard Worker         window->makeCurrent();
347*8975f5c5SAndroid Build Coastguard Worker         eglDestroySurface(display, pbuffer);
348*8975f5c5SAndroid Build Coastguard Worker     }
349*8975f5c5SAndroid Build Coastguard Worker }
350*8975f5c5SAndroid Build Coastguard Worker 
351*8975f5c5SAndroid Build Coastguard Worker // Test binding a pbuffer created from a D3D texture as a texture image with several different DXGI
352*8975f5c5SAndroid Build Coastguard Worker // formats. The test renders to and samples from the pbuffer.
TEST_P(D3DTextureTest,TestD3D11SupportedFormatsTexture)353*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureTest, TestD3D11SupportedFormatsTexture)
354*8975f5c5SAndroid Build Coastguard Worker {
355*8975f5c5SAndroid Build Coastguard Worker     bool srgb8alpha8TextureAttachmentSupported = getClientMajorVersion() >= 3;
356*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!valid() || !mD3D11Device || !srgb8alpha8TextureAttachmentSupported);
357*8975f5c5SAndroid Build Coastguard Worker 
358*8975f5c5SAndroid Build Coastguard Worker     bool srgbWriteControlSupported =
359*8975f5c5SAndroid Build Coastguard Worker         IsGLExtensionEnabled("GL_EXT_sRGB_write_control") && !IsOpenGL();
360*8975f5c5SAndroid Build Coastguard Worker 
361*8975f5c5SAndroid Build Coastguard Worker     const DXGI_FORMAT formats[] = {DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM,
362*8975f5c5SAndroid Build Coastguard Worker                                    DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
363*8975f5c5SAndroid Build Coastguard Worker                                    DXGI_FORMAT_B8G8R8A8_UNORM_SRGB};
364*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < 4; ++i)
365*8975f5c5SAndroid Build Coastguard Worker     {
366*8975f5c5SAndroid Build Coastguard Worker         if (formats[i] == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB)
367*8975f5c5SAndroid Build Coastguard Worker         {
368*8975f5c5SAndroid Build Coastguard Worker             if (IsOpenGL())
369*8975f5c5SAndroid Build Coastguard Worker             {
370*8975f5c5SAndroid Build Coastguard Worker                 // This generates an invalid format error when calling wglDXRegisterObjectNV().
371*8975f5c5SAndroid Build Coastguard Worker                 // Reproducible at least on NVIDIA driver 390.65 on Windows 10.
372*8975f5c5SAndroid Build Coastguard Worker                 std::cout << "DXGI_FORMAT_B8G8R8A8_UNORM_SRGB subtest skipped: IsOpenGL().\n";
373*8975f5c5SAndroid Build Coastguard Worker                 continue;
374*8975f5c5SAndroid Build Coastguard Worker             }
375*8975f5c5SAndroid Build Coastguard Worker         }
376*8975f5c5SAndroid Build Coastguard Worker 
377*8975f5c5SAndroid Build Coastguard Worker         SCOPED_TRACE(std::string("Test case:") + std::to_string(i));
378*8975f5c5SAndroid Build Coastguard Worker         EGLWindow *window  = getEGLWindow();
379*8975f5c5SAndroid Build Coastguard Worker         EGLDisplay display = window->getDisplay();
380*8975f5c5SAndroid Build Coastguard Worker 
381*8975f5c5SAndroid Build Coastguard Worker         EGLSurface pbuffer =
382*8975f5c5SAndroid Build Coastguard Worker             createD3D11PBuffer(32, 32, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D, 1, 0,
383*8975f5c5SAndroid Build Coastguard Worker                                D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, formats[i]);
384*8975f5c5SAndroid Build Coastguard Worker         ASSERT_EGL_SUCCESS();
385*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(EGL_NO_SURFACE, pbuffer);
386*8975f5c5SAndroid Build Coastguard Worker 
387*8975f5c5SAndroid Build Coastguard Worker         EGLint colorspace = EGL_NONE;
388*8975f5c5SAndroid Build Coastguard Worker         eglQuerySurface(display, pbuffer, EGL_GL_COLORSPACE, &colorspace);
389*8975f5c5SAndroid Build Coastguard Worker 
390*8975f5c5SAndroid Build Coastguard Worker         GLuint texture = 0u;
391*8975f5c5SAndroid Build Coastguard Worker         glGenTextures(1, &texture);
392*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, texture);
393*8975f5c5SAndroid Build Coastguard Worker         EGLBoolean result = eglBindTexImage(display, pbuffer, EGL_BACK_BUFFER);
394*8975f5c5SAndroid Build Coastguard Worker         ASSERT_EGL_SUCCESS();
395*8975f5c5SAndroid Build Coastguard Worker         ASSERT_EGL_TRUE(result);
396*8975f5c5SAndroid Build Coastguard Worker 
397*8975f5c5SAndroid Build Coastguard Worker         GLuint fbo = 0u;
398*8975f5c5SAndroid Build Coastguard Worker         glGenFramebuffers(1, &fbo);
399*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
400*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
401*8975f5c5SAndroid Build Coastguard Worker         glViewport(0, 0, 32, 32);
402*8975f5c5SAndroid Build Coastguard Worker 
403*8975f5c5SAndroid Build Coastguard Worker         GLint colorEncoding = 0;
404*8975f5c5SAndroid Build Coastguard Worker         glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
405*8975f5c5SAndroid Build Coastguard Worker                                               GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT,
406*8975f5c5SAndroid Build Coastguard Worker                                               &colorEncoding);
407*8975f5c5SAndroid Build Coastguard Worker 
408*8975f5c5SAndroid Build Coastguard Worker         if (formats[i] == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB ||
409*8975f5c5SAndroid Build Coastguard Worker             formats[i] == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB)
410*8975f5c5SAndroid Build Coastguard Worker         {
411*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(EGL_GL_COLORSPACE_SRGB, colorspace);
412*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(GL_SRGB_EXT, colorEncoding);
413*8975f5c5SAndroid Build Coastguard Worker         }
414*8975f5c5SAndroid Build Coastguard Worker         else
415*8975f5c5SAndroid Build Coastguard Worker         {
416*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(EGL_GL_COLORSPACE_LINEAR, colorspace);
417*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(GL_LINEAR, colorEncoding);
418*8975f5c5SAndroid Build Coastguard Worker         }
419*8975f5c5SAndroid Build Coastguard Worker 
420*8975f5c5SAndroid Build Coastguard Worker         // Clear the texture with 50% green and check that the color value written is correct.
421*8975f5c5SAndroid Build Coastguard Worker         glClearColor(0.0f, 0.5f, 0.0f, 1.0f);
422*8975f5c5SAndroid Build Coastguard Worker 
423*8975f5c5SAndroid Build Coastguard Worker         if (colorEncoding == GL_SRGB_EXT)
424*8975f5c5SAndroid Build Coastguard Worker         {
425*8975f5c5SAndroid Build Coastguard Worker             glClear(GL_COLOR_BUFFER_BIT);
426*8975f5c5SAndroid Build Coastguard Worker             EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0u, 188u, 0u, 255u), 2);
427*8975f5c5SAndroid Build Coastguard Worker             // Disable SRGB and run the non-sRGB test case.
428*8975f5c5SAndroid Build Coastguard Worker             if (srgbWriteControlSupported)
429*8975f5c5SAndroid Build Coastguard Worker                 glDisable(GL_FRAMEBUFFER_SRGB_EXT);
430*8975f5c5SAndroid Build Coastguard Worker         }
431*8975f5c5SAndroid Build Coastguard Worker 
432*8975f5c5SAndroid Build Coastguard Worker         if (colorEncoding == GL_LINEAR || srgbWriteControlSupported)
433*8975f5c5SAndroid Build Coastguard Worker         {
434*8975f5c5SAndroid Build Coastguard Worker             glClear(GL_COLOR_BUFFER_BIT);
435*8975f5c5SAndroid Build Coastguard Worker             EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0u, 127u, 0u, 255u), 2);
436*8975f5c5SAndroid Build Coastguard Worker         }
437*8975f5c5SAndroid Build Coastguard Worker 
438*8975f5c5SAndroid Build Coastguard Worker         // Draw with the texture to a linear framebuffer and check that the color value written is
439*8975f5c5SAndroid Build Coastguard Worker         // correct.
440*8975f5c5SAndroid Build Coastguard Worker         testTextureSamplesAs50PercentGreen(texture);
441*8975f5c5SAndroid Build Coastguard Worker 
442*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, 0u);
443*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, 0u);
444*8975f5c5SAndroid Build Coastguard Worker         glDeleteTextures(1, &texture);
445*8975f5c5SAndroid Build Coastguard Worker         glDeleteFramebuffers(1, &fbo);
446*8975f5c5SAndroid Build Coastguard Worker         eglDestroySurface(display, pbuffer);
447*8975f5c5SAndroid Build Coastguard Worker     }
448*8975f5c5SAndroid Build Coastguard Worker }
449*8975f5c5SAndroid Build Coastguard Worker 
450*8975f5c5SAndroid Build Coastguard Worker // Test binding a pbuffer created from a D3D texture as a texture image with typeless texture
451*8975f5c5SAndroid Build Coastguard Worker // formats.
TEST_P(D3DTextureTest,TestD3D11TypelessTexture)452*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureTest, TestD3D11TypelessTexture)
453*8975f5c5SAndroid Build Coastguard Worker {
454*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
455*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
456*8975f5c5SAndroid Build Coastguard Worker 
457*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!valid());
458*8975f5c5SAndroid Build Coastguard Worker 
459*8975f5c5SAndroid Build Coastguard Worker     // Typeless formats are optional in the spec and currently only supported on D3D11 backend.
460*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsD3D11());
461*8975f5c5SAndroid Build Coastguard Worker 
462*8975f5c5SAndroid Build Coastguard Worker     // GL_SRGB8_ALPHA8 texture attachment support is required.
463*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
464*8975f5c5SAndroid Build Coastguard Worker 
465*8975f5c5SAndroid Build Coastguard Worker     const std::array<EGLint, 2> eglGlColorspaces = {EGL_GL_COLORSPACE_LINEAR,
466*8975f5c5SAndroid Build Coastguard Worker                                                     EGL_GL_COLORSPACE_SRGB};
467*8975f5c5SAndroid Build Coastguard Worker     const std::array<DXGI_FORMAT, 2> dxgiFormats = {DXGI_FORMAT_R8G8B8A8_TYPELESS,
468*8975f5c5SAndroid Build Coastguard Worker                                                     DXGI_FORMAT_B8G8R8A8_TYPELESS};
469*8975f5c5SAndroid Build Coastguard Worker     for (auto eglGlColorspace : eglGlColorspaces)
470*8975f5c5SAndroid Build Coastguard Worker     {
471*8975f5c5SAndroid Build Coastguard Worker         for (auto dxgiFormat : dxgiFormats)
472*8975f5c5SAndroid Build Coastguard Worker         {
473*8975f5c5SAndroid Build Coastguard Worker             SCOPED_TRACE(std::string("Test case:") + std::to_string(eglGlColorspace) + " / " +
474*8975f5c5SAndroid Build Coastguard Worker                          std::to_string(dxgiFormat));
475*8975f5c5SAndroid Build Coastguard Worker 
476*8975f5c5SAndroid Build Coastguard Worker             EGLint attribs[] = {
477*8975f5c5SAndroid Build Coastguard Worker                 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
478*8975f5c5SAndroid Build Coastguard Worker                 EGL_GL_COLORSPACE,  eglGlColorspace,  EGL_NONE,           EGL_NONE,
479*8975f5c5SAndroid Build Coastguard Worker             };
480*8975f5c5SAndroid Build Coastguard Worker 
481*8975f5c5SAndroid Build Coastguard Worker             EGLSurface pbuffer = createD3D11PBuffer(
482*8975f5c5SAndroid Build Coastguard Worker                 32, 32, 1, 0, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, dxgiFormat,
483*8975f5c5SAndroid Build Coastguard Worker                 attribs);
484*8975f5c5SAndroid Build Coastguard Worker 
485*8975f5c5SAndroid Build Coastguard Worker             ASSERT_EGL_SUCCESS();
486*8975f5c5SAndroid Build Coastguard Worker             ASSERT_NE(EGL_NO_SURFACE, pbuffer);
487*8975f5c5SAndroid Build Coastguard Worker 
488*8975f5c5SAndroid Build Coastguard Worker             EGLint colorspace = EGL_NONE;
489*8975f5c5SAndroid Build Coastguard Worker             eglQuerySurface(display, pbuffer, EGL_GL_COLORSPACE, &colorspace);
490*8975f5c5SAndroid Build Coastguard Worker 
491*8975f5c5SAndroid Build Coastguard Worker             GLuint texture = 0u;
492*8975f5c5SAndroid Build Coastguard Worker             glGenTextures(1, &texture);
493*8975f5c5SAndroid Build Coastguard Worker             glBindTexture(GL_TEXTURE_2D, texture);
494*8975f5c5SAndroid Build Coastguard Worker             EGLBoolean result = eglBindTexImage(display, pbuffer, EGL_BACK_BUFFER);
495*8975f5c5SAndroid Build Coastguard Worker             ASSERT_EGL_SUCCESS();
496*8975f5c5SAndroid Build Coastguard Worker             ASSERT_EGL_TRUE(result);
497*8975f5c5SAndroid Build Coastguard Worker 
498*8975f5c5SAndroid Build Coastguard Worker             GLuint fbo = 0u;
499*8975f5c5SAndroid Build Coastguard Worker             glGenFramebuffers(1, &fbo);
500*8975f5c5SAndroid Build Coastguard Worker             glBindFramebuffer(GL_FRAMEBUFFER, fbo);
501*8975f5c5SAndroid Build Coastguard Worker             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
502*8975f5c5SAndroid Build Coastguard Worker             glViewport(0, 0, 32, 32);
503*8975f5c5SAndroid Build Coastguard Worker 
504*8975f5c5SAndroid Build Coastguard Worker             GLint colorEncoding = 0;
505*8975f5c5SAndroid Build Coastguard Worker             glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
506*8975f5c5SAndroid Build Coastguard Worker                                                   GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT,
507*8975f5c5SAndroid Build Coastguard Worker                                                   &colorEncoding);
508*8975f5c5SAndroid Build Coastguard Worker 
509*8975f5c5SAndroid Build Coastguard Worker             if (eglGlColorspace == EGL_GL_COLORSPACE_LINEAR)
510*8975f5c5SAndroid Build Coastguard Worker             {
511*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_EQ(EGL_GL_COLORSPACE_LINEAR, colorspace);
512*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_EQ(GL_LINEAR, colorEncoding);
513*8975f5c5SAndroid Build Coastguard Worker             }
514*8975f5c5SAndroid Build Coastguard Worker             else
515*8975f5c5SAndroid Build Coastguard Worker             {
516*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_EQ(EGL_GL_COLORSPACE_SRGB, colorspace);
517*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_EQ(GL_SRGB_EXT, colorEncoding);
518*8975f5c5SAndroid Build Coastguard Worker             }
519*8975f5c5SAndroid Build Coastguard Worker 
520*8975f5c5SAndroid Build Coastguard Worker             // Clear the texture with 50% green and check that the color value written is correct.
521*8975f5c5SAndroid Build Coastguard Worker             glClearColor(0.0f, 0.5f, 0.0f, 1.0f);
522*8975f5c5SAndroid Build Coastguard Worker 
523*8975f5c5SAndroid Build Coastguard Worker             if (colorEncoding == GL_SRGB_EXT)
524*8975f5c5SAndroid Build Coastguard Worker             {
525*8975f5c5SAndroid Build Coastguard Worker                 glClear(GL_COLOR_BUFFER_BIT);
526*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0u, 188u, 0u, 255u), 2);
527*8975f5c5SAndroid Build Coastguard Worker             }
528*8975f5c5SAndroid Build Coastguard Worker             if (colorEncoding == GL_LINEAR)
529*8975f5c5SAndroid Build Coastguard Worker             {
530*8975f5c5SAndroid Build Coastguard Worker                 glClear(GL_COLOR_BUFFER_BIT);
531*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0u, 127u, 0u, 255u), 2);
532*8975f5c5SAndroid Build Coastguard Worker             }
533*8975f5c5SAndroid Build Coastguard Worker 
534*8975f5c5SAndroid Build Coastguard Worker             // Draw with the texture to a linear framebuffer and check that the color value written
535*8975f5c5SAndroid Build Coastguard Worker             // is correct.
536*8975f5c5SAndroid Build Coastguard Worker             testTextureSamplesAs50PercentGreen(texture);
537*8975f5c5SAndroid Build Coastguard Worker 
538*8975f5c5SAndroid Build Coastguard Worker             glBindFramebuffer(GL_FRAMEBUFFER, 0u);
539*8975f5c5SAndroid Build Coastguard Worker             glBindTexture(GL_TEXTURE_2D, 0u);
540*8975f5c5SAndroid Build Coastguard Worker             glDeleteTextures(1, &texture);
541*8975f5c5SAndroid Build Coastguard Worker             glDeleteFramebuffers(1, &fbo);
542*8975f5c5SAndroid Build Coastguard Worker             eglDestroySurface(display, pbuffer);
543*8975f5c5SAndroid Build Coastguard Worker         }
544*8975f5c5SAndroid Build Coastguard Worker     }
545*8975f5c5SAndroid Build Coastguard Worker }
546*8975f5c5SAndroid Build Coastguard Worker 
547*8975f5c5SAndroid Build Coastguard Worker class D3DTextureTestES3 : public D3DTextureTest
548*8975f5c5SAndroid Build Coastguard Worker {
549*8975f5c5SAndroid Build Coastguard Worker   protected:
D3DTextureTestES3()550*8975f5c5SAndroid Build Coastguard Worker     D3DTextureTestES3() : D3DTextureTest() {}
551*8975f5c5SAndroid Build Coastguard Worker };
552*8975f5c5SAndroid Build Coastguard Worker 
553*8975f5c5SAndroid Build Coastguard Worker // Test swizzling a pbuffer created from a D3D texture as a texture image with typeless texture
554*8975f5c5SAndroid Build Coastguard Worker // formats.
TEST_P(D3DTextureTestES3,TestD3D11TypelessTextureSwizzle)555*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureTestES3, TestD3D11TypelessTextureSwizzle)
556*8975f5c5SAndroid Build Coastguard Worker {
557*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
558*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
559*8975f5c5SAndroid Build Coastguard Worker 
560*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!valid());
561*8975f5c5SAndroid Build Coastguard Worker 
562*8975f5c5SAndroid Build Coastguard Worker     // Typeless formats are optional in the spec and currently only supported on D3D11 backend.
563*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsD3D11());
564*8975f5c5SAndroid Build Coastguard Worker 
565*8975f5c5SAndroid Build Coastguard Worker     const std::array<EGLint, 2> eglGlColorspaces = {EGL_GL_COLORSPACE_LINEAR,
566*8975f5c5SAndroid Build Coastguard Worker                                                     EGL_GL_COLORSPACE_SRGB};
567*8975f5c5SAndroid Build Coastguard Worker     const std::array<DXGI_FORMAT, 2> dxgiFormats = {DXGI_FORMAT_R8G8B8A8_TYPELESS,
568*8975f5c5SAndroid Build Coastguard Worker                                                     DXGI_FORMAT_B8G8R8A8_TYPELESS};
569*8975f5c5SAndroid Build Coastguard Worker     for (auto eglGlColorspace : eglGlColorspaces)
570*8975f5c5SAndroid Build Coastguard Worker     {
571*8975f5c5SAndroid Build Coastguard Worker         for (auto dxgiFormat : dxgiFormats)
572*8975f5c5SAndroid Build Coastguard Worker         {
573*8975f5c5SAndroid Build Coastguard Worker             SCOPED_TRACE(std::string("Test case:") + std::to_string(eglGlColorspace) + " / " +
574*8975f5c5SAndroid Build Coastguard Worker                          std::to_string(dxgiFormat));
575*8975f5c5SAndroid Build Coastguard Worker 
576*8975f5c5SAndroid Build Coastguard Worker             EGLint attribs[] = {
577*8975f5c5SAndroid Build Coastguard Worker                 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
578*8975f5c5SAndroid Build Coastguard Worker                 EGL_GL_COLORSPACE,  eglGlColorspace,  EGL_NONE,           EGL_NONE,
579*8975f5c5SAndroid Build Coastguard Worker             };
580*8975f5c5SAndroid Build Coastguard Worker 
581*8975f5c5SAndroid Build Coastguard Worker             EGLSurface pbuffer = createD3D11PBuffer(
582*8975f5c5SAndroid Build Coastguard Worker                 32, 32, 1, 0, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, dxgiFormat,
583*8975f5c5SAndroid Build Coastguard Worker                 attribs);
584*8975f5c5SAndroid Build Coastguard Worker 
585*8975f5c5SAndroid Build Coastguard Worker             ASSERT_EGL_SUCCESS();
586*8975f5c5SAndroid Build Coastguard Worker             ASSERT_NE(EGL_NO_SURFACE, pbuffer);
587*8975f5c5SAndroid Build Coastguard Worker 
588*8975f5c5SAndroid Build Coastguard Worker             EGLint colorspace = EGL_NONE;
589*8975f5c5SAndroid Build Coastguard Worker             eglQuerySurface(display, pbuffer, EGL_GL_COLORSPACE, &colorspace);
590*8975f5c5SAndroid Build Coastguard Worker 
591*8975f5c5SAndroid Build Coastguard Worker             GLuint texture = 0u;
592*8975f5c5SAndroid Build Coastguard Worker             glGenTextures(1, &texture);
593*8975f5c5SAndroid Build Coastguard Worker             glBindTexture(GL_TEXTURE_2D, texture);
594*8975f5c5SAndroid Build Coastguard Worker             EGLBoolean result = eglBindTexImage(display, pbuffer, EGL_BACK_BUFFER);
595*8975f5c5SAndroid Build Coastguard Worker             ASSERT_EGL_SUCCESS();
596*8975f5c5SAndroid Build Coastguard Worker             ASSERT_EGL_TRUE(result);
597*8975f5c5SAndroid Build Coastguard Worker 
598*8975f5c5SAndroid Build Coastguard Worker             GLuint fbo = 0u;
599*8975f5c5SAndroid Build Coastguard Worker             glGenFramebuffers(1, &fbo);
600*8975f5c5SAndroid Build Coastguard Worker             glBindFramebuffer(GL_FRAMEBUFFER, fbo);
601*8975f5c5SAndroid Build Coastguard Worker             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
602*8975f5c5SAndroid Build Coastguard Worker             glViewport(0, 0, 32, 32);
603*8975f5c5SAndroid Build Coastguard Worker 
604*8975f5c5SAndroid Build Coastguard Worker             GLint colorEncoding = 0;
605*8975f5c5SAndroid Build Coastguard Worker             glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
606*8975f5c5SAndroid Build Coastguard Worker                                                   GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT,
607*8975f5c5SAndroid Build Coastguard Worker                                                   &colorEncoding);
608*8975f5c5SAndroid Build Coastguard Worker 
609*8975f5c5SAndroid Build Coastguard Worker             // Clear the texture with 50% blue and check that the color value written is correct.
610*8975f5c5SAndroid Build Coastguard Worker             glClearColor(0.0f, 0.0f, 0.5f, 1.0f);
611*8975f5c5SAndroid Build Coastguard Worker 
612*8975f5c5SAndroid Build Coastguard Worker             if (colorEncoding == GL_SRGB_EXT)
613*8975f5c5SAndroid Build Coastguard Worker             {
614*8975f5c5SAndroid Build Coastguard Worker                 glClear(GL_COLOR_BUFFER_BIT);
615*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0u, 0u, 188u, 255u), 2);
616*8975f5c5SAndroid Build Coastguard Worker             }
617*8975f5c5SAndroid Build Coastguard Worker             if (colorEncoding == GL_LINEAR)
618*8975f5c5SAndroid Build Coastguard Worker             {
619*8975f5c5SAndroid Build Coastguard Worker                 glClear(GL_COLOR_BUFFER_BIT);
620*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0u, 0u, 127u, 255u), 2);
621*8975f5c5SAndroid Build Coastguard Worker             }
622*8975f5c5SAndroid Build Coastguard Worker 
623*8975f5c5SAndroid Build Coastguard Worker             // Swizzle the green channel to be sampled from the blue channel of the texture and vice
624*8975f5c5SAndroid Build Coastguard Worker             // versa.
625*8975f5c5SAndroid Build Coastguard Worker             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_BLUE);
626*8975f5c5SAndroid Build Coastguard Worker             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_GREEN);
627*8975f5c5SAndroid Build Coastguard Worker             ASSERT_GL_NO_ERROR();
628*8975f5c5SAndroid Build Coastguard Worker 
629*8975f5c5SAndroid Build Coastguard Worker             // Draw with the texture to a linear framebuffer and check that the color value written
630*8975f5c5SAndroid Build Coastguard Worker             // is correct.
631*8975f5c5SAndroid Build Coastguard Worker             testTextureSamplesAs50PercentGreen(texture);
632*8975f5c5SAndroid Build Coastguard Worker 
633*8975f5c5SAndroid Build Coastguard Worker             glBindFramebuffer(GL_FRAMEBUFFER, 0u);
634*8975f5c5SAndroid Build Coastguard Worker             glBindTexture(GL_TEXTURE_2D, 0u);
635*8975f5c5SAndroid Build Coastguard Worker             glDeleteTextures(1, &texture);
636*8975f5c5SAndroid Build Coastguard Worker             glDeleteFramebuffers(1, &fbo);
637*8975f5c5SAndroid Build Coastguard Worker             eglDestroySurface(display, pbuffer);
638*8975f5c5SAndroid Build Coastguard Worker         }
639*8975f5c5SAndroid Build Coastguard Worker     }
640*8975f5c5SAndroid Build Coastguard Worker }
641*8975f5c5SAndroid Build Coastguard Worker 
642*8975f5c5SAndroid Build Coastguard Worker // Test that EGL_GL_COLORSPACE attrib is not allowed for typed D3D textures.
TEST_P(D3DTextureTest,GlColorspaceNotAllowedForTypedD3DTexture)643*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureTest, GlColorspaceNotAllowedForTypedD3DTexture)
644*8975f5c5SAndroid Build Coastguard Worker {
645*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!valid());
646*8975f5c5SAndroid Build Coastguard Worker 
647*8975f5c5SAndroid Build Coastguard Worker     // D3D11 device is required to be able to create the texture.
648*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!mD3D11Device);
649*8975f5c5SAndroid Build Coastguard Worker 
650*8975f5c5SAndroid Build Coastguard Worker     // SRGB support is required.
651*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_sRGB") && getClientMajorVersion() < 3);
652*8975f5c5SAndroid Build Coastguard Worker 
653*8975f5c5SAndroid Build Coastguard Worker     EGLint attribsExplicitColorspace[] = {
654*8975f5c5SAndroid Build Coastguard Worker         EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,       EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
655*8975f5c5SAndroid Build Coastguard Worker         EGL_GL_COLORSPACE,  EGL_GL_COLORSPACE_SRGB, EGL_NONE,           EGL_NONE,
656*8975f5c5SAndroid Build Coastguard Worker     };
657*8975f5c5SAndroid Build Coastguard Worker     EGLSurface pbuffer =
658*8975f5c5SAndroid Build Coastguard Worker         createD3D11PBuffer(32, 32, 1, 0, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE,
659*8975f5c5SAndroid Build Coastguard Worker                            DXGI_FORMAT_R8G8B8A8_UNORM, attribsExplicitColorspace);
660*8975f5c5SAndroid Build Coastguard Worker 
661*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_ERROR(EGL_BAD_MATCH);
662*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(EGL_NO_SURFACE, pbuffer);
663*8975f5c5SAndroid Build Coastguard Worker }
664*8975f5c5SAndroid Build Coastguard Worker 
665*8975f5c5SAndroid Build Coastguard Worker // Test that trying to create a pbuffer from a typeless texture fails as expected on the backends
666*8975f5c5SAndroid Build Coastguard Worker // where they are known not to be supported.
TEST_P(D3DTextureTest,TypelessD3DTextureNotSupported)667*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureTest, TypelessD3DTextureNotSupported)
668*8975f5c5SAndroid Build Coastguard Worker {
669*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!valid());
670*8975f5c5SAndroid Build Coastguard Worker 
671*8975f5c5SAndroid Build Coastguard Worker     // D3D11 device is required to be able to create the texture.
672*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!mD3D11Device);
673*8975f5c5SAndroid Build Coastguard Worker 
674*8975f5c5SAndroid Build Coastguard Worker     // Currently typeless textures are supported on the D3D11 backend. We're testing the backends
675*8975f5c5SAndroid Build Coastguard Worker     // where there is no support.
676*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsD3D11());
677*8975f5c5SAndroid Build Coastguard Worker 
678*8975f5c5SAndroid Build Coastguard Worker     // SRGB support is required.
679*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_sRGB") && getClientMajorVersion() < 3);
680*8975f5c5SAndroid Build Coastguard Worker 
681*8975f5c5SAndroid Build Coastguard Worker     EGLint attribs[] = {
682*8975f5c5SAndroid Build Coastguard Worker         EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, EGL_TEXTURE_TARGET,
683*8975f5c5SAndroid Build Coastguard Worker         EGL_TEXTURE_2D,     EGL_NONE,         EGL_NONE,
684*8975f5c5SAndroid Build Coastguard Worker     };
685*8975f5c5SAndroid Build Coastguard Worker     EGLSurface pbuffer =
686*8975f5c5SAndroid Build Coastguard Worker         createD3D11PBuffer(32, 32, 1, 0, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE,
687*8975f5c5SAndroid Build Coastguard Worker                            DXGI_FORMAT_R8G8B8A8_TYPELESS, attribs);
688*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_ERROR(EGL_BAD_PARAMETER);
689*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(EGL_NO_SURFACE, pbuffer);
690*8975f5c5SAndroid Build Coastguard Worker }
691*8975f5c5SAndroid Build Coastguard Worker 
692*8975f5c5SAndroid Build Coastguard Worker // Test creating a pbuffer with unnecessary EGL_WIDTH and EGL_HEIGHT attributes because that's what
693*8975f5c5SAndroid Build Coastguard Worker // Chromium does. This is a regression test for crbug.com/794086
TEST_P(D3DTextureTest,UnnecessaryWidthHeightAttributes)694*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureTest, UnnecessaryWidthHeightAttributes)
695*8975f5c5SAndroid Build Coastguard Worker {
696*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11());
697*8975f5c5SAndroid Build Coastguard Worker     ASSERT_TRUE(mD3D11Device != nullptr);
698*8975f5c5SAndroid Build Coastguard Worker     ID3D11Texture2D *texture = nullptr;
699*8975f5c5SAndroid Build Coastguard Worker     CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, 1, 1, D3D11_BIND_RENDER_TARGET);
700*8975f5c5SAndroid Build Coastguard Worker     desc.SampleDesc.Count   = 1;
701*8975f5c5SAndroid Build Coastguard Worker     desc.SampleDesc.Quality = 0;
702*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &texture)));
703*8975f5c5SAndroid Build Coastguard Worker 
704*8975f5c5SAndroid Build Coastguard Worker     EGLint attribs[] = {
705*8975f5c5SAndroid Build Coastguard Worker         EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
706*8975f5c5SAndroid Build Coastguard Worker         EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
707*8975f5c5SAndroid Build Coastguard Worker         EGL_WIDTH,          1,
708*8975f5c5SAndroid Build Coastguard Worker         EGL_HEIGHT,         1,
709*8975f5c5SAndroid Build Coastguard Worker         EGL_NONE,           EGL_NONE,
710*8975f5c5SAndroid Build Coastguard Worker     };
711*8975f5c5SAndroid Build Coastguard Worker 
712*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
713*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
714*8975f5c5SAndroid Build Coastguard Worker     EGLConfig config   = window->getConfig();
715*8975f5c5SAndroid Build Coastguard Worker 
716*8975f5c5SAndroid Build Coastguard Worker     EGLSurface pbuffer =
717*8975f5c5SAndroid Build Coastguard Worker         eglCreatePbufferFromClientBuffer(display, EGL_D3D_TEXTURE_ANGLE, texture, config, attribs);
718*8975f5c5SAndroid Build Coastguard Worker 
719*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
720*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(pbuffer, EGL_NO_SURFACE);
721*8975f5c5SAndroid Build Coastguard Worker 
722*8975f5c5SAndroid Build Coastguard Worker     texture->Release();
723*8975f5c5SAndroid Build Coastguard Worker 
724*8975f5c5SAndroid Build Coastguard Worker     // Make current with fixture EGL to ensure the Surface can be released immediately.
725*8975f5c5SAndroid Build Coastguard Worker     getEGLWindow()->makeCurrent();
726*8975f5c5SAndroid Build Coastguard Worker     eglDestroySurface(display, pbuffer);
727*8975f5c5SAndroid Build Coastguard Worker }
728*8975f5c5SAndroid Build Coastguard Worker 
729*8975f5c5SAndroid Build Coastguard Worker // Test creating a pbuffer from a d3d surface and clearing it
TEST_P(D3DTextureTest,Clear)730*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureTest, Clear)
731*8975f5c5SAndroid Build Coastguard Worker {
732*8975f5c5SAndroid Build Coastguard Worker     if (!valid())
733*8975f5c5SAndroid Build Coastguard Worker     {
734*8975f5c5SAndroid Build Coastguard Worker         return;
735*8975f5c5SAndroid Build Coastguard Worker     }
736*8975f5c5SAndroid Build Coastguard Worker 
737*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
738*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
739*8975f5c5SAndroid Build Coastguard Worker 
740*8975f5c5SAndroid Build Coastguard Worker     const size_t bufferSize = 32;
741*8975f5c5SAndroid Build Coastguard Worker 
742*8975f5c5SAndroid Build Coastguard Worker     EGLSurface pbuffer =
743*8975f5c5SAndroid Build Coastguard Worker         createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 1, 0);
744*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
745*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(pbuffer, EGL_NO_SURFACE);
746*8975f5c5SAndroid Build Coastguard Worker 
747*8975f5c5SAndroid Build Coastguard Worker     // Apply the Pbuffer and clear it to purple and verify
748*8975f5c5SAndroid Build Coastguard Worker     eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
749*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
750*8975f5c5SAndroid Build Coastguard Worker 
751*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
752*8975f5c5SAndroid Build Coastguard Worker     glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
753*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
754*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
755*8975f5c5SAndroid Build Coastguard Worker 
756*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 255, 0,
757*8975f5c5SAndroid Build Coastguard Worker                     255, 255);
758*8975f5c5SAndroid Build Coastguard Worker 
759*8975f5c5SAndroid Build Coastguard Worker     // Make current with fixture EGL to ensure the Surface can be released immediately.
760*8975f5c5SAndroid Build Coastguard Worker     getEGLWindow()->makeCurrent();
761*8975f5c5SAndroid Build Coastguard Worker     eglDestroySurface(display, pbuffer);
762*8975f5c5SAndroid Build Coastguard Worker }
763*8975f5c5SAndroid Build Coastguard Worker 
764*8975f5c5SAndroid Build Coastguard Worker // Test creating a pbuffer with a D3D texture and depth stencil bits in the EGL config creates keeps
765*8975f5c5SAndroid Build Coastguard Worker // its depth stencil buffer
TEST_P(D3DTextureTest,DepthStencil)766*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureTest, DepthStencil)
767*8975f5c5SAndroid Build Coastguard Worker {
768*8975f5c5SAndroid Build Coastguard Worker     if (!valid())
769*8975f5c5SAndroid Build Coastguard Worker     {
770*8975f5c5SAndroid Build Coastguard Worker         return;
771*8975f5c5SAndroid Build Coastguard Worker     }
772*8975f5c5SAndroid Build Coastguard Worker 
773*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
774*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
775*8975f5c5SAndroid Build Coastguard Worker 
776*8975f5c5SAndroid Build Coastguard Worker     const size_t bufferSize = 32;
777*8975f5c5SAndroid Build Coastguard Worker 
778*8975f5c5SAndroid Build Coastguard Worker     EGLSurface pbuffer =
779*8975f5c5SAndroid Build Coastguard Worker         createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 1, 0);
780*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
781*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(pbuffer, EGL_NO_SURFACE);
782*8975f5c5SAndroid Build Coastguard Worker 
783*8975f5c5SAndroid Build Coastguard Worker     // Apply the Pbuffer and clear it to purple and verify
784*8975f5c5SAndroid Build Coastguard Worker     eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
785*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
786*8975f5c5SAndroid Build Coastguard Worker 
787*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
788*8975f5c5SAndroid Build Coastguard Worker     glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
789*8975f5c5SAndroid Build Coastguard Worker     glClearDepthf(0.5f);
790*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
791*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
792*8975f5c5SAndroid Build Coastguard Worker 
793*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_DEPTH_TEST);
794*8975f5c5SAndroid Build Coastguard Worker     glDepthMask(GL_FALSE);
795*8975f5c5SAndroid Build Coastguard Worker 
796*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mTextureProgram);
797*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(mTextureUniformLocation, 0);
798*8975f5c5SAndroid Build Coastguard Worker 
799*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
800*8975f5c5SAndroid Build Coastguard Worker 
801*8975f5c5SAndroid Build Coastguard Worker     // Draw a quad that will fail the depth test and verify that the buffer is unchanged
802*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mTextureProgram, "position", 1.0f);
803*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2,
804*8975f5c5SAndroid Build Coastguard Worker                           GLColor::cyan);
805*8975f5c5SAndroid Build Coastguard Worker 
806*8975f5c5SAndroid Build Coastguard Worker     // Draw a quad that will pass the depth test and verify that the buffer is green
807*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mTextureProgram, "position", -1.0f);
808*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2,
809*8975f5c5SAndroid Build Coastguard Worker                           GLColor::green);
810*8975f5c5SAndroid Build Coastguard Worker 
811*8975f5c5SAndroid Build Coastguard Worker     // Make current with fixture EGL to ensure the Surface can be released immediately.
812*8975f5c5SAndroid Build Coastguard Worker     getEGLWindow()->makeCurrent();
813*8975f5c5SAndroid Build Coastguard Worker     eglDestroySurface(display, pbuffer);
814*8975f5c5SAndroid Build Coastguard Worker }
815*8975f5c5SAndroid Build Coastguard Worker 
816*8975f5c5SAndroid Build Coastguard Worker // Test creating a pbuffer from a d3d surface and binding it to a texture
TEST_P(D3DTextureTest,BindTexImage)817*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureTest, BindTexImage)
818*8975f5c5SAndroid Build Coastguard Worker {
819*8975f5c5SAndroid Build Coastguard Worker     if (!valid())
820*8975f5c5SAndroid Build Coastguard Worker     {
821*8975f5c5SAndroid Build Coastguard Worker         return;
822*8975f5c5SAndroid Build Coastguard Worker     }
823*8975f5c5SAndroid Build Coastguard Worker 
824*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
825*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
826*8975f5c5SAndroid Build Coastguard Worker 
827*8975f5c5SAndroid Build Coastguard Worker     const size_t bufferSize = 32;
828*8975f5c5SAndroid Build Coastguard Worker 
829*8975f5c5SAndroid Build Coastguard Worker     EGLSurface pbuffer =
830*8975f5c5SAndroid Build Coastguard Worker         createPBuffer(bufferSize, bufferSize, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D, 1, 0);
831*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
832*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(pbuffer, EGL_NO_SURFACE);
833*8975f5c5SAndroid Build Coastguard Worker 
834*8975f5c5SAndroid Build Coastguard Worker     // Apply the Pbuffer and clear it to purple
835*8975f5c5SAndroid Build Coastguard Worker     eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
836*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
837*8975f5c5SAndroid Build Coastguard Worker 
838*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
839*8975f5c5SAndroid Build Coastguard Worker     glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
840*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
841*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
842*8975f5c5SAndroid Build Coastguard Worker 
843*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 255, 0,
844*8975f5c5SAndroid Build Coastguard Worker                     255, 255);
845*8975f5c5SAndroid Build Coastguard Worker 
846*8975f5c5SAndroid Build Coastguard Worker     // Apply the window surface
847*8975f5c5SAndroid Build Coastguard Worker     eglMakeCurrent(display, window->getSurface(), window->getSurface(), window->getContext());
848*8975f5c5SAndroid Build Coastguard Worker 
849*8975f5c5SAndroid Build Coastguard Worker     // Create a texture and bind the Pbuffer to it
850*8975f5c5SAndroid Build Coastguard Worker     GLuint texture = 0;
851*8975f5c5SAndroid Build Coastguard Worker     glGenTextures(1, &texture);
852*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
853*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
854*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
855*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
856*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
857*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
858*8975f5c5SAndroid Build Coastguard Worker 
859*8975f5c5SAndroid Build Coastguard Worker     eglBindTexImage(display, pbuffer, EGL_BACK_BUFFER);
860*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, getWindowWidth(), getWindowHeight());
861*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
862*8975f5c5SAndroid Build Coastguard Worker 
863*8975f5c5SAndroid Build Coastguard Worker     // Draw a quad and verify that it is purple
864*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mTextureProgram);
865*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(mTextureUniformLocation, 0);
866*8975f5c5SAndroid Build Coastguard Worker 
867*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mTextureProgram, "position", 0.5f);
868*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
869*8975f5c5SAndroid Build Coastguard Worker 
870*8975f5c5SAndroid Build Coastguard Worker     // Unbind the texture
871*8975f5c5SAndroid Build Coastguard Worker     eglReleaseTexImage(display, pbuffer, EGL_BACK_BUFFER);
872*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
873*8975f5c5SAndroid Build Coastguard Worker 
874*8975f5c5SAndroid Build Coastguard Worker     // Verify that purple was drawn
875*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 255, 0, 255, 255);
876*8975f5c5SAndroid Build Coastguard Worker 
877*8975f5c5SAndroid Build Coastguard Worker     glDeleteTextures(1, &texture);
878*8975f5c5SAndroid Build Coastguard Worker 
879*8975f5c5SAndroid Build Coastguard Worker     // Make current with fixture EGL to ensure the Surface can be released immediately.
880*8975f5c5SAndroid Build Coastguard Worker     getEGLWindow()->makeCurrent();
881*8975f5c5SAndroid Build Coastguard Worker     eglDestroySurface(display, pbuffer);
882*8975f5c5SAndroid Build Coastguard Worker }
883*8975f5c5SAndroid Build Coastguard Worker 
884*8975f5c5SAndroid Build Coastguard Worker // Verify that creating a pbuffer with a multisampled texture will fail on a non-multisampled
885*8975f5c5SAndroid Build Coastguard Worker // window.
TEST_P(D3DTextureTest,CheckSampleMismatch)886*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureTest, CheckSampleMismatch)
887*8975f5c5SAndroid Build Coastguard Worker {
888*8975f5c5SAndroid Build Coastguard Worker     if (!valid())
889*8975f5c5SAndroid Build Coastguard Worker     {
890*8975f5c5SAndroid Build Coastguard Worker         return;
891*8975f5c5SAndroid Build Coastguard Worker     }
892*8975f5c5SAndroid Build Coastguard Worker 
893*8975f5c5SAndroid Build Coastguard Worker     // Multisampling is not supported on D3D9 or OpenGL.
894*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsD3D9() || IsOpenGL());
895*8975f5c5SAndroid Build Coastguard Worker 
896*8975f5c5SAndroid Build Coastguard Worker     constexpr size_t bufferSize = 32;
897*8975f5c5SAndroid Build Coastguard Worker 
898*8975f5c5SAndroid Build Coastguard Worker     EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 2,
899*8975f5c5SAndroid Build Coastguard Worker                                        static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));
900*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
901*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(pbuffer, nullptr);
902*8975f5c5SAndroid Build Coastguard Worker }
903*8975f5c5SAndroid Build Coastguard Worker 
904*8975f5c5SAndroid Build Coastguard Worker // Tests what happens when we make a PBuffer that isn't shader-readable.
TEST_P(D3DTextureTest,NonReadablePBuffer)905*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureTest, NonReadablePBuffer)
906*8975f5c5SAndroid Build Coastguard Worker {
907*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11());
908*8975f5c5SAndroid Build Coastguard Worker 
909*8975f5c5SAndroid Build Coastguard Worker     constexpr size_t bufferSize = 32;
910*8975f5c5SAndroid Build Coastguard Worker 
911*8975f5c5SAndroid Build Coastguard Worker     EGLSurface pbuffer =
912*8975f5c5SAndroid Build Coastguard Worker         createD3D11PBuffer(bufferSize, bufferSize, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D, 1, 0,
913*8975f5c5SAndroid Build Coastguard Worker                            D3D11_BIND_RENDER_TARGET, DXGI_FORMAT_R8G8B8A8_UNORM);
914*8975f5c5SAndroid Build Coastguard Worker 
915*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
916*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(pbuffer, EGL_NO_SURFACE);
917*8975f5c5SAndroid Build Coastguard Worker 
918*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
919*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
920*8975f5c5SAndroid Build Coastguard Worker 
921*8975f5c5SAndroid Build Coastguard Worker     eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
922*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
923*8975f5c5SAndroid Build Coastguard Worker 
924*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
925*8975f5c5SAndroid Build Coastguard Worker 
926*8975f5c5SAndroid Build Coastguard Worker     // Clear to green.
927*8975f5c5SAndroid Build Coastguard Worker     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
928*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
929*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
930*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
931*8975f5c5SAndroid Build Coastguard Worker 
932*8975f5c5SAndroid Build Coastguard Worker     // Copy the green color to a texture.
933*8975f5c5SAndroid Build Coastguard Worker     GLTexture tex;
934*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, tex);
935*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
936*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
937*8975f5c5SAndroid Build Coastguard Worker     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, bufferSize, bufferSize, 0);
938*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
939*8975f5c5SAndroid Build Coastguard Worker 
940*8975f5c5SAndroid Build Coastguard Worker     // Clear to red.
941*8975f5c5SAndroid Build Coastguard Worker     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
942*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
943*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
944*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
945*8975f5c5SAndroid Build Coastguard Worker 
946*8975f5c5SAndroid Build Coastguard Worker     // Draw with the texture and expect green.
947*8975f5c5SAndroid Build Coastguard Worker     draw2DTexturedQuad(0.5f, 1.0f, false);
948*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
949*8975f5c5SAndroid Build Coastguard Worker 
950*8975f5c5SAndroid Build Coastguard Worker     // Make current with fixture EGL to ensure the Surface can be released immediately.
951*8975f5c5SAndroid Build Coastguard Worker     getEGLWindow()->makeCurrent();
952*8975f5c5SAndroid Build Coastguard Worker     eglDestroySurface(display, pbuffer);
953*8975f5c5SAndroid Build Coastguard Worker }
954*8975f5c5SAndroid Build Coastguard Worker 
955*8975f5c5SAndroid Build Coastguard Worker class D3DTextureTestMS : public D3DTextureTest
956*8975f5c5SAndroid Build Coastguard Worker {
957*8975f5c5SAndroid Build Coastguard Worker   protected:
D3DTextureTestMS()958*8975f5c5SAndroid Build Coastguard Worker     D3DTextureTestMS() : D3DTextureTest()
959*8975f5c5SAndroid Build Coastguard Worker     {
960*8975f5c5SAndroid Build Coastguard Worker         setSamples(4);
961*8975f5c5SAndroid Build Coastguard Worker         setMultisampleEnabled(true);
962*8975f5c5SAndroid Build Coastguard Worker     }
963*8975f5c5SAndroid Build Coastguard Worker };
964*8975f5c5SAndroid Build Coastguard Worker 
965*8975f5c5SAndroid Build Coastguard Worker // Test creating a pbuffer from a multisampled d3d surface and clearing it.
TEST_P(D3DTextureTestMS,Clear)966*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureTestMS, Clear)
967*8975f5c5SAndroid Build Coastguard Worker {
968*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
969*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
970*8975f5c5SAndroid Build Coastguard Worker 
971*8975f5c5SAndroid Build Coastguard Worker     constexpr size_t bufferSize = 32;
972*8975f5c5SAndroid Build Coastguard Worker     constexpr UINT testpoint    = bufferSize / 2;
973*8975f5c5SAndroid Build Coastguard Worker 
974*8975f5c5SAndroid Build Coastguard Worker     EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 4,
975*8975f5c5SAndroid Build Coastguard Worker                                        static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));
976*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
977*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(pbuffer, EGL_NO_SURFACE);
978*8975f5c5SAndroid Build Coastguard Worker 
979*8975f5c5SAndroid Build Coastguard Worker     // Apply the Pbuffer and clear it to magenta and verify
980*8975f5c5SAndroid Build Coastguard Worker     eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
981*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
982*8975f5c5SAndroid Build Coastguard Worker 
983*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
984*8975f5c5SAndroid Build Coastguard Worker     glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
985*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
986*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
987*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(testpoint, testpoint, GLColor::magenta);
988*8975f5c5SAndroid Build Coastguard Worker 
989*8975f5c5SAndroid Build Coastguard Worker     // Make current with fixture EGL to ensure the Surface can be released immediately.
990*8975f5c5SAndroid Build Coastguard Worker     getEGLWindow()->makeCurrent();
991*8975f5c5SAndroid Build Coastguard Worker     eglDestroySurface(display, pbuffer);
992*8975f5c5SAndroid Build Coastguard Worker }
993*8975f5c5SAndroid Build Coastguard Worker 
994*8975f5c5SAndroid Build Coastguard Worker // Test creating a pbuffer from a multisampled d3d surface and drawing with a program.
TEST_P(D3DTextureTestMS,DrawProgram)995*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureTestMS, DrawProgram)
996*8975f5c5SAndroid Build Coastguard Worker {
997*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
998*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
999*8975f5c5SAndroid Build Coastguard Worker 
1000*8975f5c5SAndroid Build Coastguard Worker     constexpr size_t bufferSize = 32;
1001*8975f5c5SAndroid Build Coastguard Worker 
1002*8975f5c5SAndroid Build Coastguard Worker     EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 4,
1003*8975f5c5SAndroid Build Coastguard Worker                                        static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));
1004*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
1005*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(pbuffer, EGL_NO_SURFACE);
1006*8975f5c5SAndroid Build Coastguard Worker 
1007*8975f5c5SAndroid Build Coastguard Worker     // Apply the Pbuffer and clear it to magenta
1008*8975f5c5SAndroid Build Coastguard Worker     eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
1009*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
1010*8975f5c5SAndroid Build Coastguard Worker 
1011*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
1012*8975f5c5SAndroid Build Coastguard Worker     glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
1013*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
1014*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1015*8975f5c5SAndroid Build Coastguard Worker 
1016*8975f5c5SAndroid Build Coastguard Worker     constexpr GLint testPoint = bufferSize / 2;
1017*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(testPoint, testPoint, GLColor::magenta);
1018*8975f5c5SAndroid Build Coastguard Worker 
1019*8975f5c5SAndroid Build Coastguard Worker     // Apply the window surface
1020*8975f5c5SAndroid Build Coastguard Worker     eglMakeCurrent(display, window->getSurface(), window->getSurface(), window->getContext());
1021*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
1022*8975f5c5SAndroid Build Coastguard Worker 
1023*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, getWindowWidth(), getWindowHeight());
1024*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
1025*8975f5c5SAndroid Build Coastguard Worker 
1026*8975f5c5SAndroid Build Coastguard Worker     // Draw a quad and verify that it is magenta
1027*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mTextureProgramNoSampling);
1028*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1029*8975f5c5SAndroid Build Coastguard Worker 
1030*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mTextureProgramNoSampling, "position", 0.5f);
1031*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1032*8975f5c5SAndroid Build Coastguard Worker 
1033*8975f5c5SAndroid Build Coastguard Worker     // Verify that magenta was drawn
1034*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::magenta);
1035*8975f5c5SAndroid Build Coastguard Worker 
1036*8975f5c5SAndroid Build Coastguard Worker     // Make current with fixture EGL to ensure the Surface can be released immediately.
1037*8975f5c5SAndroid Build Coastguard Worker     getEGLWindow()->makeCurrent();
1038*8975f5c5SAndroid Build Coastguard Worker     eglDestroySurface(display, pbuffer);
1039*8975f5c5SAndroid Build Coastguard Worker }
1040*8975f5c5SAndroid Build Coastguard Worker 
1041*8975f5c5SAndroid Build Coastguard Worker // Test for failure when creating a pbuffer from a multisampled d3d surface to bind to a texture.
TEST_P(D3DTextureTestMS,BindTexture)1042*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureTestMS, BindTexture)
1043*8975f5c5SAndroid Build Coastguard Worker {
1044*8975f5c5SAndroid Build Coastguard Worker     constexpr size_t bufferSize = 32;
1045*8975f5c5SAndroid Build Coastguard Worker 
1046*8975f5c5SAndroid Build Coastguard Worker     EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D, 4,
1047*8975f5c5SAndroid Build Coastguard Worker                                        static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));
1048*8975f5c5SAndroid Build Coastguard Worker 
1049*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
1050*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(pbuffer, nullptr);
1051*8975f5c5SAndroid Build Coastguard Worker }
1052*8975f5c5SAndroid Build Coastguard Worker 
1053*8975f5c5SAndroid Build Coastguard Worker // Verify that creating a pbuffer from a multisampled texture with a multisampled window will fail
1054*8975f5c5SAndroid Build Coastguard Worker // when the sample counts do not match.
TEST_P(D3DTextureTestMS,CheckSampleMismatch)1055*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureTestMS, CheckSampleMismatch)
1056*8975f5c5SAndroid Build Coastguard Worker {
1057*8975f5c5SAndroid Build Coastguard Worker     constexpr size_t bufferSize = 32;
1058*8975f5c5SAndroid Build Coastguard Worker 
1059*8975f5c5SAndroid Build Coastguard Worker     EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 2,
1060*8975f5c5SAndroid Build Coastguard Worker                                        static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));
1061*8975f5c5SAndroid Build Coastguard Worker 
1062*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
1063*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(pbuffer, nullptr);
1064*8975f5c5SAndroid Build Coastguard Worker }
1065*8975f5c5SAndroid Build Coastguard Worker 
1066*8975f5c5SAndroid Build Coastguard Worker // Test creating a pbuffer with a D3D texture and depth stencil bits in the EGL config creates keeps
1067*8975f5c5SAndroid Build Coastguard Worker // its depth stencil buffer
TEST_P(D3DTextureTestMS,DepthStencil)1068*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureTestMS, DepthStencil)
1069*8975f5c5SAndroid Build Coastguard Worker {
1070*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
1071*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
1072*8975f5c5SAndroid Build Coastguard Worker 
1073*8975f5c5SAndroid Build Coastguard Worker     const size_t bufferSize = 32;
1074*8975f5c5SAndroid Build Coastguard Worker 
1075*8975f5c5SAndroid Build Coastguard Worker     EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 4,
1076*8975f5c5SAndroid Build Coastguard Worker                                        static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));
1077*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
1078*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(EGL_NO_SURFACE, pbuffer);
1079*8975f5c5SAndroid Build Coastguard Worker 
1080*8975f5c5SAndroid Build Coastguard Worker     // Apply the Pbuffer and clear it to purple and verify
1081*8975f5c5SAndroid Build Coastguard Worker     eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
1082*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
1083*8975f5c5SAndroid Build Coastguard Worker 
1084*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
1085*8975f5c5SAndroid Build Coastguard Worker     glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
1086*8975f5c5SAndroid Build Coastguard Worker     glClearDepthf(0.5f);
1087*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1088*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1089*8975f5c5SAndroid Build Coastguard Worker 
1090*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_DEPTH_TEST);
1091*8975f5c5SAndroid Build Coastguard Worker     glDepthMask(GL_FALSE);
1092*8975f5c5SAndroid Build Coastguard Worker 
1093*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mTextureProgram);
1094*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(mTextureUniformLocation, 0);
1095*8975f5c5SAndroid Build Coastguard Worker 
1096*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
1097*8975f5c5SAndroid Build Coastguard Worker 
1098*8975f5c5SAndroid Build Coastguard Worker     // Draw a quad that will fail the depth test and verify that the buffer is unchanged
1099*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mTextureProgram, "position", 1.0f);
1100*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2,
1101*8975f5c5SAndroid Build Coastguard Worker                           GLColor::cyan);
1102*8975f5c5SAndroid Build Coastguard Worker 
1103*8975f5c5SAndroid Build Coastguard Worker     // Draw a quad that will pass the depth test and verify that the buffer is green
1104*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mTextureProgram, "position", -1.0f);
1105*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2,
1106*8975f5c5SAndroid Build Coastguard Worker                           GLColor::green);
1107*8975f5c5SAndroid Build Coastguard Worker 
1108*8975f5c5SAndroid Build Coastguard Worker     // Make current with fixture EGL to ensure the Surface can be released immediately.
1109*8975f5c5SAndroid Build Coastguard Worker     getEGLWindow()->makeCurrent();
1110*8975f5c5SAndroid Build Coastguard Worker     eglDestroySurface(display, pbuffer);
1111*8975f5c5SAndroid Build Coastguard Worker }
1112*8975f5c5SAndroid Build Coastguard Worker 
1113*8975f5c5SAndroid Build Coastguard Worker // Test copyTexImage2D with a multisampled resource
TEST_P(D3DTextureTestMS,CopyTexImage2DTest)1114*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureTestMS, CopyTexImage2DTest)
1115*8975f5c5SAndroid Build Coastguard Worker {
1116*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
1117*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
1118*8975f5c5SAndroid Build Coastguard Worker 
1119*8975f5c5SAndroid Build Coastguard Worker     constexpr size_t bufferSize = 32;
1120*8975f5c5SAndroid Build Coastguard Worker 
1121*8975f5c5SAndroid Build Coastguard Worker     EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 4,
1122*8975f5c5SAndroid Build Coastguard Worker                                        static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));
1123*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
1124*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(EGL_NO_SURFACE, pbuffer);
1125*8975f5c5SAndroid Build Coastguard Worker 
1126*8975f5c5SAndroid Build Coastguard Worker     // Apply the Pbuffer and clear it to magenta and verify
1127*8975f5c5SAndroid Build Coastguard Worker     eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
1128*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
1129*8975f5c5SAndroid Build Coastguard Worker 
1130*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
1131*8975f5c5SAndroid Build Coastguard Worker     glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
1132*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1133*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1134*8975f5c5SAndroid Build Coastguard Worker 
1135*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mTextureProgram);
1136*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(mTextureUniformLocation, 0);
1137*8975f5c5SAndroid Build Coastguard Worker 
1138*8975f5c5SAndroid Build Coastguard Worker     // Specify a 2D texture and set it to green
1139*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
1140*8975f5c5SAndroid Build Coastguard Worker 
1141*8975f5c5SAndroid Build Coastguard Worker     // Copy from the multisampled framebuffer to the 2D texture
1142*8975f5c5SAndroid Build Coastguard Worker     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 1, 1, 0);
1143*8975f5c5SAndroid Build Coastguard Worker 
1144*8975f5c5SAndroid Build Coastguard Worker     // Draw a quad and verify the color is magenta, not green
1145*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mTextureProgram, "position", 1.0f);
1146*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2,
1147*8975f5c5SAndroid Build Coastguard Worker                           GLColor::magenta);
1148*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1149*8975f5c5SAndroid Build Coastguard Worker 
1150*8975f5c5SAndroid Build Coastguard Worker     // Make current with fixture EGL to ensure the Surface can be released immediately.
1151*8975f5c5SAndroid Build Coastguard Worker     getEGLWindow()->makeCurrent();
1152*8975f5c5SAndroid Build Coastguard Worker     eglDestroySurface(display, pbuffer);
1153*8975f5c5SAndroid Build Coastguard Worker }
1154*8975f5c5SAndroid Build Coastguard Worker 
1155*8975f5c5SAndroid Build Coastguard Worker // Test copyTexSubImage2D with a multisampled resource
TEST_P(D3DTextureTestMS,CopyTexSubImage2DTest)1156*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureTestMS, CopyTexSubImage2DTest)
1157*8975f5c5SAndroid Build Coastguard Worker {
1158*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
1159*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
1160*8975f5c5SAndroid Build Coastguard Worker 
1161*8975f5c5SAndroid Build Coastguard Worker     constexpr size_t bufferSize = 32;
1162*8975f5c5SAndroid Build Coastguard Worker 
1163*8975f5c5SAndroid Build Coastguard Worker     EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 4,
1164*8975f5c5SAndroid Build Coastguard Worker                                        static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));
1165*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
1166*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(EGL_NO_SURFACE, pbuffer);
1167*8975f5c5SAndroid Build Coastguard Worker 
1168*8975f5c5SAndroid Build Coastguard Worker     // Apply the Pbuffer and clear it to magenta and verify
1169*8975f5c5SAndroid Build Coastguard Worker     eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
1170*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
1171*8975f5c5SAndroid Build Coastguard Worker 
1172*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
1173*8975f5c5SAndroid Build Coastguard Worker     glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
1174*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1175*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1176*8975f5c5SAndroid Build Coastguard Worker 
1177*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mTextureProgram);
1178*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(mTextureUniformLocation, 0);
1179*8975f5c5SAndroid Build Coastguard Worker 
1180*8975f5c5SAndroid Build Coastguard Worker     // Specify a 2D texture and set it to green
1181*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
1182*8975f5c5SAndroid Build Coastguard Worker 
1183*8975f5c5SAndroid Build Coastguard Worker     // Copy from the multisampled framebuffer to the 2D texture
1184*8975f5c5SAndroid Build Coastguard Worker     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
1185*8975f5c5SAndroid Build Coastguard Worker 
1186*8975f5c5SAndroid Build Coastguard Worker     // Draw a quad and verify the color is magenta, not green
1187*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mTextureProgram, "position", 1.0f);
1188*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2,
1189*8975f5c5SAndroid Build Coastguard Worker                           GLColor::magenta);
1190*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1191*8975f5c5SAndroid Build Coastguard Worker 
1192*8975f5c5SAndroid Build Coastguard Worker     // Make current with fixture EGL to ensure the Surface can be released immediately.
1193*8975f5c5SAndroid Build Coastguard Worker     getEGLWindow()->makeCurrent();
1194*8975f5c5SAndroid Build Coastguard Worker     eglDestroySurface(display, pbuffer);
1195*8975f5c5SAndroid Build Coastguard Worker }
1196*8975f5c5SAndroid Build Coastguard Worker 
1197*8975f5c5SAndroid Build Coastguard Worker class D3DTextureClearTest : public D3DTextureTest
1198*8975f5c5SAndroid Build Coastguard Worker {
1199*8975f5c5SAndroid Build Coastguard Worker   protected:
D3DTextureClearTest()1200*8975f5c5SAndroid Build Coastguard Worker     D3DTextureClearTest() : D3DTextureTest() {}
1201*8975f5c5SAndroid Build Coastguard Worker 
RunClearTest(DXGI_FORMAT format)1202*8975f5c5SAndroid Build Coastguard Worker     void RunClearTest(DXGI_FORMAT format)
1203*8975f5c5SAndroid Build Coastguard Worker     {
1204*8975f5c5SAndroid Build Coastguard Worker         ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11());
1205*8975f5c5SAndroid Build Coastguard Worker 
1206*8975f5c5SAndroid Build Coastguard Worker         EGLWindow *window  = getEGLWindow();
1207*8975f5c5SAndroid Build Coastguard Worker         EGLDisplay display = window->getDisplay();
1208*8975f5c5SAndroid Build Coastguard Worker 
1209*8975f5c5SAndroid Build Coastguard Worker         window->makeCurrent();
1210*8975f5c5SAndroid Build Coastguard Worker 
1211*8975f5c5SAndroid Build Coastguard Worker         const UINT bufferSize = 32;
1212*8975f5c5SAndroid Build Coastguard Worker         EXPECT_TRUE(mD3D11Device != nullptr);
1213*8975f5c5SAndroid Build Coastguard Worker         ID3D11Texture2D *d3d11Texture = nullptr;
1214*8975f5c5SAndroid Build Coastguard Worker         CD3D11_TEXTURE2D_DESC desc(format, bufferSize, bufferSize, 1, 1,
1215*8975f5c5SAndroid Build Coastguard Worker                                    D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
1216*8975f5c5SAndroid Build Coastguard Worker         EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &d3d11Texture)));
1217*8975f5c5SAndroid Build Coastguard Worker 
1218*8975f5c5SAndroid Build Coastguard Worker         // Can use unsized formats for all cases, but use sized ones to match Chromium.
1219*8975f5c5SAndroid Build Coastguard Worker         EGLint internalFormat = GL_NONE;
1220*8975f5c5SAndroid Build Coastguard Worker         switch (format)
1221*8975f5c5SAndroid Build Coastguard Worker         {
1222*8975f5c5SAndroid Build Coastguard Worker             case DXGI_FORMAT_R8G8B8A8_UNORM:
1223*8975f5c5SAndroid Build Coastguard Worker             case DXGI_FORMAT_R16G16B16A16_FLOAT:
1224*8975f5c5SAndroid Build Coastguard Worker                 internalFormat = GL_RGBA;
1225*8975f5c5SAndroid Build Coastguard Worker                 break;
1226*8975f5c5SAndroid Build Coastguard Worker             case DXGI_FORMAT_B8G8R8A8_UNORM:
1227*8975f5c5SAndroid Build Coastguard Worker                 internalFormat = GL_BGRA_EXT;
1228*8975f5c5SAndroid Build Coastguard Worker                 break;
1229*8975f5c5SAndroid Build Coastguard Worker             case DXGI_FORMAT_R8_UNORM:
1230*8975f5c5SAndroid Build Coastguard Worker                 internalFormat = GL_RED_EXT;
1231*8975f5c5SAndroid Build Coastguard Worker                 break;
1232*8975f5c5SAndroid Build Coastguard Worker             case DXGI_FORMAT_R8G8_UNORM:
1233*8975f5c5SAndroid Build Coastguard Worker                 internalFormat = GL_RG_EXT;
1234*8975f5c5SAndroid Build Coastguard Worker                 break;
1235*8975f5c5SAndroid Build Coastguard Worker             case DXGI_FORMAT_R10G10B10A2_UNORM:
1236*8975f5c5SAndroid Build Coastguard Worker                 internalFormat = GL_RGB10_A2_EXT;
1237*8975f5c5SAndroid Build Coastguard Worker                 break;
1238*8975f5c5SAndroid Build Coastguard Worker             case DXGI_FORMAT_R16_UNORM:
1239*8975f5c5SAndroid Build Coastguard Worker                 internalFormat = GL_R16_EXT;
1240*8975f5c5SAndroid Build Coastguard Worker                 break;
1241*8975f5c5SAndroid Build Coastguard Worker             case DXGI_FORMAT_R16G16_UNORM:
1242*8975f5c5SAndroid Build Coastguard Worker                 internalFormat = GL_RG16_EXT;
1243*8975f5c5SAndroid Build Coastguard Worker                 break;
1244*8975f5c5SAndroid Build Coastguard Worker             default:
1245*8975f5c5SAndroid Build Coastguard Worker                 ASSERT_TRUE(false);
1246*8975f5c5SAndroid Build Coastguard Worker                 break;
1247*8975f5c5SAndroid Build Coastguard Worker         }
1248*8975f5c5SAndroid Build Coastguard Worker 
1249*8975f5c5SAndroid Build Coastguard Worker         const EGLint attribs[] = {EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, internalFormat, EGL_NONE};
1250*8975f5c5SAndroid Build Coastguard Worker 
1251*8975f5c5SAndroid Build Coastguard Worker         EGLImage image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_D3D11_TEXTURE_ANGLE,
1252*8975f5c5SAndroid Build Coastguard Worker                                            static_cast<EGLClientBuffer>(d3d11Texture), attribs);
1253*8975f5c5SAndroid Build Coastguard Worker         ASSERT_EGL_SUCCESS();
1254*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(image, EGL_NO_IMAGE_KHR);
1255*8975f5c5SAndroid Build Coastguard Worker 
1256*8975f5c5SAndroid Build Coastguard Worker         GLuint texture;
1257*8975f5c5SAndroid Build Coastguard Worker         glGenTextures(1, &texture);
1258*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, texture);
1259*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1260*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1261*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1262*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1263*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1264*8975f5c5SAndroid Build Coastguard Worker 
1265*8975f5c5SAndroid Build Coastguard Worker         glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
1266*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1267*8975f5c5SAndroid Build Coastguard Worker 
1268*8975f5c5SAndroid Build Coastguard Worker         GLuint fbo;
1269*8975f5c5SAndroid Build Coastguard Worker         glGenFramebuffers(1, &fbo);
1270*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1271*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
1272*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
1273*8975f5c5SAndroid Build Coastguard Worker                   static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));
1274*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1275*8975f5c5SAndroid Build Coastguard Worker 
1276*8975f5c5SAndroid Build Coastguard Worker         glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
1277*8975f5c5SAndroid Build Coastguard Worker         glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
1278*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
1279*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1280*8975f5c5SAndroid Build Coastguard Worker 
1281*8975f5c5SAndroid Build Coastguard Worker         if (format == DXGI_FORMAT_R16G16B16A16_FLOAT)
1282*8975f5c5SAndroid Build Coastguard Worker         {
1283*8975f5c5SAndroid Build Coastguard Worker             EXPECT_PIXEL_32F_EQ(static_cast<GLint>(bufferSize) / 2,
1284*8975f5c5SAndroid Build Coastguard Worker                                 static_cast<GLint>(bufferSize) / 2, 1.0f, 1.0f, 1.0f, 1.0f);
1285*8975f5c5SAndroid Build Coastguard Worker         }
1286*8975f5c5SAndroid Build Coastguard Worker         else if (format == DXGI_FORMAT_R16_UNORM)
1287*8975f5c5SAndroid Build Coastguard Worker         {
1288*8975f5c5SAndroid Build Coastguard Worker             EXPECT_PIXEL_16_NEAR(static_cast<GLint>(bufferSize) / 2,
1289*8975f5c5SAndroid Build Coastguard Worker                                  static_cast<GLint>(bufferSize) / 2, 65535, 0, 0, 65535, 0);
1290*8975f5c5SAndroid Build Coastguard Worker         }
1291*8975f5c5SAndroid Build Coastguard Worker         else if (format == DXGI_FORMAT_R16G16_UNORM)
1292*8975f5c5SAndroid Build Coastguard Worker         {
1293*8975f5c5SAndroid Build Coastguard Worker             EXPECT_PIXEL_16_NEAR(static_cast<GLint>(bufferSize) / 2,
1294*8975f5c5SAndroid Build Coastguard Worker                                  static_cast<GLint>(bufferSize) / 2, 65535, 65535, 0, 65535, 0);
1295*8975f5c5SAndroid Build Coastguard Worker         }
1296*8975f5c5SAndroid Build Coastguard Worker         else
1297*8975f5c5SAndroid Build Coastguard Worker         {
1298*8975f5c5SAndroid Build Coastguard Worker             GLuint readColor[4] = {0, 0, 0, 255};
1299*8975f5c5SAndroid Build Coastguard Worker             switch (internalFormat)
1300*8975f5c5SAndroid Build Coastguard Worker             {
1301*8975f5c5SAndroid Build Coastguard Worker                 case GL_RGBA:
1302*8975f5c5SAndroid Build Coastguard Worker                 case GL_BGRA_EXT:
1303*8975f5c5SAndroid Build Coastguard Worker                 case GL_RGB10_A2_EXT:
1304*8975f5c5SAndroid Build Coastguard Worker                     readColor[0] = readColor[1] = readColor[2] = 255;
1305*8975f5c5SAndroid Build Coastguard Worker                     break;
1306*8975f5c5SAndroid Build Coastguard Worker                 case GL_RG_EXT:
1307*8975f5c5SAndroid Build Coastguard Worker                     readColor[0] = readColor[1] = 255;
1308*8975f5c5SAndroid Build Coastguard Worker                     break;
1309*8975f5c5SAndroid Build Coastguard Worker                 case GL_RED_EXT:
1310*8975f5c5SAndroid Build Coastguard Worker                     readColor[0] = 255;
1311*8975f5c5SAndroid Build Coastguard Worker                     break;
1312*8975f5c5SAndroid Build Coastguard Worker             }
1313*8975f5c5SAndroid Build Coastguard Worker             // Read back as GL_UNSIGNED_BYTE even though the texture might have more than 8bpc.
1314*8975f5c5SAndroid Build Coastguard Worker             EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2,
1315*8975f5c5SAndroid Build Coastguard Worker                             readColor[0], readColor[1], readColor[2], readColor[3]);
1316*8975f5c5SAndroid Build Coastguard Worker         }
1317*8975f5c5SAndroid Build Coastguard Worker 
1318*8975f5c5SAndroid Build Coastguard Worker         glDeleteFramebuffers(1, &fbo);
1319*8975f5c5SAndroid Build Coastguard Worker         glDeleteTextures(1, &texture);
1320*8975f5c5SAndroid Build Coastguard Worker         eglDestroyImageKHR(display, image);
1321*8975f5c5SAndroid Build Coastguard Worker 
1322*8975f5c5SAndroid Build Coastguard Worker         d3d11Texture->Release();
1323*8975f5c5SAndroid Build Coastguard Worker     }
1324*8975f5c5SAndroid Build Coastguard Worker };
1325*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(D3DTextureClearTest,ClearRGBA8)1326*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureClearTest, ClearRGBA8)
1327*8975f5c5SAndroid Build Coastguard Worker {
1328*8975f5c5SAndroid Build Coastguard Worker     RunClearTest(DXGI_FORMAT_R8G8B8A8_UNORM);
1329*8975f5c5SAndroid Build Coastguard Worker }
1330*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(D3DTextureClearTest,ClearBGRA8)1331*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureClearTest, ClearBGRA8)
1332*8975f5c5SAndroid Build Coastguard Worker {
1333*8975f5c5SAndroid Build Coastguard Worker     RunClearTest(DXGI_FORMAT_B8G8R8A8_UNORM);
1334*8975f5c5SAndroid Build Coastguard Worker }
1335*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(D3DTextureClearTest,ClearR8)1336*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureClearTest, ClearR8)
1337*8975f5c5SAndroid Build Coastguard Worker {
1338*8975f5c5SAndroid Build Coastguard Worker     RunClearTest(DXGI_FORMAT_R8_UNORM);
1339*8975f5c5SAndroid Build Coastguard Worker }
1340*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(D3DTextureClearTest,ClearRG8)1341*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureClearTest, ClearRG8)
1342*8975f5c5SAndroid Build Coastguard Worker {
1343*8975f5c5SAndroid Build Coastguard Worker     RunClearTest(DXGI_FORMAT_R8G8_UNORM);
1344*8975f5c5SAndroid Build Coastguard Worker }
1345*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(D3DTextureClearTest,ClearRGB10A2)1346*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureClearTest, ClearRGB10A2)
1347*8975f5c5SAndroid Build Coastguard Worker {
1348*8975f5c5SAndroid Build Coastguard Worker     RunClearTest(DXGI_FORMAT_R10G10B10A2_UNORM);
1349*8975f5c5SAndroid Build Coastguard Worker }
1350*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(D3DTextureClearTest,ClearRGBAF16)1351*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureClearTest, ClearRGBAF16)
1352*8975f5c5SAndroid Build Coastguard Worker {
1353*8975f5c5SAndroid Build Coastguard Worker     RunClearTest(DXGI_FORMAT_R16G16B16A16_FLOAT);
1354*8975f5c5SAndroid Build Coastguard Worker }
1355*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(D3DTextureClearTest,ClearR16)1356*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureClearTest, ClearR16)
1357*8975f5c5SAndroid Build Coastguard Worker {
1358*8975f5c5SAndroid Build Coastguard Worker     RunClearTest(DXGI_FORMAT_R16_UNORM);
1359*8975f5c5SAndroid Build Coastguard Worker }
1360*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(D3DTextureClearTest,ClearRG16)1361*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureClearTest, ClearRG16)
1362*8975f5c5SAndroid Build Coastguard Worker {
1363*8975f5c5SAndroid Build Coastguard Worker     RunClearTest(DXGI_FORMAT_R16G16_UNORM);
1364*8975f5c5SAndroid Build Coastguard Worker }
1365*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(D3DTextureTest,NonRenderableTextureImage)1366*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureTest, NonRenderableTextureImage)
1367*8975f5c5SAndroid Build Coastguard Worker {
1368*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11());
1369*8975f5c5SAndroid Build Coastguard Worker 
1370*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
1371*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
1372*8975f5c5SAndroid Build Coastguard Worker 
1373*8975f5c5SAndroid Build Coastguard Worker     window->makeCurrent();
1374*8975f5c5SAndroid Build Coastguard Worker 
1375*8975f5c5SAndroid Build Coastguard Worker     const UINT bufferSize = 32;
1376*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(mD3D11Device != nullptr);
1377*8975f5c5SAndroid Build Coastguard Worker     ID3D11Texture2D *d3d11Texture = nullptr;
1378*8975f5c5SAndroid Build Coastguard Worker     CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, bufferSize, bufferSize, 1, 1,
1379*8975f5c5SAndroid Build Coastguard Worker                                D3D11_BIND_SHADER_RESOURCE);
1380*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &d3d11Texture)));
1381*8975f5c5SAndroid Build Coastguard Worker 
1382*8975f5c5SAndroid Build Coastguard Worker     const EGLint attribs[] = {EGL_NONE};
1383*8975f5c5SAndroid Build Coastguard Worker 
1384*8975f5c5SAndroid Build Coastguard Worker     EGLImage image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_D3D11_TEXTURE_ANGLE,
1385*8975f5c5SAndroid Build Coastguard Worker                                        static_cast<EGLClientBuffer>(d3d11Texture), attribs);
1386*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
1387*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(image, EGL_NO_IMAGE_KHR);
1388*8975f5c5SAndroid Build Coastguard Worker 
1389*8975f5c5SAndroid Build Coastguard Worker     GLuint texture;
1390*8975f5c5SAndroid Build Coastguard Worker     glGenTextures(1, &texture);
1391*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
1392*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1393*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1394*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1395*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1396*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1397*8975f5c5SAndroid Build Coastguard Worker 
1398*8975f5c5SAndroid Build Coastguard Worker     glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
1399*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1400*8975f5c5SAndroid Build Coastguard Worker 
1401*8975f5c5SAndroid Build Coastguard Worker     GLuint fbo;
1402*8975f5c5SAndroid Build Coastguard Worker     glGenFramebuffers(1, &fbo);
1403*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1404*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
1405*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
1406*8975f5c5SAndroid Build Coastguard Worker               static_cast<unsigned>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT));
1407*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1408*8975f5c5SAndroid Build Coastguard Worker 
1409*8975f5c5SAndroid Build Coastguard Worker     glDeleteFramebuffers(1, &fbo);
1410*8975f5c5SAndroid Build Coastguard Worker     glDeleteTextures(1, &texture);
1411*8975f5c5SAndroid Build Coastguard Worker     eglDestroyImageKHR(display, image);
1412*8975f5c5SAndroid Build Coastguard Worker 
1413*8975f5c5SAndroid Build Coastguard Worker     d3d11Texture->Release();
1414*8975f5c5SAndroid Build Coastguard Worker }
1415*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(D3DTextureTest,RGBEmulationTextureImage)1416*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureTest, RGBEmulationTextureImage)
1417*8975f5c5SAndroid Build Coastguard Worker {
1418*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11());
1419*8975f5c5SAndroid Build Coastguard Worker 
1420*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
1421*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
1422*8975f5c5SAndroid Build Coastguard Worker 
1423*8975f5c5SAndroid Build Coastguard Worker     window->makeCurrent();
1424*8975f5c5SAndroid Build Coastguard Worker 
1425*8975f5c5SAndroid Build Coastguard Worker     const UINT bufferSize = 32;
1426*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(mD3D11Device != nullptr);
1427*8975f5c5SAndroid Build Coastguard Worker     ID3D11Texture2D *d3d11Texture = nullptr;
1428*8975f5c5SAndroid Build Coastguard Worker     CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, bufferSize, bufferSize, 1, 1,
1429*8975f5c5SAndroid Build Coastguard Worker                                D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
1430*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &d3d11Texture)));
1431*8975f5c5SAndroid Build Coastguard Worker 
1432*8975f5c5SAndroid Build Coastguard Worker     const EGLint attribs[] = {EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_RGB, EGL_NONE};
1433*8975f5c5SAndroid Build Coastguard Worker 
1434*8975f5c5SAndroid Build Coastguard Worker     EGLImage image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_D3D11_TEXTURE_ANGLE,
1435*8975f5c5SAndroid Build Coastguard Worker                                        static_cast<EGLClientBuffer>(d3d11Texture), attribs);
1436*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
1437*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(image, EGL_NO_IMAGE_KHR);
1438*8975f5c5SAndroid Build Coastguard Worker 
1439*8975f5c5SAndroid Build Coastguard Worker     GLuint texture;
1440*8975f5c5SAndroid Build Coastguard Worker     glGenTextures(1, &texture);
1441*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
1442*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1443*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1444*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1445*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1446*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1447*8975f5c5SAndroid Build Coastguard Worker 
1448*8975f5c5SAndroid Build Coastguard Worker     glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
1449*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1450*8975f5c5SAndroid Build Coastguard Worker 
1451*8975f5c5SAndroid Build Coastguard Worker     GLuint fbo;
1452*8975f5c5SAndroid Build Coastguard Worker     glGenFramebuffers(1, &fbo);
1453*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1454*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
1455*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
1456*8975f5c5SAndroid Build Coastguard Worker               static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));
1457*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1458*8975f5c5SAndroid Build Coastguard Worker 
1459*8975f5c5SAndroid Build Coastguard Worker     // Although we are writing 0.5 to the alpha channel it should have the same
1460*8975f5c5SAndroid Build Coastguard Worker     // side effects as if alpha were 1.0.
1461*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
1462*8975f5c5SAndroid Build Coastguard Worker     glClearColor(1.0f, 0.0f, 1.0f, 0.5f);
1463*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
1464*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1465*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 255, 0,
1466*8975f5c5SAndroid Build Coastguard Worker                     255, 255);
1467*8975f5c5SAndroid Build Coastguard Worker 
1468*8975f5c5SAndroid Build Coastguard Worker     GLuint rgbaRbo;
1469*8975f5c5SAndroid Build Coastguard Worker     glGenRenderbuffers(1, &rgbaRbo);
1470*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, rgbaRbo);
1471*8975f5c5SAndroid Build Coastguard Worker     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, bufferSize, bufferSize);
1472*8975f5c5SAndroid Build Coastguard Worker 
1473*8975f5c5SAndroid Build Coastguard Worker     GLuint rgbaFbo;
1474*8975f5c5SAndroid Build Coastguard Worker     glGenFramebuffers(1, &rgbaFbo);
1475*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, rgbaFbo);
1476*8975f5c5SAndroid Build Coastguard Worker     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rgbaRbo);
1477*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
1478*8975f5c5SAndroid Build Coastguard Worker               static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));
1479*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1480*8975f5c5SAndroid Build Coastguard Worker 
1481*8975f5c5SAndroid Build Coastguard Worker     // BlitFramebuffer from/to RGBA framebuffer fails.
1482*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, rgbaFbo);
1483*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
1484*8975f5c5SAndroid Build Coastguard Worker     glBlitFramebufferANGLE(0, 0, bufferSize, bufferSize, 0, 0, bufferSize, bufferSize,
1485*8975f5c5SAndroid Build Coastguard Worker                            GL_COLOR_BUFFER_BIT, GL_NEAREST);
1486*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
1487*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1488*8975f5c5SAndroid Build Coastguard Worker 
1489*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1490*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, rgbaFbo);
1491*8975f5c5SAndroid Build Coastguard Worker     glBlitFramebufferANGLE(0, 0, bufferSize, bufferSize, 0, 0, bufferSize, bufferSize,
1492*8975f5c5SAndroid Build Coastguard Worker                            GL_COLOR_BUFFER_BIT, GL_NEAREST);
1493*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
1494*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1495*8975f5c5SAndroid Build Coastguard Worker 
1496*8975f5c5SAndroid Build Coastguard Worker     GLuint rgbRbo;
1497*8975f5c5SAndroid Build Coastguard Worker     glGenRenderbuffers(1, &rgbRbo);
1498*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, rgbRbo);
1499*8975f5c5SAndroid Build Coastguard Worker     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB8_OES, bufferSize, bufferSize);
1500*8975f5c5SAndroid Build Coastguard Worker 
1501*8975f5c5SAndroid Build Coastguard Worker     GLuint rgbFbo;
1502*8975f5c5SAndroid Build Coastguard Worker     glGenFramebuffers(1, &rgbFbo);
1503*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, rgbFbo);
1504*8975f5c5SAndroid Build Coastguard Worker     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rgbRbo);
1505*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
1506*8975f5c5SAndroid Build Coastguard Worker               static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));
1507*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1508*8975f5c5SAndroid Build Coastguard Worker     glClearColor(1.0f, 0.0f, 1.0f, 0.5f);
1509*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
1510*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1511*8975f5c5SAndroid Build Coastguard Worker 
1512*8975f5c5SAndroid Build Coastguard Worker     // Clear texture framebuffer.
1513*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1514*8975f5c5SAndroid Build Coastguard Worker     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
1515*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
1516*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1517*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 0, 0, 0,
1518*8975f5c5SAndroid Build Coastguard Worker                     255);
1519*8975f5c5SAndroid Build Coastguard Worker 
1520*8975f5c5SAndroid Build Coastguard Worker     // BlitFramebuffer from/to RGB framebuffer succeeds.
1521*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, rgbFbo);
1522*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
1523*8975f5c5SAndroid Build Coastguard Worker     glBlitFramebufferANGLE(0, 0, bufferSize, bufferSize, 0, 0, bufferSize, bufferSize,
1524*8975f5c5SAndroid Build Coastguard Worker                            GL_COLOR_BUFFER_BIT, GL_NEAREST);
1525*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1526*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 255, 0,
1527*8975f5c5SAndroid Build Coastguard Worker                     255, 255);
1528*8975f5c5SAndroid Build Coastguard Worker 
1529*8975f5c5SAndroid Build Coastguard Worker     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
1530*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
1531*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1532*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, rgbFbo);
1533*8975f5c5SAndroid Build Coastguard Worker     glBlitFramebufferANGLE(0, 0, bufferSize, bufferSize, 0, 0, bufferSize, bufferSize,
1534*8975f5c5SAndroid Build Coastguard Worker                            GL_COLOR_BUFFER_BIT, GL_NEAREST);
1535*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1536*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, rgbFbo);
1537*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 0, 0, 0,
1538*8975f5c5SAndroid Build Coastguard Worker                     255);
1539*8975f5c5SAndroid Build Coastguard Worker 
1540*8975f5c5SAndroid Build Coastguard Worker     glDeleteFramebuffers(1, &rgbFbo);
1541*8975f5c5SAndroid Build Coastguard Worker     glDeleteRenderbuffers(1, &rgbRbo);
1542*8975f5c5SAndroid Build Coastguard Worker     glDeleteFramebuffers(1, &rgbaFbo);
1543*8975f5c5SAndroid Build Coastguard Worker     glDeleteRenderbuffers(1, &rgbaRbo);
1544*8975f5c5SAndroid Build Coastguard Worker     glDeleteFramebuffers(1, &fbo);
1545*8975f5c5SAndroid Build Coastguard Worker     glDeleteTextures(1, &texture);
1546*8975f5c5SAndroid Build Coastguard Worker     eglDestroyImageKHR(display, image);
1547*8975f5c5SAndroid Build Coastguard Worker 
1548*8975f5c5SAndroid Build Coastguard Worker     d3d11Texture->Release();
1549*8975f5c5SAndroid Build Coastguard Worker }
1550*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(D3DTextureTest,TextureArray)1551*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureTest, TextureArray)
1552*8975f5c5SAndroid Build Coastguard Worker {
1553*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11());
1554*8975f5c5SAndroid Build Coastguard Worker 
1555*8975f5c5SAndroid Build Coastguard Worker     EGLWindow *window  = getEGLWindow();
1556*8975f5c5SAndroid Build Coastguard Worker     EGLDisplay display = window->getDisplay();
1557*8975f5c5SAndroid Build Coastguard Worker 
1558*8975f5c5SAndroid Build Coastguard Worker     window->makeCurrent();
1559*8975f5c5SAndroid Build Coastguard Worker 
1560*8975f5c5SAndroid Build Coastguard Worker     const UINT bufferSize = 32;
1561*8975f5c5SAndroid Build Coastguard Worker     const UINT arraySize  = 4;
1562*8975f5c5SAndroid Build Coastguard Worker 
1563*8975f5c5SAndroid Build Coastguard Worker     ID3D11Texture2D *d3d11Texture = nullptr;
1564*8975f5c5SAndroid Build Coastguard Worker     CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, bufferSize, bufferSize, arraySize, 1,
1565*8975f5c5SAndroid Build Coastguard Worker                                D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
1566*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &d3d11Texture)));
1567*8975f5c5SAndroid Build Coastguard Worker 
1568*8975f5c5SAndroid Build Coastguard Worker     const unsigned char kRFill = 0x12;
1569*8975f5c5SAndroid Build Coastguard Worker     const unsigned char kGFill = 0x23;
1570*8975f5c5SAndroid Build Coastguard Worker     const unsigned char kBFill = 0x34;
1571*8975f5c5SAndroid Build Coastguard Worker     const unsigned char kAFill = 0x45;
1572*8975f5c5SAndroid Build Coastguard Worker 
1573*8975f5c5SAndroid Build Coastguard Worker     std::vector<unsigned char> imageData(bufferSize * bufferSize * 4, 0);
1574*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < imageData.size(); i += 4)
1575*8975f5c5SAndroid Build Coastguard Worker     {
1576*8975f5c5SAndroid Build Coastguard Worker         imageData[i]     = kRFill;
1577*8975f5c5SAndroid Build Coastguard Worker         imageData[i + 1] = kGFill;
1578*8975f5c5SAndroid Build Coastguard Worker         imageData[i + 2] = kBFill;
1579*8975f5c5SAndroid Build Coastguard Worker         imageData[i + 3] = kAFill;
1580*8975f5c5SAndroid Build Coastguard Worker     }
1581*8975f5c5SAndroid Build Coastguard Worker 
1582*8975f5c5SAndroid Build Coastguard Worker     ID3D11DeviceContext *context = nullptr;
1583*8975f5c5SAndroid Build Coastguard Worker     mD3D11Device->GetImmediateContext(&context);
1584*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(context, nullptr);
1585*8975f5c5SAndroid Build Coastguard Worker 
1586*8975f5c5SAndroid Build Coastguard Worker     D3D11_BOX dstBox = {0, 0, 0, bufferSize, bufferSize, 1};
1587*8975f5c5SAndroid Build Coastguard Worker     context->UpdateSubresource(d3d11Texture, arraySize - 1, &dstBox, imageData.data(),
1588*8975f5c5SAndroid Build Coastguard Worker                                bufferSize * 4, imageData.size());
1589*8975f5c5SAndroid Build Coastguard Worker 
1590*8975f5c5SAndroid Build Coastguard Worker     const EGLint attribs[] = {EGL_D3D11_TEXTURE_ARRAY_SLICE_ANGLE, arraySize - 1, EGL_NONE};
1591*8975f5c5SAndroid Build Coastguard Worker     EGLImage image         = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_D3D11_TEXTURE_ANGLE,
1592*8975f5c5SAndroid Build Coastguard Worker                                                static_cast<EGLClientBuffer>(d3d11Texture), attribs);
1593*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EGL_SUCCESS();
1594*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(image, EGL_NO_IMAGE_KHR);
1595*8975f5c5SAndroid Build Coastguard Worker 
1596*8975f5c5SAndroid Build Coastguard Worker     GLuint texture;
1597*8975f5c5SAndroid Build Coastguard Worker     glGenTextures(1, &texture);
1598*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texture);
1599*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1600*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1601*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1602*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1603*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1604*8975f5c5SAndroid Build Coastguard Worker 
1605*8975f5c5SAndroid Build Coastguard Worker     glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
1606*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1607*8975f5c5SAndroid Build Coastguard Worker 
1608*8975f5c5SAndroid Build Coastguard Worker     GLuint fbo;
1609*8975f5c5SAndroid Build Coastguard Worker     glGenFramebuffers(1, &fbo);
1610*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1611*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
1612*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
1613*8975f5c5SAndroid Build Coastguard Worker               static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));
1614*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1615*8975f5c5SAndroid Build Coastguard Worker 
1616*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, kRFill,
1617*8975f5c5SAndroid Build Coastguard Worker                     kGFill, kBFill, kAFill);
1618*8975f5c5SAndroid Build Coastguard Worker 
1619*8975f5c5SAndroid Build Coastguard Worker     glDeleteFramebuffers(1, &fbo);
1620*8975f5c5SAndroid Build Coastguard Worker     glDeleteTextures(1, &texture);
1621*8975f5c5SAndroid Build Coastguard Worker     eglDestroyImageKHR(display, image);
1622*8975f5c5SAndroid Build Coastguard Worker 
1623*8975f5c5SAndroid Build Coastguard Worker     d3d11Texture->Release();
1624*8975f5c5SAndroid Build Coastguard Worker }
1625*8975f5c5SAndroid Build Coastguard Worker 
1626*8975f5c5SAndroid Build Coastguard Worker class D3DTextureYUVTest : public D3DTextureTest
1627*8975f5c5SAndroid Build Coastguard Worker {
1628*8975f5c5SAndroid Build Coastguard Worker   protected:
CreateAndBindImageToTexture(EGLDisplay display,ID3D11Texture2D * d3d11Texture,EGLint plane,GLenum internalFormat,GLenum target,EGLImage * image,GLuint * texture)1629*8975f5c5SAndroid Build Coastguard Worker     void CreateAndBindImageToTexture(EGLDisplay display,
1630*8975f5c5SAndroid Build Coastguard Worker                                      ID3D11Texture2D *d3d11Texture,
1631*8975f5c5SAndroid Build Coastguard Worker                                      EGLint plane,
1632*8975f5c5SAndroid Build Coastguard Worker                                      GLenum internalFormat,
1633*8975f5c5SAndroid Build Coastguard Worker                                      GLenum target,
1634*8975f5c5SAndroid Build Coastguard Worker                                      EGLImage *image,
1635*8975f5c5SAndroid Build Coastguard Worker                                      GLuint *texture)
1636*8975f5c5SAndroid Build Coastguard Worker     {
1637*8975f5c5SAndroid Build Coastguard Worker         const EGLint attribs[] = {EGL_TEXTURE_INTERNAL_FORMAT_ANGLE,
1638*8975f5c5SAndroid Build Coastguard Worker                                   static_cast<EGLint>(internalFormat),
1639*8975f5c5SAndroid Build Coastguard Worker                                   EGL_D3D11_TEXTURE_PLANE_ANGLE, plane, EGL_NONE};
1640*8975f5c5SAndroid Build Coastguard Worker         *image                 = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_D3D11_TEXTURE_ANGLE,
1641*8975f5c5SAndroid Build Coastguard Worker                                                    static_cast<EGLClientBuffer>(d3d11Texture), attribs);
1642*8975f5c5SAndroid Build Coastguard Worker         ASSERT_EGL_SUCCESS();
1643*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(*image, EGL_NO_IMAGE_KHR);
1644*8975f5c5SAndroid Build Coastguard Worker 
1645*8975f5c5SAndroid Build Coastguard Worker         // Create and bind Y plane texture to image.
1646*8975f5c5SAndroid Build Coastguard Worker         glGenTextures(1, texture);
1647*8975f5c5SAndroid Build Coastguard Worker         glActiveTexture(GL_TEXTURE0);
1648*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(target, *texture);
1649*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1650*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1651*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1652*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1653*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1654*8975f5c5SAndroid Build Coastguard Worker 
1655*8975f5c5SAndroid Build Coastguard Worker         glEGLImageTargetTexture2DOES(target, *image);
1656*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1657*8975f5c5SAndroid Build Coastguard Worker     }
1658*8975f5c5SAndroid Build Coastguard Worker 
RunYUVSamplerTest(DXGI_FORMAT format)1659*8975f5c5SAndroid Build Coastguard Worker     void RunYUVSamplerTest(DXGI_FORMAT format)
1660*8975f5c5SAndroid Build Coastguard Worker     {
1661*8975f5c5SAndroid Build Coastguard Worker         ASSERT_TRUE(format == DXGI_FORMAT_NV12 || format == DXGI_FORMAT_P010 ||
1662*8975f5c5SAndroid Build Coastguard Worker                     format == DXGI_FORMAT_P016);
1663*8975f5c5SAndroid Build Coastguard Worker         UINT formatSupport;
1664*8975f5c5SAndroid Build Coastguard Worker         ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11() ||
1665*8975f5c5SAndroid Build Coastguard Worker                            FAILED(mD3D11Device->CheckFormatSupport(format, &formatSupport)));
1666*8975f5c5SAndroid Build Coastguard Worker         ASSERT_TRUE(formatSupport &
1667*8975f5c5SAndroid Build Coastguard Worker                     (D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE));
1668*8975f5c5SAndroid Build Coastguard Worker 
1669*8975f5c5SAndroid Build Coastguard Worker         const bool isNV12          = (format == DXGI_FORMAT_NV12);
1670*8975f5c5SAndroid Build Coastguard Worker         const unsigned kYFillValue = isNV12 ? 0x12 : 0x1234;
1671*8975f5c5SAndroid Build Coastguard Worker         const unsigned kUFillValue = isNV12 ? 0x23 : 0x2345;
1672*8975f5c5SAndroid Build Coastguard Worker         const unsigned kVFillValue = isNV12 ? 0x34 : 0x3456;
1673*8975f5c5SAndroid Build Coastguard Worker 
1674*8975f5c5SAndroid Build Coastguard Worker         constexpr char kVS[] =
1675*8975f5c5SAndroid Build Coastguard Worker             R"(precision highp float;
1676*8975f5c5SAndroid Build Coastguard Worker             attribute vec4 position;
1677*8975f5c5SAndroid Build Coastguard Worker             varying vec2 texcoord;
1678*8975f5c5SAndroid Build Coastguard Worker 
1679*8975f5c5SAndroid Build Coastguard Worker             void main()
1680*8975f5c5SAndroid Build Coastguard Worker             {
1681*8975f5c5SAndroid Build Coastguard Worker                 gl_Position = position;
1682*8975f5c5SAndroid Build Coastguard Worker                 texcoord = (position.xy * 0.5) + 0.5;
1683*8975f5c5SAndroid Build Coastguard Worker                 texcoord.y = 1.0 - texcoord.y;
1684*8975f5c5SAndroid Build Coastguard Worker             })";
1685*8975f5c5SAndroid Build Coastguard Worker 
1686*8975f5c5SAndroid Build Coastguard Worker         constexpr char kFS[] =
1687*8975f5c5SAndroid Build Coastguard Worker             R"(#extension GL_OES_EGL_image_external : require
1688*8975f5c5SAndroid Build Coastguard Worker             precision highp float;
1689*8975f5c5SAndroid Build Coastguard Worker             uniform samplerExternalOES tex;
1690*8975f5c5SAndroid Build Coastguard Worker             varying vec2 texcoord;
1691*8975f5c5SAndroid Build Coastguard Worker 
1692*8975f5c5SAndroid Build Coastguard Worker             void main()
1693*8975f5c5SAndroid Build Coastguard Worker             {
1694*8975f5c5SAndroid Build Coastguard Worker                 gl_FragColor = texture2D(tex, texcoord);
1695*8975f5c5SAndroid Build Coastguard Worker             })";
1696*8975f5c5SAndroid Build Coastguard Worker 
1697*8975f5c5SAndroid Build Coastguard Worker         GLuint program = CompileProgram(kVS, kFS);
1698*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(0u, program) << "shader compilation failed.";
1699*8975f5c5SAndroid Build Coastguard Worker 
1700*8975f5c5SAndroid Build Coastguard Worker         GLint textureLocation = glGetUniformLocation(program, "tex");
1701*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(-1, textureLocation);
1702*8975f5c5SAndroid Build Coastguard Worker 
1703*8975f5c5SAndroid Build Coastguard Worker         EGLWindow *window  = getEGLWindow();
1704*8975f5c5SAndroid Build Coastguard Worker         EGLDisplay display = window->getDisplay();
1705*8975f5c5SAndroid Build Coastguard Worker 
1706*8975f5c5SAndroid Build Coastguard Worker         window->makeCurrent();
1707*8975f5c5SAndroid Build Coastguard Worker 
1708*8975f5c5SAndroid Build Coastguard Worker         const UINT bufferSize = 32;
1709*8975f5c5SAndroid Build Coastguard Worker         EXPECT_TRUE(mD3D11Device != nullptr);
1710*8975f5c5SAndroid Build Coastguard Worker         Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11Texture;
1711*8975f5c5SAndroid Build Coastguard Worker         CD3D11_TEXTURE2D_DESC desc(format, bufferSize, bufferSize, 1, 1,
1712*8975f5c5SAndroid Build Coastguard Worker                                    D3D11_BIND_SHADER_RESOURCE);
1713*8975f5c5SAndroid Build Coastguard Worker 
1714*8975f5c5SAndroid Build Coastguard Worker         std::vector<unsigned char> imageData;
1715*8975f5c5SAndroid Build Coastguard Worker 
1716*8975f5c5SAndroid Build Coastguard Worker         if (isNV12)
1717*8975f5c5SAndroid Build Coastguard Worker         {
1718*8975f5c5SAndroid Build Coastguard Worker             imageData.resize(bufferSize * bufferSize * 3 / 2);
1719*8975f5c5SAndroid Build Coastguard Worker             memset(imageData.data(), kYFillValue, bufferSize * bufferSize);
1720*8975f5c5SAndroid Build Coastguard Worker             const size_t kUVOffset = bufferSize * bufferSize;
1721*8975f5c5SAndroid Build Coastguard Worker             for (size_t i = 0; i < bufferSize * bufferSize / 2; i += 2)
1722*8975f5c5SAndroid Build Coastguard Worker             {
1723*8975f5c5SAndroid Build Coastguard Worker                 imageData[kUVOffset + i]     = kUFillValue;
1724*8975f5c5SAndroid Build Coastguard Worker                 imageData[kUVOffset + i + 1] = kVFillValue;
1725*8975f5c5SAndroid Build Coastguard Worker             }
1726*8975f5c5SAndroid Build Coastguard Worker         }
1727*8975f5c5SAndroid Build Coastguard Worker         else
1728*8975f5c5SAndroid Build Coastguard Worker         {
1729*8975f5c5SAndroid Build Coastguard Worker             imageData.resize(bufferSize * bufferSize * 3);
1730*8975f5c5SAndroid Build Coastguard Worker             const size_t kUVOffset = bufferSize * bufferSize * 2;
1731*8975f5c5SAndroid Build Coastguard Worker             for (size_t i = 0; i < kUVOffset; i += 2)
1732*8975f5c5SAndroid Build Coastguard Worker             {
1733*8975f5c5SAndroid Build Coastguard Worker                 imageData[i]     = kYFillValue & 0xff;
1734*8975f5c5SAndroid Build Coastguard Worker                 imageData[i + 1] = (kYFillValue >> 8) & 0xff;
1735*8975f5c5SAndroid Build Coastguard Worker                 if (kUVOffset + i < imageData.size())
1736*8975f5c5SAndroid Build Coastguard Worker                 {
1737*8975f5c5SAndroid Build Coastguard Worker                     // Interleave U & V samples.
1738*8975f5c5SAndroid Build Coastguard Worker                     const unsigned fill          = (i % 4 == 0) ? kUFillValue : kVFillValue;
1739*8975f5c5SAndroid Build Coastguard Worker                     imageData[kUVOffset + i]     = fill & 0xff;
1740*8975f5c5SAndroid Build Coastguard Worker                     imageData[kUVOffset + i + 1] = (fill >> 8) & 0xff;
1741*8975f5c5SAndroid Build Coastguard Worker                 }
1742*8975f5c5SAndroid Build Coastguard Worker             }
1743*8975f5c5SAndroid Build Coastguard Worker         }
1744*8975f5c5SAndroid Build Coastguard Worker 
1745*8975f5c5SAndroid Build Coastguard Worker         D3D11_SUBRESOURCE_DATA data = {};
1746*8975f5c5SAndroid Build Coastguard Worker         data.pSysMem                = static_cast<const void *>(imageData.data());
1747*8975f5c5SAndroid Build Coastguard Worker         data.SysMemPitch            = isNV12 ? bufferSize : bufferSize * 2;
1748*8975f5c5SAndroid Build Coastguard Worker 
1749*8975f5c5SAndroid Build Coastguard Worker         EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, &data, &d3d11Texture)));
1750*8975f5c5SAndroid Build Coastguard Worker 
1751*8975f5c5SAndroid Build Coastguard Worker         // Create and bind Y plane texture to image.
1752*8975f5c5SAndroid Build Coastguard Worker         EGLImage yImage;
1753*8975f5c5SAndroid Build Coastguard Worker         GLuint yTexture;
1754*8975f5c5SAndroid Build Coastguard Worker 
1755*8975f5c5SAndroid Build Coastguard Worker         GLenum internalFormat = format == DXGI_FORMAT_NV12 ? GL_RED_EXT : GL_R16_EXT;
1756*8975f5c5SAndroid Build Coastguard Worker         CreateAndBindImageToTexture(display, d3d11Texture.Get(), 0, internalFormat,
1757*8975f5c5SAndroid Build Coastguard Worker                                     GL_TEXTURE_EXTERNAL_OES, &yImage, &yTexture);
1758*8975f5c5SAndroid Build Coastguard Worker 
1759*8975f5c5SAndroid Build Coastguard Worker         GLuint rbo;
1760*8975f5c5SAndroid Build Coastguard Worker         glGenRenderbuffers(1, &rbo);
1761*8975f5c5SAndroid Build Coastguard Worker         glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1762*8975f5c5SAndroid Build Coastguard Worker         glRenderbufferStorage(GL_RENDERBUFFER, isNV12 ? GL_RGBA8_OES : GL_RGBA16_EXT, bufferSize,
1763*8975f5c5SAndroid Build Coastguard Worker                               bufferSize);
1764*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1765*8975f5c5SAndroid Build Coastguard Worker 
1766*8975f5c5SAndroid Build Coastguard Worker         GLuint fbo;
1767*8975f5c5SAndroid Build Coastguard Worker         glGenFramebuffers(1, &fbo);
1768*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1769*8975f5c5SAndroid Build Coastguard Worker         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1770*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
1771*8975f5c5SAndroid Build Coastguard Worker                   static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));
1772*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1773*8975f5c5SAndroid Build Coastguard Worker 
1774*8975f5c5SAndroid Build Coastguard Worker         // Draw the Y plane using a shader.
1775*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(program);
1776*8975f5c5SAndroid Build Coastguard Worker         glUniform1i(textureLocation, 0);
1777*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1778*8975f5c5SAndroid Build Coastguard Worker 
1779*8975f5c5SAndroid Build Coastguard Worker         glViewport(0, 0, bufferSize, bufferSize);
1780*8975f5c5SAndroid Build Coastguard Worker         drawQuad(program, "position", 1.0f);
1781*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1782*8975f5c5SAndroid Build Coastguard Worker 
1783*8975f5c5SAndroid Build Coastguard Worker         if (isNV12)
1784*8975f5c5SAndroid Build Coastguard Worker         {
1785*8975f5c5SAndroid Build Coastguard Worker 
1786*8975f5c5SAndroid Build Coastguard Worker             EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2,
1787*8975f5c5SAndroid Build Coastguard Worker                             kYFillValue, 0, 0, 0xff);
1788*8975f5c5SAndroid Build Coastguard Worker         }
1789*8975f5c5SAndroid Build Coastguard Worker         else
1790*8975f5c5SAndroid Build Coastguard Worker         {
1791*8975f5c5SAndroid Build Coastguard Worker             EXPECT_PIXEL_16_NEAR(static_cast<GLint>(bufferSize) / 2,
1792*8975f5c5SAndroid Build Coastguard Worker                                  static_cast<GLint>(bufferSize) / 2, kYFillValue, 0, 0, 0xffff, 0);
1793*8975f5c5SAndroid Build Coastguard Worker         }
1794*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1795*8975f5c5SAndroid Build Coastguard Worker 
1796*8975f5c5SAndroid Build Coastguard Worker         // Create and bind UV plane texture to image.
1797*8975f5c5SAndroid Build Coastguard Worker         EGLImage uvImage;
1798*8975f5c5SAndroid Build Coastguard Worker         GLuint uvTexture;
1799*8975f5c5SAndroid Build Coastguard Worker 
1800*8975f5c5SAndroid Build Coastguard Worker         internalFormat = format == DXGI_FORMAT_NV12 ? GL_RG_EXT : GL_RG16_EXT;
1801*8975f5c5SAndroid Build Coastguard Worker         CreateAndBindImageToTexture(display, d3d11Texture.Get(), 1, internalFormat,
1802*8975f5c5SAndroid Build Coastguard Worker                                     GL_TEXTURE_EXTERNAL_OES, &uvImage, &uvTexture);
1803*8975f5c5SAndroid Build Coastguard Worker 
1804*8975f5c5SAndroid Build Coastguard Worker         // Draw the UV plane using a shader.
1805*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(program);
1806*8975f5c5SAndroid Build Coastguard Worker         glUniform1i(textureLocation, 0);
1807*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1808*8975f5c5SAndroid Build Coastguard Worker 
1809*8975f5c5SAndroid Build Coastguard Worker         // Use only half of the framebuffer to match UV plane dimensions.
1810*8975f5c5SAndroid Build Coastguard Worker         glViewport(0, 0, bufferSize / 2, bufferSize / 2);
1811*8975f5c5SAndroid Build Coastguard Worker         drawQuad(program, "position", 1.0f);
1812*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1813*8975f5c5SAndroid Build Coastguard Worker 
1814*8975f5c5SAndroid Build Coastguard Worker         if (isNV12)
1815*8975f5c5SAndroid Build Coastguard Worker         {
1816*8975f5c5SAndroid Build Coastguard Worker 
1817*8975f5c5SAndroid Build Coastguard Worker             EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 4, static_cast<GLint>(bufferSize) / 4,
1818*8975f5c5SAndroid Build Coastguard Worker                             kUFillValue, kVFillValue, 0, 0xff);
1819*8975f5c5SAndroid Build Coastguard Worker         }
1820*8975f5c5SAndroid Build Coastguard Worker         else
1821*8975f5c5SAndroid Build Coastguard Worker         {
1822*8975f5c5SAndroid Build Coastguard Worker             EXPECT_PIXEL_16_NEAR(static_cast<GLint>(bufferSize) / 4,
1823*8975f5c5SAndroid Build Coastguard Worker                                  static_cast<GLint>(bufferSize) / 4, kUFillValue, kVFillValue, 0,
1824*8975f5c5SAndroid Build Coastguard Worker                                  0xffff, 0);
1825*8975f5c5SAndroid Build Coastguard Worker         }
1826*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1827*8975f5c5SAndroid Build Coastguard Worker 
1828*8975f5c5SAndroid Build Coastguard Worker         glDeleteProgram(program);
1829*8975f5c5SAndroid Build Coastguard Worker         glDeleteTextures(1, &yTexture);
1830*8975f5c5SAndroid Build Coastguard Worker         glDeleteTextures(1, &uvTexture);
1831*8975f5c5SAndroid Build Coastguard Worker         glDeleteFramebuffers(1, &fbo);
1832*8975f5c5SAndroid Build Coastguard Worker         glDeleteRenderbuffers(1, &rbo);
1833*8975f5c5SAndroid Build Coastguard Worker         eglDestroyImageKHR(display, yImage);
1834*8975f5c5SAndroid Build Coastguard Worker         eglDestroyImageKHR(display, uvImage);
1835*8975f5c5SAndroid Build Coastguard Worker     }
1836*8975f5c5SAndroid Build Coastguard Worker 
RunYUVRenderTest(DXGI_FORMAT format)1837*8975f5c5SAndroid Build Coastguard Worker     void RunYUVRenderTest(DXGI_FORMAT format)
1838*8975f5c5SAndroid Build Coastguard Worker     {
1839*8975f5c5SAndroid Build Coastguard Worker         ASSERT(format == DXGI_FORMAT_NV12 || format == DXGI_FORMAT_P010 ||
1840*8975f5c5SAndroid Build Coastguard Worker                format == DXGI_FORMAT_P016);
1841*8975f5c5SAndroid Build Coastguard Worker         UINT formatSupport;
1842*8975f5c5SAndroid Build Coastguard Worker         ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11() ||
1843*8975f5c5SAndroid Build Coastguard Worker                            FAILED(mD3D11Device->CheckFormatSupport(format, &formatSupport)));
1844*8975f5c5SAndroid Build Coastguard Worker         ASSERT_TRUE(formatSupport &
1845*8975f5c5SAndroid Build Coastguard Worker                     (D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_RENDER_TARGET));
1846*8975f5c5SAndroid Build Coastguard Worker 
1847*8975f5c5SAndroid Build Coastguard Worker         const bool isNV12          = (format == DXGI_FORMAT_NV12);
1848*8975f5c5SAndroid Build Coastguard Worker         const unsigned kYFillValue = isNV12 ? 0x12 : 0x1234;
1849*8975f5c5SAndroid Build Coastguard Worker         const unsigned kUFillValue = isNV12 ? 0x23 : 0x2345;
1850*8975f5c5SAndroid Build Coastguard Worker         const unsigned kVFillValue = isNV12 ? 0x34 : 0x3456;
1851*8975f5c5SAndroid Build Coastguard Worker 
1852*8975f5c5SAndroid Build Coastguard Worker         constexpr char kVS[] =
1853*8975f5c5SAndroid Build Coastguard Worker             R"(precision highp float;
1854*8975f5c5SAndroid Build Coastguard Worker             attribute vec4 position;
1855*8975f5c5SAndroid Build Coastguard Worker             varying vec2 texcoord;
1856*8975f5c5SAndroid Build Coastguard Worker 
1857*8975f5c5SAndroid Build Coastguard Worker             void main()
1858*8975f5c5SAndroid Build Coastguard Worker             {
1859*8975f5c5SAndroid Build Coastguard Worker                 gl_Position = position;
1860*8975f5c5SAndroid Build Coastguard Worker                 texcoord = (position.xy * 0.5) + 0.5;
1861*8975f5c5SAndroid Build Coastguard Worker                 texcoord.y = 1.0 - texcoord.y;
1862*8975f5c5SAndroid Build Coastguard Worker             })";
1863*8975f5c5SAndroid Build Coastguard Worker 
1864*8975f5c5SAndroid Build Coastguard Worker         constexpr char kFS[] =
1865*8975f5c5SAndroid Build Coastguard Worker             R"(precision highp float;
1866*8975f5c5SAndroid Build Coastguard Worker             uniform vec4 color;
1867*8975f5c5SAndroid Build Coastguard Worker             varying vec2 texcoord;
1868*8975f5c5SAndroid Build Coastguard Worker 
1869*8975f5c5SAndroid Build Coastguard Worker             void main()
1870*8975f5c5SAndroid Build Coastguard Worker             {
1871*8975f5c5SAndroid Build Coastguard Worker                 gl_FragColor = color;
1872*8975f5c5SAndroid Build Coastguard Worker             })";
1873*8975f5c5SAndroid Build Coastguard Worker 
1874*8975f5c5SAndroid Build Coastguard Worker         GLuint program = CompileProgram(kVS, kFS);
1875*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(0u, program) << "shader compilation failed.";
1876*8975f5c5SAndroid Build Coastguard Worker 
1877*8975f5c5SAndroid Build Coastguard Worker         GLint colorLocation = glGetUniformLocation(program, "color");
1878*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(-1, colorLocation);
1879*8975f5c5SAndroid Build Coastguard Worker 
1880*8975f5c5SAndroid Build Coastguard Worker         EGLWindow *window  = getEGLWindow();
1881*8975f5c5SAndroid Build Coastguard Worker         EGLDisplay display = window->getDisplay();
1882*8975f5c5SAndroid Build Coastguard Worker 
1883*8975f5c5SAndroid Build Coastguard Worker         window->makeCurrent();
1884*8975f5c5SAndroid Build Coastguard Worker 
1885*8975f5c5SAndroid Build Coastguard Worker         const UINT bufferSize = 32;
1886*8975f5c5SAndroid Build Coastguard Worker         EXPECT_TRUE(mD3D11Device != nullptr);
1887*8975f5c5SAndroid Build Coastguard Worker         Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11Texture;
1888*8975f5c5SAndroid Build Coastguard Worker         CD3D11_TEXTURE2D_DESC desc(format, bufferSize, bufferSize, 1, 1,
1889*8975f5c5SAndroid Build Coastguard Worker                                    D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
1890*8975f5c5SAndroid Build Coastguard Worker 
1891*8975f5c5SAndroid Build Coastguard Worker         EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &d3d11Texture)));
1892*8975f5c5SAndroid Build Coastguard Worker 
1893*8975f5c5SAndroid Build Coastguard Worker         // Create and bind Y plane texture to image.
1894*8975f5c5SAndroid Build Coastguard Worker         EGLImage yImage;
1895*8975f5c5SAndroid Build Coastguard Worker         GLuint yTexture;
1896*8975f5c5SAndroid Build Coastguard Worker 
1897*8975f5c5SAndroid Build Coastguard Worker         GLenum internalFormat = format == DXGI_FORMAT_NV12 ? GL_RED_EXT : GL_R16_EXT;
1898*8975f5c5SAndroid Build Coastguard Worker         CreateAndBindImageToTexture(display, d3d11Texture.Get(), 0, internalFormat, GL_TEXTURE_2D,
1899*8975f5c5SAndroid Build Coastguard Worker                                     &yImage, &yTexture);
1900*8975f5c5SAndroid Build Coastguard Worker 
1901*8975f5c5SAndroid Build Coastguard Worker         glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, yImage);
1902*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1903*8975f5c5SAndroid Build Coastguard Worker 
1904*8975f5c5SAndroid Build Coastguard Worker         GLuint fbo;
1905*8975f5c5SAndroid Build Coastguard Worker         glGenFramebuffers(1, &fbo);
1906*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1907*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, yTexture, 0);
1908*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
1909*8975f5c5SAndroid Build Coastguard Worker                   static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));
1910*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1911*8975f5c5SAndroid Build Coastguard Worker 
1912*8975f5c5SAndroid Build Coastguard Worker         // Draw the Y plane using a shader.
1913*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(program);
1914*8975f5c5SAndroid Build Coastguard Worker         glUniform4f(colorLocation, kYFillValue * 1.0f / (isNV12 ? 0xff : 0xffff), 0, 0, 0);
1915*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1916*8975f5c5SAndroid Build Coastguard Worker 
1917*8975f5c5SAndroid Build Coastguard Worker         drawQuad(program, "position", 1.0f);
1918*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1919*8975f5c5SAndroid Build Coastguard Worker 
1920*8975f5c5SAndroid Build Coastguard Worker         // Create and bind UV plane texture to image.
1921*8975f5c5SAndroid Build Coastguard Worker         EGLImage uvImage;
1922*8975f5c5SAndroid Build Coastguard Worker         GLuint uvTexture;
1923*8975f5c5SAndroid Build Coastguard Worker 
1924*8975f5c5SAndroid Build Coastguard Worker         internalFormat = format == DXGI_FORMAT_NV12 ? GL_RG_EXT : GL_RG16_EXT;
1925*8975f5c5SAndroid Build Coastguard Worker         CreateAndBindImageToTexture(display, d3d11Texture.Get(), 1, internalFormat, GL_TEXTURE_2D,
1926*8975f5c5SAndroid Build Coastguard Worker                                     &uvImage, &uvTexture);
1927*8975f5c5SAndroid Build Coastguard Worker 
1928*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, uvTexture, 0);
1929*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
1930*8975f5c5SAndroid Build Coastguard Worker                   static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));
1931*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1932*8975f5c5SAndroid Build Coastguard Worker 
1933*8975f5c5SAndroid Build Coastguard Worker         // Draw the UV plane using a shader.
1934*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(program);
1935*8975f5c5SAndroid Build Coastguard Worker         glUniform4f(colorLocation, kUFillValue * 1.0f / (isNV12 ? 0xff : 0xffff),
1936*8975f5c5SAndroid Build Coastguard Worker                     kVFillValue * 1.0f / (isNV12 ? 0xff : 0xffff), 0, 0);
1937*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1938*8975f5c5SAndroid Build Coastguard Worker 
1939*8975f5c5SAndroid Build Coastguard Worker         drawQuad(program, "position", 1.0f);
1940*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1941*8975f5c5SAndroid Build Coastguard Worker 
1942*8975f5c5SAndroid Build Coastguard Worker         Microsoft::WRL::ComPtr<ID3D11Texture2D> stagingTexture;
1943*8975f5c5SAndroid Build Coastguard Worker         CD3D11_TEXTURE2D_DESC stagingDesc = desc;
1944*8975f5c5SAndroid Build Coastguard Worker         stagingDesc.BindFlags             = 0;
1945*8975f5c5SAndroid Build Coastguard Worker         stagingDesc.Usage                 = D3D11_USAGE_STAGING;
1946*8975f5c5SAndroid Build Coastguard Worker         stagingDesc.CPUAccessFlags        = D3D11_CPU_ACCESS_READ;
1947*8975f5c5SAndroid Build Coastguard Worker 
1948*8975f5c5SAndroid Build Coastguard Worker         EXPECT_TRUE(
1949*8975f5c5SAndroid Build Coastguard Worker             SUCCEEDED(mD3D11Device->CreateTexture2D(&stagingDesc, nullptr, &stagingTexture)));
1950*8975f5c5SAndroid Build Coastguard Worker 
1951*8975f5c5SAndroid Build Coastguard Worker         Microsoft::WRL::ComPtr<ID3D11DeviceContext> context;
1952*8975f5c5SAndroid Build Coastguard Worker         mD3D11Device->GetImmediateContext(&context);
1953*8975f5c5SAndroid Build Coastguard Worker 
1954*8975f5c5SAndroid Build Coastguard Worker         context->CopyResource(stagingTexture.Get(), d3d11Texture.Get());
1955*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
1956*8975f5c5SAndroid Build Coastguard Worker 
1957*8975f5c5SAndroid Build Coastguard Worker         D3D11_MAPPED_SUBRESOURCE mapped = {};
1958*8975f5c5SAndroid Build Coastguard Worker         EXPECT_TRUE(SUCCEEDED(context->Map(stagingTexture.Get(), 0, D3D11_MAP_READ, 0, &mapped)));
1959*8975f5c5SAndroid Build Coastguard Worker 
1960*8975f5c5SAndroid Build Coastguard Worker         uint8_t *yPlane  = reinterpret_cast<uint8_t *>(mapped.pData);
1961*8975f5c5SAndroid Build Coastguard Worker         uint8_t *uvPlane = yPlane + bufferSize * mapped.RowPitch;
1962*8975f5c5SAndroid Build Coastguard Worker         if (isNV12)
1963*8975f5c5SAndroid Build Coastguard Worker         {
1964*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(yPlane[mapped.RowPitch * bufferSize / 2], kYFillValue);
1965*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(uvPlane[mapped.RowPitch * bufferSize / 4], kUFillValue);
1966*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(uvPlane[mapped.RowPitch * bufferSize / 4 + 1], kVFillValue);
1967*8975f5c5SAndroid Build Coastguard Worker         }
1968*8975f5c5SAndroid Build Coastguard Worker         else
1969*8975f5c5SAndroid Build Coastguard Worker         {
1970*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(yPlane[mapped.RowPitch * bufferSize / 2], kYFillValue & 0xff);
1971*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(yPlane[mapped.RowPitch * bufferSize / 2 + 1], (kYFillValue >> 8) & 0xff);
1972*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(uvPlane[mapped.RowPitch * bufferSize / 4], kUFillValue & 0xff);
1973*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(uvPlane[mapped.RowPitch * bufferSize / 4 + 1], (kUFillValue >> 8) & 0xff);
1974*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(uvPlane[mapped.RowPitch * bufferSize / 4 + 2], kVFillValue & 0xff);
1975*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(uvPlane[mapped.RowPitch * bufferSize / 4 + 3], (kVFillValue >> 8) & 0xff);
1976*8975f5c5SAndroid Build Coastguard Worker         }
1977*8975f5c5SAndroid Build Coastguard Worker 
1978*8975f5c5SAndroid Build Coastguard Worker         context->Unmap(stagingTexture.Get(), 0);
1979*8975f5c5SAndroid Build Coastguard Worker 
1980*8975f5c5SAndroid Build Coastguard Worker         glDeleteProgram(program);
1981*8975f5c5SAndroid Build Coastguard Worker         glDeleteTextures(1, &yTexture);
1982*8975f5c5SAndroid Build Coastguard Worker         glDeleteTextures(1, &uvTexture);
1983*8975f5c5SAndroid Build Coastguard Worker         glDeleteFramebuffers(1, &fbo);
1984*8975f5c5SAndroid Build Coastguard Worker         eglDestroyImageKHR(display, yImage);
1985*8975f5c5SAndroid Build Coastguard Worker         eglDestroyImageKHR(display, uvImage);
1986*8975f5c5SAndroid Build Coastguard Worker     }
1987*8975f5c5SAndroid Build Coastguard Worker 
RunYUVReadPixelTest(DXGI_FORMAT format)1988*8975f5c5SAndroid Build Coastguard Worker     void RunYUVReadPixelTest(DXGI_FORMAT format)
1989*8975f5c5SAndroid Build Coastguard Worker     {
1990*8975f5c5SAndroid Build Coastguard Worker         ASSERT(format == DXGI_FORMAT_NV12 || format == DXGI_FORMAT_P010 ||
1991*8975f5c5SAndroid Build Coastguard Worker                format == DXGI_FORMAT_P016);
1992*8975f5c5SAndroid Build Coastguard Worker         UINT formatSupport;
1993*8975f5c5SAndroid Build Coastguard Worker         ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11() ||
1994*8975f5c5SAndroid Build Coastguard Worker                            FAILED(mD3D11Device->CheckFormatSupport(format, &formatSupport)));
1995*8975f5c5SAndroid Build Coastguard Worker         ASSERT_TRUE(formatSupport &
1996*8975f5c5SAndroid Build Coastguard Worker                     (D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_RENDER_TARGET));
1997*8975f5c5SAndroid Build Coastguard Worker 
1998*8975f5c5SAndroid Build Coastguard Worker         const bool isNV12          = (format == DXGI_FORMAT_NV12);
1999*8975f5c5SAndroid Build Coastguard Worker         const unsigned kYFillValue = isNV12 ? 0x12 : 0x1234;
2000*8975f5c5SAndroid Build Coastguard Worker         const unsigned kUFillValue = isNV12 ? 0x23 : 0x2345;
2001*8975f5c5SAndroid Build Coastguard Worker         const unsigned kVFillValue = isNV12 ? 0x34 : 0x3456;
2002*8975f5c5SAndroid Build Coastguard Worker 
2003*8975f5c5SAndroid Build Coastguard Worker         constexpr char kVS[] =
2004*8975f5c5SAndroid Build Coastguard Worker             R"(precision highp float;
2005*8975f5c5SAndroid Build Coastguard Worker             attribute vec4 position;
2006*8975f5c5SAndroid Build Coastguard Worker             varying vec2 texcoord;
2007*8975f5c5SAndroid Build Coastguard Worker 
2008*8975f5c5SAndroid Build Coastguard Worker             void main()
2009*8975f5c5SAndroid Build Coastguard Worker             {
2010*8975f5c5SAndroid Build Coastguard Worker                 gl_Position = position;
2011*8975f5c5SAndroid Build Coastguard Worker                 texcoord = (position.xy * 0.5) + 0.5;
2012*8975f5c5SAndroid Build Coastguard Worker                 texcoord.y = 1.0 - texcoord.y;
2013*8975f5c5SAndroid Build Coastguard Worker             })";
2014*8975f5c5SAndroid Build Coastguard Worker 
2015*8975f5c5SAndroid Build Coastguard Worker         constexpr char kFS[] =
2016*8975f5c5SAndroid Build Coastguard Worker             R"(precision highp float;
2017*8975f5c5SAndroid Build Coastguard Worker             uniform vec4 color;
2018*8975f5c5SAndroid Build Coastguard Worker             varying vec2 texcoord;
2019*8975f5c5SAndroid Build Coastguard Worker 
2020*8975f5c5SAndroid Build Coastguard Worker             void main()
2021*8975f5c5SAndroid Build Coastguard Worker             {
2022*8975f5c5SAndroid Build Coastguard Worker                 gl_FragColor = color;
2023*8975f5c5SAndroid Build Coastguard Worker             })";
2024*8975f5c5SAndroid Build Coastguard Worker 
2025*8975f5c5SAndroid Build Coastguard Worker         GLuint program = CompileProgram(kVS, kFS);
2026*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(0u, program) << "shader compilation failed.";
2027*8975f5c5SAndroid Build Coastguard Worker 
2028*8975f5c5SAndroid Build Coastguard Worker         GLint colorLocation = glGetUniformLocation(program, "color");
2029*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(-1, colorLocation);
2030*8975f5c5SAndroid Build Coastguard Worker 
2031*8975f5c5SAndroid Build Coastguard Worker         EGLWindow *window  = getEGLWindow();
2032*8975f5c5SAndroid Build Coastguard Worker         EGLDisplay display = window->getDisplay();
2033*8975f5c5SAndroid Build Coastguard Worker 
2034*8975f5c5SAndroid Build Coastguard Worker         window->makeCurrent();
2035*8975f5c5SAndroid Build Coastguard Worker 
2036*8975f5c5SAndroid Build Coastguard Worker         const UINT bufferSize = 32;
2037*8975f5c5SAndroid Build Coastguard Worker         EXPECT_TRUE(mD3D11Device != nullptr);
2038*8975f5c5SAndroid Build Coastguard Worker         Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11Texture;
2039*8975f5c5SAndroid Build Coastguard Worker         CD3D11_TEXTURE2D_DESC desc(format, bufferSize, bufferSize, 1, 1,
2040*8975f5c5SAndroid Build Coastguard Worker                                    D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
2041*8975f5c5SAndroid Build Coastguard Worker 
2042*8975f5c5SAndroid Build Coastguard Worker         EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &d3d11Texture)));
2043*8975f5c5SAndroid Build Coastguard Worker 
2044*8975f5c5SAndroid Build Coastguard Worker         // Create and bind Y plane texture to image.
2045*8975f5c5SAndroid Build Coastguard Worker         EGLImage yImage;
2046*8975f5c5SAndroid Build Coastguard Worker         GLuint yTexture;
2047*8975f5c5SAndroid Build Coastguard Worker 
2048*8975f5c5SAndroid Build Coastguard Worker         GLenum internalFormat = format == DXGI_FORMAT_NV12 ? GL_RED_EXT : GL_R16_EXT;
2049*8975f5c5SAndroid Build Coastguard Worker         CreateAndBindImageToTexture(display, d3d11Texture.Get(), 0, internalFormat, GL_TEXTURE_2D,
2050*8975f5c5SAndroid Build Coastguard Worker                                     &yImage, &yTexture);
2051*8975f5c5SAndroid Build Coastguard Worker 
2052*8975f5c5SAndroid Build Coastguard Worker         glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, yImage);
2053*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2054*8975f5c5SAndroid Build Coastguard Worker 
2055*8975f5c5SAndroid Build Coastguard Worker         GLuint fbo;
2056*8975f5c5SAndroid Build Coastguard Worker         glGenFramebuffers(1, &fbo);
2057*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2058*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, yTexture, 0);
2059*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
2060*8975f5c5SAndroid Build Coastguard Worker                   static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));
2061*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2062*8975f5c5SAndroid Build Coastguard Worker 
2063*8975f5c5SAndroid Build Coastguard Worker         // Draw the Y plane using a shader.
2064*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(program);
2065*8975f5c5SAndroid Build Coastguard Worker         glUniform4f(colorLocation, kYFillValue * 1.0f / (isNV12 ? 0xff : 0xffff), 0, 0, 0);
2066*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2067*8975f5c5SAndroid Build Coastguard Worker 
2068*8975f5c5SAndroid Build Coastguard Worker         drawQuad(program, "position", 1.0f);
2069*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2070*8975f5c5SAndroid Build Coastguard Worker 
2071*8975f5c5SAndroid Build Coastguard Worker         // Read the Y plane pixels.
2072*8975f5c5SAndroid Build Coastguard Worker         if (isNV12)
2073*8975f5c5SAndroid Build Coastguard Worker         {
2074*8975f5c5SAndroid Build Coastguard Worker             GLubyte yPixels[4] = {};
2075*8975f5c5SAndroid Build Coastguard Worker             glReadPixels(0, bufferSize / 2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, yPixels);
2076*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(yPixels[0], kYFillValue);
2077*8975f5c5SAndroid Build Coastguard Worker         }
2078*8975f5c5SAndroid Build Coastguard Worker         else
2079*8975f5c5SAndroid Build Coastguard Worker         {
2080*8975f5c5SAndroid Build Coastguard Worker             GLushort yPixels[4] = {};
2081*8975f5c5SAndroid Build Coastguard Worker             glReadPixels(0, bufferSize / 2, 1, 1, GL_RGBA, GL_UNSIGNED_SHORT, yPixels);
2082*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(yPixels[0], kYFillValue);
2083*8975f5c5SAndroid Build Coastguard Worker         }
2084*8975f5c5SAndroid Build Coastguard Worker 
2085*8975f5c5SAndroid Build Coastguard Worker         // Create and bind UV plane texture to image.
2086*8975f5c5SAndroid Build Coastguard Worker         EGLImage uvImage;
2087*8975f5c5SAndroid Build Coastguard Worker         GLuint uvTexture;
2088*8975f5c5SAndroid Build Coastguard Worker 
2089*8975f5c5SAndroid Build Coastguard Worker         internalFormat = format == DXGI_FORMAT_NV12 ? GL_RG_EXT : GL_RG16_EXT;
2090*8975f5c5SAndroid Build Coastguard Worker         CreateAndBindImageToTexture(display, d3d11Texture.Get(), 1, internalFormat, GL_TEXTURE_2D,
2091*8975f5c5SAndroid Build Coastguard Worker                                     &uvImage, &uvTexture);
2092*8975f5c5SAndroid Build Coastguard Worker 
2093*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, uvTexture, 0);
2094*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
2095*8975f5c5SAndroid Build Coastguard Worker                   static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));
2096*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2097*8975f5c5SAndroid Build Coastguard Worker 
2098*8975f5c5SAndroid Build Coastguard Worker         // Draw the UV plane using a shader.
2099*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(program);
2100*8975f5c5SAndroid Build Coastguard Worker         glUniform4f(colorLocation, kUFillValue * 1.0f / (isNV12 ? 0xff : 0xffff),
2101*8975f5c5SAndroid Build Coastguard Worker                     kVFillValue * 1.0f / (isNV12 ? 0xff : 0xffff), 0, 0);
2102*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2103*8975f5c5SAndroid Build Coastguard Worker 
2104*8975f5c5SAndroid Build Coastguard Worker         drawQuad(program, "position", 1.0f);
2105*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2106*8975f5c5SAndroid Build Coastguard Worker 
2107*8975f5c5SAndroid Build Coastguard Worker         // Read the UV plane pixels.
2108*8975f5c5SAndroid Build Coastguard Worker         if (isNV12)
2109*8975f5c5SAndroid Build Coastguard Worker         {
2110*8975f5c5SAndroid Build Coastguard Worker             GLubyte uvPixels[4] = {};
2111*8975f5c5SAndroid Build Coastguard Worker             glReadPixels(0, bufferSize / 4, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, uvPixels);
2112*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(uvPixels[0], kUFillValue);
2113*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(uvPixels[1], kVFillValue);
2114*8975f5c5SAndroid Build Coastguard Worker         }
2115*8975f5c5SAndroid Build Coastguard Worker         else
2116*8975f5c5SAndroid Build Coastguard Worker         {
2117*8975f5c5SAndroid Build Coastguard Worker             GLushort uvPixels[4] = {};
2118*8975f5c5SAndroid Build Coastguard Worker             glReadPixels(0, bufferSize / 4, 1, 1, GL_RGBA, GL_UNSIGNED_SHORT, uvPixels);
2119*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(uvPixels[0], kUFillValue);
2120*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(uvPixels[1], kVFillValue);
2121*8975f5c5SAndroid Build Coastguard Worker         }
2122*8975f5c5SAndroid Build Coastguard Worker 
2123*8975f5c5SAndroid Build Coastguard Worker         Microsoft::WRL::ComPtr<ID3D11Texture2D> stagingTexture;
2124*8975f5c5SAndroid Build Coastguard Worker         CD3D11_TEXTURE2D_DESC stagingDesc = desc;
2125*8975f5c5SAndroid Build Coastguard Worker         stagingDesc.BindFlags             = 0;
2126*8975f5c5SAndroid Build Coastguard Worker         stagingDesc.Usage                 = D3D11_USAGE_STAGING;
2127*8975f5c5SAndroid Build Coastguard Worker         stagingDesc.CPUAccessFlags        = D3D11_CPU_ACCESS_READ;
2128*8975f5c5SAndroid Build Coastguard Worker 
2129*8975f5c5SAndroid Build Coastguard Worker         EXPECT_TRUE(
2130*8975f5c5SAndroid Build Coastguard Worker             SUCCEEDED(mD3D11Device->CreateTexture2D(&stagingDesc, nullptr, &stagingTexture)));
2131*8975f5c5SAndroid Build Coastguard Worker 
2132*8975f5c5SAndroid Build Coastguard Worker         Microsoft::WRL::ComPtr<ID3D11DeviceContext> context;
2133*8975f5c5SAndroid Build Coastguard Worker         mD3D11Device->GetImmediateContext(&context);
2134*8975f5c5SAndroid Build Coastguard Worker 
2135*8975f5c5SAndroid Build Coastguard Worker         context->CopyResource(stagingTexture.Get(), d3d11Texture.Get());
2136*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2137*8975f5c5SAndroid Build Coastguard Worker 
2138*8975f5c5SAndroid Build Coastguard Worker         D3D11_MAPPED_SUBRESOURCE mapped = {};
2139*8975f5c5SAndroid Build Coastguard Worker         EXPECT_TRUE(SUCCEEDED(context->Map(stagingTexture.Get(), 0, D3D11_MAP_READ, 0, &mapped)));
2140*8975f5c5SAndroid Build Coastguard Worker 
2141*8975f5c5SAndroid Build Coastguard Worker         uint8_t *yPlane  = reinterpret_cast<uint8_t *>(mapped.pData);
2142*8975f5c5SAndroid Build Coastguard Worker         uint8_t *uvPlane = yPlane + bufferSize * mapped.RowPitch;
2143*8975f5c5SAndroid Build Coastguard Worker         if (isNV12)
2144*8975f5c5SAndroid Build Coastguard Worker         {
2145*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(yPlane[mapped.RowPitch * bufferSize / 2], kYFillValue);
2146*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(uvPlane[mapped.RowPitch * bufferSize / 4], kUFillValue);
2147*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(uvPlane[mapped.RowPitch * bufferSize / 4 + 1], kVFillValue);
2148*8975f5c5SAndroid Build Coastguard Worker         }
2149*8975f5c5SAndroid Build Coastguard Worker         else
2150*8975f5c5SAndroid Build Coastguard Worker         {
2151*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(yPlane[mapped.RowPitch * bufferSize / 2], kYFillValue & 0xff);
2152*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(yPlane[mapped.RowPitch * bufferSize / 2 + 1], (kYFillValue >> 8) & 0xff);
2153*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(uvPlane[mapped.RowPitch * bufferSize / 4], kUFillValue & 0xff);
2154*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(uvPlane[mapped.RowPitch * bufferSize / 4 + 1], (kUFillValue >> 8) & 0xff);
2155*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(uvPlane[mapped.RowPitch * bufferSize / 4 + 2], kVFillValue & 0xff);
2156*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(uvPlane[mapped.RowPitch * bufferSize / 4 + 3], (kVFillValue >> 8) & 0xff);
2157*8975f5c5SAndroid Build Coastguard Worker         }
2158*8975f5c5SAndroid Build Coastguard Worker 
2159*8975f5c5SAndroid Build Coastguard Worker         context->Unmap(stagingTexture.Get(), 0);
2160*8975f5c5SAndroid Build Coastguard Worker 
2161*8975f5c5SAndroid Build Coastguard Worker         glDeleteProgram(program);
2162*8975f5c5SAndroid Build Coastguard Worker         glDeleteTextures(1, &yTexture);
2163*8975f5c5SAndroid Build Coastguard Worker         glDeleteTextures(1, &uvTexture);
2164*8975f5c5SAndroid Build Coastguard Worker         glDeleteFramebuffers(1, &fbo);
2165*8975f5c5SAndroid Build Coastguard Worker         eglDestroyImageKHR(display, yImage);
2166*8975f5c5SAndroid Build Coastguard Worker         eglDestroyImageKHR(display, uvImage);
2167*8975f5c5SAndroid Build Coastguard Worker     }
2168*8975f5c5SAndroid Build Coastguard Worker 
2169*8975f5c5SAndroid Build Coastguard Worker     template <typename T>
RunYUVWritePixelTest(DXGI_FORMAT format)2170*8975f5c5SAndroid Build Coastguard Worker     void RunYUVWritePixelTest(DXGI_FORMAT format)
2171*8975f5c5SAndroid Build Coastguard Worker     {
2172*8975f5c5SAndroid Build Coastguard Worker         ASSERT(format == DXGI_FORMAT_NV12 || format == DXGI_FORMAT_P010 ||
2173*8975f5c5SAndroid Build Coastguard Worker                format == DXGI_FORMAT_P016);
2174*8975f5c5SAndroid Build Coastguard Worker         UINT formatSupport;
2175*8975f5c5SAndroid Build Coastguard Worker         ANGLE_SKIP_TEST_IF(!valid() || !IsD3D11() ||
2176*8975f5c5SAndroid Build Coastguard Worker                            FAILED(mD3D11Device->CheckFormatSupport(format, &formatSupport)));
2177*8975f5c5SAndroid Build Coastguard Worker         ASSERT_TRUE(formatSupport &
2178*8975f5c5SAndroid Build Coastguard Worker                     (D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_RENDER_TARGET));
2179*8975f5c5SAndroid Build Coastguard Worker 
2180*8975f5c5SAndroid Build Coastguard Worker         const bool isNV12                = (format == DXGI_FORMAT_NV12);
2181*8975f5c5SAndroid Build Coastguard Worker         const unsigned kYFillValueFull   = isNV12 ? 0x12 : 0x1234;
2182*8975f5c5SAndroid Build Coastguard Worker         const unsigned kUFillValueFull   = isNV12 ? 0x23 : 0x2345;
2183*8975f5c5SAndroid Build Coastguard Worker         const unsigned kVFillValueFull   = isNV12 ? 0x34 : 0x3456;
2184*8975f5c5SAndroid Build Coastguard Worker         const unsigned kYFillValueOffset = isNV12 ? 0x56 : 0x5678;
2185*8975f5c5SAndroid Build Coastguard Worker         const unsigned kUFillValueOffset = isNV12 ? 0x67 : 0x6789;
2186*8975f5c5SAndroid Build Coastguard Worker         const unsigned kVFillValueOffset = isNV12 ? 0x78 : 0x7890;
2187*8975f5c5SAndroid Build Coastguard Worker 
2188*8975f5c5SAndroid Build Coastguard Worker         EGLWindow *window  = getEGLWindow();
2189*8975f5c5SAndroid Build Coastguard Worker         EGLDisplay display = window->getDisplay();
2190*8975f5c5SAndroid Build Coastguard Worker         window->makeCurrent();
2191*8975f5c5SAndroid Build Coastguard Worker 
2192*8975f5c5SAndroid Build Coastguard Worker         const UINT bufferSize = 32;
2193*8975f5c5SAndroid Build Coastguard Worker         EXPECT_TRUE(mD3D11Device != nullptr);
2194*8975f5c5SAndroid Build Coastguard Worker         Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11Texture;
2195*8975f5c5SAndroid Build Coastguard Worker         CD3D11_TEXTURE2D_DESC desc(format, bufferSize, bufferSize, 1, 1,
2196*8975f5c5SAndroid Build Coastguard Worker                                    D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
2197*8975f5c5SAndroid Build Coastguard Worker 
2198*8975f5c5SAndroid Build Coastguard Worker         EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &d3d11Texture)));
2199*8975f5c5SAndroid Build Coastguard Worker 
2200*8975f5c5SAndroid Build Coastguard Worker         // Create and bind Y plane texture to image.
2201*8975f5c5SAndroid Build Coastguard Worker         EGLImage yImage;
2202*8975f5c5SAndroid Build Coastguard Worker         GLuint yTexture;
2203*8975f5c5SAndroid Build Coastguard Worker         GLenum internalFormat = isNV12 ? GL_RED_EXT : GL_R16_EXT;
2204*8975f5c5SAndroid Build Coastguard Worker         CreateAndBindImageToTexture(display, d3d11Texture.Get(), 0, internalFormat, GL_TEXTURE_2D,
2205*8975f5c5SAndroid Build Coastguard Worker                                     &yImage, &yTexture);
2206*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2207*8975f5c5SAndroid Build Coastguard Worker 
2208*8975f5c5SAndroid Build Coastguard Worker         // Write the Y plane data to full texture (0, 0) to (32, 32).
2209*8975f5c5SAndroid Build Coastguard Worker         GLenum type = isNV12 ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
2210*8975f5c5SAndroid Build Coastguard Worker         std::vector<T> yData(bufferSize * bufferSize, kYFillValueFull);
2211*8975f5c5SAndroid Build Coastguard Worker         glTexSubImage2D(GL_TEXTURE_2D, /*level=*/0, /*xoffset=*/0, /*yoffset=*/0,
2212*8975f5c5SAndroid Build Coastguard Worker                         /*width=*/bufferSize,
2213*8975f5c5SAndroid Build Coastguard Worker                         /*height=*/bufferSize, GL_RED_EXT, type, yData.data());
2214*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2215*8975f5c5SAndroid Build Coastguard Worker 
2216*8975f5c5SAndroid Build Coastguard Worker         GLuint fbo;
2217*8975f5c5SAndroid Build Coastguard Worker         glGenFramebuffers(1, &fbo);
2218*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2219*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, yTexture, 0);
2220*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
2221*8975f5c5SAndroid Build Coastguard Worker                   static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));
2222*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2223*8975f5c5SAndroid Build Coastguard Worker 
2224*8975f5c5SAndroid Build Coastguard Worker         // Read the Y plane pixels for a region starting at 0, 0 offsets.
2225*8975f5c5SAndroid Build Coastguard Worker         // yPixels of size (4*4) region (*4) bytes per RGBA pixel
2226*8975f5c5SAndroid Build Coastguard Worker         T yPixels[4 * 4 * 4] = {};
2227*8975f5c5SAndroid Build Coastguard Worker         glReadPixels(/*x=*/0, /*y=*/0, /*width*/ 4, /*height=*/4, GL_RGBA, type, yPixels);
2228*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(yPixels[0], kYFillValueFull);
2229*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(yPixels[4], kYFillValueFull);
2230*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(yPixels[16], kYFillValueFull);
2231*8975f5c5SAndroid Build Coastguard Worker 
2232*8975f5c5SAndroid Build Coastguard Worker         // Write the Y plane data with offseted values for subregion (16, 16) - (32, 32).
2233*8975f5c5SAndroid Build Coastguard Worker         std::vector<T> yDataOffset(bufferSize * bufferSize, kYFillValueOffset);
2234*8975f5c5SAndroid Build Coastguard Worker         glTexSubImage2D(GL_TEXTURE_2D, /*level=*/0, /*xoffset=*/bufferSize / 2,
2235*8975f5c5SAndroid Build Coastguard Worker                         /*yoffset=*/bufferSize / 2, /*width=*/bufferSize / 2,
2236*8975f5c5SAndroid Build Coastguard Worker                         /*height=*/bufferSize / 2, GL_RED_EXT, type, yDataOffset.data());
2237*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2238*8975f5c5SAndroid Build Coastguard Worker 
2239*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, yTexture, 0);
2240*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
2241*8975f5c5SAndroid Build Coastguard Worker                   static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));
2242*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2243*8975f5c5SAndroid Build Coastguard Worker 
2244*8975f5c5SAndroid Build Coastguard Worker         // Read the Y plane pixels for a region starting at some offsets.
2245*8975f5c5SAndroid Build Coastguard Worker         // yPixels of size (16*16) region (*4) bytes per RGBA pixel
2246*8975f5c5SAndroid Build Coastguard Worker         T yPixelsOffset[16 * 16 * 4] = {};
2247*8975f5c5SAndroid Build Coastguard Worker         glReadPixels(/*x=*/bufferSize / 2, /*y=*/bufferSize / 2, /*width=*/bufferSize / 2,
2248*8975f5c5SAndroid Build Coastguard Worker                      /*height=*/bufferSize / 2, GL_RGBA, type, yPixelsOffset);
2249*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(yPixelsOffset[0], kYFillValueOffset);
2250*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(yPixelsOffset[12], kYFillValueOffset);
2251*8975f5c5SAndroid Build Coastguard Worker 
2252*8975f5c5SAndroid Build Coastguard Worker         // Create and bind UV plane texture to image.
2253*8975f5c5SAndroid Build Coastguard Worker         EGLImage uvImage;
2254*8975f5c5SAndroid Build Coastguard Worker         GLuint uvTexture;
2255*8975f5c5SAndroid Build Coastguard Worker         internalFormat = format == DXGI_FORMAT_NV12 ? GL_RG_EXT : GL_RG16_EXT;
2256*8975f5c5SAndroid Build Coastguard Worker         CreateAndBindImageToTexture(display, d3d11Texture.Get(), 1, internalFormat, GL_TEXTURE_2D,
2257*8975f5c5SAndroid Build Coastguard Worker                                     &uvImage, &uvTexture);
2258*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2259*8975f5c5SAndroid Build Coastguard Worker 
2260*8975f5c5SAndroid Build Coastguard Worker         // Write the UV plane data to texture's full uv plane (0, 0,) - (16, 16).
2261*8975f5c5SAndroid Build Coastguard Worker         std::vector<T> uvData((bufferSize * bufferSize) / 2);
2262*8975f5c5SAndroid Build Coastguard Worker         for (UINT i = 0; i < (bufferSize * bufferSize) / 2; i++)
2263*8975f5c5SAndroid Build Coastguard Worker         {
2264*8975f5c5SAndroid Build Coastguard Worker             uvData[i] = i % 2 == 0 ? kUFillValueFull : kVFillValueFull;
2265*8975f5c5SAndroid Build Coastguard Worker         }
2266*8975f5c5SAndroid Build Coastguard Worker         glTexSubImage2D(GL_TEXTURE_2D, /*level=*/0, /*xoffset=*/0, /*yoffset=*/0,
2267*8975f5c5SAndroid Build Coastguard Worker                         /*width=*/bufferSize / 2,
2268*8975f5c5SAndroid Build Coastguard Worker                         /*height=*/bufferSize / 2, GL_RG_EXT, type, uvData.data());
2269*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2270*8975f5c5SAndroid Build Coastguard Worker 
2271*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, uvTexture, 0);
2272*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
2273*8975f5c5SAndroid Build Coastguard Worker                   static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));
2274*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2275*8975f5c5SAndroid Build Coastguard Worker 
2276*8975f5c5SAndroid Build Coastguard Worker         // Read the UV plane pixels for a region starting at 0, 0 offsets.
2277*8975f5c5SAndroid Build Coastguard Worker         // uvPixels of size (4*4) region (*4) bytes per RGBA pixel
2278*8975f5c5SAndroid Build Coastguard Worker         T uvPixels[4 * 4 * 4] = {};
2279*8975f5c5SAndroid Build Coastguard Worker         glReadPixels(/*x=*/0, /*y=*/0, /*width=*/4, /*height=*/4, GL_RGBA, type, uvPixels);
2280*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(uvPixels[0], kUFillValueFull);
2281*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(uvPixels[1], kVFillValueFull);
2282*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(uvPixels[4], kUFillValueFull);
2283*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(uvPixels[5], kVFillValueFull);
2284*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(uvPixels[16], kUFillValueFull);
2285*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(uvPixels[17], kVFillValueFull);
2286*8975f5c5SAndroid Build Coastguard Worker 
2287*8975f5c5SAndroid Build Coastguard Worker         // Write the UV plane data with offset values for subregion (8, 8) - (16, 16).
2288*8975f5c5SAndroid Build Coastguard Worker         std::vector<T> uvDataOffset((bufferSize * bufferSize) / 2);
2289*8975f5c5SAndroid Build Coastguard Worker         for (UINT i = 0; i < (bufferSize * bufferSize) / 2; i++)
2290*8975f5c5SAndroid Build Coastguard Worker         {
2291*8975f5c5SAndroid Build Coastguard Worker             uvDataOffset[i] = i % 2 == 0 ? kUFillValueOffset : kVFillValueOffset;
2292*8975f5c5SAndroid Build Coastguard Worker         }
2293*8975f5c5SAndroid Build Coastguard Worker         glTexSubImage2D(GL_TEXTURE_2D, /*level=*/0, /*xoffset=*/bufferSize / 4,
2294*8975f5c5SAndroid Build Coastguard Worker                         /*yoffset=*/bufferSize / 4, /*width=*/bufferSize / 4,
2295*8975f5c5SAndroid Build Coastguard Worker                         /*height=*/bufferSize / 4, GL_RG_EXT, type, uvDataOffset.data());
2296*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2297*8975f5c5SAndroid Build Coastguard Worker 
2298*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, uvTexture, 0);
2299*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
2300*8975f5c5SAndroid Build Coastguard Worker                   static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE));
2301*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2302*8975f5c5SAndroid Build Coastguard Worker 
2303*8975f5c5SAndroid Build Coastguard Worker         // Read the UV plane pixels for a region starting at some offsets.
2304*8975f5c5SAndroid Build Coastguard Worker         // uvPixels of size (8*8) region (*4) bytes per RGBA pixel
2305*8975f5c5SAndroid Build Coastguard Worker         T uvPixelsOffset[8 * 8 * 4] = {};
2306*8975f5c5SAndroid Build Coastguard Worker         glReadPixels(/*x=*/bufferSize / 4, /*y=*/bufferSize / 4, /*width=*/bufferSize / 4,
2307*8975f5c5SAndroid Build Coastguard Worker                      /*height=*/bufferSize / 4, GL_RGBA, type, uvPixelsOffset);
2308*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(uvPixelsOffset[0], kUFillValueOffset);
2309*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(uvPixelsOffset[1], kVFillValueOffset);
2310*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(uvPixelsOffset[12], kUFillValueOffset);
2311*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(uvPixelsOffset[13], kVFillValueOffset);
2312*8975f5c5SAndroid Build Coastguard Worker 
2313*8975f5c5SAndroid Build Coastguard Worker         Microsoft::WRL::ComPtr<ID3D11Texture2D> stagingTexture;
2314*8975f5c5SAndroid Build Coastguard Worker         CD3D11_TEXTURE2D_DESC stagingDesc = desc;
2315*8975f5c5SAndroid Build Coastguard Worker         stagingDesc.BindFlags             = 0;
2316*8975f5c5SAndroid Build Coastguard Worker         stagingDesc.Usage                 = D3D11_USAGE_STAGING;
2317*8975f5c5SAndroid Build Coastguard Worker         stagingDesc.CPUAccessFlags        = D3D11_CPU_ACCESS_READ;
2318*8975f5c5SAndroid Build Coastguard Worker 
2319*8975f5c5SAndroid Build Coastguard Worker         EXPECT_TRUE(
2320*8975f5c5SAndroid Build Coastguard Worker             SUCCEEDED(mD3D11Device->CreateTexture2D(&stagingDesc, nullptr, &stagingTexture)));
2321*8975f5c5SAndroid Build Coastguard Worker 
2322*8975f5c5SAndroid Build Coastguard Worker         Microsoft::WRL::ComPtr<ID3D11DeviceContext> context;
2323*8975f5c5SAndroid Build Coastguard Worker         mD3D11Device->GetImmediateContext(&context);
2324*8975f5c5SAndroid Build Coastguard Worker 
2325*8975f5c5SAndroid Build Coastguard Worker         context->CopyResource(stagingTexture.Get(), d3d11Texture.Get());
2326*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
2327*8975f5c5SAndroid Build Coastguard Worker 
2328*8975f5c5SAndroid Build Coastguard Worker         D3D11_MAPPED_SUBRESOURCE mapped = {};
2329*8975f5c5SAndroid Build Coastguard Worker         EXPECT_TRUE(SUCCEEDED(context->Map(stagingTexture.Get(), 0, D3D11_MAP_READ, 0, &mapped)));
2330*8975f5c5SAndroid Build Coastguard Worker 
2331*8975f5c5SAndroid Build Coastguard Worker         uint8_t *yPlane  = reinterpret_cast<uint8_t *>(mapped.pData);
2332*8975f5c5SAndroid Build Coastguard Worker         uint8_t *uvPlane = yPlane + bufferSize * mapped.RowPitch;
2333*8975f5c5SAndroid Build Coastguard Worker         auto getYValue   = [&](int x, int y) {
2334*8975f5c5SAndroid Build Coastguard Worker             const T *lineStart = reinterpret_cast<const T *>(yPlane + y * mapped.RowPitch);
2335*8975f5c5SAndroid Build Coastguard Worker             return lineStart[x];
2336*8975f5c5SAndroid Build Coastguard Worker         };
2337*8975f5c5SAndroid Build Coastguard Worker 
2338*8975f5c5SAndroid Build Coastguard Worker         auto getUValue = [&](int x, int y) {
2339*8975f5c5SAndroid Build Coastguard Worker             const T *lineStart = reinterpret_cast<const T *>(uvPlane + y * mapped.RowPitch);
2340*8975f5c5SAndroid Build Coastguard Worker             return lineStart[x * 2 + 0];
2341*8975f5c5SAndroid Build Coastguard Worker         };
2342*8975f5c5SAndroid Build Coastguard Worker 
2343*8975f5c5SAndroid Build Coastguard Worker         auto getVValue = [&](int x, int y) {
2344*8975f5c5SAndroid Build Coastguard Worker             const T *lineStart = reinterpret_cast<const T *>(uvPlane + y * mapped.RowPitch);
2345*8975f5c5SAndroid Build Coastguard Worker             return lineStart[x * 2 + 1];
2346*8975f5c5SAndroid Build Coastguard Worker         };
2347*8975f5c5SAndroid Build Coastguard Worker         // Compare first y pixel with full write values.
2348*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(getYValue(0, 0), kYFillValueFull);
2349*8975f5c5SAndroid Build Coastguard Worker         // Compare last y pixel with overwritten subregion values.
2350*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(getYValue(bufferSize - 1, bufferSize - 1), kYFillValueOffset);
2351*8975f5c5SAndroid Build Coastguard Worker         // Compare first uv pixel with full write values.
2352*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(getUValue(0, 0), kUFillValueFull);
2353*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(getVValue(0, 0), kVFillValueFull);
2354*8975f5c5SAndroid Build Coastguard Worker         // Compare last uv pixel with overwritten subregion values.
2355*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(getUValue(bufferSize / 2 - 1, bufferSize / 2 - 1), kUFillValueOffset);
2356*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(getVValue(bufferSize / 2 - 1, bufferSize / 2 - 1), kVFillValueOffset);
2357*8975f5c5SAndroid Build Coastguard Worker 
2358*8975f5c5SAndroid Build Coastguard Worker         context->Unmap(stagingTexture.Get(), 0);
2359*8975f5c5SAndroid Build Coastguard Worker 
2360*8975f5c5SAndroid Build Coastguard Worker         glDeleteTextures(1, &yTexture);
2361*8975f5c5SAndroid Build Coastguard Worker         glDeleteTextures(1, &uvTexture);
2362*8975f5c5SAndroid Build Coastguard Worker         glDeleteFramebuffers(1, &fbo);
2363*8975f5c5SAndroid Build Coastguard Worker         eglDestroyImageKHR(display, yImage);
2364*8975f5c5SAndroid Build Coastguard Worker         eglDestroyImageKHR(display, uvImage);
2365*8975f5c5SAndroid Build Coastguard Worker     }
2366*8975f5c5SAndroid Build Coastguard Worker };
2367*8975f5c5SAndroid Build Coastguard Worker 
2368*8975f5c5SAndroid Build Coastguard Worker // Test that an NV12 D3D11 texture can be imported as two R8 and RG8 EGLImages and the resulting GL
2369*8975f5c5SAndroid Build Coastguard Worker // textures can be sampled from.
TEST_P(D3DTextureYUVTest,NV12TextureImageSampler)2370*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureYUVTest, NV12TextureImageSampler)
2371*8975f5c5SAndroid Build Coastguard Worker {
2372*8975f5c5SAndroid Build Coastguard Worker     RunYUVSamplerTest(DXGI_FORMAT_NV12);
2373*8975f5c5SAndroid Build Coastguard Worker }
2374*8975f5c5SAndroid Build Coastguard Worker 
2375*8975f5c5SAndroid Build Coastguard Worker // ANGLE ES2/D3D11 supports GL_EXT_texture_norm16 even though the extension spec says it's ES3 only.
2376*8975f5c5SAndroid Build Coastguard Worker // Test P010 on ES2 since Chromium's Skia context is ES2 and it uses P010 for HDR video playback.
TEST_P(D3DTextureYUVTest,P010TextureImageSampler)2377*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureYUVTest, P010TextureImageSampler)
2378*8975f5c5SAndroid Build Coastguard Worker {
2379*8975f5c5SAndroid Build Coastguard Worker     RunYUVSamplerTest(DXGI_FORMAT_P010);
2380*8975f5c5SAndroid Build Coastguard Worker }
2381*8975f5c5SAndroid Build Coastguard Worker 
2382*8975f5c5SAndroid Build Coastguard Worker // Same as above, but for P016. P016 doesn't seem to be supported on all GPUs so it might be skipped
2383*8975f5c5SAndroid Build Coastguard Worker // more often than P010 and NV12 e.g. on the NVIDIA GTX 1050 Ti.
TEST_P(D3DTextureYUVTest,P016TextureImageSampler)2384*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureYUVTest, P016TextureImageSampler)
2385*8975f5c5SAndroid Build Coastguard Worker {
2386*8975f5c5SAndroid Build Coastguard Worker     RunYUVSamplerTest(DXGI_FORMAT_P016);
2387*8975f5c5SAndroid Build Coastguard Worker }
2388*8975f5c5SAndroid Build Coastguard Worker 
2389*8975f5c5SAndroid Build Coastguard Worker // Test that an NV12 D3D11 texture can be imported as two R8 and RG8 EGLImages and rendered to as
2390*8975f5c5SAndroid Build Coastguard Worker // framebuffer attachments.
TEST_P(D3DTextureYUVTest,NV12TextureImageRender)2391*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureYUVTest, NV12TextureImageRender)
2392*8975f5c5SAndroid Build Coastguard Worker {
2393*8975f5c5SAndroid Build Coastguard Worker     RunYUVRenderTest(DXGI_FORMAT_NV12);
2394*8975f5c5SAndroid Build Coastguard Worker }
2395*8975f5c5SAndroid Build Coastguard Worker 
2396*8975f5c5SAndroid Build Coastguard Worker // ANGLE ES2/D3D11 supports GL_EXT_texture_norm16 even though the extension spec says it's ES3 only.
2397*8975f5c5SAndroid Build Coastguard Worker // Test P010 on ES2 since Chromium's Skia context is ES2 and it uses P010 for HDR video playback.
TEST_P(D3DTextureYUVTest,P010TextureImageRender)2398*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureYUVTest, P010TextureImageRender)
2399*8975f5c5SAndroid Build Coastguard Worker {
2400*8975f5c5SAndroid Build Coastguard Worker     RunYUVRenderTest(DXGI_FORMAT_P010);
2401*8975f5c5SAndroid Build Coastguard Worker }
2402*8975f5c5SAndroid Build Coastguard Worker 
2403*8975f5c5SAndroid Build Coastguard Worker // Same as above, but for P016. P016 doesn't seem to be supported on all GPUs so it might be skipped
2404*8975f5c5SAndroid Build Coastguard Worker // more often than P010 and NV12 e.g. on the NVIDIA GTX 1050 Ti.
TEST_P(D3DTextureYUVTest,P016TextureImageRender)2405*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureYUVTest, P016TextureImageRender)
2406*8975f5c5SAndroid Build Coastguard Worker {
2407*8975f5c5SAndroid Build Coastguard Worker     RunYUVRenderTest(DXGI_FORMAT_P016);
2408*8975f5c5SAndroid Build Coastguard Worker }
2409*8975f5c5SAndroid Build Coastguard Worker 
2410*8975f5c5SAndroid Build Coastguard Worker // Test that an NV12 D3D11 texture can be imported as two R8 and RG8 EGLImages and rendered to as
2411*8975f5c5SAndroid Build Coastguard Worker // framebuffer attachments and then read from as individual planes.
TEST_P(D3DTextureYUVTest,NV12TextureImageReadPixel)2412*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureYUVTest, NV12TextureImageReadPixel)
2413*8975f5c5SAndroid Build Coastguard Worker {
2414*8975f5c5SAndroid Build Coastguard Worker     RunYUVReadPixelTest(DXGI_FORMAT_NV12);
2415*8975f5c5SAndroid Build Coastguard Worker }
2416*8975f5c5SAndroid Build Coastguard Worker 
2417*8975f5c5SAndroid Build Coastguard Worker // ANGLE ES2/D3D11 supports GL_EXT_texture_norm16 even though the extension spec says it's ES3 only.
2418*8975f5c5SAndroid Build Coastguard Worker // Test P010 on ES2 since Chromium's Skia context is ES2 and it uses P010 for HDR video playback.
TEST_P(D3DTextureYUVTest,P010TextureImageReadPixel)2419*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureYUVTest, P010TextureImageReadPixel)
2420*8975f5c5SAndroid Build Coastguard Worker {
2421*8975f5c5SAndroid Build Coastguard Worker     RunYUVReadPixelTest(DXGI_FORMAT_P010);
2422*8975f5c5SAndroid Build Coastguard Worker }
2423*8975f5c5SAndroid Build Coastguard Worker 
2424*8975f5c5SAndroid Build Coastguard Worker // Same as above, but for P016. P016 doesn't seem to be supported on all GPUs so it might be skipped
2425*8975f5c5SAndroid Build Coastguard Worker // more often than P010 and NV12 e.g. on the NVIDIA GTX 1050 Ti.
TEST_P(D3DTextureYUVTest,P016TextureImageReadPixel)2426*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureYUVTest, P016TextureImageReadPixel)
2427*8975f5c5SAndroid Build Coastguard Worker {
2428*8975f5c5SAndroid Build Coastguard Worker     RunYUVReadPixelTest(DXGI_FORMAT_P016);
2429*8975f5c5SAndroid Build Coastguard Worker }
2430*8975f5c5SAndroid Build Coastguard Worker 
2431*8975f5c5SAndroid Build Coastguard Worker // Test that an NV12 D3D11 texture can be imported as two R8 and RG8 EGLImages and write data to
2432*8975f5c5SAndroid Build Coastguard Worker // them through glTexSubImage2D and then rendered to as framebuffer attachments and then read from
2433*8975f5c5SAndroid Build Coastguard Worker // as individual planes.
TEST_P(D3DTextureYUVTest,NV12TextureImageWritePixel)2434*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureYUVTest, NV12TextureImageWritePixel)
2435*8975f5c5SAndroid Build Coastguard Worker {
2436*8975f5c5SAndroid Build Coastguard Worker     RunYUVWritePixelTest<uint8_t>(DXGI_FORMAT_NV12);
2437*8975f5c5SAndroid Build Coastguard Worker }
2438*8975f5c5SAndroid Build Coastguard Worker 
2439*8975f5c5SAndroid Build Coastguard Worker // Test that an P010 D3D11 texture can be imported as two R16 and RG16 EGLImages and write data to
2440*8975f5c5SAndroid Build Coastguard Worker // them through glTexSubImage2D and then rendered to as framebuffer attachments and then read from
2441*8975f5c5SAndroid Build Coastguard Worker // as individual planes.
TEST_P(D3DTextureYUVTest,P010TextureImageWritePixel)2442*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureYUVTest, P010TextureImageWritePixel)
2443*8975f5c5SAndroid Build Coastguard Worker {
2444*8975f5c5SAndroid Build Coastguard Worker     RunYUVWritePixelTest<uint16_t>(DXGI_FORMAT_P010);
2445*8975f5c5SAndroid Build Coastguard Worker }
2446*8975f5c5SAndroid Build Coastguard Worker 
2447*8975f5c5SAndroid Build Coastguard Worker // Test that an P016 D3D11 texture can be imported as two R16 and RG16 EGLImages and write data to
2448*8975f5c5SAndroid Build Coastguard Worker // them through glTexSubImage2D and then rendered to as framebuffer attachments and then read from
2449*8975f5c5SAndroid Build Coastguard Worker // as individual planes.
TEST_P(D3DTextureYUVTest,P016TextureImageWritePixel)2450*8975f5c5SAndroid Build Coastguard Worker TEST_P(D3DTextureYUVTest, P016TextureImageWritePixel)
2451*8975f5c5SAndroid Build Coastguard Worker {
2452*8975f5c5SAndroid Build Coastguard Worker     RunYUVWritePixelTest<uint16_t>(DXGI_FORMAT_P016);
2453*8975f5c5SAndroid Build Coastguard Worker }
2454*8975f5c5SAndroid Build Coastguard Worker 
2455*8975f5c5SAndroid Build Coastguard Worker // Use this to select which configurations (e.g. which renderer, which GLES major version) these
2456*8975f5c5SAndroid Build Coastguard Worker // tests should be run against.
2457*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2(D3DTextureTest);
2458*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2(D3DTextureClearTest);
2459*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2(D3DTextureYUVTest);
2460*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES3(D3DTextureTestES3);
2461*8975f5c5SAndroid Build Coastguard Worker // D3D Debug device reports an error. http://anglebug.com/40096593
2462*8975f5c5SAndroid Build Coastguard Worker // ANGLE_INSTANTIATE_TEST(D3DTextureTestMS, ES2_D3D11());
2463*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(D3DTextureTestMS);
2464*8975f5c5SAndroid Build Coastguard Worker }  // namespace angle
2465