Implemented glDrawRangeElements
This function is basically the same as
glDrawElements, except, in Debug, it
returns an error if the draw operation
reads outside of the expected range.
Change-Id: I2472c317eb5d8a1da89c5a76f076fe95adc6789e
Reviewed-on: https://swiftshader-review.googlesource.com/2829
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index 70beb74..bc6064c 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -2700,9 +2700,9 @@
}
// Applies the indices and element array bindings
-GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
+GLenum Context::applyIndexBuffer(const void *indices, GLuint start, GLuint end, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
{
- GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer, indices, indexInfo);
+ GLenum err = mIndexDataManager->prepareIndexData(type, start, end, count, mState.elementArrayBuffer, indices, indexInfo);
if(err == GL_NO_ERROR)
{
@@ -3285,7 +3285,7 @@
}
}
-void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
+void Context::drawElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices)
{
if(!mState.currentProgram)
{
@@ -3316,7 +3316,7 @@
applyState(mode);
TranslatedIndexData indexInfo;
- GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo);
+ GLenum err = applyIndexBuffer(indices, start, end, count, mode, type, &indexInfo);
if(err != GL_NO_ERROR)
{
return error(err);
diff --git a/src/OpenGL/libGLESv2/Context.h b/src/OpenGL/libGLESv2/Context.h
index 995015a..b2bd8ee 100644
--- a/src/OpenGL/libGLESv2/Context.h
+++ b/src/OpenGL/libGLESv2/Context.h
@@ -553,7 +553,7 @@
void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);
void clear(GLbitfield mask);
void drawArrays(GLenum mode, GLint first, GLsizei count);
- void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
+ void drawElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices);
void finish();
void flush();
@@ -585,7 +585,7 @@
bool applyRenderTarget();
void applyState(GLenum drawMode);
GLenum applyVertexBuffer(GLint base, GLint first, GLsizei count);
- GLenum applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
+ GLenum applyIndexBuffer(const void *indices, GLuint start, GLuint end, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
void applyShaders();
void applyTextures();
void applyTextures(sw::SamplerType type);
diff --git a/src/OpenGL/libGLESv2/IndexDataManager.cpp b/src/OpenGL/libGLESv2/IndexDataManager.cpp
index a2b468c..0bf93f0 100644
--- a/src/OpenGL/libGLESv2/IndexDataManager.cpp
+++ b/src/OpenGL/libGLESv2/IndexDataManager.cpp
@@ -90,7 +90,7 @@
else UNREACHABLE();
}
-GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *buffer, const void *indices, TranslatedIndexData *translated)
+GLenum IndexDataManager::prepareIndexData(GLenum type, GLuint start, GLuint end, GLsizei count, Buffer *buffer, const void *indices, TranslatedIndexData *translated)
{
if(!mStreamingBuffer)
{
@@ -152,6 +152,11 @@
translated->indexOffset = streamOffset;
}
+ if(translated->minIndex < start || translated->maxIndex > end)
+ {
+ ERR("glDrawRangeElements: out of range access. Range provided: [%d -> %d]. Range used: [%d -> %d].", start, end, translated->minIndex, translated->maxIndex);
+ }
+
return GL_NO_ERROR;
}
diff --git a/src/OpenGL/libGLESv2/IndexDataManager.h b/src/OpenGL/libGLESv2/IndexDataManager.h
index 0bab66e..5ff6d94 100644
--- a/src/OpenGL/libGLESv2/IndexDataManager.h
+++ b/src/OpenGL/libGLESv2/IndexDataManager.h
@@ -56,7 +56,7 @@
IndexDataManager();
virtual ~IndexDataManager();
- GLenum prepareIndexData(GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);
+ GLenum prepareIndexData(GLenum type, GLuint start, GLuint end, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);
static std::size_t typeSize(GLenum type);
diff --git a/src/OpenGL/libGLESv2/libGLESv2.cpp b/src/OpenGL/libGLESv2/libGLESv2.cpp
index 3277120..e528154 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.cpp
@@ -1819,7 +1819,7 @@
return error(GL_INVALID_ENUM);
}
- context->drawElements(mode, count, type, indices);
+ context->drawElements(mode, 0, UINT_MAX, count, type, indices);
}
}
diff --git a/src/OpenGL/libGLESv2/libGLESv3.cpp b/src/OpenGL/libGLESv2/libGLESv3.cpp
index 05f2468..4d4964a 100644
--- a/src/OpenGL/libGLESv2/libGLESv3.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv3.cpp
@@ -517,7 +517,12 @@
return error(GL_INVALID_VALUE);
}
- UNIMPLEMENTED();
+ es2::Context *context = es2::getContext();
+
+ if(context)
+ {
+ context->drawElements(mode, start, end, count, type, indices);
+ }
}
void GL_APIENTRY glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels)