Beispiel #1
0
static inline GLuint
_glMultiDrawElementsIndirect_count(GLenum type, const GLvoid *indirect, GLsizei drawcount, GLsizei stride) {
    const DrawElementsIndirectCommand *cmd;
    GLvoid *temp = 0;

    if (drawcount <= 0) {
        return 0;
    }

    if (stride == 0) {
        stride = sizeof *cmd;
    }

    GLint draw_indirect_buffer = _glGetInteger(GL_DRAW_INDIRECT_BUFFER_BINDING);
    if (draw_indirect_buffer) {
        // Read commands from indirect buffer object
        GLintptr offset = (GLintptr)indirect;
        GLsizeiptr size = sizeof *cmd + (drawcount - 1) * stride;
        GLvoid *temp = malloc(size);
        if (!temp) {
            return 0;
        }
        memset(temp, 0, size);
        _glGetBufferSubData(GL_DRAW_INDIRECT_BUFFER, offset, size, temp);
        indirect = temp;
    } else {
        if (!indirect) {
            return 0;
        }
    }

    cmd = (const DrawElementsIndirectCommand *)indirect;

    GLuint count = 0;
    for (GLsizei i = 0; i < drawcount; ++i) {
        cmd = (const DrawElementsIndirectCommand *)((const GLbyte *)indirect + i * stride);

        GLuint count_i = _glDrawElementsInstancedBaseVertexBaseInstance_count(
                             cmd->count,
                             type,
                             (GLvoid *)(uintptr_t)(cmd->firstIndex * _gl_type_size(type)),
                             cmd->primCount,
                             cmd->baseVertex,
                             cmd->baseInstance
                         );

        count = std::max(count, count_i);
    }

    if (draw_indirect_buffer) {
        free(temp);
    }

    return count;
}
Beispiel #2
0
static inline GLuint
_glDrawElementsBaseVertex_count(GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex)
{
    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
        GLintptr offset = (GLintptr)indices;
        GLsizeiptr size = count*_gl_type_size(type);
        temp = malloc(size);
        if (!temp) {
            return 0;
        }
        memset(temp, 0, size);
        _shadow_glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, size, temp);
        indices = temp;
    } else {
        if (!indices) {
            return 0;
        }
    }

    GLuint maxindex = 0;

    GLboolean restart_enabled = _glIsEnabled(GL_PRIMITIVE_RESTART);
    while ((_glGetError() == GL_INVALID_ENUM))
        ;

    GLuint restart_index = 0;
    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 += basevertex;

    return maxindex + 1;
}
Beispiel #3
0
static inline GLint
_element_array_buffer_binding(void) {
    return _glGetInteger(GL_ELEMENT_ARRAY_BUFFER_BINDING);
}
Beispiel #4
0
GLuint
_glDraw_count(gltrace::Context *ctx, const DrawElementsParams &params)
{
    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;
}