| /************************************************************************** |
| * |
| * Copyright 2010-2016 VMware, Inc. |
| * All Rights Reserved. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a copy |
| * of this software and associated documentation files (the "Software"), to deal |
| * in the Software without restriction, including without limitation the rights |
| * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| * copies of the Software, and to permit persons to whom the Software is |
| * furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included in |
| * all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| * THE SOFTWARE. |
| * |
| **************************************************************************/ |
| |
| |
| #include "gltrace_arrays.hpp" |
| #include "gltrace.hpp" |
| |
| |
| /* FIXME take in consideration instancing */ |
| |
| |
| GLuint |
| _glDraw_count(gltrace::Context *ctx, const DrawArraysParams ¶ms) |
| { |
| if (!params.count) { |
| return 0; |
| } |
| return params.first + params.count; |
| } |
| |
| |
| GLuint |
| _glDraw_count(gltrace::Context *ctx, const DrawElementsParams ¶ms) |
| { |
| if (params.end < params.start || |
| params.count <= 0) { |
| return 0; |
| } |
| |
| if (params.end != ~0U) { |
| return params.end + params.basevertex + 1; |
| } |
| |
| GLuint count = params.count; |
| GLenum type = params.type; |
| const void *indices = params.indices; |
| |
| GLvoid *temp = 0; |
| |
| if (!count) { |
| return 0; |
| } |
| |
| GLint element_array_buffer = _element_array_buffer_binding(); |
| if (element_array_buffer) { |
| // Read indices from index buffer object |
| if (ctx->profile.es()) { |
| // We could try to implement this on top of GL_OES_mapbuffer but should seldom be needed |
| os::log("apitrace: warning: %s: element array buffer with memory vertex arrays no longer supported on ES\n", __FUNCTION__); |
| return 0; |
| } |
| |
| GLintptr offset = (GLintptr)indices; |
| GLsizeiptr size = count*_gl_type_size(type); |
| temp = malloc(size); |
| if (!temp) { |
| return 0; |
| } |
| memset(temp, 0, size); |
| _glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, size, temp); |
| indices = temp; |
| } else { |
| if (!indices) { |
| return 0; |
| } |
| } |
| |
| GLuint maxindex = 0; |
| |
| GLboolean restart_enabled = GL_FALSE; |
| GLuint restart_index = 0; |
| if (ctx->features.primitive_restart) { |
| _glIsEnabled(GL_PRIMITIVE_RESTART); |
| if (restart_enabled) { |
| restart_index = (GLuint)_glGetInteger(GL_PRIMITIVE_RESTART_INDEX); |
| } |
| } |
| |
| GLsizei i; |
| if (type == GL_UNSIGNED_BYTE) { |
| const GLubyte *p = (const GLubyte *)indices; |
| for (i = 0; i < count; ++i) { |
| GLuint index = p[i]; |
| if (restart_enabled && index == restart_index) { |
| continue; |
| } |
| if (index > maxindex) { |
| maxindex = index; |
| } |
| } |
| } else if (type == GL_UNSIGNED_SHORT) { |
| const GLushort *p = (const GLushort *)indices; |
| for (i = 0; i < count; ++i) { |
| GLuint index = p[i]; |
| if (restart_enabled && index == restart_index) { |
| continue; |
| } |
| if (index > maxindex) { |
| maxindex = index; |
| } |
| } |
| } else if (type == GL_UNSIGNED_INT) { |
| const GLuint *p = (const GLuint *)indices; |
| for (i = 0; i < count; ++i) { |
| GLuint index = p[i]; |
| if (restart_enabled && index == restart_index) { |
| continue; |
| } |
| if (index > maxindex) { |
| maxindex = index; |
| } |
| } |
| } else { |
| os::log("apitrace: warning: %s: unknown GLenum 0x%04X\n", __FUNCTION__, type); |
| } |
| |
| if (element_array_buffer) { |
| free(temp); |
| } |
| |
| maxindex += params.basevertex; |
| |
| return maxindex + 1; |
| } |
| |
| |
| GLuint |
| _glDraw_count(gltrace::Context *ctx, const MultiDrawArraysParams ¶ms) |
| { |
| GLuint _count = 0; |
| for (GLsizei draw = 0; draw < params.drawcount; ++draw) { |
| DrawArraysParams params_draw; |
| if (params.first) { |
| params_draw.first = params.first[draw]; |
| } |
| if (params.count) { |
| params_draw.count = params.count[draw]; |
| } |
| params_draw.instancecount = params.instancecount; |
| params_draw.baseinstance = params.baseinstance; |
| GLuint _count_draw = _glDraw_count(ctx, params_draw); |
| _count = std::max(_count, _count_draw); |
| } |
| return _count; |
| } |
| |
| |
| GLuint |
| _glDraw_count(gltrace::Context *ctx, const MultiDrawElementsParams ¶ms) |
| { |
| GLuint _count = 0; |
| for (GLsizei draw = 0; draw < params.drawcount; ++draw) { |
| DrawElementsParams params_draw; |
| if (params.count) { |
| params_draw.count = params.count[draw]; |
| } |
| params_draw.type = params.type; |
| if (params.indices) { |
| params_draw.indices = params.indices[draw]; |
| } |
| if (params.basevertex) { |
| params_draw.basevertex = params.basevertex[draw]; |
| } |
| params_draw.instancecount = params.instancecount; |
| params_draw.baseinstance = params.baseinstance; |
| GLuint _count_draw = _glDraw_count(ctx, params_draw); |
| _count = std::max(_count, _count_draw); |
| } |
| return _count; |
| } |
| |