m_max_renderBufferSize = 0;
m_max_textureSize = 0;
m_max_3d_textureSize = 0;
+ m_max_vertexAttribStride = 0;
m_compressedTextureFormats = NULL;
m_ssbo_offset_align = 0;
OVERRIDE(glBindSampler);
- OVERRIDE(glDeleteSync);
+ OVERRIDE_CUSTOM(glFenceSync);
+ OVERRIDE_CUSTOM(glClientWaitSync);
+ OVERRIDE_CUSTOM(glWaitSync);
+ OVERRIDE_CUSTOM(glDeleteSync);
+ OVERRIDE_CUSTOM(glIsSync);
+ OVERRIDE_CUSTOM(glGetSynciv);
OVERRIDE(glGetIntegeri_v);
OVERRIDE(glGetInteger64i_v);
OVERRIDE(glGetShaderiv);
+ OVERRIDE(glActiveShaderProgram);
OVERRIDE_CUSTOM(glCreateShaderProgramv);
OVERRIDE(glProgramUniform1f);
OVERRIDE(glProgramUniform1fv);
OVERRIDE(glProgramUniformMatrix4x2fv);
OVERRIDE(glProgramUniformMatrix4x3fv);
+ OVERRIDE(glProgramParameteri);
OVERRIDE(glUseProgramStages);
OVERRIDE(glBindProgramPipeline);
+ OVERRIDE(glGetProgramResourceiv);
+ OVERRIDE(glGetProgramResourceIndex);
+ OVERRIDE(glGetProgramResourceLocation);
+ OVERRIDE(glGetProgramResourceName);
+ OVERRIDE(glGetProgramPipelineInfoLog);
+
OVERRIDE(glVertexAttribFormat);
OVERRIDE(glVertexAttribIFormat);
OVERRIDE(glVertexBindingDivisor);
GL2Encoder *ctx = (GL2Encoder *) self;
assert(ctx->m_state != NULL);
ctx->m_state->bindBuffer(target, id);
+ ctx->m_state->addBuffer(id);
// TODO set error state if needed;
ctx->m_glBindBuffer_enc(self, target, id);
}
ctx->m_glBufferSubData_enc(self, target, offset, size, data);
}
+void GL2Encoder::s_glGenBuffers(void* self, GLsizei n, GLuint* buffers) {
+ GL2Encoder *ctx = (GL2Encoder *) self;
+ SET_ERROR_IF(n<0, GL_INVALID_VALUE);
+ ctx->m_glGenBuffers_enc(self, n, buffers);
+ for (int i = 0; i < n; i++) {
+ ctx->m_state->addBuffer(buffers[i]);
+ }
+}
+
void GL2Encoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers)
{
GL2Encoder *ctx = (GL2Encoder *) self;
// use it anymore after this :)
ctx->m_shared->deleteBufferData(buffers[i]);
ctx->m_state->unBindBuffer(buffers[i]);
+ ctx->m_state->removeBuffer(buffers[i]);
ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]);
}
}
ctx->m_state->setMaxVertexAttribs(*ptr);
}
break;
+ case GL_MAX_VERTEX_ATTRIB_STRIDE:
+ if (ctx->m_max_vertexAttribStride != 0) {
+ *ptr = ctx->m_max_vertexAttribStride;
+ } else {
+ ctx->m_glGetIntegerv_enc(self, param, ptr);
+ ctx->m_max_vertexAttribStride = *ptr;
+ }
+ break;
case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
if (ctx->m_max_cubeMapTextureSize != 0) {
*ptr = ctx->m_max_cubeMapTextureSize;
// Desktop OpenGL can allow a mindboggling # samples per pixel (such as 64).
// Limit to 4 (spec minimum) to keep dEQP tests from timing out.
case GL_MAX_SAMPLES:
+ case GL_MAX_COLOR_TEXTURE_SAMPLES:
+ case GL_MAX_INTEGER_SAMPLES:
+ case GL_MAX_DEPTH_TEXTURE_SAMPLES:
*ptr = 4;
break;
default:
// The following expression actually means bufLen = stride*count;
// But the last element doesn't have to fill up the whole stride.
// So it becomes the current form.
- unsigned int bufLen = effectiveStride * (count - 1) + state.elementSize;
+ unsigned int bufLen = effectiveStride * (count ? (count - 1) : 0) + state.elementSize;
if (divisor && primcount) {
int actual_count = std::max(1, (int)((primcount + divisor - 1) / divisor));
- bufLen = effectiveStride * (actual_count - 1) + state.elementSize;
+ bufLen = effectiveStride * (actual_count ? (actual_count - 1) : 0) + state.elementSize;
}
if (buf && firstIndex >= 0 && firstIndex + bufLen <= buf->m_size) {
if (hasClientArrays) {
}
} else {
ALOGE("a vertex attribute index out of boundary is detected. Skipping corresponding vertex attribute. buf=%p", buf);
- // ALOGE("Out of bounds vertex attribute info: "
- // "clientArray? %d attribute %d vbo %u allocedBufferSize %u bufferDataSpecified? %d wantedStart %u wantedEnd %u",
- // hasClientArrays, i, bufferObject, buf->m_size, buf != NULL, firstIndex, firstIndex + bufLen);
- // m_glDisableVertexAttribArray_enc(this, i);
+ if (buf) {
+ ALOGE("Out of bounds vertex attribute info: "
+ "clientArray? %d attribute %d vbo %u allocedBufferSize %u bufferDataSpecified? %d wantedStart %u wantedEnd %u",
+ hasClientArrays, i, bufferObject, buf->m_size, buf != NULL, firstIndex, firstIndex + bufLen);
+ }
+ m_glDisableVertexAttribArray_enc(this, i);
}
}
} else {
ctx->sendVertexAttributes(0, count, false);
ctx->m_glDrawArrays_enc(ctx, mode, first, count);
}
- ctx->m_stream->flush();
+ // ctx->m_stream->flush();
}
ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1, true);
ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices,
count * glSizeof(type));
- ctx->m_stream->flush();
+ // ctx->m_stream->flush();
// XXX - OPTIMIZATION (see the other else branch) should be implemented
if(!has_indirect_arrays) {
//ALOGD("unoptimized drawelements !!!\n");
void GL2Encoder::s_glLinkProgram(void * self, GLuint program)
{
+ ALOGD("%s: link %u\n", __FUNCTION__, program);
GL2Encoder *ctx = (GL2Encoder *)self;
bool isProgram = ctx->m_shared->isProgram(program);
SET_ERROR_IF(!isProgram && !ctx->m_shared->isShader(program), GL_INVALID_VALUE);
GLint linkStatus = 0;
ctx->glGetProgramiv(self,program,GL_LINK_STATUS,&linkStatus);
- if (!linkStatus)
+ if (!linkStatus) {
return;
+ }
//get number of active uniforms in the program
GLint numUniforms=0;
GLuint GL2Encoder::s_glCreateShader(void *self, GLenum shaderType)
{
+ ALOGD("%s: create shader of type 0x%x\n", __FUNCTION__, shaderType);
GL2Encoder *ctx = (GL2Encoder*)self;
RET_AND_SET_ERROR_IF(!GLESv2Validation::shaderType(ctx, shaderType), GL_INVALID_ENUM, 0);
GLuint shader = ctx->m_glCreateShader_enc(self, shaderType);
void GL2Encoder::s_glAttachShader(void *self, GLuint program, GLuint shader)
{
+ ALOGD("%s: attach shader %u to %u\n", __FUNCTION__, shader, program);
GL2Encoder *ctx = (GL2Encoder*)self;
ctx->m_glAttachShader_enc(self, program, shader);
ctx->m_shared->attachShader(program, shader);
ctx->m_glUseProgram_enc(self, program);
ctx->m_state->setCurrentProgram(program);
+ ctx->m_state->setCurrentShaderProgram(program);
ctx->updateHostTexture2DBindingsFromProgramData(program);
}
void GL2Encoder::s_glUniform1f(void *self , GLint location, GLfloat x)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform1f_enc(self, hostLoc, x);
}
void GL2Encoder::s_glUniform1fv(void *self , GLint location, GLsizei count, const GLfloat* v)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform1fv_enc(self, hostLoc, count, v);
}
GLClientState* state = ctx->m_state;
GLSharedGroupPtr shared = ctx->m_shared;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform1i_enc(self, hostLoc, x);
GLenum target;
- if (shared->setSamplerUniform(state->currentProgram(), location, x, &target)) {
+ if (shared->setSamplerUniform(state->currentShaderProgram(), location, x, &target)) {
GLenum origActiveTexture = state->getActiveTextureUnit();
if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + x, target)) {
ctx->m_glActiveTexture_enc(self, origActiveTexture);
void GL2Encoder::s_glUniform1iv(void *self , GLint location, GLsizei count, const GLint* v)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform1iv_enc(self, hostLoc, count, v);
}
void GL2Encoder::s_glUniform2f(void *self , GLint location, GLfloat x, GLfloat y)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform2f_enc(self, hostLoc, x, y);
}
void GL2Encoder::s_glUniform2fv(void *self , GLint location, GLsizei count, const GLfloat* v)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform2fv_enc(self, hostLoc, count, v);
}
void GL2Encoder::s_glUniform2i(void *self , GLint location, GLint x, GLint y)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform2i_enc(self, hostLoc, x, y);
}
void GL2Encoder::s_glUniform2iv(void *self , GLint location, GLsizei count, const GLint* v)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform2iv_enc(self, hostLoc, count, v);
}
void GL2Encoder::s_glUniform3f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform3f_enc(self, hostLoc, x, y, z);
}
void GL2Encoder::s_glUniform3fv(void *self , GLint location, GLsizei count, const GLfloat* v)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform3fv_enc(self, hostLoc, count, v);
}
void GL2Encoder::s_glUniform3i(void *self , GLint location, GLint x, GLint y, GLint z)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform3i_enc(self, hostLoc, x, y, z);
}
void GL2Encoder::s_glUniform3iv(void *self , GLint location, GLsizei count, const GLint* v)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform3iv_enc(self, hostLoc, count, v);
}
void GL2Encoder::s_glUniform4f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform4f_enc(self, hostLoc, x, y, z, w);
}
void GL2Encoder::s_glUniform4fv(void *self , GLint location, GLsizei count, const GLfloat* v)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform4fv_enc(self, hostLoc, count, v);
}
void GL2Encoder::s_glUniform4i(void *self , GLint location, GLint x, GLint y, GLint z, GLint w)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform4i_enc(self, hostLoc, x, y, z, w);
}
void GL2Encoder::s_glUniform4iv(void *self , GLint location, GLsizei count, const GLint* v)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform4iv_enc(self, hostLoc, count, v);
}
void GL2Encoder::s_glUniformMatrix2fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniformMatrix2fv_enc(self, hostLoc, count, transpose, value);
}
void GL2Encoder::s_glUniformMatrix3fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniformMatrix3fv_enc(self, hostLoc, count, transpose, value);
}
void GL2Encoder::s_glUniformMatrix4fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniformMatrix4fv_enc(self, hostLoc, count, transpose, value);
}
// double check with underlying opengl to avoid craziness.
GLenum host_checkstatus = ctx->m_glCheckFramebufferStatus_enc(self, target);
state->setCheckFramebufferStatus(target, host_checkstatus);
+ if (host_checkstatus == GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS) return GL_FRAMEBUFFER_COMPLETE;
return host_checkstatus;
}
}
RET_AND_SET_ERROR_IF(!buf, GL_INVALID_VALUE, GL_FALSE);
RET_AND_SET_ERROR_IF(!buf->m_mapped, GL_INVALID_OPERATION, GL_FALSE);
+ if (buf->m_mappedAccess & GL_MAP_WRITE_BIT) {
+ // invalide index range cache here
+ if (buf->m_mappedAccess & GL_MAP_INVALIDATE_BUFFER_BIT) {
+ buf->m_indexRangeCache.invalidateRange(0, buf->m_size);
+ } else {
+ buf->m_indexRangeCache.invalidateRange(buf->m_mappedOffset, buf->m_mappedLength);
+ }
+ }
+
GLboolean host_res = GL_TRUE;
ctx->glUnmapBufferAEMU(
SET_ERROR_IF(offset + length > buf->m_mappedLength, GL_INVALID_VALUE);
GLintptr totalOffset = buf->m_mappedOffset + offset;
+
+ buf->m_indexRangeCache.invalidateRange(totalOffset, length);
+
ctx->glFlushMappedBufferRangeAEMU(
ctx, target,
totalOffset,
GL_INVALID_VALUE);
state->bindBuffer(target, buffer);
+ ctx->m_state->addBuffer(buffer);
state->bindIndexedBuffer(target, index, buffer, offset, size, 0, 0);
ctx->m_glBindBufferRange_enc(self, target, index, buffer, offset, size);
}
GL_INVALID_VALUE);
state->bindBuffer(target, buffer);
+ ctx->m_state->addBuffer(buffer);
BufferData* buf = ctx->getBufferDataById(buffer);
state->bindIndexedBuffer(target, index, buffer, 0, buf ? buf->m_size : 0, 0, 0);
ctx->m_glBindBufferBase_enc(self, target, index, buffer);
SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
SET_ERROR_IF(
- target == GL_ATOMIC_COUNTER_BUFFER ||
- target == GL_DISPATCH_INDIRECT_BUFFER ||
- target == GL_DRAW_INDIRECT_BUFFER ||
- target == GL_SHADER_STORAGE_BUFFER,
+ target != GL_ARRAY_BUFFER &&
+ target != GL_ELEMENT_ARRAY_BUFFER &&
+ target != GL_COPY_READ_BUFFER &&
+ target != GL_COPY_WRITE_BUFFER &&
+ target != GL_PIXEL_PACK_BUFFER &&
+ target != GL_PIXEL_UNPACK_BUFFER &&
+ target != GL_TRANSFORM_FEEDBACK_BUFFER &&
+ target != GL_UNIFORM_BUFFER,
GL_INVALID_ENUM);
SET_ERROR_IF(!GLESv2Validation::bufferParam(ctx, pname), GL_INVALID_ENUM);
SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
- SET_ERROR_IF(pname == GL_BUFFER_MAP_LENGTH ||
- pname == GL_BUFFER_MAP_OFFSET,
- GL_INVALID_OPERATION);
+ SET_ERROR_IF(pname != GL_BUFFER_ACCESS_FLAGS &&
+ pname != GL_BUFFER_MAPPED &&
+ pname != GL_BUFFER_SIZE &&
+ pname != GL_BUFFER_USAGE &&
+ pname != GL_BUFFER_MAP_LENGTH &&
+ pname != GL_BUFFER_MAP_OFFSET,
+ GL_INVALID_ENUM);
if (!params) return;
case GL_BUFFER_USAGE:
*params = buf ? buf->m_usage : GL_STATIC_DRAW;
break;
+ case GL_BUFFER_MAP_LENGTH:
+ *params = buf ? buf->m_mappedLength : 0;
+ break;
+ case GL_BUFFER_MAP_OFFSET:
+ *params = buf ? buf->m_mappedOffset : 0;
+ break;
default:
break;
}
SET_ERROR_IF(!GLESv2Validation::bufferTarget(ctx, target), GL_INVALID_ENUM);
SET_ERROR_IF(
- target == GL_ATOMIC_COUNTER_BUFFER ||
- target == GL_DISPATCH_INDIRECT_BUFFER ||
- target == GL_DRAW_INDIRECT_BUFFER ||
- target == GL_SHADER_STORAGE_BUFFER,
+ target != GL_ARRAY_BUFFER &&
+ target != GL_ELEMENT_ARRAY_BUFFER &&
+ target != GL_COPY_READ_BUFFER &&
+ target != GL_COPY_WRITE_BUFFER &&
+ target != GL_PIXEL_PACK_BUFFER &&
+ target != GL_PIXEL_UNPACK_BUFFER &&
+ target != GL_TRANSFORM_FEEDBACK_BUFFER &&
+ target != GL_UNIFORM_BUFFER,
GL_INVALID_ENUM);
SET_ERROR_IF(!GLESv2Validation::bufferParam(ctx, pname), GL_INVALID_ENUM);
SET_ERROR_IF(!ctx->boundBuffer(target), GL_INVALID_OPERATION);
- SET_ERROR_IF(pname == GL_BUFFER_ACCESS_FLAGS ||
- pname == GL_BUFFER_MAPPED ||
- pname == GL_BUFFER_USAGE,
- GL_INVALID_OPERATION);
+ SET_ERROR_IF(pname != GL_BUFFER_ACCESS_FLAGS &&
+ pname != GL_BUFFER_MAPPED &&
+ pname != GL_BUFFER_SIZE &&
+ pname != GL_BUFFER_USAGE &&
+ pname != GL_BUFFER_MAP_LENGTH &&
+ pname != GL_BUFFER_MAP_OFFSET,
+ GL_INVALID_ENUM);
if (!params) return;
BufferData* buf = ctx->getBufferData(target);
switch (pname) {
+ case GL_BUFFER_ACCESS_FLAGS:
+ *params = buf ? buf->m_mappedAccess : 0;
+ break;
+ case GL_BUFFER_MAPPED:
+ *params = buf ? (buf->m_mapped ? GL_TRUE : GL_FALSE) : GL_FALSE;
+ break;
+ case GL_BUFFER_SIZE:
+ *params = buf ? buf->m_size : 0;
+ break;
+ case GL_BUFFER_USAGE:
+ *params = buf ? buf->m_usage : GL_STATIC_DRAW;
+ break;
case GL_BUFFER_MAP_LENGTH:
*params = buf ? buf->m_mappedLength : 0;
break;
case GL_BUFFER_MAP_OFFSET:
*params = buf ? buf->m_mappedOffset : 0;
break;
- case GL_BUFFER_SIZE:
- *params = buf ? buf->m_size : 0;
- break;
default:
break;
}
GLClientState* state = ctx->m_state;
GLSharedGroupPtr shared = ctx->m_shared;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform1ui_enc(self, hostLoc, v0);
GLenum target;
- if (shared->setSamplerUniform(state->currentProgram(), location, v0, &target)) {
+ if (shared->setSamplerUniform(state->currentShaderProgram(), location, v0, &target)) {
GLenum origActiveTexture = state->getActiveTextureUnit();
if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + v0, target)) {
ctx->m_glActiveTexture_enc(self, origActiveTexture);
void GL2Encoder::s_glUniform2ui(void* self, GLint location, GLuint v0, GLuint v1) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform2ui_enc(self, hostLoc, v0, v1);
}
void GL2Encoder::s_glUniform3ui(void* self, GLint location, GLuint v0, GLuint v1, GLuint v2) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform3ui_enc(self, hostLoc, v0, v1, v2);
}
void GL2Encoder::s_glUniform4ui(void* self, GLint location, GLint v0, GLuint v1, GLuint v2, GLuint v3) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform4ui_enc(self, hostLoc, v0, v1, v2, v3);
}
void GL2Encoder::s_glUniform1uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform1uiv_enc(self, hostLoc, count, value);
}
void GL2Encoder::s_glUniform2uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform2uiv_enc(self, hostLoc, count, value);
}
void GL2Encoder::s_glUniform3uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform3uiv_enc(self, hostLoc, count, value);
}
void GL2Encoder::s_glUniform4uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniform4uiv_enc(self, hostLoc, count, value);
}
void GL2Encoder::s_glUniformMatrix2x3fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniformMatrix2x3fv_enc(self, hostLoc, count, transpose, value);
}
void GL2Encoder::s_glUniformMatrix3x2fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniformMatrix3x2fv_enc(self, hostLoc, count, transpose, value);
}
void GL2Encoder::s_glUniformMatrix2x4fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniformMatrix2x4fv_enc(self, hostLoc, count, transpose, value);
}
void GL2Encoder::s_glUniformMatrix4x2fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniformMatrix4x2fv_enc(self, hostLoc, count, transpose, value);
}
void GL2Encoder::s_glUniformMatrix3x4fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniformMatrix3x4fv_enc(self, hostLoc, count, transpose, value);
}
void GL2Encoder::s_glUniformMatrix4x3fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location);
+ GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
ctx->m_glUniformMatrix4x3fv_enc(self, hostLoc, count, transpose, value);
}
SET_ERROR_IF(pname != GL_NUM_SAMPLE_COUNTS &&
pname != GL_SAMPLES,
GL_INVALID_ENUM);
- SET_ERROR_IF(target != GL_RENDERBUFFER, GL_INVALID_ENUM);
+ ALOGD("%s: maj min %d %d", __FUNCTION__, ctx->majorVersion(), ctx->minorVersion());
+ SET_ERROR_IF(!GLESv2Validation::internalFormatTarget(ctx, target), GL_INVALID_ENUM);
SET_ERROR_IF(!GLESv2Validation::unsizedFormat(internalformat) &&
!GLESv2Validation::colorRenderableFormat(internalformat) &&
!GLESv2Validation::depthRenderableFormat(internalformat) &&
ctx->m_glBindSampler_enc(ctx, unit, sampler);
}
+GLsync GL2Encoder::s_glFenceSync(void* self, GLenum condition, GLbitfield flags) {
+ GL2Encoder *ctx = (GL2Encoder *)self;
+ uint64_t syncHandle = ctx->glFenceSyncAEMU(ctx, condition, flags);
+ return (GLsync)(uintptr_t)syncHandle;
+}
+
+GLenum GL2Encoder::s_glClientWaitSync(void* self, GLsync wait_on, GLbitfield flags, GLuint64 timeout) {
+ GL2Encoder *ctx = (GL2Encoder *)self;
+ return ctx->glClientWaitSyncAEMU(ctx, (uint64_t)(uintptr_t)wait_on, flags, timeout);
+}
+
+void GL2Encoder::s_glWaitSync(void* self, GLsync wait_on, GLbitfield flags, GLuint64 timeout) {
+ GL2Encoder *ctx = (GL2Encoder *)self;
+ ctx->glWaitSyncAEMU(ctx, (uint64_t)(uintptr_t)wait_on, flags, timeout);
+}
+
void GL2Encoder::s_glDeleteSync(void* self, GLsync sync) {
GL2Encoder *ctx = (GL2Encoder *)self;
if (!sync) return;
- ctx->m_glDeleteSync_enc(ctx, sync);
+ ctx->glDeleteSyncAEMU(ctx, (uint64_t)(uintptr_t)sync);
+}
+
+GLboolean GL2Encoder::s_glIsSync(void* self, GLsync sync) {
+ GL2Encoder *ctx = (GL2Encoder *)self;
+ return ctx->glIsSyncAEMU(ctx, (uint64_t)(uintptr_t)sync);
+}
+
+void GL2Encoder::s_glGetSynciv(void* self, GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) {
+ GL2Encoder *ctx = (GL2Encoder *)self;
+
+ SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
+
+ return ctx->glGetSyncivAEMU(ctx, (uint64_t)(uintptr_t)sync, pname, bufSize, length, values);
}
#define LIMIT_CASE(target, lim) \
case target: \
ctx->glGetIntegerv(ctx, lim, &limit); \
- SET_ERROR_IF(index >= limit, GL_INVALID_VALUE); \
+ SET_ERROR_IF(index < 0 || index >= limit, GL_INVALID_VALUE); \
break; \
void GL2Encoder::s_glGetIntegeri_v(void* self, GLenum target, GLuint index, GLint* params) {
GL2Encoder *ctx = (GL2Encoder *)self;
+ GLClientState* state = ctx->m_state;
GLint limit;
break;
}
+ const GLClientState::VertexAttribBindingVector& currBindings =
+ state->currentVertexBufferBindings();
+
+ switch (target) {
+ case GL_VERTEX_BINDING_DIVISOR:
+ case GL_VERTEX_BINDING_OFFSET:
+ case GL_VERTEX_BINDING_STRIDE:
+ case GL_VERTEX_BINDING_BUFFER:
+ SET_ERROR_IF(index < 0 || index > currBindings.size(), GL_INVALID_VALUE);
+ break;
+ default:
+ break;
+ }
+
+ switch (target) {
+ case GL_VERTEX_BINDING_DIVISOR:
+ *params = currBindings[index].divisor;
+ return;
+ case GL_VERTEX_BINDING_OFFSET:
+ *params = currBindings[index].offset;
+ return;
+ case GL_VERTEX_BINDING_STRIDE:
+ *params = currBindings[index].effectiveStride;
+ return;
+ case GL_VERTEX_BINDING_BUFFER:
+ *params = currBindings[index].buffer;
+ return;
+ default:
+ break;
+ }
+
ctx->m_glGetIntegeri_v_enc(self, target, index, params);
}
void GL2Encoder::s_glGetInteger64i_v(void* self, GLenum target, GLuint index, GLint64* params) {
GL2Encoder *ctx = (GL2Encoder *)self;
+ GLClientState* state = ctx->m_state;
GLint limit;
break;
}
+ const GLClientState::VertexAttribBindingVector& currBindings =
+ state->currentVertexBufferBindings();
+
+ switch (target) {
+ case GL_VERTEX_BINDING_DIVISOR:
+ case GL_VERTEX_BINDING_OFFSET:
+ case GL_VERTEX_BINDING_STRIDE:
+ case GL_VERTEX_BINDING_BUFFER:
+ SET_ERROR_IF(index < 0 || index > currBindings.size(), GL_INVALID_VALUE);
+ break;
+ default:
+ break;
+ }
+
+ switch (target) {
+ case GL_VERTEX_BINDING_DIVISOR:
+ *params = currBindings[index].divisor;
+ return;
+ case GL_VERTEX_BINDING_OFFSET:
+ *params = currBindings[index].offset;
+ return;
+ case GL_VERTEX_BINDING_STRIDE:
+ *params = currBindings[index].effectiveStride;
+ return;
+ case GL_VERTEX_BINDING_BUFFER:
+ *params = currBindings[index].buffer;
+ return;
+ default:
+ break;
+ }
+
ctx->m_glGetInteger64i_v_enc(self, target, index, params);
}
}
}
+void GL2Encoder::s_glActiveShaderProgram(void* self, GLuint pipeline, GLuint program) {
+ GL2Encoder *ctx = (GL2Encoder*)self;
+ GLClientState* state = ctx->m_state;
+ GLSharedGroupPtr shared = ctx->m_shared;
+
+ SET_ERROR_IF(!pipeline, GL_INVALID_OPERATION);
+ SET_ERROR_IF(program && !shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
+ SET_ERROR_IF(program && !shared->isProgram(program), GL_INVALID_OPERATION);
+
+ ctx->m_glActiveShaderProgram_enc(ctx, pipeline, program);
+ if (!state->currentProgram()) {
+ state->setCurrentShaderProgram(program);
+ }
+}
+
GLuint GL2Encoder::s_glCreateShaderProgramv(void* self, GLenum type, GLsizei count, const char** strings) {
+ ALOGD("%s: entry firststr %s", __FUNCTION__, strings[0]);
+
GLint* length = NULL;
GL2Encoder* ctx = (GL2Encoder*)self;
int len = glUtilsCalcShaderSourceLen((char**)strings, length, count);
+ ALOGD("%s: len %d\n", __FUNCTION__, len);
char *str = new char[len + 1];
glUtilsPackStrings(str, (char**)strings, (GLint*)length, count);
+ ALOGD("%s: packed %s", __FUNCTION__, str);
// Do GLSharedGroup and location WorkARound-specific initialization
// Phase 1: create a ShaderData and initialize with replaceSamplerExternalWith2D()
ShaderData* sData = spData->shaderData;
if (!replaceSamplerExternalWith2D(str, sData)) {
+ ALOGD("%s: failed to do stuf\n", __FUNCTION__);
delete [] str;
ctx->setError(GL_OUT_OF_MEMORY);
ctx->m_shared->deleteShaderProgramDataById(spDataId);
}
GLuint res = ctx->glCreateShaderProgramvAEMU(ctx, type, count, str, len + 1);
+ ALOGD("%s: return from glcreateshaderprogramv. res %u\n", __FUNCTION__, res);
delete [] str;
// Phase 2: do glLinkProgram-related initialization for locationWorkARound
GLint linkStatus = 0;
ctx->glGetProgramiv(self, res, GL_LINK_STATUS ,&linkStatus);
if (!linkStatus) {
+ ALOGD("%s: no link status :(\n", __FUNCTION__);
ctx->m_shared->deleteShaderProgramDataById(spDataId);
return -1;
}
{
GL2Encoder *ctx = (GL2Encoder*)self;
GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
- ctx->m_glProgramUniform1ui_enc(self, program, hostLoc, v0);
+ ctx->m_glProgramUniform1i_enc(self, program, hostLoc, v0);
GLClientState* state = ctx->m_state;
GLSharedGroupPtr shared = ctx->m_shared;
ctx->m_glProgramUniformMatrix4x3fv_enc(self, program, hostLoc, count, transpose, value);
}
+void GL2Encoder::s_glProgramParameteri(void* self, GLuint program, GLenum pname, GLint value) {
+ GL2Encoder* ctx = (GL2Encoder*)self;
+ ctx->m_glProgramParameteri_enc(self, program, pname, value);
+}
+
void GL2Encoder::s_glUseProgramStages(void *self, GLuint pipeline, GLbitfield stages, GLuint program)
{
GL2Encoder *ctx = (GL2Encoder*)self;
}
}
+void GL2Encoder::s_glGetProgramResourceiv(void* self, GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei * length, GLint * params) {
+ GL2Encoder *ctx = (GL2Encoder*)self;
+ SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
+ if (bufSize == 0) {
+ if (length) *length = 0;
+ return;
+ }
+
+ // Avoid modifying |name| if |*length| < bufSize.
+ GLint* intermediate = new GLint[bufSize];
+ GLsizei* myLength = length ? length : new GLsizei;
+ bool needFreeLength = length == NULL;
+
+ ctx->m_glGetProgramResourceiv_enc(self, program, programInterface, index, propCount, props, bufSize, myLength, intermediate);
+ GLsizei writtenInts = *myLength;
+ memcpy(params, intermediate, writtenInts * sizeof(GLint));
+
+ delete [] intermediate;
+ if (needFreeLength)
+ delete myLength;
+}
+
+GLuint GL2Encoder::s_glGetProgramResourceIndex(void* self, GLuint program, GLenum programInterface, const char* name) {
+ GL2Encoder *ctx = (GL2Encoder*)self;
+ return ctx->m_glGetProgramResourceIndex_enc(self, program, programInterface, name);
+}
+
+GLint GL2Encoder::s_glGetProgramResourceLocation(void* self, GLuint program, GLenum programInterface, const char* name) {
+ GL2Encoder *ctx = (GL2Encoder*)self;
+ return ctx->m_glGetProgramResourceLocation_enc(self, program, programInterface, name);
+}
+
+void GL2Encoder::s_glGetProgramResourceName(void* self, GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, char* name) {
+ GL2Encoder *ctx = (GL2Encoder*)self;
+ SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
+ if (bufSize == 0) {
+ if (length) *length = 0;
+ return;
+ }
+
+ // Avoid modifying |name| if |*length| < bufSize.
+ char* intermediate = new char[bufSize];
+ GLsizei* myLength = length ? length : new GLsizei;
+ bool needFreeLength = length == NULL;
+
+ ctx->m_glGetProgramResourceName_enc(self, program, programInterface, index, bufSize, myLength, intermediate);
+ GLsizei writtenStrLen = *myLength;
+ memcpy(name, intermediate, writtenStrLen + 1);
+
+ delete [] intermediate;
+ if (needFreeLength)
+ delete myLength;
+}
+
+void GL2Encoder::s_glGetProgramPipelineInfoLog(void* self, GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
+ GL2Encoder *ctx = (GL2Encoder*)self;
+ SET_ERROR_IF(bufSize < 0, GL_INVALID_VALUE);
+ if (bufSize == 0) {
+ if (length) *length = 0;
+ return;
+ }
+
+ // Avoid modifying |infoLog| if |*length| < bufSize.
+ GLchar* intermediate = new GLchar[bufSize];
+ GLsizei* myLength = length ? length : new GLsizei;
+ bool needFreeLength = length == NULL;
+
+ ctx->m_glGetProgramPipelineInfoLog_enc(self, pipeline, bufSize, myLength, intermediate);
+ GLsizei writtenStrLen = *myLength;
+ memcpy(infoLog, intermediate, writtenStrLen + 1);
+
+ delete [] intermediate;
+ if (needFreeLength)
+ delete myLength;
+}
+
void GL2Encoder::s_glVertexAttribFormat(void* self, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) {
GL2Encoder *ctx = (GL2Encoder*)self;
GLClientState* state = ctx->m_state;
+ SET_ERROR_IF(!isValidVertexAttribIndex(self, attribindex), GL_INVALID_VALUE);
+ SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
+
state->setVertexAttribFormat(attribindex, size, type, normalized, relativeoffset, false);
ctx->m_glVertexAttribFormat_enc(ctx, attribindex, size, type, normalized, relativeoffset);
}
GL2Encoder *ctx = (GL2Encoder*)self;
GLClientState* state = ctx->m_state;
+ SET_ERROR_IF(!isValidVertexAttribIndex(self, attribindex), GL_INVALID_VALUE);
+ SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
+
state->setVertexAttribFormat(attribindex, size, type, GL_FALSE, relativeoffset, true);
ctx->m_glVertexAttribIFormat_enc(ctx, attribindex, size, type, relativeoffset);
}
void GL2Encoder::s_glVertexBindingDivisor(void* self, GLuint bindingindex, GLuint divisor) {
-
GL2Encoder *ctx = (GL2Encoder*)self;
GLClientState* state = ctx->m_state;
+ SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
+
state->setVertexBindingDivisor(bindingindex, divisor);
ctx->m_glVertexBindingDivisor_enc(ctx, bindingindex, divisor);
}
void GL2Encoder::s_glVertexAttribBinding(void* self, GLuint attribindex, GLuint bindingindex) {
GL2Encoder *ctx = (GL2Encoder*)self;
GLClientState* state = ctx->m_state;
+ SET_ERROR_IF(!isValidVertexAttribIndex(self, attribindex), GL_INVALID_VALUE);
+ SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
state->setVertexAttribBinding(attribindex, bindingindex);
ctx->m_glVertexAttribBinding_enc(ctx, attribindex, bindingindex);
GL2Encoder *ctx = (GL2Encoder*)self;
GLClientState* state = ctx->m_state;
+ SET_ERROR_IF(offset < 0, GL_INVALID_VALUE);
+
+ GLint maxStride;
+ ctx->glGetIntegerv(ctx, GL_MAX_VERTEX_ATTRIB_STRIDE, &maxStride);
+ SET_ERROR_IF(stride < 0 || stride > maxStride, GL_INVALID_VALUE);
+
+ SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
+
state->bindIndexedBuffer(0, bindingindex, buffer, offset, 0, stride, stride);
ctx->m_glBindVertexBuffer_enc(ctx, bindingindex, buffer, offset, stride);
}
void GL2Encoder::s_glDrawArraysIndirect(void* self, GLenum mode, const void* indirect) {
GL2Encoder *ctx = (GL2Encoder*)self;
+ GLClientState* state = ctx->m_state;
+
+ bool hasClientArrays = false;
+ ctx->getVBOUsage(&hasClientArrays, NULL);
+
+ SET_ERROR_IF(hasClientArrays, GL_INVALID_OPERATION);
+ SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
+ SET_ERROR_IF(!ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER), GL_INVALID_OPERATION);
+ GLuint indirectStructSize = glUtilsIndirectStructSize(INDIRECT_COMMAND_DRAWARRAYS);
if (ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER)) {
+ // BufferData* buf = ctx->getBufferData(target);
+ // if (buf) {
+ // SET_ERROR_IF((GLuint)(uintptr_t)indirect + indirectStructSize > buf->m_size, GL_INVALID_VALUE);
+ // }
ctx->glDrawArraysIndirectOffsetAEMU(ctx, mode, (uintptr_t)indirect);
} else {
- GLuint indirectStructSize = glUtilsIndirectStructSize(INDIRECT_COMMAND_DRAWARRAYS);
+ // Client command structs are technically allowed in desktop OpenGL, but not in ES.
+ // This is purely for debug/dev purposes.
ctx->glDrawArraysIndirectDataAEMU(ctx, mode, indirect, indirectStructSize);
}
}
void GL2Encoder::s_glDrawElementsIndirect(void* self, GLenum mode, GLenum type, const void* indirect) {
GL2Encoder *ctx = (GL2Encoder*)self;
+ GLClientState* state = ctx->m_state;
+
+ bool hasClientArrays = false;
+ ctx->getVBOUsage(&hasClientArrays, NULL);
+
+ SET_ERROR_IF(hasClientArrays, GL_INVALID_OPERATION);
+ SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
+ SET_ERROR_IF(!ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER), GL_INVALID_OPERATION);
+
SET_ERROR_IF(ctx->m_state->getTransformFeedbackActiveUnpaused(), GL_INVALID_OPERATION);
+
+ GLuint indirectStructSize = glUtilsIndirectStructSize(INDIRECT_COMMAND_DRAWELEMENTS);
if (ctx->boundBuffer(GL_DRAW_INDIRECT_BUFFER)) {
+ // BufferData* buf = ctx->getBufferData(target);
+ // if (buf) {
+ // SET_ERROR_IF((GLuint)(uintptr_t)indirect + indirectStructSize > buf->m_size, GL_INVALID_VALUE);
+ // }
ctx->glDrawElementsIndirectOffsetAEMU(ctx, mode, type, (uintptr_t)indirect);
} else {
- GLuint indirectStructSize = glUtilsIndirectStructSize(INDIRECT_COMMAND_DRAWELEMENTS);
+ // Client command structs are technically allowed in desktop OpenGL, but not in ES.
+ // This is purely for debug/dev purposes.
ctx->glDrawElementsIndirectDataAEMU(ctx, mode, type, indirect, indirectStructSize);
}
SET_ERROR_IF(!state->getBoundTexture(target), GL_INVALID_OPERATION);
SET_ERROR_IF(width < 1 || height < 1, GL_INVALID_VALUE);
SET_ERROR_IF(state->isBoundTextureImmutableFormat(target), GL_INVALID_OPERATION);
+ GLint max_samples;
+ ctx->s_glGetInternalformativ(ctx, target, internalformat, GL_SAMPLES, 1, &max_samples);
+ SET_ERROR_IF(samples > max_samples, GL_INVALID_OPERATION);
state->setBoundTextureInternalFormat(target, internalformat);
state->setBoundTextureDims(target, 0, width, height, 1);