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
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#endif\n");
@@ -222,6 +228,13 @@ int ApiGen::genEntryPoints(const std::string & filename, SideType side)
bool shouldReturn = !e->retval().isVoid();
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",
shouldReturn ? "return " : "",
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
pos = last;
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") {
pos = last;
std::string varname = getNextToken(line, pos, &last, WHITESPACE);

View File

@@ -30,7 +30,8 @@ public:
m_lenExpression(""),
m_pointerDir(POINTER_IN),
m_nullAllowed(false),
m_packExpression("")
m_packExpression(""),
m_paramCheckExpression("")
{
}
@@ -45,7 +46,8 @@ public:
m_lenExpression(lenExpression),
m_pointerDir(dir),
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())); }
const std::string & lenExpression() const { return m_lenExpression; }
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 setPackExpression(const std::string & packExpression) { m_packExpression = packExpression; }
void setParamCheckExpression(const std::string & paramCheckExpression) { m_paramCheckExpression = paramCheckExpression; }
void setPointerDir(PointerDir dir) { m_pointerDir = dir; }
PointerDir pointerDir() { return m_pointerDir; }
void setNullAllowed(bool state) { m_nullAllowed = state; }
@@ -84,6 +88,7 @@ private:
PointerDir m_pointerDir;
bool m_nullAllowed;
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? */
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

View File

@@ -36,6 +36,18 @@ static GLubyte *gExtensionsString= (GLubyte *) ""; // no extensions at this poin
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()
{
@@ -453,6 +465,7 @@ GLEncoder::GLEncoder(IOStream *stream) : gl_encoder_context_t(stream)
{
m_initialized = false;
m_state = NULL;
m_error = GL_NO_ERROR;
m_num_compressedTextureFormats = 0;
m_compressedTextureFormats = NULL;
// overrides;
@@ -481,6 +494,7 @@ GLEncoder::GLEncoder(IOStream *stream) : gl_encoder_context_t(stream)
m_glDrawElements_enc = set_glDrawElements(s_glDrawElements);
set_glGetString(s_glGetString);
set_glFinish(s_glFinish);
m_glGetError_enc = set_glGetError(s_glGetError);
}

View File

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

View File

@@ -99,10 +99,12 @@ glCompressedTexSubImage2D
#void glDeleteBuffers(GLsizei n, GLuint *buffers)
glDeleteBuffers
len buffers (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glDeleteTextures(GLsizei n, GLuint *textures)
glDeleteTextures
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
#instead it translated into - glDrawDirectElements and glDrawIndirectElements
@@ -129,11 +131,13 @@ glGetBufferParameteriv
glGenBuffers
len buffers (n * sizeof(GLuint))
dir buffers out
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGenTextures(GLsizei n, GLuint *textures)
glGenTextures
len textures (n * sizeof(GLuint))
dir textures out
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGetFixedv(GLenum pname, GLfixed *params)
glGetFixedv
@@ -465,11 +469,13 @@ glTexParameterxvOES
glDeleteRenderbuffersOES
dir renderbuffers in
len renderbuffers (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGenRenderbuffersOES(GLsizei n, GLuint *renderbuffers)
glGenRenderbuffersOES
dir renderbuffers in
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)
glGetRenderbufferParameterivOES
@@ -480,11 +486,13 @@ glGetRenderbufferParameterivOES
glDeleteFramebuffersOES
dir framebuffers in
len framebuffers (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGenFramebuffersOES(GLsizei n, GLuint *framebuffers)
glGenFramebuffersOES
dir framebuffers out
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)
glGetFramebufferAttachmentParameterivOES
@@ -559,11 +567,13 @@ glGetTexGenxvOES
glDeleteVertexArraysOES
dir arrays in
len arrays (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGenVertexArraysOES(GLsizei n, GLuint *arrays)
glGenVertexArraysOES
dir arrays out
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)
glDiscardFramebufferEXT
@@ -590,11 +600,13 @@ glMultiDrawElementsSUN
glDeleteFencesNV
dir fences in
len fences (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGenFencesNV(GLsizei n, GLuint *fences)
glGenFencesNV
dir fences in
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)
glGetFenceivNV

View File

@@ -11,6 +11,7 @@ GL2Encoder::GL2Encoder(IOStream *stream) : gl2_encoder_context_t(stream)
{
m_initialized = false;
m_state = NULL;
m_error = GL_NO_ERROR;
m_num_compressedTextureFormats = 0;
m_compressedTextureFormats = NULL;
//overrides
@@ -31,6 +32,7 @@ GL2Encoder::GL2Encoder(IOStream *stream) : gl2_encoder_context_t(stream)
m_glGetVertexAttribPointerv = set_glGetVertexAttribPointerv(s_glGetVertexAttribPointerv);
set_glShaderSource(s_glShaderSource);
set_glFinish(s_glFinish);
m_glGetError_enc = set_glGetError(s_glGetError);
}
GL2Encoder::~GL2Encoder()
@@ -38,6 +40,19 @@ GL2Encoder::~GL2Encoder()
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)
{
GL2Encoder *ctx = (GL2Encoder *) self;

View File

@@ -37,10 +37,14 @@ public:
void setInitialized(){ m_initialized = true; };
bool isInitialized(){ return m_initialized; };
virtual void setError(GLenum error){ m_error = error; };
virtual GLenum getError() { return m_error; };
private:
bool m_initialized;
GLClientState *m_state;
GLenum m_error;
GLint *m_compressedTextureFormats;
GLint m_num_compressedTextureFormats;
@@ -50,6 +54,9 @@ private:
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;
static void s_glFlush(void * self);

View File

@@ -26,18 +26,22 @@ glCompressedTexSubImage2D
#void glDeleteBuffers(GLsizei n, GLuint *buffers)
glDeleteBuffers
len buffers (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glDeleteFramebuffers(GLsizei n, GLuint *framebuffers)
glDeleteFramebuffers
len framebuffers (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glDeleteRenderbuffers(GLsizei n, GLuint *renderbuffers)
glDeleteRenderbuffers
len renderbuffers (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glDeleteTextures(GLsizei n, GLuint *textures)
glDeleteTextures
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)
glDrawElements
@@ -47,21 +51,25 @@ glDrawElements
glGenBuffers
len buffers (n * sizeof(GLuint))
dir buffers out
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGenFramebuffers(GLsizei n, GLuint *framebuffers)
glGenFramebuffers
len framebuffers (n * sizeof(GLuint))
dir framebuffers out
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGenRenderbuffers(GLsizei n, GLuint *renderbuffers)
glGenRenderbuffers
len renderbuffers (n * sizeof(GLuint))
dir renderbuffers out
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGenTextures(GLsizei n, GLuint *textures)
glGenTextures
len textures (n * sizeof(GLuint))
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)
glGetActiveAttrib
@@ -330,11 +338,13 @@ glCompressedTexSubImage3DOES
#void glDeleteVertexArraysOES(GLsizei n, GLuint *arrays)
glDeleteVertexArraysOES
len arrays (n * sizeof(GLuint))
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glGenVertexArraysOES(GLsizei n, GLuint *arrays)
glGenVertexArraysOES
len arrays (n * sizeof(GLuint))
dir arrays out
param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; }
#void glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, GLenum *attachments)