//// Created by Gabriel Calero & Cristian Duarte on 9/27/2016.// Copyright 2016 High Fidelity, Inc.//// Distributed under the Apache License, Version 2.0.// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html//#include "GLESBackend.h" #include <mutex>#include <queue>#include <list>#include <functional>#include <glm/gtc/type_ptr.hpp> Q_LOGGING_CATEGORY(gpugleslogging, "hifi.gpu.gles") using namespace gpu;using namespace gpu::gles; const std::string GLESBackend::GLES_VERSION { "GLES" }; void GLESBackend::draw(GLenum mode, uint32 numVertices, uint32 startVertex) { if (isStereo()) {#ifdef GPU_STEREO_DRAWCALL_INSTANCED glDrawArraysInstanced(mode, startVertex, numVertices, 2);#else setupStereoSide(0); glDrawArrays(mode, startVertex, numVertices); setupStereoSide(1); glDrawArrays(mode, startVertex, numVertices);#endif _stats._DSNumTriangles += 2 * numVertices / 3; _stats._DSNumDrawcalls += 2; } else { glDrawArrays(mode, startVertex, numVertices); _stats._DSNumTriangles += numVertices / 3; _stats._DSNumDrawcalls++; } _stats._DSNumAPIDrawcalls++; (void)CHECK_GL_ERROR();} void GLESBackend::do_draw(const Batch& batch, size_t paramOffset) { Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint; GLenum mode = gl::PRIMITIVE_TO_GL[primitiveType]; uint32 numVertices = batch._params[paramOffset + 1]._uint; uint32 startVertex = batch._params[paramOffset + 0]._uint; draw(mode, numVertices, startVertex);} void GLESBackend::do_drawIndexed(const Batch& batch, size_t paramOffset) { Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint; GLenum mode = gl::PRIMITIVE_TO_GL[primitiveType]; uint32 numIndices = batch._params[paramOffset + 1]._uint; uint32 startIndex = batch._params[paramOffset + 0]._uint; GLenum glType = gl::ELEMENT_TYPE_TO_GL[_input._indexBufferType]; auto typeByteSize = TYPE_SIZE[_input._indexBufferType]; GLvoid* indexBufferByteOffset = reinterpret_cast<GLvoid*>(startIndex * typeByteSize + _input._indexBufferOffset); if (isStereo()) {#ifdef GPU_STEREO_DRAWCALL_INSTANCED glDrawElementsInstanced(mode, numIndices, glType, indexBufferByteOffset, 2);#else setupStereoSide(0); glDrawElements(mode, numIndices, glType, indexBufferByteOffset); setupStereoSide(1); glDrawElements(mode, numIndices, glType, indexBufferByteOffset);#endif _stats._DSNumTriangles += 2 * numIndices / 3; _stats._DSNumDrawcalls += 2; } else { //qDebug() << "GLESBackend::do_drawIndexed glDrawElements " << numIndices; glDrawElements(mode, numIndices, glType, indexBufferByteOffset); _stats._DSNumTriangles += numIndices / 3; _stats._DSNumDrawcalls++; } _stats._DSNumAPIDrawcalls++; (void) CHECK_GL_ERROR();} void GLESBackend::do_drawInstanced(const Batch& batch, size_t paramOffset) { GLint numInstances = batch._params[paramOffset + 4]._uint; Primitive primitiveType = (Primitive)batch._params[paramOffset + 3]._uint; GLenum mode = gl::PRIMITIVE_TO_GL[primitiveType]; uint32 numVertices = batch._params[paramOffset + 2]._uint; uint32 startVertex = batch._params[paramOffset + 1]._uint; if (isStereo()) { GLint trueNumInstances = 2 * numInstances; #ifdef GPU_STEREO_DRAWCALL_INSTANCED glDrawArraysInstanced(mode, startVertex, numVertices, trueNumInstances);#else setupStereoSide(0); glDrawArraysInstanced(mode, startVertex, numVertices, numInstances); setupStereoSide(1); glDrawArraysInstanced(mode, startVertex, numVertices, numInstances);#endif _stats._DSNumTriangles += (trueNumInstances * numVertices) / 3; _stats._DSNumDrawcalls += trueNumInstances; } else { //qDebug() << "GLESBackend::do_drawInstanced glDrawArraysInstancedEXT " << numVertices << "," << numInstances; glDrawArraysInstanced(mode, startVertex, numVertices, numInstances); _stats._DSNumTriangles += (numInstances * numVertices) / 3; _stats._DSNumDrawcalls += numInstances; } _stats._DSNumAPIDrawcalls++; (void) CHECK_GL_ERROR();} void glesbackend_glDrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex, GLuint baseinstance) {//#if (GPU_INPUT_PROFILE == GPU_CORE_43) //glDrawElementsInstancedBaseVertexBaseInstance(mode, count, type, indices, primcount, basevertex, baseinstance);//#else glDrawElementsInstanced(mode, count, type, indices, primcount);//#endif} void GLESBackend::do_drawIndexedInstanced(const Batch& batch, size_t paramOffset) { GLint numInstances = batch._params[paramOffset + 4]._uint; GLenum mode = gl::PRIMITIVE_TO_GL[(Primitive)batch._params[paramOffset + 3]._uint]; uint32 numIndices = batch._params[paramOffset + 2]._uint; uint32 startIndex = batch._params[paramOffset + 1]._uint; // FIXME glDrawElementsInstancedBaseVertexBaseInstance is only available in GL 4.3 // and higher, so currently we ignore this field uint32 startInstance = batch._params[paramOffset + 0]._uint; GLenum glType = gl::ELEMENT_TYPE_TO_GL[_input._indexBufferType]; auto typeByteSize = TYPE_SIZE[_input._indexBufferType]; GLvoid* indexBufferByteOffset = reinterpret_cast<GLvoid*>(startIndex * typeByteSize + _input._indexBufferOffset); if (isStereo()) { GLint trueNumInstances = 2 * numInstances; #ifdef GPU_STEREO_DRAWCALL_INSTANCED glesbackend_glDrawElementsInstancedBaseVertexBaseInstance(mode, numIndices, glType, indexBufferByteOffset, trueNumInstances, 0, startInstance);#else setupStereoSide(0); glesbackend_glDrawElementsInstancedBaseVertexBaseInstance(mode, numIndices, glType, indexBufferByteOffset, numInstances, 0, startInstance); setupStereoSide(1); glesbackend_glDrawElementsInstancedBaseVertexBaseInstance(mode, numIndices, glType, indexBufferByteOffset, numInstances, 0, startInstance);#endif _stats._DSNumTriangles += (trueNumInstances * numIndices) / 3; _stats._DSNumDrawcalls += trueNumInstances; } else { //qDebug() << "GLESBackend::do_drawIndexedInstanced glesbackend_glDrawElementsInstancedBaseVertexBaseInstance " << numInstances; glesbackend_glDrawElementsInstancedBaseVertexBaseInstance(mode, numIndices, glType, indexBufferByteOffset, numInstances, 0, startInstance); _stats._DSNumTriangles += (numInstances * numIndices) / 3; _stats._DSNumDrawcalls += numInstances; } _stats._DSNumAPIDrawcalls++; (void)CHECK_GL_ERROR();} void GLESBackend::do_multiDrawIndirect(const Batch& batch, size_t paramOffset) {#if (GPU_INPUT_PROFILE == GPU_CORE_43) uint commandCount = batch._params[paramOffset + 0]._uint; //GLenum mode = gl::PRIMITIVE_TO_GL[(Primitive)batch._params[paramOffset + 1]._uint]; //glMultiDrawArraysIndirect(mode, reinterpret_cast<GLvoid*>(_input._indirectBufferOffset), commandCount, (GLsizei)_input._indirectBufferStride); qDebug() << "TODO: GLESBackend.cpp:do_multiDrawIndirect do_multiDrawIndirect"; _stats._DSNumDrawcalls += commandCount; _stats._DSNumAPIDrawcalls++; #else // FIXME implement the slow path#endif (void)CHECK_GL_ERROR(); } void GLESBackend::do_multiDrawIndexedIndirect(const Batch& batch, size_t paramOffset) {//#if (GPU_INPUT_PROFILE == GPU_CORE_43) uint commandCount = batch._params[paramOffset + 0]._uint; //GLenum mode = gl::PRIMITIVE_TO_GL[(Primitive)batch._params[paramOffset + 1]._uint]; //GLenum indexType = gl::ELEMENT_TYPE_TO_GL[_input._indexBufferType]; //glMultiDrawElementsIndirect(mode, indexType, reinterpret_cast<GLvoid*>(_input._indirectBufferOffset), commandCount, (GLsizei)_input._indirectBufferStride); qDebug() << "TODO: GLESBackend.cpp:do_multiDrawIndexedIndirect glMultiDrawElementsIndirect"; _stats._DSNumDrawcalls += commandCount; _stats._DSNumAPIDrawcalls++;//#else // FIXME implement the slow path//#endif (void)CHECK_GL_ERROR();}
//
// Created by Gabriel Calero & Cristian Duarte on 9/27/2016.
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "GLESBackend.h"
#include <mutex>
#include <queue>
#include <list>
#include <functional>
#include <glm/gtc/type_ptr.hpp>
Q_LOGGING_CATEGORY(gpugleslogging, "hifi.gpu.gles")
using namespace gpu;
using namespace gpu::gles;
const std::string GLESBackend::GLES_VERSION { "GLES" };
void GLESBackend::draw(GLenum mode, uint32 numVertices, uint32 startVertex) {
if (isStereo()) {
#ifdef GPU_STEREO_DRAWCALL_INSTANCED
glDrawArraysInstanced(mode, startVertex, numVertices, 2);
#else
setupStereoSide(0);
glDrawArrays(mode, startVertex, numVertices);
setupStereoSide(1);
glDrawArrays(mode, startVertex, numVertices);
#endif
_stats._DSNumTriangles += 2 * numVertices / 3;
_stats._DSNumDrawcalls += 2;
} else {
glDrawArrays(mode, startVertex, numVertices);
_stats._DSNumTriangles += numVertices / 3;
_stats._DSNumDrawcalls++;
}
_stats._DSNumAPIDrawcalls++;
(void)CHECK_GL_ERROR();
}
void GLESBackend::do_draw(const Batch& batch, size_t paramOffset) {
Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint;
GLenum mode = gl::PRIMITIVE_TO_GL[primitiveType];
uint32 numVertices = batch._params[paramOffset + 1]._uint;
uint32 startVertex = batch._params[paramOffset + 0]._uint;
draw(mode, numVertices, startVertex);
}
void GLESBackend::do_drawIndexed(const Batch& batch, size_t paramOffset) {
Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint;
GLenum mode = gl::PRIMITIVE_TO_GL[primitiveType];
uint32 numIndices = batch._params[paramOffset + 1]._uint;
uint32 startIndex = batch._params[paramOffset + 0]._uint;
GLenum glType = gl::ELEMENT_TYPE_TO_GL[_input._indexBufferType];
auto typeByteSize = TYPE_SIZE[_input._indexBufferType];
GLvoid* indexBufferByteOffset = reinterpret_cast<GLvoid*>(startIndex * typeByteSize + _input._indexBufferOffset);
if (isStereo()) {
#ifdef GPU_STEREO_DRAWCALL_INSTANCED
glDrawElementsInstanced(mode, numIndices, glType, indexBufferByteOffset, 2);
#else
setupStereoSide(0);
glDrawElements(mode, numIndices, glType, indexBufferByteOffset);
setupStereoSide(1);
glDrawElements(mode, numIndices, glType, indexBufferByteOffset);
#endif
_stats._DSNumTriangles += 2 * numIndices / 3;
_stats._DSNumDrawcalls += 2;
} else {
//qDebug() << "GLESBackend::do_drawIndexed glDrawElements " << numIndices;
glDrawElements(mode, numIndices, glType, indexBufferByteOffset);
_stats._DSNumTriangles += numIndices / 3;
_stats._DSNumDrawcalls++;
}
_stats._DSNumAPIDrawcalls++;
(void) CHECK_GL_ERROR();
}
void GLESBackend::do_drawInstanced(const Batch& batch, size_t paramOffset) {
GLint numInstances = batch._params[paramOffset + 4]._uint;
Primitive primitiveType = (Primitive)batch._params[paramOffset + 3]._uint;
GLenum mode = gl::PRIMITIVE_TO_GL[primitiveType];
uint32 numVertices = batch._params[paramOffset + 2]._uint;
uint32 startVertex = batch._params[paramOffset + 1]._uint;
if (isStereo()) {
GLint trueNumInstances = 2 * numInstances;
#ifdef GPU_STEREO_DRAWCALL_INSTANCED
glDrawArraysInstanced(mode, startVertex, numVertices, trueNumInstances);
#else
setupStereoSide(0);
glDrawArraysInstanced(mode, startVertex, numVertices, numInstances);
setupStereoSide(1);
glDrawArraysInstanced(mode, startVertex, numVertices, numInstances);
#endif
_stats._DSNumTriangles += (trueNumInstances * numVertices) / 3;
_stats._DSNumDrawcalls += trueNumInstances;
} else {
//qDebug() << "GLESBackend::do_drawInstanced glDrawArraysInstancedEXT " << numVertices << "," << numInstances;
glDrawArraysInstanced(mode, startVertex, numVertices, numInstances);
_stats._DSNumTriangles += (numInstances * numVertices) / 3;
_stats._DSNumDrawcalls += numInstances;
}
_stats._DSNumAPIDrawcalls++;
(void) CHECK_GL_ERROR();
}
void glesbackend_glDrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex, GLuint baseinstance) {
//#if (GPU_INPUT_PROFILE == GPU_CORE_43)
//glDrawElementsInstancedBaseVertexBaseInstance(mode, count, type, indices, primcount, basevertex, baseinstance);
//#else
glDrawElementsInstanced(mode, count, type, indices, primcount);
//#endif
}
void GLESBackend::do_drawIndexedInstanced(const Batch& batch, size_t paramOffset) {
GLint numInstances = batch._params[paramOffset + 4]._uint;
GLenum mode = gl::PRIMITIVE_TO_GL[(Primitive)batch._params[paramOffset + 3]._uint];
uint32 numIndices = batch._params[paramOffset + 2]._uint;
uint32 startIndex = batch._params[paramOffset + 1]._uint;
// FIXME glDrawElementsInstancedBaseVertexBaseInstance is only available in GL 4.3
// and higher, so currently we ignore this field
uint32 startInstance = batch._params[paramOffset + 0]._uint;
GLenum glType = gl::ELEMENT_TYPE_TO_GL[_input._indexBufferType];
auto typeByteSize = TYPE_SIZE[_input._indexBufferType];
GLvoid* indexBufferByteOffset = reinterpret_cast<GLvoid*>(startIndex * typeByteSize + _input._indexBufferOffset);
if (isStereo()) {
GLint trueNumInstances = 2 * numInstances;
#ifdef GPU_STEREO_DRAWCALL_INSTANCED
glesbackend_glDrawElementsInstancedBaseVertexBaseInstance(mode, numIndices, glType, indexBufferByteOffset,
trueNumInstances, 0, startInstance);
#else
setupStereoSide(0);
glesbackend_glDrawElementsInstancedBaseVertexBaseInstance(mode, numIndices, glType, indexBufferByteOffset, numInstances,
0, startInstance);
setupStereoSide(1);
glesbackend_glDrawElementsInstancedBaseVertexBaseInstance(mode, numIndices, glType, indexBufferByteOffset, numInstances,
0, startInstance);
#endif
_stats._DSNumTriangles += (trueNumInstances * numIndices) / 3;
_stats._DSNumDrawcalls += trueNumInstances;
} else {
//qDebug() << "GLESBackend::do_drawIndexedInstanced glesbackend_glDrawElementsInstancedBaseVertexBaseInstance " << numInstances;
glesbackend_glDrawElementsInstancedBaseVertexBaseInstance(mode, numIndices, glType, indexBufferByteOffset, numInstances,
0, startInstance);
_stats._DSNumTriangles += (numInstances * numIndices) / 3;
_stats._DSNumDrawcalls += numInstances;
}
_stats._DSNumAPIDrawcalls++;
(void)CHECK_GL_ERROR();
}
void GLESBackend::do_multiDrawIndirect(const Batch& batch, size_t paramOffset) {
#if (GPU_INPUT_PROFILE == GPU_CORE_43)
uint commandCount = batch._params[paramOffset + 0]._uint;
//GLenum mode = gl::PRIMITIVE_TO_GL[(Primitive)batch._params[paramOffset + 1]._uint];
//glMultiDrawArraysIndirect(mode, reinterpret_cast<GLvoid*>(_input._indirectBufferOffset), commandCount, (GLsizei)_input._indirectBufferStride);
qDebug() << "TODO: GLESBackend.cpp:do_multiDrawIndirect do_multiDrawIndirect";
_stats._DSNumDrawcalls += commandCount;
_stats._DSNumAPIDrawcalls++;
#else
// FIXME implement the slow path
#endif
(void)CHECK_GL_ERROR();
}
void GLESBackend::do_multiDrawIndexedIndirect(const Batch& batch, size_t paramOffset) {
//#if (GPU_INPUT_PROFILE == GPU_CORE_43)
uint commandCount = batch._params[paramOffset + 0]._uint;
//GLenum mode = gl::PRIMITIVE_TO_GL[(Primitive)batch._params[paramOffset + 1]._uint];
//GLenum indexType = gl::ELEMENT_TYPE_TO_GL[_input._indexBufferType];
//glMultiDrawElementsIndirect(mode, indexType, reinterpret_cast<GLvoid*>(_input._indirectBufferOffset), commandCount, (GLsizei)_input._indirectBufferStride);
qDebug() << "TODO: GLESBackend.cpp:do_multiDrawIndexedIndirect glMultiDrawElementsIndirect";
_stats._DSNumDrawcalls += commandCount;
_stats._DSNumAPIDrawcalls++;
//#else
// FIXME implement the slow path
//#endif
(void)CHECK_GL_ERROR();
}