opengl emulator: Added gl error tracking on the guest (encoder)

Sometimes we need to check parameter values before encoding
to prevent crashes, for example:
glDeleteBufferes(-1, ptr); - would crash
For that we need to check some gl errors on the guest.

The change adds error state to the encoder and also
adds new feature to emugen which allows to insert
parameter check code into the attribute file.
Added such parameter check code in the appropiate
gl functions in gl.attrib and gl2.attrib

Change-Id: I7f317df52ac8fbd96979100a1031cf023a0b49d3
This commit is contained in:
Stas Gurtovoy
2011-07-07 15:16:47 +03:00
committed by Guy Zadickario
parent dd3849c9ed
commit d6f18cdf80
10 changed files with 113 additions and 2 deletions

View File

@@ -165,6 +165,12 @@ int ApiGen::genContext(const std::string & filename, SideType side)
// init function // init function
fprintf(fp, "\tint initDispatchByName( void *(*getProc)(const char *name, void *userData), void *userData);\n"); fprintf(fp, "\tint initDispatchByName( void *(*getProc)(const char *name, void *userData), void *userData);\n");
//client site set error virtual func
if (side == CLIENT_SIDE) {
fprintf(fp, "\tvirtual void setError(unsigned int error){};\n");
fprintf(fp, "\tvirtual unsigned int getError(){ return 0; };\n");
}
fprintf(fp, "};\n"); fprintf(fp, "};\n");
fprintf(fp, "\n#endif\n"); fprintf(fp, "\n#endif\n");
@@ -222,6 +228,13 @@ int ApiGen::genEntryPoints(const std::string & filename, SideType side)
bool shouldReturn = !e->retval().isVoid(); bool shouldReturn = !e->retval().isVoid();
bool shouldCallWithContext = (side == CLIENT_SIDE); bool shouldCallWithContext = (side == CLIENT_SIDE);
//param check
if (shouldCallWithContext) {
for (size_t j=0; j<e->vars().size(); j++) {
if (e->vars()[j].paramCheckExpression() != "")
fprintf(fp, "\t%s\n", e->vars()[j].paramCheckExpression().c_str());
}
}
fprintf(fp, "\t %sctx->%s(%s", fprintf(fp, "\t %sctx->%s(%s",
shouldReturn ? "return " : "", shouldReturn ? "return " : "",
e->name().c_str(), e->name().c_str(),

View File

@@ -225,6 +225,24 @@ int EntryPoint::setAttribute(const std::string &line, size_t lc)
// set the size expression into var // set the size expression into var
pos = last; pos = last;
v->setLenExpression(line.substr(pos)); v->setLenExpression(line.substr(pos));
} else if (token == "param_check") {
pos = last;
std::string varname = getNextToken(line, pos, &last, WHITESPACE);
if (varname.size() == 0) {
fprintf(stderr, "ERROR: %u: Missing variable name in 'param_check' attribute\n", (unsigned int)lc);
return -1;
}
Var * v = var(varname);
if (v == NULL) {
fprintf(stderr, "ERROR: %u: variable %s is not a parameter of %s\n",
(unsigned int)lc, varname.c_str(), name().c_str());
return -2;
}
// set the size expression into var
pos = last;
v->setParamCheckExpression(line.substr(pos));
} else if (token == "dir") { } else if (token == "dir") {
pos = last; pos = last;
std::string varname = getNextToken(line, pos, &last, WHITESPACE); std::string varname = getNextToken(line, pos, &last, WHITESPACE);

View File

@@ -30,7 +30,8 @@ public:
m_lenExpression(""), m_lenExpression(""),
m_pointerDir(POINTER_IN), m_pointerDir(POINTER_IN),
m_nullAllowed(false), m_nullAllowed(false),
m_packExpression("") m_packExpression(""),
m_paramCheckExpression("")
{ {
} }
@@ -45,7 +46,8 @@ public:
m_lenExpression(lenExpression), m_lenExpression(lenExpression),
m_pointerDir(dir), m_pointerDir(dir),
m_nullAllowed(false), m_nullAllowed(false),
m_packExpression(packExpression) m_packExpression(packExpression),
m_paramCheckExpression("")
{ {
} }
@@ -67,8 +69,10 @@ public:
bool isVoid() const { return ((m_type->bytes() == 0) && (!m_type->isPointer())); } bool isVoid() const { return ((m_type->bytes() == 0) && (!m_type->isPointer())); }
const std::string & lenExpression() const { return m_lenExpression; } const std::string & lenExpression() const { return m_lenExpression; }
const std::string & packExpression() const { return(m_packExpression); } const std::string & packExpression() const { return(m_packExpression); }
const std::string & paramCheckExpression() const { return m_paramCheckExpression; }
void setLenExpression(const std::string & lenExpression) { m_lenExpression = lenExpression; } void setLenExpression(const std::string & lenExpression) { m_lenExpression = lenExpression; }
void setPackExpression(const std::string & packExpression) { m_packExpression = packExpression; } void setPackExpression(const std::string & packExpression) { m_packExpression = packExpression; }
void setParamCheckExpression(const std::string & paramCheckExpression) { m_paramCheckExpression = paramCheckExpression; }
void setPointerDir(PointerDir dir) { m_pointerDir = dir; } void setPointerDir(PointerDir dir) { m_pointerDir = dir; }
PointerDir pointerDir() { return m_pointerDir; } PointerDir pointerDir() { return m_pointerDir; }
void setNullAllowed(bool state) { m_nullAllowed = state; } void setNullAllowed(bool state) { m_nullAllowed = state; }
@@ -84,6 +88,7 @@ private:
PointerDir m_pointerDir; PointerDir m_pointerDir;
bool m_nullAllowed; bool m_nullAllowed;
std::string m_packExpression; // an expression to pack data into the stream std::string m_packExpression; // an expression to pack data into the stream
std::string m_paramCheckExpression; //an expression to check parameter value
}; };

