diff --git a/tools/emulator/opengl/host/tools/emugen/ApiGen.cpp b/tools/emulator/opengl/host/tools/emugen/ApiGen.cpp index 9818e5db4..3df3107a9 100644 --- a/tools/emulator/opengl/host/tools/emugen/ApiGen.cpp +++ b/tools/emulator/opengl/host/tools/emugen/ApiGen.cpp @@ -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; jvars().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(), diff --git a/tools/emulator/opengl/host/tools/emugen/EntryPoint.cpp b/tools/emulator/opengl/host/tools/emugen/EntryPoint.cpp index 03410272e..413b56af6 100644 --- a/tools/emulator/opengl/host/tools/emugen/EntryPoint.cpp +++ b/tools/emulator/opengl/host/tools/emugen/EntryPoint.cpp @@ -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); diff --git a/tools/emulator/opengl/host/tools/emugen/Var.h b/tools/emulator/opengl/host/tools/emugen/Var.h index ba74cea48..c9735c714 100644 --- a/tools/emulator/opengl/host/tools/emugen/Var.h +++ b/tools/emulator/opengl/host/tools/emugen/Var.h @@ -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 }; diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/gl_base_types.h b/tools/emulator/opengl/shared/OpenglCodecCommon/gl_base_types.h index 8a7ad58f0..d7bdef8bf 100644 --- a/tools/emulator/opengl/shared/OpenglCodecCommon/gl_base_types.h +++ b/tools/emulator/opengl/shared/OpenglCodecCommon/gl_base_types.h @@ -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 diff --git a/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp b/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp index ef1e4b8fe..653f71f1d 100644 --- a/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp +++ b/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp @@ -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); } diff --git a/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.h b/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.h index 6275820dc..7471bfb38 100644 --- a/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.h +++ b/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.h @@ -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); diff --git a/tools/emulator/opengl/system/GLESv1_enc/gl.attrib b/tools/emulator/opengl/system/GLESv1_enc/gl.attrib index d3d97fcc2..8c0308460 100644 --- a/tools/emulator/opengl/system/GLESv1_enc/gl.attrib +++ b/tools/emulator/opengl/system/GLESv1_enc/gl.attrib @@ -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 diff --git a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp index 1d645914e..969c0c981 100644 --- a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp +++ b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp @@ -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; diff --git a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.h b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.h index 3365d0603..bbe5659a7 100644 --- a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.h +++ b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.h @@ -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); diff --git a/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib b/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib index 118fe5841..3b37bd898 100644 --- a/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib +++ b/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib @@ -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)