1 /*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <OpenGLESDispatch/GLESv3Dispatch.h>
18
19 #include "GLESv3.h"
20
21 #include <string>
22 #include <vector>
23
24 // Stubs (common)
25
glDeleteFencesNV(GLsizei,const GLuint *)26 static void glDeleteFencesNV(GLsizei, const GLuint*) {
27 printf("%s: not implemented\n", __func__);
28 }
29
glDisableDriverControlQCOM(GLuint)30 static void glDisableDriverControlQCOM(GLuint) {
31 printf("%s: not implemented\n", __func__);
32 }
33
glDiscardFramebufferEXT(GLenum,GLsizei,const GLenum *)34 static void glDiscardFramebufferEXT(GLenum, GLsizei, const GLenum*) {
35 printf("%s: not implemented\n", __func__);
36 }
37
glEnableDriverControlQCOM(GLuint)38 static void glEnableDriverControlQCOM(GLuint) {
39 printf("%s: not implemented\n", __func__);
40 }
41
glEndTilingQCOM(GLbitfield)42 static void glEndTilingQCOM(GLbitfield) {
43 printf("%s: not implemented\n", __func__);
44 }
45
glExtGetBufferPointervQCOM(GLenum,GLvoid **)46 static void glExtGetBufferPointervQCOM(GLenum, GLvoid**) {
47 printf("%s: not implemented\n", __func__);
48 }
49
glExtGetBuffersQCOM(GLuint *,GLint,GLint *)50 static void glExtGetBuffersQCOM(GLuint*, GLint, GLint*) {
51 printf("%s: not implemented\n", __func__);
52 }
53
glExtGetFramebuffersQCOM(GLuint *,GLint,GLint *)54 static void glExtGetFramebuffersQCOM(GLuint*, GLint, GLint*) {
55 printf("%s: not implemented\n", __func__);
56 }
57
glExtGetProgramBinarySourceQCOM(GLuint,GLenum,GLchar *,GLint *)58 static void glExtGetProgramBinarySourceQCOM(GLuint, GLenum, GLchar*, GLint*) {
59 printf("%s: not implemented\n", __func__);
60 }
61
glExtGetProgramsQCOM(GLuint *,GLint,GLint *)62 static void glExtGetProgramsQCOM(GLuint*, GLint, GLint*) {
63 printf("%s: not implemented\n", __func__);
64 }
65
glExtGetRenderbuffersQCOM(GLuint *,GLint,GLint *)66 static void glExtGetRenderbuffersQCOM(GLuint*, GLint, GLint*) {
67 printf("%s: not implemented\n", __func__);
68 }
69
glExtGetShadersQCOM(GLuint *,GLint,GLint *)70 static void glExtGetShadersQCOM(GLuint*, GLint, GLint*) {
71 printf("%s: not implemented\n", __func__);
72 }
73
glExtGetTexLevelParameterivQCOM(GLuint,GLenum,GLint,GLenum,GLint *)74 static void glExtGetTexLevelParameterivQCOM(GLuint, GLenum, GLint, GLenum, GLint*) {
75 printf("%s: not implemented\n", __func__);
76 }
77
glExtGetTexSubImageQCOM(GLenum,GLint,GLint,GLint,GLint,GLsizei,GLsizei,GLsizei,GLenum,GLenum,GLvoid *)78 static void glExtGetTexSubImageQCOM(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei,
79 GLenum, GLenum, GLvoid*) {
80 printf("%s: not implemented\n", __func__);
81 }
82
glExtGetTexturesQCOM(GLuint *,GLint,GLint *)83 static void glExtGetTexturesQCOM(GLuint*, GLint, GLint*) {
84 printf("%s: not implemented\n", __func__);
85 }
86
glExtIsProgramBinaryQCOM(GLuint)87 static GLboolean glExtIsProgramBinaryQCOM(GLuint) {
88 printf("%s: not implemented\n", __func__);
89 return GL_FALSE;
90 }
91
glExtTexObjectStateOverrideiQCOM(GLenum,GLenum,GLint)92 static void glExtTexObjectStateOverrideiQCOM(GLenum, GLenum, GLint) {
93 printf("%s: not implemented\n", __func__);
94 }
95
glFinishFenceNV(GLuint)96 static void glFinishFenceNV(GLuint) {
97 printf("%s: not implemented\n", __func__);
98 }
99
glFramebufferTexture2DMultisampleIMG(GLenum,GLenum,GLenum,GLuint,GLint,GLsizei)100 static void glFramebufferTexture2DMultisampleIMG(GLenum, GLenum, GLenum, GLuint, GLint, GLsizei) {
101 printf("%s: not implemented\n", __func__);
102 }
103
glGenFencesNV(GLsizei,GLuint *)104 static void glGenFencesNV(GLsizei, GLuint*) {
105 printf("%s: not implemented\n", __func__);
106 }
107
glGetDriverControlsQCOM(GLint *,GLsizei,GLuint *)108 static void glGetDriverControlsQCOM(GLint*, GLsizei, GLuint*) {
109 printf("%s: not implemented\n", __func__);
110 }
111
glGetDriverControlStringQCOM(GLuint,GLsizei,GLsizei *,GLchar *)112 static void glGetDriverControlStringQCOM(GLuint, GLsizei, GLsizei*, GLchar*) {
113 printf("%s: not implemented\n", __func__);
114 }
115
glGetFenceivNV(GLuint,GLenum,GLint *)116 static void glGetFenceivNV(GLuint, GLenum, GLint*) {
117 printf("%s: not implemented\n", __func__);
118 }
119
glIsFenceNV(GLuint)120 static GLboolean glIsFenceNV(GLuint) {
121 printf("%s: not implemented\n", __func__);
122 return GL_FALSE;
123 }
124
glMapBufferOES(GLenum,GLenum)125 static void* glMapBufferOES(GLenum, GLenum) {
126 printf("%s: not implemented\n", __func__);
127 return nullptr;
128 }
129
glMultiDrawArraysEXT(GLenum,const GLint *,const GLsizei *,GLsizei)130 static void glMultiDrawArraysEXT(GLenum, const GLint*, const GLsizei*, GLsizei) {
131 printf("%s: not implemented\n", __func__);
132 }
133
glMultiDrawElementsEXT(GLenum,const GLsizei *,GLenum,const GLvoid * const *,GLsizei)134 static void glMultiDrawElementsEXT(GLenum, const GLsizei*, GLenum, const GLvoid* const*, GLsizei) {
135 printf("%s: not implemented\n", __func__);
136 }
137
glRenderbufferStorageMultisampleIMG(GLenum,GLsizei,GLenum,GLsizei,GLsizei)138 static void glRenderbufferStorageMultisampleIMG(GLenum, GLsizei, GLenum, GLsizei, GLsizei) {
139 printf("%s: not implemented\n", __func__);
140 }
141
glSetFenceNV(GLuint,GLenum)142 static void glSetFenceNV(GLuint, GLenum) {
143 printf("%s: not implemented\n", __func__);
144 }
145
glStartTilingQCOM(GLuint,GLuint,GLuint,GLuint,GLbitfield)146 static void glStartTilingQCOM(GLuint, GLuint, GLuint, GLuint, GLbitfield) {
147 printf("%s: not implemented\n", __func__);
148 }
149
glTestFenceNV(GLuint)150 static GLboolean glTestFenceNV(GLuint) {
151 printf("%s: not implemented\n", __func__);
152 return GL_FALSE;
153 }
154
155 // Stubs (ES 3.1)
156
glBeginPerfMonitorAMD(GLuint)157 static void glBeginPerfMonitorAMD(GLuint) {
158 printf("%s: not implemented\n", __func__);
159 }
160
glCoverageMaskNV(GLboolean)161 static void glCoverageMaskNV(GLboolean) {
162 printf("%s: not implemented\n", __func__);
163 }
164
glCoverageOperationNV(GLenum)165 static void glCoverageOperationNV(GLenum) {
166 printf("%s: not implemented\n", __func__);
167 }
168
glDeletePerfMonitorsAMD(GLsizei,GLuint *)169 static void glDeletePerfMonitorsAMD(GLsizei, GLuint*) {
170 printf("%s: not implemented\n", __func__);
171 }
172
glEndPerfMonitorAMD(GLuint)173 static void glEndPerfMonitorAMD(GLuint) {
174 printf("%s: not implemented\n", __func__);
175 }
176
glGenPerfMonitorsAMD(GLsizei,GLuint *)177 static void glGenPerfMonitorsAMD(GLsizei, GLuint*) {
178 printf("%s: not implemented\n", __func__);
179 }
180
glGetPerfMonitorCounterDataAMD(GLuint,GLenum,GLsizei,GLuint *,GLint *)181 static void glGetPerfMonitorCounterDataAMD(GLuint, GLenum, GLsizei, GLuint*, GLint*) {
182 printf("%s: not implemented\n", __func__);
183 }
184
glGetPerfMonitorCounterInfoAMD(GLuint,GLuint,GLenum,GLvoid *)185 static void glGetPerfMonitorCounterInfoAMD(GLuint, GLuint, GLenum, GLvoid*) {
186 printf("%s: not implemented\n", __func__);
187 }
188
glGetPerfMonitorCountersAMD(GLuint,GLint *,GLint *,GLsizei,GLuint *)189 static void glGetPerfMonitorCountersAMD(GLuint, GLint*, GLint*, GLsizei, GLuint*) {
190 printf("%s: not implemented\n", __func__);
191 }
192
glGetPerfMonitorCounterStringAMD(GLuint,GLuint,GLsizei,GLsizei *,GLchar *)193 static void glGetPerfMonitorCounterStringAMD(GLuint, GLuint, GLsizei, GLsizei*, GLchar*) {
194 printf("%s: not implemented\n", __func__);
195 }
196
glGetPerfMonitorGroupsAMD(GLint *,GLsizei,GLuint *)197 static void glGetPerfMonitorGroupsAMD(GLint*, GLsizei, GLuint*) {
198 printf("%s: not implemented\n", __func__);
199 }
200
glGetPerfMonitorGroupStringAMD(GLuint,GLsizei,GLsizei *,GLchar *)201 static void glGetPerfMonitorGroupStringAMD(GLuint, GLsizei, GLsizei*, GLchar*) {
202 printf("%s: not implemented\n", __func__);
203 }
204
glSelectPerfMonitorCountersAMD(GLuint,GLboolean,GLuint,GLint,GLuint *)205 static void glSelectPerfMonitorCountersAMD(GLuint, GLboolean, GLuint, GLint, GLuint*) {
206 printf("%s: not implemented\n", __func__);
207 }
208
209 // Non-stubs (common)
210
glDrawElementsData(GLenum mode,GLsizei count,GLenum type,void * indices,GLuint)211 static void glDrawElementsData(GLenum mode, GLsizei count, GLenum type, void* indices, GLuint) {
212 s_gles3.glDrawElements(mode, count, type, indices);
213 }
214
glDrawElementsOffset(GLenum mode,GLsizei count,GLenum type,GLuint offset)215 static void glDrawElementsOffset(GLenum mode, GLsizei count, GLenum type, GLuint offset) {
216 s_gles3.glDrawElements(mode, count, type, reinterpret_cast<const GLvoid*>(offset));
217 }
218
glFinishRoundTrip()219 static GLint glFinishRoundTrip() {
220 s_gles3.glFinish();
221 return 0;
222 }
223
glGetCompressedTextureFormats(int count,GLint * formats)224 static void glGetCompressedTextureFormats(int count, GLint* formats) {
225 int nFormats;
226 s_gles3.glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &nFormats);
227 if (nFormats <= count)
228 s_gles3.glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats);
229 }
230
231 // Non-stubs (ES 3.1)
232
233 struct GlSync {
GlSyncGlSync234 GlSync(GLESv3* ctx_, GLsync sync_) : sync(sync_), id(ctx_->sync_nextId++), ctx(ctx_) {
235 ctx->sync_map.emplace(id, this);
236 }
237
~GlSyncGlSync238 ~GlSync() {
239 ctx->sync_map.erase(id);
240 }
241
242 GLsync sync;
243 uint64_t id;
244
245 private:
246 GLESv3* ctx;
247 };
248
glClientWaitSyncAEMU(void * ctx_,uint64_t wait_on,GLbitfield flags,GLuint64 timeout)249 static GLenum glClientWaitSyncAEMU(void* ctx_, uint64_t wait_on, GLbitfield flags,
250 GLuint64 timeout) {
251 GLESv3* ctx = static_cast<GLESv3*>(ctx_);
252
253 std::map<uint64_t, GlSync*>::iterator it;
254 it = ctx->sync_map.find(wait_on);
255 if (it == ctx->sync_map.end())
256 return GL_INVALID_VALUE;
257
258 GlSync* sync = it->second;
259 return s_gles3.glClientWaitSync(sync->sync, flags, timeout);
260 }
261
glCompressedTexImage2DOffsetAEMU(GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,GLuint offset)262 static void glCompressedTexImage2DOffsetAEMU(GLenum target, GLint level, GLenum internalformat,
263 GLsizei width, GLsizei height, GLint border,
264 GLsizei imageSize, GLuint offset) {
265 s_gles3.glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize,
266 reinterpret_cast<const GLvoid*>(offset));
267 }
268
glCompressedTexImage3DOffsetAEMU(GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei imageSize,GLuint offset)269 static void glCompressedTexImage3DOffsetAEMU(GLenum target, GLint level, GLenum internalformat,
270 GLsizei width, GLsizei height, GLsizei depth,
271 GLint border, GLsizei imageSize, GLuint offset) {
272 s_gles3.glCompressedTexImage3D(target, level, internalformat, width, height, depth, border,
273 imageSize, reinterpret_cast<const GLvoid*>(offset));
274 }
275
glCompressedTexSubImage2DOffsetAEMU(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,GLuint offset)276 static void glCompressedTexSubImage2DOffsetAEMU(GLenum target, GLint level, GLint xoffset,
277 GLint yoffset, GLsizei width, GLsizei height,
278 GLenum format, GLsizei imageSize, GLuint offset) {
279 s_gles3.glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format,
280 imageSize, reinterpret_cast<const GLvoid*>(offset));
281 }
282
glCompressedTexSubImage3DOffsetAEMU(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei imageSize,GLuint offset)283 static void glCompressedTexSubImage3DOffsetAEMU(GLenum target, GLint level, GLint xoffset,
284 GLint yoffset, GLint zoffset, GLsizei width,
285 GLsizei height, GLsizei depth, GLenum format,
286 GLsizei imageSize, GLuint offset) {
287 s_gles3.glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth,
288 format, imageSize, reinterpret_cast<const GLvoid*>(offset));
289 }
290
glCreateShaderProgramvAEMU(GLenum type,GLsizei,const char * packedStrings,GLuint)291 static GLuint glCreateShaderProgramvAEMU(GLenum type, GLsizei, const char* packedStrings, GLuint) {
292 return s_gles3.glCreateShaderProgramv(type, 1, &packedStrings);
293 }
294
glDeleteSyncAEMU(void * ctx_,uint64_t to_delete)295 static void glDeleteSyncAEMU(void* ctx_, uint64_t to_delete) {
296 GLESv3* ctx = static_cast<GLESv3*>(ctx_);
297
298 std::map<uint64_t, GlSync*>::iterator it;
299 it = ctx->sync_map.find(to_delete);
300 if (it == ctx->sync_map.end())
301 return;
302
303 GlSync* sync = it->second;
304 s_gles3.glDeleteSync(sync->sync);
305 delete sync;
306 }
307
glDrawArraysIndirectDataAEMU(GLenum mode,const void * indirect,GLuint)308 static void glDrawArraysIndirectDataAEMU(GLenum mode, const void* indirect, GLuint) {
309 s_gles3.glDrawArraysIndirect(mode, indirect);
310 }
311
glDrawArraysIndirectOffsetAEMU(GLenum mode,GLuint offset)312 static void glDrawArraysIndirectOffsetAEMU(GLenum mode, GLuint offset) {
313 s_gles3.glDrawArraysIndirect(mode, reinterpret_cast<const void*>(offset));
314 }
315
glDrawElementsIndirectDataAEMU(GLenum mode,GLenum type,const void * indirect,GLuint)316 static void glDrawElementsIndirectDataAEMU(GLenum mode, GLenum type, const void* indirect, GLuint) {
317 s_gles3.glDrawElementsIndirect(mode, type, indirect);
318 }
319
glDrawElementsIndirectOffsetAEMU(GLenum mode,GLenum type,GLuint offset)320 static void glDrawElementsIndirectOffsetAEMU(GLenum mode, GLenum type, GLuint offset) {
321 s_gles3.glDrawElementsIndirect(mode, type, reinterpret_cast<const void*>(offset));
322 }
323
glDrawElementsInstancedDataAEMU(GLenum mode,GLsizei count,GLenum type,const void * indices,GLsizei primcount,GLsizei)324 static void glDrawElementsInstancedDataAEMU(GLenum mode, GLsizei count, GLenum type,
325 const void* indices, GLsizei primcount, GLsizei) {
326 s_gles3.glDrawElementsInstanced(mode, count, type, indices, primcount);
327 }
328
glDrawElementsInstancedOffsetAEMU(GLenum mode,GLsizei count,GLenum type,GLuint offset,GLsizei primcount)329 static void glDrawElementsInstancedOffsetAEMU(GLenum mode, GLsizei count, GLenum type,
330 GLuint offset, GLsizei primcount) {
331 s_gles3.glDrawElementsInstanced(mode, count, type, reinterpret_cast<const void*>(offset),
332 primcount);
333 }
334
glDrawRangeElementsDataAEMU(GLenum mode,GLuint start,GLuint end,GLsizei count,GLenum type,const GLvoid * indices,GLsizei)335 static void glDrawRangeElementsDataAEMU(GLenum mode, GLuint start, GLuint end, GLsizei count,
336 GLenum type, const GLvoid* indices, GLsizei) {
337 s_gles3.glDrawRangeElements(mode, start, end, count, type, indices);
338 }
339
glDrawRangeElementsOffsetAEMU(GLenum mode,GLuint start,GLuint end,GLsizei count,GLenum type,GLuint offset)340 static void glDrawRangeElementsOffsetAEMU(GLenum mode, GLuint start, GLuint end, GLsizei count,
341 GLenum type, GLuint offset) {
342 s_gles3.glDrawRangeElements(mode, start, end, count, type,
343 reinterpret_cast<const GLvoid*>(offset));
344 }
345
glFenceSyncAEMU(void * ctx_,GLenum condition,GLbitfield flags)346 static uint64_t glFenceSyncAEMU(void* ctx_, GLenum condition, GLbitfield flags) {
347 GLsync sync_ = s_gles3.glFenceSync(condition, flags);
348 if (sync_ == 0)
349 return 0U;
350
351 GLESv3* ctx = static_cast<GLESv3*>(ctx_);
352 GlSync* sync = new (std::nothrow) GlSync(ctx, sync_);
353 if (!sync) {
354 s_gles3.glDeleteSync(sync_);
355 return 0U;
356 }
357
358 return sync->id;
359 }
360
glFlushMappedBufferRangeAEMU(GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access,void * guest_buffer)361 static void glFlushMappedBufferRangeAEMU(GLenum target, GLintptr offset, GLsizeiptr length,
362 GLbitfield access, void* guest_buffer) {
363 if (guest_buffer && length) {
364 void* gpuPtr = s_gles3.glMapBufferRange(target, offset, length, access);
365 if (gpuPtr) {
366 memcpy(gpuPtr, guest_buffer, length);
367 s_gles3.glFlushMappedBufferRange(target, 0, length);
368 s_gles3.glUnmapBuffer(target);
369 }
370 }
371 }
372
glGetSyncivAEMU(void * ctx_,uint64_t sync_,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * values)373 static void glGetSyncivAEMU(void* ctx_, uint64_t sync_, GLenum pname, GLsizei bufSize,
374 GLsizei* length, GLint* values) {
375 GLESv3* ctx = static_cast<GLESv3*>(ctx_);
376
377 std::map<uint64_t, GlSync*>::iterator it;
378 it = ctx->sync_map.find(sync_);
379 if (it == ctx->sync_map.end())
380 return;
381
382 GlSync* sync = it->second;
383 s_gles3.glGetSynciv(sync->sync, pname, bufSize, length, values);
384 }
385
sUnpackVarNames(GLsizei count,const char * packedNames)386 static std::vector<std::string> sUnpackVarNames(GLsizei count, const char* packedNames) {
387 std::vector<std::string> unpacked;
388 GLsizei current = 0;
389
390 while (current < count) {
391 const char* delimPos = strstr(packedNames, ";");
392 size_t nameLen = delimPos - packedNames;
393 std::string next;
394 next.resize(nameLen);
395 memcpy(&next[0], packedNames, nameLen);
396 unpacked.push_back(next);
397 packedNames = delimPos + 1;
398 current++;
399 }
400
401 return unpacked;
402 }
403
glGetUniformIndicesAEMU(GLuint program,GLsizei uniformCount,const GLchar * packedNames,GLsizei packedLen,GLuint * uniformIndices)404 static void glGetUniformIndicesAEMU(GLuint program, GLsizei uniformCount, const GLchar* packedNames,
405 GLsizei packedLen, GLuint* uniformIndices) {
406 std::vector<std::string> unpacked = sUnpackVarNames(uniformCount, packedNames);
407 GLchar** unpackedArray = new GLchar*[unpacked.size()];
408 GLsizei i = 0;
409 for (auto& elt : unpacked) {
410 unpackedArray[i] = (GLchar*)&elt[0];
411 i++;
412 }
413
414 s_gles3.glGetUniformIndices(program, uniformCount, const_cast<const GLchar**>(unpackedArray),
415 uniformIndices);
416 delete[] unpackedArray;
417 }
418
glIsSyncAEMU(void * ctx_,uint64_t sync)419 static GLboolean glIsSyncAEMU(void* ctx_, uint64_t sync) {
420 GLESv3* ctx = static_cast<GLESv3*>(ctx_);
421 return ctx->sync_map.count(sync) ? GL_TRUE : GL_FALSE;
422 }
423
glMapBufferRangeAEMU(GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access,void * mapped)424 static void glMapBufferRangeAEMU(GLenum target, GLintptr offset, GLsizeiptr length,
425 GLbitfield access, void* mapped) {
426 if ((access & GL_MAP_READ_BIT) ||
427 ((access & GL_MAP_WRITE_BIT) &&
428 (!(access & GL_MAP_INVALIDATE_RANGE_BIT) && !(access & GL_MAP_INVALIDATE_BUFFER_BIT)))) {
429 void* gpuPtr = s_gles3.glMapBufferRange(target, offset, length, access);
430 if (gpuPtr) {
431 if (mapped)
432 memcpy(mapped, gpuPtr, length);
433 s_gles3.glUnmapBuffer(target);
434 }
435 }
436 }
437
glReadPixelsOffsetAEMU(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLuint offset)438 static void glReadPixelsOffsetAEMU(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
439 GLenum type, GLuint offset) {
440 s_gles3.glReadPixels(x, y, width, height, format, type, reinterpret_cast<GLvoid*>(offset));
441 }
442
glShaderString(GLuint shader,const GLchar * string,GLsizei)443 static void glShaderString(GLuint shader, const GLchar* string, GLsizei) {
444 s_gles3.glShaderSource(shader, 1, &string, NULL);
445 }
446
glTexImage2DOffsetAEMU(GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,GLuint offset)447 static void glTexImage2DOffsetAEMU(GLenum target, GLint level, GLint internalformat, GLsizei width,
448 GLsizei height, GLint border, GLenum format, GLenum type,
449 GLuint offset) {
450 s_gles3.glTexImage2D(target, level, internalformat, width, height, border, format, type,
451 reinterpret_cast<const GLvoid*>(offset));
452 }
453
glTexImage3DOffsetAEMU(GLenum target,GLint level,GLint internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,GLuint offset)454 static void glTexImage3DOffsetAEMU(GLenum target, GLint level, GLint internalFormat, GLsizei width,
455 GLsizei height, GLsizei depth, GLint border, GLenum format,
456 GLenum type, GLuint offset) {
457 s_gles3.glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type,
458 reinterpret_cast<const GLvoid*>(offset));
459 }
460
glTexSubImage2DOffsetAEMU(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,GLuint offset)461 static void glTexSubImage2DOffsetAEMU(GLenum target, GLint level, GLint xoffset, GLint yoffset,
462 GLsizei width, GLsizei height, GLenum format, GLenum type,
463 GLuint offset) {
464 s_gles3.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type,
465 reinterpret_cast<const GLvoid*>(offset));
466 }
467
glTexSubImage3DOffsetAEMU(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,GLuint offset)468 static void glTexSubImage3DOffsetAEMU(GLenum target, GLint level, GLint xoffset, GLint yoffset,
469 GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
470 GLenum format, GLenum type, GLuint offset) {
471 s_gles3.glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format,
472 type, reinterpret_cast<const GLvoid*>(offset));
473 }
474
glTransformFeedbackVaryingsAEMU(GLuint program,GLsizei count,const char * packedVaryings,GLuint packedVaryingsLen,GLenum bufferMode)475 static void glTransformFeedbackVaryingsAEMU(GLuint program, GLsizei count,
476 const char* packedVaryings, GLuint packedVaryingsLen,
477 GLenum bufferMode) {
478 std::vector<std::string> unpacked = sUnpackVarNames(count, packedVaryings);
479 char** unpackedArray = new char*[unpacked.size()];
480 GLsizei i = 0;
481 for (auto& elt : unpacked) {
482 unpackedArray[i] = &elt[0];
483 i++;
484 }
485
486 s_gles3.glTransformFeedbackVaryings(program, count, const_cast<const char**>(unpackedArray),
487 bufferMode);
488 delete[] unpackedArray;
489 }
490
glUnmapBufferAEMU(GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access,void * guest_buffer,GLboolean * out_res)491 static void glUnmapBufferAEMU(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access,
492 void* guest_buffer, GLboolean* out_res) {
493 *out_res = GL_TRUE;
494
495 if (access & GL_MAP_WRITE_BIT) {
496 if (guest_buffer) {
497 void* gpuPtr = s_gles3.glMapBufferRange(target, offset, length, access);
498 if (gpuPtr)
499 memcpy(gpuPtr, guest_buffer, length);
500 }
501
502 *out_res = s_gles3.glUnmapBuffer(target);
503 }
504 }
505
glVertexAttribIPointerDataAEMU(GLuint index,GLint size,GLenum type,GLsizei,void * data,GLuint)506 static void glVertexAttribIPointerDataAEMU(GLuint index, GLint size, GLenum type, GLsizei,
507 void* data, GLuint) {
508 s_gles3.glVertexAttribIPointer(index, size, type, 0, data);
509 }
510
glVertexAttribIPointerOffsetAEMU(GLuint index,GLint size,GLenum type,GLsizei,GLuint offset)511 static void glVertexAttribIPointerOffsetAEMU(GLuint index, GLint size, GLenum type, GLsizei,
512 GLuint offset) {
513 s_gles3.glVertexAttribIPointer(index, size, type, 0, reinterpret_cast<const GLvoid*>(offset));
514 }
515
glVertexAttribPointerData(GLuint indx,GLint size,GLenum type,GLboolean normalized,GLsizei,void * data,GLuint)516 static void glVertexAttribPointerData(GLuint indx, GLint size, GLenum type, GLboolean normalized,
517 GLsizei, void* data, GLuint) {
518 s_gles3.glVertexAttribPointer(indx, size, type, normalized, 0, data);
519 }
520
glVertexAttribPointerOffset(GLuint indx,GLint size,GLenum type,GLboolean normalized,GLsizei,GLuint offset)521 static void glVertexAttribPointerOffset(GLuint indx, GLint size, GLenum type, GLboolean normalized,
522 GLsizei, GLuint offset) {
523 s_gles3.glVertexAttribPointer(indx, size, type, normalized, 0,
524 reinterpret_cast<const GLvoid*>(offset));
525 }
526
glWaitSyncAEMU(void * ctx_,uint64_t wait_on,GLbitfield flags,GLuint64 timeout)527 static void glWaitSyncAEMU(void* ctx_, uint64_t wait_on, GLbitfield flags, GLuint64 timeout) {
528 GLESv3* ctx = static_cast<GLESv3*>(ctx_);
529
530 std::map<uint64_t, GlSync*>::iterator it;
531 it = ctx->sync_map.find(wait_on);
532 if (it == ctx->sync_map.end())
533 return;
534
535 GlSync* sync = it->second;
536 s_gles3.glWaitSync(sync->sync, flags, timeout);
537 }
538
539 #define KNIT(return_type, function_name, signature, callargs) function_name = s_gles3.function_name;
540
GLESv3()541 GLESv3::GLESv3() {
542 LIST_GLES3_FUNCTIONS(KNIT, KNIT)
543
544 // Remap some ES 2.0 extensions that become core in ES 3.1
545 glBindVertexArrayOES = glBindVertexArray;
546 glDeleteVertexArraysOES = glDeleteVertexArrays;
547 glGenVertexArraysOES = glGenVertexArrays;
548 glGetProgramBinaryOES = glGetProgramBinary;
549 glIsVertexArrayOES = glIsVertexArray;
550 glProgramBinaryOES = glProgramBinary;
551 glUnmapBufferOES = glUnmapBuffer;
552
553 // Entrypoints requiring custom wrappers (common)
554 glDrawElementsData = ::glDrawElementsData;
555 glDrawElementsOffset = ::glDrawElementsOffset;
556 glFinishRoundTrip = ::glFinishRoundTrip;
557 glGetCompressedTextureFormats = ::glGetCompressedTextureFormats;
558
559 // Entrypoints requiring custom wrappers (ES 3.1)
560 glClientWaitSyncAEMU = ::glClientWaitSyncAEMU;
561 glCompressedTexImage2DOffsetAEMU = ::glCompressedTexImage2DOffsetAEMU;
562 glCompressedTexImage3DOffsetAEMU = ::glCompressedTexImage3DOffsetAEMU;
563 glCompressedTexSubImage2DOffsetAEMU = ::glCompressedTexSubImage2DOffsetAEMU;
564 glCompressedTexSubImage3DOffsetAEMU = ::glCompressedTexSubImage3DOffsetAEMU;
565 glCreateShaderProgramvAEMU = ::glCreateShaderProgramvAEMU;
566 glDeleteSyncAEMU = ::glDeleteSyncAEMU;
567 glDrawArraysIndirectDataAEMU = ::glDrawArraysIndirectDataAEMU;
568 glDrawArraysIndirectOffsetAEMU = ::glDrawArraysIndirectOffsetAEMU;
569 glDrawElementsIndirectDataAEMU = ::glDrawElementsIndirectDataAEMU;
570 glDrawElementsIndirectOffsetAEMU = ::glDrawElementsIndirectOffsetAEMU;
571 glDrawElementsInstancedDataAEMU = ::glDrawElementsInstancedDataAEMU;
572 glDrawElementsInstancedOffsetAEMU = ::glDrawElementsInstancedOffsetAEMU;
573 glDrawRangeElementsDataAEMU = ::glDrawRangeElementsDataAEMU;
574 glDrawRangeElementsOffsetAEMU = ::glDrawRangeElementsOffsetAEMU;
575 glFenceSyncAEMU = ::glFenceSyncAEMU;
576 glFlushMappedBufferRangeAEMU = ::glFlushMappedBufferRangeAEMU;
577 glGetSyncivAEMU = ::glGetSyncivAEMU;
578 glGetUniformIndicesAEMU = ::glGetUniformIndicesAEMU;
579 glIsSyncAEMU = ::glIsSyncAEMU;
580 glMapBufferRangeAEMU = ::glMapBufferRangeAEMU;
581 glReadPixelsOffsetAEMU = ::glReadPixelsOffsetAEMU;
582 glShaderString = ::glShaderString;
583 glTexImage2DOffsetAEMU = ::glTexImage2DOffsetAEMU;
584 glTexImage3DOffsetAEMU = ::glTexImage3DOffsetAEMU;
585 glTexSubImage2DOffsetAEMU = ::glTexSubImage2DOffsetAEMU;
586 glTexSubImage3DOffsetAEMU = ::glTexSubImage3DOffsetAEMU;
587 glTransformFeedbackVaryingsAEMU = ::glTransformFeedbackVaryingsAEMU;
588 glUnmapBufferAEMU = ::glUnmapBufferAEMU;
589 glVertexAttribIPointerDataAEMU = ::glVertexAttribIPointerDataAEMU;
590 glVertexAttribIPointerOffsetAEMU = ::glVertexAttribIPointerOffsetAEMU;
591 glVertexAttribPointerData = ::glVertexAttribPointerData;
592 glVertexAttribPointerOffset = ::glVertexAttribPointerOffset;
593 glWaitSyncAEMU = ::glWaitSyncAEMU;
594
595 // Stub some extensions we will never implement (common)
596 glDeleteFencesNV = ::glDeleteFencesNV;
597 glDisableDriverControlQCOM = ::glDisableDriverControlQCOM;
598 glDiscardFramebufferEXT = ::glDiscardFramebufferEXT;
599 glEnableDriverControlQCOM = ::glEnableDriverControlQCOM;
600 glEndTilingQCOM = ::glEndTilingQCOM;
601 glExtGetBufferPointervQCOM = ::glExtGetBufferPointervQCOM;
602 glExtGetBuffersQCOM = ::glExtGetBuffersQCOM;
603 glExtGetFramebuffersQCOM = ::glExtGetFramebuffersQCOM;
604 glExtGetProgramBinarySourceQCOM = ::glExtGetProgramBinarySourceQCOM;
605 glExtGetProgramsQCOM = ::glExtGetProgramsQCOM;
606 glExtGetRenderbuffersQCOM = ::glExtGetRenderbuffersQCOM;
607 glExtGetShadersQCOM = ::glExtGetShadersQCOM;
608 glExtGetTexLevelParameterivQCOM = ::glExtGetTexLevelParameterivQCOM;
609 glExtGetTexSubImageQCOM = ::glExtGetTexSubImageQCOM;
610 glExtGetTexturesQCOM = ::glExtGetTexturesQCOM;
611 glExtIsProgramBinaryQCOM = ::glExtIsProgramBinaryQCOM;
612 glExtTexObjectStateOverrideiQCOM = ::glExtTexObjectStateOverrideiQCOM;
613 glFinishFenceNV = ::glFinishFenceNV;
614 glFramebufferTexture2DMultisampleIMG = ::glFramebufferTexture2DMultisampleIMG;
615 glGenFencesNV = ::glGenFencesNV;
616 glGetDriverControlsQCOM = ::glGetDriverControlsQCOM;
617 glGetDriverControlStringQCOM = ::glGetDriverControlStringQCOM;
618 glGetFenceivNV = ::glGetFenceivNV;
619 glIsFenceNV = ::glIsFenceNV;
620 glMapBufferOES = ::glMapBufferOES;
621 glMultiDrawArraysEXT = ::glMultiDrawArraysEXT;
622 glMultiDrawElementsEXT = ::glMultiDrawElementsEXT;
623 glRenderbufferStorageMultisampleIMG = ::glRenderbufferStorageMultisampleIMG;
624 glSetFenceNV = ::glSetFenceNV;
625 glStartTilingQCOM = ::glStartTilingQCOM;
626 glTestFenceNV = ::glTestFenceNV;
627
628 // Stub some extensions we will never implement (ES 3.1)
629 glBeginPerfMonitorAMD = ::glBeginPerfMonitorAMD;
630 glCoverageMaskNV = ::glCoverageMaskNV;
631 glCoverageOperationNV = ::glCoverageOperationNV;
632 glDeletePerfMonitorsAMD = ::glDeletePerfMonitorsAMD;
633 glEndPerfMonitorAMD = ::glEndPerfMonitorAMD;
634 glGenPerfMonitorsAMD = ::glGenPerfMonitorsAMD;
635 glGetPerfMonitorCounterDataAMD = ::glGetPerfMonitorCounterDataAMD;
636 glGetPerfMonitorCounterInfoAMD = ::glGetPerfMonitorCounterInfoAMD;
637 glGetPerfMonitorCountersAMD = ::glGetPerfMonitorCountersAMD;
638 glGetPerfMonitorCounterStringAMD = ::glGetPerfMonitorCounterStringAMD;
639 glGetPerfMonitorGroupsAMD = ::glGetPerfMonitorGroupsAMD;
640 glGetPerfMonitorGroupStringAMD = ::glGetPerfMonitorGroupStringAMD;
641 glSelectPerfMonitorCountersAMD = ::glSelectPerfMonitorCountersAMD;
642 }
643