View File

@@ -48,4 +48,15 @@ typedef char *GLstr;
/* JR XXX Treating this as an in handle - is this correct? */ /* JR XXX Treating this as an in handle - is this correct? */
typedef void * GLeglImageOES; typedef void * GLeglImageOES;
/* ErrorCode */
#ifndef GL_INVALID_ENUM
#define GL_NO_ERROR 0
#define GL_INVALID_ENUM 0x0500
#define GL_INVALID_VALUE 0x0501
#define GL_INVALID_OPERATION 0x0502
#define GL_STACK_OVERFLOW 0x0503
#define GL_STACK_UNDERFLOW 0x0504
#define GL_OUT_OF_MEMORY 0x0505
#endif
#endif #endif

View File

@@ -36,6 +36,18 @@ static GLubyte *gExtensionsString= (GLubyte *) ""; // no extensions at this poin
return ret; \ return ret; \
} }
GLenum GLEncoder::s_glGetError(void * self)
{
GLEncoder *ctx = (GLEncoder *)self;
GLenum err = ctx->getError();
if(err != GL_NO_ERROR) {
ctx->setError(GL_NO_ERROR);
return err;
}
return ctx->m_glGetError_enc(self);
}
GLint * GLEncoder::getCompressedTextureFormats() GLint * GLEncoder::getCompressedTextureFormats()
{ {
@@ -453,6 +465,7 @@ GLEncoder::GLEncoder(IOStream *stream) : gl_encoder_context_t(stream)
{ {
m_initialized = false; m_initialized = false;
m_state = NULL; m_state = NULL;
m_error = GL_NO_ERROR;
m_num_compressedTextureFormats = 0; m_num_compressedTextureFormats = 0;
m_compressedTextureFormats = NULL; m_compressedTextureFormats = NULL;
// overrides; // overrides;
@@ -481,6 +494,7 @@ GLEncoder::GLEncoder(IOStream *stream) : gl_encoder_context_t(stream)
m_glDrawElements_enc = set_glDrawElements(s_glDrawElements); m_glDrawElements_enc = set_glDrawElements(s_glDrawElements);
set_glGetString(s_glGetString); set_glGetString(s_glGetString);
set_glFinish(s_glFinish); set_glFinish(s_glFinish);
m_glGetError_enc = set_glGetError(s_glGetError);
} }

View File

@@ -34,16 +34,21 @@ public:
void setInitialized(){ m_initialized = true; }; void setInitialized(){ m_initialized = true; };
bool isInitialized(){ return m_initialized; }; bool isInitialized(){ return m_initialized; };
virtual void setError(GLenum error){ m_error = error; };
virtual GLenum getError() { return m_error; };
private: private:
bool m_initialized; bool m_initialized;
GLClientState *m_state; GLClientState *m_state;
GLenum m_error;
FixedBuffer m_fixedBuffer; FixedBuffer m_fixedBuffer;
GLint *m_compressedTextureFormats; GLint *m_compressedTextureFormats;
GLint m_num_compressedTextureFormats; GLint m_num_compressedTextureFormats;
GLint *getCompressedTextureFormats(); GLint *getCompressedTextureFormats();
// original functions; // original functions;
glGetError_client_proc_t m_glGetError_enc;
glGetIntegerv_client_proc_t m_glGetIntegerv_enc; glGetIntegerv_client_proc_t m_glGetIntegerv_enc;
glGetFloatv_client_proc_t m_glGetFloatv_enc; glGetFloatv_client_proc_t m_glGetFloatv_enc;
glGetFixedv_client_proc_t m_glGetFixedv_enc; glGetFixedv_client_proc_t m_glGetFixedv_enc;
@@ -69,6 +74,7 @@ private:
glFlush_client_proc_t m_glFlush_enc; glFlush_client_proc_t m_glFlush_enc;
// statics // statics
static GLenum s_glGetError(void * self);
static void s_glGetIntegerv(void *self, GLenum pname, GLint *ptr); static void s_glGetIntegerv(void *self, GLenum pname, GLint *ptr);
static void s_glGetBooleanv(void *self, GLenum pname, GLboolean *ptr); static void s_glGetBooleanv(void *self, GLenum pname, GLboolean *ptr);
static void s_glGetFloatv(void *self, GLenum pname, GLfloat *ptr); static void s_glGetFloatv(void *self, GLenum pname, GLfloat *ptr);

View File

@@ -99,10 +99,12 @@ glCompressedTexSubImage2D
#void glDeleteBuffers(GLsizei n, GLuint *buffers) #void glDeleteBuffers(GLsizei n, GLuint *buffers)
glDeleteBuffers glDeleteBuffers
len buffers (n * sizeof(GLuint)) len buffers (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glDeleteTextures(GLsizei n, GLuint *textures) #void glDeleteTextures(GLsizei n, GLuint *textures)
glDeleteTextures glDeleteTextures
len textures (n * sizeof(GLuint)) len textures (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#this function is marked as unsupported - it shouldn't be called directly #this function is marked as unsupported - it shouldn't be called directly
#instead it translated into - glDrawDirectElements and glDrawIndirectElements #instead it translated into - glDrawDirectElements and glDrawIndirectElements
@@ -129,11 +131,13 @@ glGetBufferParameteriv
glGenBuffers glGenBuffers
len buffers (n * sizeof(GLuint)) len buffers (n * sizeof(GLuint))
dir buffers out dir buffers out
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGenTextures(GLsizei n, GLuint *textures) #void glGenTextures(GLsizei n, GLuint *textures)
glGenTextures glGenTextures
len textures (n * sizeof(GLuint)) len textures (n * sizeof(GLuint))
dir textures out dir textures out
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGetFixedv(GLenum pname, GLfixed *params) #void glGetFixedv(GLenum pname, GLfixed *params)
glGetFixedv glGetFixedv
@@ -465,11 +469,13 @@ glTexParameterxvOES
glDeleteRenderbuffersOES glDeleteRenderbuffersOES
dir renderbuffers in dir renderbuffers in
len renderbuffers (n * sizeof(GLuint)) len renderbuffers (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGenRenderbuffersOES(GLsizei n, GLuint *renderbuffers) #void glGenRenderbuffersOES(GLsizei n, GLuint *renderbuffers)
glGenRenderbuffersOES glGenRenderbuffersOES
dir renderbuffers in dir renderbuffers in
len renderbuffers (n * sizeof(GLuint)) len renderbuffers (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint *params) #void glGetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint *params)
glGetRenderbufferParameterivOES glGetRenderbufferParameterivOES
@@ -480,11 +486,13 @@ glGetRenderbufferParameterivOES
glDeleteFramebuffersOES glDeleteFramebuffersOES
dir framebuffers in dir framebuffers in
len framebuffers (n * sizeof(GLuint)) len framebuffers (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGenFramebuffersOES(GLsizei n, GLuint *framebuffers) #void glGenFramebuffersOES(GLsizei n, GLuint *framebuffers)
glGenFramebuffersOES glGenFramebuffersOES
dir framebuffers out dir framebuffers out
len framebuffers (n * sizeof(GLuint)) len framebuffers (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint *params) #void glGetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint *params)
glGetFramebufferAttachmentParameterivOES glGetFramebufferAttachmentParameterivOES
@@ -559,11 +567,13 @@ glGetTexGenxvOES
glDeleteVertexArraysOES glDeleteVertexArraysOES
dir arrays in dir arrays in
len arrays (n * sizeof(GLuint)) len arrays (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGenVertexArraysOES(GLsizei n, GLuint *arrays) #void glGenVertexArraysOES(GLsizei n, GLuint *arrays)
glGenVertexArraysOES glGenVertexArraysOES
dir arrays out dir arrays out
len arrays (n * sizeof(GLuint)) len arrays (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments) #void glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments)
glDiscardFramebufferEXT glDiscardFramebufferEXT
@@ -590,11 +600,13 @@ glMultiDrawElementsSUN
glDeleteFencesNV glDeleteFencesNV
dir fences in dir fences in
len fences (n * sizeof(GLuint)) len fences (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGenFencesNV(GLsizei n, GLuint *fences) #void glGenFencesNV(GLsizei n, GLuint *fences)
glGenFencesNV glGenFencesNV
dir fences in dir fences in
len fences (n * sizeof(GLuint)) len fences (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGetFenceivNV(GLuint fence, GLenum pname, GLint *params) #void glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
glGetFenceivNV glGetFenceivNV

View File

@@ -11,6 +11,7 @@ GL2Encoder::GL2Encoder(IOStream *stream) : gl2_encoder_context_t(stream)
{ {
m_initialized = false; m_initialized = false;
m_state = NULL; m_state = NULL;
m_error = GL_NO_ERROR;
m_num_compressedTextureFormats = 0; m_num_compressedTextureFormats = 0;
m_compressedTextureFormats = NULL; m_compressedTextureFormats = NULL;
//overrides //overrides
@@ -31,6 +32,7 @@ GL2Encoder::GL2Encoder(IOStream *stream) : gl2_encoder_context_t(stream)
m_glGetVertexAttribPointerv = set_glGetVertexAttribPointerv(s_glGetVertexAttribPointerv); m_glGetVertexAttribPointerv = set_glGetVertexAttribPointerv(s_glGetVertexAttribPointerv);
set_glShaderSource(s_glShaderSource); set_glShaderSource(s_glShaderSource);
set_glFinish(s_glFinish); set_glFinish(s_glFinish);
m_glGetError_enc = set_glGetError(s_glGetError);
} }
GL2Encoder::~GL2Encoder() GL2Encoder::~GL2Encoder()
@@ -38,6 +40,19 @@ GL2Encoder::~GL2Encoder()
delete m_compressedTextureFormats; delete m_compressedTextureFormats;
} }
GLenum GL2Encoder::s_glGetError(void * self)
{
GL2Encoder *ctx = (GL2Encoder *)self;
GLenum err = ctx->getError();
if(err != GL_NO_ERROR) {
ctx->setError(GL_NO_ERROR);
return err;
}
return ctx->m_glGetError_enc(self);
}
void GL2Encoder::s_glFlush(void *self) void GL2Encoder::s_glFlush(void *self)
{ {
GL2Encoder *ctx = (GL2Encoder *) self; GL2Encoder *ctx = (GL2Encoder *) self;

View File

@@ -37,10 +37,14 @@ public:
void setInitialized(){ m_initialized = true; }; void setInitialized(){ m_initialized = true; };
bool isInitialized(){ return m_initialized; }; bool isInitialized(){ return m_initialized; };
virtual void setError(GLenum error){ m_error = error; };
virtual GLenum getError() { return m_error; };
private: private:
bool m_initialized; bool m_initialized;
GLClientState *m_state; GLClientState *m_state;
GLenum m_error;
GLint *m_compressedTextureFormats; GLint *m_compressedTextureFormats;
GLint m_num_compressedTextureFormats; GLint m_num_compressedTextureFormats;
@@ -50,6 +54,9 @@ private:
void sendVertexAttributes(GLint first, GLsizei count); void sendVertexAttributes(GLint first, GLsizei count);
glGetError_client_proc_t m_glGetError_enc;
static GLenum s_glGetError(void * self);
glFlush_client_proc_t m_glFlush_enc; glFlush_client_proc_t m_glFlush_enc;
static void s_glFlush(void * self); static void s_glFlush(void * self);

View File

@@ -26,18 +26,22 @@ glCompressedTexSubImage2D
#void glDeleteBuffers(GLsizei n, GLuint *buffers) #void glDeleteBuffers(GLsizei n, GLuint *buffers)
glDeleteBuffers glDeleteBuffers
len buffers (n * sizeof(GLuint)) len buffers (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glDeleteFramebuffers(GLsizei n, GLuint *framebuffers) #void glDeleteFramebuffers(GLsizei n, GLuint *framebuffers)
glDeleteFramebuffers glDeleteFramebuffers
len framebuffers (n * sizeof(GLuint)) len framebuffers (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glDeleteRenderbuffers(GLsizei n, GLuint *renderbuffers) #void glDeleteRenderbuffers(GLsizei n, GLuint *renderbuffers)
glDeleteRenderbuffers glDeleteRenderbuffers
len renderbuffers (n * sizeof(GLuint)) len renderbuffers (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glDeleteTextures(GLsizei n, GLuint *textures) #void glDeleteTextures(GLsizei n, GLuint *textures)
glDeleteTextures glDeleteTextures
len textures (n * sizeof(GLuint)) len textures (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glDrawElements(GLenum mode, GLsizei count, GLenum type, GLvoid *indices) #void glDrawElements(GLenum mode, GLsizei count, GLenum type, GLvoid *indices)
glDrawElements glDrawElements
@@ -47,21 +51,25 @@ glDrawElements
glGenBuffers glGenBuffers
len buffers (n * sizeof(GLuint)) len buffers (n * sizeof(GLuint))
dir buffers out dir buffers out
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGenFramebuffers(GLsizei n, GLuint *framebuffers) #void glGenFramebuffers(GLsizei n, GLuint *framebuffers)
glGenFramebuffers glGenFramebuffers
len framebuffers (n * sizeof(GLuint)) len framebuffers (n * sizeof(GLuint))
dir framebuffers out dir framebuffers out
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGenRenderbuffers(GLsizei n, GLuint *renderbuffers) #void glGenRenderbuffers(GLsizei n, GLuint *renderbuffers)
glGenRenderbuffers glGenRenderbuffers
len renderbuffers (n * sizeof(GLuint)) len renderbuffers (n * sizeof(GLuint))
dir renderbuffers out dir renderbuffers out
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGenTextures(GLsizei n, GLuint *textures) #void glGenTextures(GLsizei n, GLuint *textures)
glGenTextures glGenTextures
len textures (n * sizeof(GLuint)) len textures (n * sizeof(GLuint))
dir textures out dir textures out
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) #void glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
glGetActiveAttrib glGetActiveAttrib
@@ -330,11 +338,13 @@ glCompressedTexSubImage3DOES
#void glDeleteVertexArraysOES(GLsizei n, GLuint *arrays) #void glDeleteVertexArraysOES(GLsizei n, GLuint *arrays)
glDeleteVertexArraysOES glDeleteVertexArraysOES
len arrays (n * sizeof(GLuint)) len arrays (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGenVertexArraysOES(GLsizei n, GLuint *arrays) #void glGenVertexArraysOES(GLsizei n, GLuint *arrays)
glGenVertexArraysOES glGenVertexArraysOES
len arrays (n * sizeof(GLuint)) len arrays (n * sizeof(GLuint))
dir arrays out dir arrays out
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, GLenum *attachments) #void glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, GLenum *attachments)