| /* |
| * Copyright 2011 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "GLESv2Decoder.h" |
| #include "OpenGLESDispatch/GLESv2Dispatch.h" |
| |
| #include "aemu/base/synchronization/Lock.h" |
| |
| #include "host-common/emugl_vm_operations.h" |
| #include "host-common/vm_operations.h" |
| #include "host-common/dma_device.h" |
| |
| #include <EGL/egl.h> |
| #include <GLES2/gl2.h> |
| #include <GLES2/gl2ext.h> |
| #include <GLES3/gl3.h> |
| #include <GLES3/gl31.h> |
| |
| #include <string> |
| #include <vector> |
| |
| #include <string.h> |
| |
| namespace gfxstream { |
| namespace gl { |
| |
| using android::base::AutoLock; |
| using android::base::StaticLock; |
| |
| static inline void* SafePointerFromUInt(GLuint value) { |
| return (void*)(uintptr_t)value; |
| } |
| |
| int gles2_decoder_extended_context::initDispatch( |
| GLESv2Decoder::get_proc_func_t getProc, void *userData) { |
| gles2_server_context_t::initDispatchByName(getProc, userData); |
| glVertexAttribPointerWithDataSize = |
| (glVertexAttribPointerWithDataSize_server_proc_t) |
| getProc("glVertexAttribPointerWithDataSize", userData); |
| glVertexAttribIPointerWithDataSize = |
| (glVertexAttribIPointerWithDataSize_server_proc_t) |
| getProc("glVertexAttribIPointerWithDataSize", userData); |
| return 0; |
| } |
| |
| static StaticLock sLock; |
| static GLESv2Decoder::get_proc_func_t sGetProcFunc; |
| static void* sGetProcFuncData; |
| |
| namespace { |
| |
| struct ContextTemplateLoader { |
| ContextTemplateLoader() { |
| context.initDispatch(sGetProcFunc, sGetProcFuncData); |
| } |
| gles2_decoder_extended_context context; |
| }; |
| |
| } // namespace |
| |
| static ContextTemplateLoader* sContextTemplate() { |
| static ContextTemplateLoader* c = new ContextTemplateLoader; |
| return c; |
| } |
| |
| GLESv2Decoder::GLESv2Decoder() |
| { |
| m_contextData = NULL; |
| m_GL2library = NULL; |
| m_snapshot = NULL; |
| } |
| |
| GLESv2Decoder::~GLESv2Decoder() |
| { |
| } |
| |
| void *GLESv2Decoder::s_getProc(const char *name, void *userData) |
| { |
| GLESv2Decoder *ctx = (GLESv2Decoder *) userData; |
| |
| if (ctx == NULL || ctx->m_GL2library == NULL) { |
| return NULL; |
| } |
| |
| void *func = NULL; |
| #ifdef USE_EGL_GETPROCADDRESS |
| func = (void *) eglGetProcAddress(name); |
| #endif |
| if (func == NULL) { |
| func = (void *) ctx->m_GL2library->findSymbol(name); |
| } |
| return func; |
| } |
| |
| #define OVERRIDE_DEC(func) func##_dec = s_##func; |
| |
| int GLESv2Decoder::initGL(get_proc_func_t getProcFunc, void *getProcFuncData) |
| { |
| AutoLock lock(sLock); |
| sGetProcFunc = getProcFunc; |
| sGetProcFuncData = getProcFuncData; |
| static_cast<gles2_decoder_extended_context&>(*this) = sContextTemplate()->context; |
| |
| glGetCompressedTextureFormats = s_glGetCompressedTextureFormats; |
| glVertexAttribPointerData = s_glVertexAttribPointerData; |
| glVertexAttribPointerOffset = s_glVertexAttribPointerOffset; |
| glShaderString = s_glShaderString; |
| |
| glDrawElementsOffset = s_glDrawElementsOffset; |
| glDrawElementsData = s_glDrawElementsData; |
| glDrawElementsOffsetNullAEMU = s_glDrawElementsOffsetNullAEMU; |
| glDrawElementsDataNullAEMU = s_glDrawElementsDataNullAEMU; |
| glFinishRoundTrip = s_glFinishRoundTrip; |
| glMapBufferRangeAEMU = s_glMapBufferRangeAEMU; |
| glUnmapBufferAEMU = s_glUnmapBufferAEMU; |
| glMapBufferRangeDMA = s_glMapBufferRangeDMA; |
| glUnmapBufferDMA = s_glUnmapBufferDMA; |
| glFlushMappedBufferRangeAEMU = s_glFlushMappedBufferRangeAEMU; |
| glMapBufferRangeDirect = s_glMapBufferRangeDirect; |
| glUnmapBufferDirect = s_glUnmapBufferDirect; |
| glFlushMappedBufferRangeDirect = s_glFlushMappedBufferRangeDirect; |
| glCompressedTexImage2DOffsetAEMU = s_glCompressedTexImage2DOffsetAEMU; |
| glCompressedTexSubImage2DOffsetAEMU = s_glCompressedTexSubImage2DOffsetAEMU; |
| glTexImage2DOffsetAEMU = s_glTexImage2DOffsetAEMU; |
| glTexSubImage2DOffsetAEMU = s_glTexSubImage2DOffsetAEMU; |
| glGetUniformIndicesAEMU = s_glGetUniformIndicesAEMU; |
| glVertexAttribIPointerDataAEMU = s_glVertexAttribIPointerDataAEMU; |
| glVertexAttribIPointerOffsetAEMU = s_glVertexAttribIPointerOffsetAEMU; |
| glTransformFeedbackVaryingsAEMU = s_glTransformFeedbackVaryingsAEMU; |
| glTexImage3DOffsetAEMU = s_glTexImage3DOffsetAEMU; |
| glTexSubImage3DOffsetAEMU = s_glTexSubImage3DOffsetAEMU; |
| glCompressedTexImage3DOffsetAEMU = s_glCompressedTexImage3DOffsetAEMU; |
| glCompressedTexSubImage3DOffsetAEMU = s_glCompressedTexSubImage3DOffsetAEMU; |
| glDrawElementsInstancedOffsetAEMU = s_glDrawElementsInstancedOffsetAEMU; |
| glDrawElementsInstancedDataAEMU = s_glDrawElementsInstancedDataAEMU; |
| glReadPixelsOffsetAEMU = s_glReadPixelsOffsetAEMU; |
| |
| glCreateShaderProgramvAEMU = s_glCreateShaderProgramvAEMU; |
| |
| glDrawArraysIndirectDataAEMU = s_glDrawArraysIndirectDataAEMU; |
| glDrawArraysIndirectOffsetAEMU = s_glDrawArraysIndirectOffsetAEMU; |
| |
| glDrawElementsIndirectDataAEMU = s_glDrawElementsIndirectDataAEMU; |
| glDrawElementsIndirectOffsetAEMU = s_glDrawElementsIndirectOffsetAEMU; |
| |
| glFenceSyncAEMU = s_glFenceSyncAEMU; |
| glClientWaitSyncAEMU = s_glClientWaitSyncAEMU; |
| glWaitSyncAEMU = s_glWaitSyncAEMU; |
| glIsSyncAEMU = s_glIsSyncAEMU; |
| glGetSyncivAEMU = s_glGetSyncivAEMU; |
| glDeleteSyncAEMU = s_glDeleteSyncAEMU; |
| |
| glBufferDataSyncAEMU = s_glBufferDataSyncAEMU; |
| |
| OVERRIDE_DEC(glCreateShader) |
| OVERRIDE_DEC(glCreateProgram) |
| |
| OVERRIDE_DEC(glGenBuffers) |
| |
| OVERRIDE_DEC(glGenFramebuffers) |
| OVERRIDE_DEC(glGenRenderbuffers) |
| OVERRIDE_DEC(glGenTextures) |
| |
| OVERRIDE_DEC(glGenVertexArraysOES) |
| OVERRIDE_DEC(glGenVertexArrays) |
| |
| OVERRIDE_DEC(glGenTransformFeedbacks) |
| OVERRIDE_DEC(glGenSamplers) |
| OVERRIDE_DEC(glGenQueries) |
| OVERRIDE_DEC(glGenProgramPipelines) |
| |
| OVERRIDE_DEC(glDeleteShader) |
| OVERRIDE_DEC(glDeleteProgram) |
| |
| OVERRIDE_DEC(glDeleteBuffers) |
| OVERRIDE_DEC(glDeleteFramebuffers) |
| OVERRIDE_DEC(glDeleteRenderbuffers) |
| OVERRIDE_DEC(glDeleteTextures) |
| |
| OVERRIDE_DEC(glDeleteVertexArraysOES) |
| OVERRIDE_DEC(glDeleteVertexArrays) |
| |
| OVERRIDE_DEC(glDeleteTransformFeedbacks) |
| OVERRIDE_DEC(glDeleteSamplers) |
| OVERRIDE_DEC(glDeleteQueries) |
| OVERRIDE_DEC(glDeleteProgramPipelines) |
| |
| // Shaders and programs |
| OVERRIDE_DEC(glCompileShader) |
| OVERRIDE_DEC(glAttachShader) |
| OVERRIDE_DEC(glDetachShader) |
| OVERRIDE_DEC(glLinkProgram) |
| OVERRIDE_DEC(glUseProgram) |
| OVERRIDE_DEC(glValidateProgram) |
| OVERRIDE_DEC(glIsShader) |
| OVERRIDE_DEC(glIsProgram) |
| OVERRIDE_DEC(glGetShaderiv) |
| OVERRIDE_DEC(glGetProgramiv) |
| OVERRIDE_DEC(glGetShaderInfoLog) |
| OVERRIDE_DEC(glGetProgramInfoLog) |
| OVERRIDE_DEC(glGetShaderSource) |
| OVERRIDE_DEC(glBindAttribLocation) |
| OVERRIDE_DEC(glGetActiveAttrib) |
| OVERRIDE_DEC(glGetActiveUniform) |
| OVERRIDE_DEC(glGetAttachedShaders) |
| OVERRIDE_DEC(glGetAttribLocation) |
| OVERRIDE_DEC(glGetUniformfv) |
| OVERRIDE_DEC(glGetUniformiv) |
| OVERRIDE_DEC(glGetUniformLocation) |
| OVERRIDE_DEC(glGetProgramBinaryOES) |
| OVERRIDE_DEC(glProgramBinaryOES) |
| OVERRIDE_DEC(glUniformBlockBinding) |
| OVERRIDE_DEC(glGetUniformBlockIndex) |
| OVERRIDE_DEC(glGetActiveUniformBlockiv) |
| OVERRIDE_DEC(glGetActiveUniformBlockName) |
| OVERRIDE_DEC(glGetUniformuiv) |
| OVERRIDE_DEC(glGetActiveUniformsiv) |
| OVERRIDE_DEC(glTransformFeedbackVaryings) |
| OVERRIDE_DEC(glGetTransformFeedbackVarying) |
| OVERRIDE_DEC(glProgramParameteri) |
| OVERRIDE_DEC(glProgramBinary) |
| OVERRIDE_DEC(glGetProgramBinary) |
| OVERRIDE_DEC(glGetFragDataLocation) |
| OVERRIDE_DEC(glUseProgramStages) |
| OVERRIDE_DEC(glActiveShaderProgram) |
| OVERRIDE_DEC(glProgramUniform1f) |
| OVERRIDE_DEC(glProgramUniform2f) |
| OVERRIDE_DEC(glProgramUniform3f) |
| OVERRIDE_DEC(glProgramUniform4f) |
| OVERRIDE_DEC(glProgramUniform1i) |
| OVERRIDE_DEC(glProgramUniform2i) |
| OVERRIDE_DEC(glProgramUniform3i) |
| OVERRIDE_DEC(glProgramUniform4i) |
| OVERRIDE_DEC(glProgramUniform1ui) |
| OVERRIDE_DEC(glProgramUniform2ui) |
| OVERRIDE_DEC(glProgramUniform3ui) |
| OVERRIDE_DEC(glProgramUniform4ui) |
| OVERRIDE_DEC(glProgramUniform1fv) |
| OVERRIDE_DEC(glProgramUniform2fv) |
| OVERRIDE_DEC(glProgramUniform3fv) |
| OVERRIDE_DEC(glProgramUniform4fv) |
| OVERRIDE_DEC(glProgramUniform1iv) |
| OVERRIDE_DEC(glProgramUniform2iv) |
| OVERRIDE_DEC(glProgramUniform3iv) |
| OVERRIDE_DEC(glProgramUniform4iv) |
| OVERRIDE_DEC(glProgramUniform1uiv) |
| OVERRIDE_DEC(glProgramUniform2uiv) |
| OVERRIDE_DEC(glProgramUniform3uiv) |
| OVERRIDE_DEC(glProgramUniform4uiv) |
| OVERRIDE_DEC(glProgramUniformMatrix2fv) |
| OVERRIDE_DEC(glProgramUniformMatrix3fv) |
| OVERRIDE_DEC(glProgramUniformMatrix4fv) |
| OVERRIDE_DEC(glProgramUniformMatrix2x3fv) |
| OVERRIDE_DEC(glProgramUniformMatrix3x2fv) |
| OVERRIDE_DEC(glProgramUniformMatrix2x4fv) |
| OVERRIDE_DEC(glProgramUniformMatrix4x2fv) |
| OVERRIDE_DEC(glProgramUniformMatrix3x4fv) |
| OVERRIDE_DEC(glProgramUniformMatrix4x3fv) |
| OVERRIDE_DEC(glGetProgramInterfaceiv) |
| OVERRIDE_DEC(glGetProgramResourceiv) |
| OVERRIDE_DEC(glGetProgramResourceIndex) |
| OVERRIDE_DEC(glGetProgramResourceLocation) |
| OVERRIDE_DEC(glGetProgramResourceName) |
| OVERRIDE_DEC(glTexBufferOES) |
| OVERRIDE_DEC(glTexBufferRangeOES) |
| OVERRIDE_DEC(glTexBufferEXT) |
| OVERRIDE_DEC(glTexBufferRangeEXT) |
| OVERRIDE_DEC(glEnableiEXT); |
| OVERRIDE_DEC(glDisableiEXT); |
| OVERRIDE_DEC(glBlendEquationiEXT); |
| OVERRIDE_DEC(glBlendEquationSeparateiEXT); |
| OVERRIDE_DEC(glBlendFunciEXT); |
| OVERRIDE_DEC(glBlendFuncSeparateiEXT); |
| OVERRIDE_DEC(glColorMaskiEXT); |
| OVERRIDE_DEC(glIsEnablediEXT); |
| |
| return 0; |
| |
| } |
| |
| int GLESv2Decoder::s_glFinishRoundTrip(void *self) |
| { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glFinish(); |
| return 0; |
| } |
| |
| void GLESv2Decoder::s_glGetCompressedTextureFormats(void *self, int count, GLint *formats) |
| { |
| GLESv2Decoder *ctx = (GLESv2Decoder *) self; |
| |
| int nFormats; |
| ctx->glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &nFormats); |
| if (nFormats > count) { |
| fprintf(stderr, "%s: GetCompressedTextureFormats: The requested number of formats does not match the number that is reported by OpenGL\n", __FUNCTION__); |
| } else { |
| ctx->glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats); |
| } |
| } |
| |
| void GLESv2Decoder::s_glVertexAttribPointerData(void *self, GLuint indx, GLint size, GLenum type, |
| GLboolean normalized, GLsizei stride, void * data, GLuint datalen) |
| { |
| GLESv2Decoder *ctx = (GLESv2Decoder *) self; |
| if (ctx->m_contextData != NULL) { |
| ctx->m_contextData->storePointerData(indx, data, datalen); |
| // note - the stride of the data is always zero when it comes out of the codec. |
| // See gl2.attrib for the packing function call. |
| if ((void*)ctx->glVertexAttribPointerWithDataSize != gles2_unimplemented) { |
| ctx->glVertexAttribPointerWithDataSize(indx, size, type, normalized, |
| 0, ctx->m_contextData->pointerData(indx), datalen); |
| } else { |
| ctx->glVertexAttribPointer(indx, size, type, normalized, 0, |
| ctx->m_contextData->pointerData(indx)); |
| } |
| } |
| } |
| |
| void GLESv2Decoder::s_glVertexAttribPointerOffset(void *self, GLuint indx, GLint size, GLenum type, |
| GLboolean normalized, GLsizei stride, GLuint data) |
| { |
| GLESv2Decoder *ctx = (GLESv2Decoder *) self; |
| ctx->glVertexAttribPointer(indx, size, type, normalized, stride, SafePointerFromUInt(data)); |
| } |
| |
| |
| void GLESv2Decoder::s_glDrawElementsData(void *self, GLenum mode, GLsizei count, GLenum type, void * data, GLuint datalen) |
| { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDrawElements(mode, count, type, data); |
| } |
| |
| |
| void GLESv2Decoder::s_glDrawElementsOffset(void *self, GLenum mode, GLsizei count, GLenum type, GLuint offset) |
| { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDrawElements(mode, count, type, SafePointerFromUInt(offset)); |
| } |
| |
| void GLESv2Decoder::s_glDrawElementsDataNullAEMU(void *self, GLenum mode, GLsizei count, GLenum type, void * data, GLuint datalen) |
| { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDrawElementsNullAEMU(mode, count, type, data); |
| } |
| |
| |
| void GLESv2Decoder::s_glDrawElementsOffsetNullAEMU(void *self, GLenum mode, GLsizei count, GLenum type, GLuint offset) |
| { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDrawElementsNullAEMU(mode, count, type, SafePointerFromUInt(offset)); |
| } |
| |
| void GLESv2Decoder::s_glMapBufferRangeAEMU(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, void* mapped) |
| { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| if ((access & GL_MAP_READ_BIT) || |
| ((access & GL_MAP_WRITE_BIT) && |
| (!(access & GL_MAP_INVALIDATE_RANGE_BIT) && |
| !(access & GL_MAP_INVALIDATE_BUFFER_BIT)))) { |
| void* gpu_ptr = ctx->glMapBufferRange(target, offset, length, access); |
| |
| // map failed, no need to copy or unmap |
| if (!gpu_ptr) { |
| fprintf(stderr, "%s: error: could not map host gpu buffer\n", __func__); |
| return; |
| } |
| |
| memcpy(mapped, gpu_ptr, length); |
| ctx->glUnmapBuffer(target); |
| } else { |
| // if writing while not wanting to preserve previous contents, |
| // let |mapped| stay as garbage. |
| } |
| } |
| |
| void GLESv2Decoder::s_glUnmapBufferAEMU(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, void* guest_buffer, GLboolean* out_res) |
| { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| *out_res = GL_TRUE; |
| |
| if (access & GL_MAP_WRITE_BIT) { |
| if (!guest_buffer) { |
| // guest can flush 0 in some cases |
| return; |
| } |
| void* gpu_ptr = ctx->glMapBufferRange(target, offset, length, access); |
| if (!gpu_ptr) { |
| fprintf(stderr, "%s: could not get host gpu pointer!\n", __FUNCTION__); |
| return; |
| } |
| memcpy(gpu_ptr, guest_buffer, length); |
| *out_res = ctx->glUnmapBuffer(target); |
| } |
| } |
| |
| void GLESv2Decoder::s_glMapBufferRangeDMA(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, uint64_t paddr) |
| { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| // Check if this is a read or write request and not an invalidate one. |
| if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) && |
| !(access & (GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT))) { |
| void* guest_buffer = emugl::g_emugl_dma_get_host_addr(paddr); |
| void* gpu_ptr = ctx->glMapBufferRange(target, offset, length, access); |
| |
| // map failed, no need to copy or unmap |
| if (!gpu_ptr) { |
| fprintf(stderr, "%s: error: could not map host gpu buffer\n", __func__); |
| return; |
| } |
| |
| memcpy(guest_buffer, gpu_ptr, length); |
| ctx->glUnmapBuffer(target); |
| } else { |
| // if writing while not wanting to preserve previous contents, |
| // let |mapped| stay as garbage. |
| } |
| } |
| |
| void GLESv2Decoder::s_glUnmapBufferDMA(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, uint64_t paddr, GLboolean* out_res) |
| { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| *out_res = GL_TRUE; |
| |
| if (access & GL_MAP_WRITE_BIT) { |
| if (!paddr) { |
| // guest can flush 0 in some cases |
| return; |
| } |
| void* guest_buffer = emugl::g_emugl_dma_get_host_addr(paddr); |
| void* gpu_ptr = ctx->glMapBufferRange(target, offset, length, access); |
| if (!gpu_ptr) { |
| fprintf(stderr, "%s: could not get host gpu pointer!\n", __FUNCTION__); |
| return; |
| } |
| memcpy(gpu_ptr, guest_buffer, length); |
| *out_res = ctx->glUnmapBuffer(target); |
| } |
| } |
| |
| static std::pair<void*, GLsizeiptr> align_pointer_size(void* ptr, GLsizeiptr length) |
| { |
| constexpr size_t kPageBits = 12; |
| constexpr size_t kPageSize = 1u << kPageBits; |
| constexpr size_t kPageOffsetMask = kPageSize - 1; |
| |
| uintptr_t addr = reinterpret_cast<uintptr_t>(ptr); |
| uintptr_t page_offset = addr & kPageOffsetMask; |
| |
| return { reinterpret_cast<void*>(addr - page_offset), |
| ((length + page_offset + kPageSize - 1) >> kPageBits) << kPageBits |
| }; |
| } |
| |
| uint64_t GLESv2Decoder::s_glMapBufferRangeDirect(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, uint64_t paddr) |
| { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| // Check if this is a read or write request and not an invalidate one. |
| if (access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) { |
| void* gpu_ptr = ctx->glMapBufferRange(target, offset, length, access); |
| |
| if (gpu_ptr) { |
| std::pair<void*, GLsizeiptr> aligned = align_pointer_size(gpu_ptr, length); |
| get_emugl_vm_operations().mapUserBackedRam(paddr, aligned.first, aligned.second); |
| return reinterpret_cast<uint64_t>(gpu_ptr); |
| } else { |
| fprintf(stderr, "%s: error: could not map host gpu buffer\n", __func__); |
| return 0; |
| } |
| } else { |
| // if writing while not wanting to preserve previous contents, |
| // let |mapped| stay as garbage. |
| return 0; |
| } |
| } |
| |
| void GLESv2Decoder::s_glUnmapBufferDirect(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, uint64_t paddr, uint64_t gpu_ptr, GLboolean* out_res) |
| { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| GLboolean res = GL_TRUE; |
| |
| if (access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) { |
| get_emugl_vm_operations().unmapUserBackedRam(paddr, align_pointer_size(reinterpret_cast<void*>(gpu_ptr), length).second); |
| res = ctx->glUnmapBuffer(target); |
| } |
| |
| *out_res = res; |
| } |
| |
| void GLESv2Decoder::s_glFlushMappedBufferRangeAEMU(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, void* guest_buffer) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| if (!guest_buffer) { |
| // guest can end up flushing 0 bytes in a lot of cases |
| return; |
| } |
| void* gpu_ptr = ctx->glMapBufferRange(target, offset, length, access); |
| |
| // map failed, no need to copy or unmap |
| if (!gpu_ptr) { |
| fprintf(stderr, "%s: error: could not map host gpu buffer\n", __func__); |
| return; |
| } |
| |
| memcpy(gpu_ptr, guest_buffer, length); |
| // |offset| was the absolute offset into the mapping, so just flush offset 0. |
| ctx->glFlushMappedBufferRange(target, 0, length); |
| ctx->glUnmapBuffer(target); |
| } |
| |
| void GLESv2Decoder::s_glFlushMappedBufferRangeDirect(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glFlushMappedBufferRange(target, offset, length); |
| } |
| |
| void GLESv2Decoder::s_glCompressedTexImage2DOffsetAEMU(void* self, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, GLuint offset) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, SafePointerFromUInt(offset)); |
| } |
| void GLESv2Decoder::s_glCompressedTexSubImage2DOffsetAEMU(void* self, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, GLuint offset) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, SafePointerFromUInt(offset)); |
| } |
| void GLESv2Decoder::s_glTexImage2DOffsetAEMU(void* self, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLuint offset) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glTexImage2D(target, level, internalformat, width, height, border, format, type, SafePointerFromUInt(offset)); |
| } |
| void GLESv2Decoder::s_glTexSubImage2DOffsetAEMU(void* self, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLuint offset) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, SafePointerFromUInt(offset)); |
| } |
| |
| static const char* const kNameDelimiter = ";"; |
| |
| static std::vector<std::string> sUnpackVarNames(GLsizei count, const char* packedNames) { |
| std::vector<std::string> unpacked; |
| GLsizei current = 0; |
| |
| while (current < count) { |
| const char* delimPos = strstr(packedNames, kNameDelimiter); |
| size_t nameLen = delimPos - packedNames; |
| std::string next; |
| next.resize(nameLen); |
| memcpy(&next[0], packedNames, nameLen); |
| unpacked.push_back(next); |
| packedNames = delimPos + 1; |
| current++; |
| } |
| |
| return unpacked; |
| } |
| |
| void GLESv2Decoder::s_glGetUniformIndicesAEMU(void* self, GLuint program, GLsizei uniformCount, const GLchar* packedNames, GLsizei packedLen, GLuint* uniformIndices) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| |
| std::vector<std::string> unpacked = sUnpackVarNames(uniformCount, packedNames); |
| |
| GLchar** unpackedArray = new GLchar*[unpacked.size()]; |
| GLsizei i = 0; |
| for (auto& elt : unpacked) { |
| unpackedArray[i] = (GLchar*)&elt[0]; |
| i++; |
| } |
| |
| ctx->glGetUniformIndices(program, uniformCount, (const GLchar**)unpackedArray, uniformIndices); |
| |
| delete [] unpackedArray; |
| } |
| |
| void GLESv2Decoder::s_glVertexAttribIPointerDataAEMU(void *self, GLuint indx, GLint size, GLenum type, GLsizei stride, void * data, GLuint datalen) |
| { |
| GLESv2Decoder *ctx = (GLESv2Decoder *) self; |
| if (ctx->m_contextData != NULL) { |
| ctx->m_contextData->storePointerData(indx, data, datalen); |
| // note - the stride of the data is always zero when it comes out of the codec. |
| // See gl2.attrib for the packing function call. |
| if ((void*)ctx->glVertexAttribIPointerWithDataSize != gles2_unimplemented) { |
| ctx->glVertexAttribIPointerWithDataSize(indx, size, type, 0, |
| ctx->m_contextData->pointerData(indx), datalen); |
| } else { |
| ctx->glVertexAttribIPointer(indx, size, type, 0, |
| ctx->m_contextData->pointerData(indx)); |
| } |
| } |
| } |
| |
| void GLESv2Decoder::s_glVertexAttribIPointerOffsetAEMU(void *self, GLuint indx, GLint size, GLenum type, GLsizei stride, GLuint data) |
| { |
| GLESv2Decoder *ctx = (GLESv2Decoder *) self; |
| ctx->glVertexAttribIPointer(indx, size, type, stride, SafePointerFromUInt(data)); |
| } |
| |
| void GLESv2Decoder::s_glTransformFeedbackVaryingsAEMU(void* self, GLuint program, GLsizei count, const char* packedVaryings, GLuint packedVaryingsLen, GLenum bufferMode) { |
| |
| GLESv2Decoder *ctx = (GLESv2Decoder *) self; |
| |
| std::vector<std::string> unpacked = sUnpackVarNames(count, packedVaryings); |
| |
| char** unpackedArray = new char*[unpacked.size()]; |
| GLsizei i = 0; |
| for (auto& elt : unpacked) { |
| unpackedArray[i] = &elt[0]; |
| i++; |
| } |
| |
| ctx->glTransformFeedbackVaryings(program, count, (const char**)unpackedArray, bufferMode); |
| |
| delete [] unpackedArray; |
| } |
| |
| void GLESv2Decoder::s_glTexImage3DOffsetAEMU(void* self, GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, GLuint offset) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *) self; |
| ctx->glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, SafePointerFromUInt(offset)); |
| } |
| void GLESv2Decoder::s_glTexSubImage3DOffsetAEMU(void* self, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLuint offset) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *) self; |
| ctx->glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, SafePointerFromUInt(offset)); |
| } |
| void GLESv2Decoder::s_glCompressedTexImage3DOffsetAEMU(void* self, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, GLuint offset) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *) self; |
| ctx->glCompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, SafePointerFromUInt(offset)); |
| } |
| void GLESv2Decoder::s_glCompressedTexSubImage3DOffsetAEMU(void* self, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, GLuint offset) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *) self; |
| ctx->glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, SafePointerFromUInt(offset)); |
| } |
| |
| void GLESv2Decoder::s_glDrawElementsInstancedOffsetAEMU(void* self, GLenum mode, GLsizei count, GLenum type, GLuint offset, GLsizei primcount) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDrawElementsInstanced(mode, count, type, SafePointerFromUInt(offset), primcount); |
| } |
| |
| void GLESv2Decoder::s_glDrawElementsInstancedDataAEMU(void* self, GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount, GLsizei datalen) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDrawElementsInstanced(mode, count, type, indices, primcount); |
| } |
| |
| void GLESv2Decoder::s_glReadPixelsOffsetAEMU(void* self, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLuint offset) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glReadPixels(x, y, width, height, format, type, SafePointerFromUInt(offset)); |
| } |
| |
| GLuint GLESv2Decoder::s_glCreateShaderProgramvAEMU(void* self, GLenum type, GLsizei count, const char* packedStrings, GLuint packedLen) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| return ctx->glCreateShaderProgramv(type, 1, &packedStrings); |
| // TODO: Snapshot names |
| } |
| |
| void GLESv2Decoder::s_glDrawArraysIndirectDataAEMU(void* self, GLenum mode, const void* indirect, GLuint datalen) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDrawArraysIndirect(mode, indirect); |
| } |
| |
| void GLESv2Decoder::s_glDrawArraysIndirectOffsetAEMU(void* self, GLenum mode, GLuint offset) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDrawArraysIndirect(mode, SafePointerFromUInt(offset)); |
| } |
| |
| void GLESv2Decoder::s_glDrawElementsIndirectDataAEMU(void* self, GLenum mode, GLenum type, const void* indirect, GLuint datalen) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDrawElementsIndirect(mode, type, indirect); |
| } |
| |
| void GLESv2Decoder::s_glDrawElementsIndirectOffsetAEMU(void* self, GLenum mode, GLenum type, GLuint offset) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDrawElementsIndirect(mode, type, SafePointerFromUInt(offset)); |
| } |
| |
| uint64_t GLESv2Decoder::s_glFenceSyncAEMU(void* self, GLenum condition, GLbitfield flags) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| return (uint64_t)(uintptr_t)ctx->glFenceSync(condition, flags); |
| } |
| |
| GLenum GLESv2Decoder::s_glClientWaitSyncAEMU(void* self, uint64_t wait_on, GLbitfield flags, GLuint64 timeout) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| return ctx->glClientWaitSync((GLsync)(uintptr_t)wait_on, flags, timeout); |
| } |
| |
| void GLESv2Decoder::s_glWaitSyncAEMU(void* self, uint64_t wait_on, GLbitfield flags, GLuint64 timeout) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glWaitSync((GLsync)(uintptr_t)wait_on, flags, timeout); |
| } |
| |
| void GLESv2Decoder::s_glDeleteSyncAEMU(void* self, uint64_t to_delete) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDeleteSync((GLsync)(uintptr_t)to_delete); |
| } |
| |
| GLboolean GLESv2Decoder::s_glIsSyncAEMU(void* self, uint64_t sync) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| return ctx->glIsSync((GLsync)(uintptr_t)sync); |
| } |
| |
| void GLESv2Decoder::s_glGetSyncivAEMU(void* self, uint64_t sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glGetSynciv((GLsync)(uintptr_t)sync, pname, bufSize, length, values); |
| } |
| |
| GLboolean GLESv2Decoder::s_glBufferDataSyncAEMU(void* self, GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glBufferData(target, size, data, usage); |
| return GL_TRUE; |
| } |
| |
| GLuint GLESv2Decoder::s_glCreateShader(void* self, GLenum shaderType) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| GLuint shader = ctx->glCreateShader(shaderType); |
| |
| if (ctx->m_snapshot) { |
| GLuint emuName = ctx->m_snapshot->createShader(shader, shaderType); |
| return emuName; |
| } |
| |
| return shader; |
| } |
| |
| GLuint GLESv2Decoder::s_glCreateProgram(void* self) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| return ctx->glCreateProgram(); |
| } |
| |
| void GLESv2Decoder::s_glGenBuffers(void* self, GLsizei n, GLuint* buffers) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glGenBuffers(n, buffers); |
| |
| if (ctx->m_snapshot) { |
| ctx->m_snapshot->genBuffers(n, buffers); |
| } |
| } |
| |
| void GLESv2Decoder::s_glGenFramebuffers(void* self, GLsizei n, GLuint* framebuffers) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glGenFramebuffers(n, framebuffers); |
| // TODO: Snapshot names |
| } |
| |
| void GLESv2Decoder::s_glGenRenderbuffers(void* self, GLsizei n, GLuint* renderbuffers) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glGenRenderbuffers(n, renderbuffers); |
| // TODO: Snapshot names |
| } |
| |
| void GLESv2Decoder::s_glGenTextures(void* self, GLsizei n, GLuint* textures) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glGenTextures(n, textures); |
| // TODO: Snapshot names |
| } |
| |
| void GLESv2Decoder::s_glGenVertexArraysOES(void* self, GLsizei n, GLuint* arrays) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glGenVertexArraysOES(n, arrays); |
| // TODO: Snapshot names |
| } |
| |
| void GLESv2Decoder::s_glGenVertexArrays(void* self, GLsizei n, GLuint* arrays) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glGenVertexArrays(n, arrays); |
| // TODO: Snapshot names |
| } |
| |
| void GLESv2Decoder::s_glGenTransformFeedbacks(void* self, GLsizei n, GLuint* transformFeedbacks) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glGenTransformFeedbacks(n, transformFeedbacks); |
| // TODO: Snapshot names |
| } |
| |
| void GLESv2Decoder::s_glGenSamplers(void* self, GLsizei n, GLuint* samplers) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glGenSamplers(n, samplers); |
| // TODO: Snapshot names |
| |
| } |
| |
| void GLESv2Decoder::s_glGenQueries(void* self, GLsizei n, GLuint* queries) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glGenQueries(n, queries); |
| // TODO: Snapshot names |
| |
| } |
| |
| void GLESv2Decoder::s_glGenProgramPipelines(void* self, GLsizei n, GLuint* pipelines) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glGenProgramPipelines(n, pipelines); |
| // TODO: Snapshot names |
| } |
| |
| void GLESv2Decoder::s_glDeleteShader(void* self, GLuint shader) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDeleteShader(shader); |
| // TODO: Snapshot names |
| } |
| |
| void GLESv2Decoder::s_glDeleteProgram(void* self, GLuint program) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDeleteProgram(program); |
| // TODO: Snapshot names |
| } |
| |
| void GLESv2Decoder::s_glDeleteBuffers(void* self, GLsizei n, const GLuint *buffers) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDeleteBuffers(n, buffers); |
| // TODO: Snapshot names |
| } |
| |
| void GLESv2Decoder::s_glDeleteFramebuffers(void* self, GLsizei n, const GLuint *framebuffers) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDeleteFramebuffers(n, framebuffers); |
| // TODO: Snapshot names |
| } |
| |
| void GLESv2Decoder::s_glDeleteRenderbuffers(void* self, GLsizei n, const GLuint *renderbuffers) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDeleteRenderbuffers(n, renderbuffers); |
| // TODO: Snapshot names |
| } |
| |
| void GLESv2Decoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint *textures) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDeleteTextures(n, textures); |
| // TODO: Snapshot names |
| } |
| |
| |
| void GLESv2Decoder::s_glDeleteVertexArraysOES(void* self, GLsizei n, const GLuint *arrays) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDeleteVertexArraysOES(n, arrays); |
| // TODO: Snapshot names |
| } |
| |
| void GLESv2Decoder::s_glDeleteVertexArrays(void* self, GLsizei n, const GLuint *arrays) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDeleteVertexArrays(n, arrays); |
| // TODO: Snapshot names |
| } |
| |
| |
| void GLESv2Decoder::s_glDeleteTransformFeedbacks(void* self, GLsizei n, const GLuint *transformFeedbacks) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDeleteTransformFeedbacks(n, transformFeedbacks); |
| // TODO: Snapshot names |
| } |
| |
| void GLESv2Decoder::s_glDeleteSamplers(void* self, GLsizei n, const GLuint *samplers) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDeleteSamplers(n, samplers); |
| // TODO: Snapshot names |
| } |
| |
| void GLESv2Decoder::s_glDeleteQueries(void* self, GLsizei n, const GLuint *queries) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDeleteQueries(n, queries); |
| // TODO: Snapshot names |
| } |
| |
| void GLESv2Decoder::s_glDeleteProgramPipelines(void* self, GLsizei n, const GLuint *pipelines) { |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; |
| ctx->glDeleteProgramPipelines(n, pipelines); |
| // TODO: Snapshot names |
| } |
| |
| #define SNAPSHOT_PROGRAM_NAME(x) \ |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; \ |
| if (ctx->m_snapshot) { x = ctx->m_snapshot->getProgramName(x); } \ |
| |
| #define SNAPSHOT_PROGRAM_NAME2(x,y) \ |
| GLESv2Decoder *ctx = (GLESv2Decoder *)self; \ |
| if (ctx->m_snapshot) { \ |
| x = ctx->m_snapshot->getProgramName(x); \ |
| y = ctx->m_snapshot->getProgramName(y); \ |
| } \ |
| |
| #define SNAPSHOT_SHADER_CALL(funcname,argtypes,args) \ |
| void GLESv2Decoder::s_##funcname argtypes { \ |
| SNAPSHOT_PROGRAM_NAME(shader) \ |
| ctx-> funcname args ; \ |
| } \ |
| |
| #define SNAPSHOT_PROGRAM_CALL(funcname,argtypes,args) \ |
| void GLESv2Decoder::s_##funcname argtypes { \ |
| SNAPSHOT_PROGRAM_NAME(program) \ |
| ctx-> funcname args ; \ |
| } \ |
| |
| #define SNAPSHOT_PROGRAM_CALL_RET(rettype, funcname, argtypes, args) \ |
| rettype GLESv2Decoder::s_##funcname argtypes { \ |
| SNAPSHOT_PROGRAM_NAME(program) \ |
| return ctx-> funcname args; \ |
| } \ |
| |
| |
| void GLESv2Decoder::s_glShaderString(void *self, GLuint shader, const GLchar* string, GLsizei len) |
| { |
| SNAPSHOT_PROGRAM_NAME(shader); |
| |
| ctx->glShaderSource(shader, 1, &string, NULL); |
| |
| if (ctx->m_snapshot) { |
| ctx->m_snapshot->shaderString(shader, string); |
| } |
| } |
| |
| void GLESv2Decoder::s_glAttachShader(void* self, GLuint program, GLuint shader) { |
| SNAPSHOT_PROGRAM_NAME2(program, shader) |
| ctx->glAttachShader(program, shader); |
| } |
| |
| void GLESv2Decoder::s_glTexBufferOES(void* self, GLenum target, GLenum internalformat, GLuint buffer) { |
| GLESv2Decoder* ctx = (GLESv2Decoder*)self; |
| ctx->glTexBufferOES(target, internalformat, buffer); |
| } |
| |
| void GLESv2Decoder::s_glTexBufferEXT(void* self, GLenum target, GLenum internalformat, |
| GLuint buffer) { |
| GLESv2Decoder* ctx = (GLESv2Decoder*)self; |
| ctx->glTexBufferEXT(target, internalformat, buffer); |
| } |
| |
| void GLESv2Decoder::s_glTexBufferRangeOES(void* self, GLenum target, GLenum internalformat, |
| GLuint buffer, |
| GLintptr offset, GLsizeiptr size) { |
| GLESv2Decoder* ctx = (GLESv2Decoder*)self; |
| ctx->glTexBufferRangeOES(target, internalformat, buffer, offset, size); |
| } |
| |
| void GLESv2Decoder::s_glTexBufferRangeEXT(void* self, GLenum target, GLenum internalformat, |
| GLuint buffer, GLintptr offset, GLsizeiptr size) { |
| GLESv2Decoder* ctx = (GLESv2Decoder*)self; |
| ctx->glTexBufferRangeEXT(target, internalformat, buffer, offset, size); |
| } |
| |
| void GLESv2Decoder::s_glEnableiEXT(void* self, GLenum cap, GLuint index) { |
| GLESv2Decoder* ctx = (GLESv2Decoder*)self; |
| ctx->glEnableiEXT(cap, index); |
| } |
| |
| void GLESv2Decoder::s_glDisableiEXT(void* self, GLenum cap, GLuint index) { |
| GLESv2Decoder* ctx = (GLESv2Decoder*)self; |
| ctx->glDisableiEXT(cap, index); |
| } |
| |
| void GLESv2Decoder::s_glBlendEquationiEXT(void* self, GLuint buf, GLenum mode) { |
| GLESv2Decoder* ctx = (GLESv2Decoder*)self; |
| ctx->glBlendEquationiEXT(buf, mode); |
| } |
| |
| void GLESv2Decoder::s_glBlendEquationSeparateiEXT(void* self, GLuint buf, GLenum modeRGB, |
| GLenum modeAlpha) { |
| GLESv2Decoder* ctx = (GLESv2Decoder*)self; |
| ctx->glBlendEquationSeparateiEXT(buf, modeRGB, modeAlpha); |
| } |
| |
| void GLESv2Decoder::s_glBlendFunciEXT(void* self, GLuint buf, GLenum sfactor, GLenum dfactor) { |
| GLESv2Decoder* ctx = (GLESv2Decoder*)self; |
| ctx->glBlendFunciEXT(buf, sfactor, dfactor); |
| } |
| |
| void GLESv2Decoder::s_glBlendFuncSeparateiEXT(void* self, GLuint buf, GLenum srcRGB, GLenum dstRGB, |
| GLenum srcAlpha, GLenum dstAlpha) { |
| GLESv2Decoder* ctx = (GLESv2Decoder*)self; |
| ctx->glBlendFuncSeparateiEXT(buf, srcRGB, dstRGB, srcAlpha, dstAlpha); |
| } |
| |
| void GLESv2Decoder::s_glColorMaskiEXT(void* self, GLuint buf, GLboolean red, GLboolean green, |
| GLboolean blue, GLboolean alpha) { |
| GLESv2Decoder* ctx = (GLESv2Decoder*)self; |
| ctx->glColorMaskiEXT(buf, red, green, blue, alpha); |
| } |
| |
| GLboolean GLESv2Decoder::s_glIsEnablediEXT(void* self, GLenum cap, GLuint index) { |
| GLESv2Decoder* ctx = (GLESv2Decoder*)self; |
| return ctx->glIsEnablediEXT(cap, index); |
| } |
| |
| void GLESv2Decoder::s_glDetachShader(void* self, GLuint program, GLuint shader) { |
| SNAPSHOT_PROGRAM_NAME2(program, shader) |
| ctx->glDetachShader(program, shader); |
| } |
| |
| GLboolean GLESv2Decoder::s_glIsShader(void* self, GLuint shader) { |
| SNAPSHOT_PROGRAM_NAME(shader); |
| return ctx->glIsShader(shader); |
| } |
| |
| GLboolean GLESv2Decoder::s_glIsProgram(void* self, GLuint program) { |
| SNAPSHOT_PROGRAM_NAME(program); |
| return ctx->glIsProgram(program); |
| } |
| |
| SNAPSHOT_SHADER_CALL(glCompileShader, (void* self, GLuint shader), (shader)) |
| SNAPSHOT_SHADER_CALL(glGetShaderiv, (void* self, GLuint shader, GLenum pname, GLint* params), (shader, pname, params)) |
| SNAPSHOT_SHADER_CALL(glGetShaderInfoLog, (void* self, GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog), (shader, bufsize, length, infolog)) |
| SNAPSHOT_SHADER_CALL(glGetShaderSource, (void* self, GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source), (shader, bufsize, length, source)) |
| SNAPSHOT_PROGRAM_CALL(glLinkProgram, (void* self, GLuint program), (program)) |
| SNAPSHOT_PROGRAM_CALL(glUseProgram, (void* self, GLuint program), (program)) |
| SNAPSHOT_PROGRAM_CALL(glValidateProgram, (void* self, GLuint program), (program)) |
| SNAPSHOT_PROGRAM_CALL(glGetProgramiv, (void* self, GLuint program, GLenum pname, GLint* params), (program, pname, params)) |
| SNAPSHOT_PROGRAM_CALL(glGetProgramInfoLog, (void* self, GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog), (program, bufsize, length, infolog)) |
| SNAPSHOT_PROGRAM_CALL(glBindAttribLocation, (void* self, GLuint program, GLuint index, const GLchar* name), (program, index, name)) |
| SNAPSHOT_PROGRAM_CALL(glGetActiveAttrib, (void* self, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name), (program, index, bufsize, length, size, type, name)) |
| SNAPSHOT_PROGRAM_CALL(glGetActiveUniform, (void* self, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name), (program, index, bufsize, length, size, type, name)) |
| SNAPSHOT_PROGRAM_CALL(glGetAttachedShaders, (void* self, GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders), (program, maxcount, count, shaders)) |
| SNAPSHOT_PROGRAM_CALL_RET(GLint, glGetAttribLocation, (void* self, GLuint program, const GLchar* name), (program, name)) |
| SNAPSHOT_PROGRAM_CALL(glGetUniformfv, (void* self, GLuint program, GLint location, GLfloat* params), (program, location, params)) |
| SNAPSHOT_PROGRAM_CALL(glGetUniformiv, (void* self, GLuint program, GLint location, GLint* params), (program, location, params)) |
| SNAPSHOT_PROGRAM_CALL_RET(GLint, glGetUniformLocation, (void* self, GLuint program, const GLchar* name), (program, name)) |
| SNAPSHOT_PROGRAM_CALL(glGetProgramBinaryOES, (void* self, GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary), (program, bufSize, length, binaryFormat, binary)) |
| SNAPSHOT_PROGRAM_CALL(glProgramBinaryOES, (void* self, GLuint program, GLenum binaryFormat, const GLvoid* binary, GLint length), (program, binaryFormat, binary, length)) |
| SNAPSHOT_PROGRAM_CALL(glUniformBlockBinding, (void* self, GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding), (program, uniformBlockIndex, uniformBlockBinding)) |
| SNAPSHOT_PROGRAM_CALL_RET(GLuint, glGetUniformBlockIndex, (void* self, GLuint program, const GLchar* uniformBlockName), (program, uniformBlockName)) |
| SNAPSHOT_PROGRAM_CALL(glGetActiveUniformBlockiv, (void* self, GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params), (program, uniformBlockIndex, pname, params)) |
| SNAPSHOT_PROGRAM_CALL(glGetActiveUniformBlockName, (void* self, GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName), (program, uniformBlockIndex, bufSize, length, uniformBlockName)) |
| SNAPSHOT_PROGRAM_CALL(glGetUniformuiv, (void* self, GLuint program, GLint location, GLuint* params), (program, location, params)) |
| SNAPSHOT_PROGRAM_CALL(glGetActiveUniformsiv, (void* self, GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params), (program, uniformCount, uniformIndices, pname, params)) |
| SNAPSHOT_PROGRAM_CALL(glTransformFeedbackVaryings, (void* self, GLuint program, GLsizei count, const char** varyings, GLenum bufferMode), (program, count, varyings, bufferMode)) |
| SNAPSHOT_PROGRAM_CALL(glGetTransformFeedbackVarying, (void* self, GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, char* name), (program, index, bufSize, length, size, type, name)) |
| SNAPSHOT_PROGRAM_CALL(glProgramParameteri, (void* self, GLuint program, GLenum pname, GLint value), (program, pname, value)) |
| SNAPSHOT_PROGRAM_CALL(glProgramBinary, (void* self, GLuint program, GLenum binaryFormat, const void* binary, GLsizei length), (program, binaryFormat, binary, length)) |
| SNAPSHOT_PROGRAM_CALL(glGetProgramBinary, (void* self, GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void* binary), (program, bufSize, length, binaryFormat, binary)) |
| SNAPSHOT_PROGRAM_CALL_RET(GLint, glGetFragDataLocation, (void* self, GLuint program, const char* name), (program, name)) |
| SNAPSHOT_PROGRAM_CALL(glUseProgramStages, (void* self, GLuint pipeline, GLbitfield stages, GLuint program), (pipeline, stages, program)) |
| SNAPSHOT_PROGRAM_CALL(glActiveShaderProgram, (void* self, GLuint pipeline, GLuint program), (pipeline, program)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform1f, (void* self, GLuint program, GLint location, GLfloat v0), (program, location, v0)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform2f, (void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1), (program, location, v0, v1)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform3f, (void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2), (program, location, v0, v1, v2)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform4f, (void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3), (program, location, v0, v1, v2, v3)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform1i, (void* self, GLuint program, GLint location, GLint v0), (program, location, v0)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform2i, (void* self, GLuint program, GLint location, GLint v0, GLint v1), (program, location, v0, v1)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform3i, (void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2), (program, location, v0, v1, v2)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform4i, (void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3), (program, location, v0, v1, v2, v3)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform1ui, (void* self, GLuint program, GLint location, GLuint v0), (program, location, v0)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform2ui, (void* self, GLuint program, GLint location, GLint v0, GLuint v1), (program, location, v0, v1)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform3ui, (void* self, GLuint program, GLint location, GLint v0, GLint v1, GLuint v2), (program, location, v0, v1, v2)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform4ui, (void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLuint v3), (program, location, v0, v1, v2, v3)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform1fv, (void* self, GLuint program, GLint location, GLsizei count, const GLfloat* value), (program, location, count, value)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform2fv, (void* self, GLuint program, GLint location, GLsizei count, const GLfloat* value), (program, location, count, value)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform3fv, (void* self, GLuint program, GLint location, GLsizei count, const GLfloat* value), (program, location, count, value)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform4fv, (void* self, GLuint program, GLint location, GLsizei count, const GLfloat* value), (program, location, count, value)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform1iv, (void* self, GLuint program, GLint location, GLsizei count, const GLint* value), (program, location, count, value)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform2iv, (void* self, GLuint program, GLint location, GLsizei count, const GLint* value), (program, location, count, value)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform3iv, (void* self, GLuint program, GLint location, GLsizei count, const GLint* value), (program, location, count, value)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform4iv, (void* self, GLuint program, GLint location, GLsizei count, const GLint* value), (program, location, count, value)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform1uiv, (void* self, GLuint program, GLint location, GLsizei count, const GLuint* value), (program, location, count, value)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform2uiv, (void* self, GLuint program, GLint location, GLsizei count, const GLuint* value), (program, location, count, value)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform3uiv, (void* self, GLuint program, GLint location, GLsizei count, const GLuint* value), (program, location, count, value)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniform4uiv, (void* self, GLuint program, GLint location, GLsizei count, const GLuint* value), (program, location, count, value)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniformMatrix2fv, (void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (program, location, count, transpose, value)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniformMatrix3fv, (void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (program, location, count, transpose, value)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniformMatrix4fv, (void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (program, location, count, transpose, value)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniformMatrix2x3fv, (void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (program, location, count, transpose, value)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniformMatrix3x2fv, (void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (program, location, count, transpose, value)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniformMatrix2x4fv, (void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (program, location, count, transpose, value)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniformMatrix4x2fv, (void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (program, location, count, transpose, value)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniformMatrix3x4fv, (void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (program, location, count, transpose, value)) |
| SNAPSHOT_PROGRAM_CALL(glProgramUniformMatrix4x3fv, (void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (program, location, count, transpose, value)) |
| SNAPSHOT_PROGRAM_CALL(glGetProgramInterfaceiv, (void* self, GLuint program, GLenum programInterface, GLenum pname, GLint* params), (program, programInterface, pname, params)) |
| SNAPSHOT_PROGRAM_CALL(glGetProgramResourceiv, (void* self, GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum* props, GLsizei bufSize, GLsizei* length, GLint* params), (program, programInterface, index, propCount, props, bufSize, length, params)) |
| SNAPSHOT_PROGRAM_CALL_RET(GLuint, glGetProgramResourceIndex, (void* self, GLuint program, GLenum programInterface, const char * name), (program, programInterface, name)) |
| SNAPSHOT_PROGRAM_CALL_RET(GLint, glGetProgramResourceLocation, (void* self, GLuint program, GLenum programInterface, const char * name), (program, programInterface, name)) |
| SNAPSHOT_PROGRAM_CALL(glGetProgramResourceName, (void* self, GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, char* name), (program, programInterface, index, bufSize, length, name)) |
| |
| } // namespace gl |
| } // namespace gfxstream |