am f7e07ec9: Merge "opengles emulator: make glFramebufferTexture2D work"
* commit 'f7e07ec9ea77ea6a589a4708df13f805998a6ba9': opengles emulator: make glFramebufferTexture2D work
This commit is contained in:
@@ -354,6 +354,8 @@ GL_API void GL_APIENTRY glBufferSubData( GLenum target, GLintptr offset, GLsize
|
||||
|
||||
GL_API void GL_APIENTRY glClear( GLbitfield mask) {
|
||||
GET_CTX()
|
||||
ctx->drawValidate();
|
||||
|
||||
ctx->dispatcher().glClear(mask);
|
||||
}
|
||||
|
||||
@@ -557,6 +559,8 @@ GL_API void GL_APIENTRY glDrawArrays( GLenum mode, GLint first, GLsizei count)
|
||||
SET_ERROR_IF(count < 0,GL_INVALID_VALUE)
|
||||
SET_ERROR_IF(!GLEScmValidate::drawMode(mode),GL_INVALID_ENUM)
|
||||
|
||||
ctx->drawValidate();
|
||||
|
||||
if(!ctx->isArrEnabled(GL_VERTEX_ARRAY)) return;
|
||||
|
||||
GLESConversionArrays tmpArrs;
|
||||
@@ -576,6 +580,8 @@ GL_API void GL_APIENTRY glDrawElements( GLenum mode, GLsizei count, GLenum type
|
||||
SET_ERROR_IF((!GLEScmValidate::drawMode(mode) || !GLEScmValidate::drawType(type)),GL_INVALID_ENUM)
|
||||
if(!ctx->isArrEnabled(GL_VERTEX_ARRAY)) return;
|
||||
|
||||
ctx->drawValidate();
|
||||
|
||||
const GLvoid* indices = elementsIndices;
|
||||
GLESConversionArrays tmpArrs;
|
||||
if(ctx->isBindedBuffer(GL_ELEMENT_ARRAY_BUFFER)) { // if vbo is binded take the indices from the vbo
|
||||
@@ -2215,6 +2221,8 @@ void glDrawTexOES (T x, T y, T z, T width, T height) {
|
||||
|
||||
SET_ERROR_IF((width<=0 || height<=0),GL_INVALID_VALUE);
|
||||
|
||||
ctx->drawValidate();
|
||||
|
||||
int numClipPlanes;
|
||||
|
||||
GLint viewport[4];
|
||||
|
||||
@@ -317,6 +317,8 @@ GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target){
|
||||
|
||||
GL_APICALL void GL_APIENTRY glClear(GLbitfield mask){
|
||||
GET_CTX();
|
||||
ctx->drawValidate();
|
||||
|
||||
ctx->dispatcher().glClear(mask);
|
||||
}
|
||||
GL_APICALL void GL_APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha){
|
||||
@@ -535,12 +537,13 @@ GL_APICALL void GL_APIENTRY glDisableVertexAttribArray(GLuint index){
|
||||
ctx->dispatcher().glDisableVertexAttribArray(index);
|
||||
}
|
||||
|
||||
|
||||
GL_APICALL void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count){
|
||||
GET_CTX();
|
||||
SET_ERROR_IF(count < 0,GL_INVALID_VALUE)
|
||||
SET_ERROR_IF(!GLESv2Validate::drawMode(mode),GL_INVALID_ENUM);
|
||||
|
||||
ctx->drawValidate();
|
||||
|
||||
GLESConversionArrays tmpArrs;
|
||||
ctx->setupArraysPointers(tmpArrs,first,count,0,NULL,true);
|
||||
|
||||
@@ -564,6 +567,8 @@ GL_APICALL void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum t
|
||||
SET_ERROR_IF(count < 0,GL_INVALID_VALUE)
|
||||
SET_ERROR_IF(!(GLESv2Validate::drawMode(mode) && GLESv2Validate::drawType(type)),GL_INVALID_ENUM);
|
||||
|
||||
ctx->drawValidate();
|
||||
|
||||
const GLvoid* indices = elementsIndices;
|
||||
if(ctx->isBindedBuffer(GL_ELEMENT_ARRAY_BUFFER)) { // if vbo is binded take the indices from the vbo
|
||||
const unsigned char* buf = static_cast<unsigned char *>(ctx->getBindedBuffer(GL_ELEMENT_ARRAY_BUFFER));
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <GLES/gl.h>
|
||||
#include <GLES/glext.h>
|
||||
#include <GLcommon/FramebufferData.h>
|
||||
#include <GLcommon/GLEScontext.h>
|
||||
|
||||
RenderbufferData::RenderbufferData() : sourceEGLImage(0),
|
||||
eglImageDetach(NULL),
|
||||
@@ -29,7 +30,7 @@ RenderbufferData::~RenderbufferData() {
|
||||
}
|
||||
|
||||
|
||||
FramebufferData::FramebufferData(GLuint name) {
|
||||
FramebufferData::FramebufferData(GLuint name):m_dirty(false) {
|
||||
m_fbName = name;
|
||||
for (int i=0; i<MAX_ATTACH_POINTS; i++) {
|
||||
m_attachPoints[i].target = 0;
|
||||
@@ -47,24 +48,29 @@ for (int i=0; i<MAX_ATTACH_POINTS; i++) {
|
||||
void FramebufferData::setAttachment(GLenum attachment,
|
||||
GLenum target,
|
||||
GLuint name,
|
||||
ObjectDataPtr obj) {
|
||||
ObjectDataPtr obj,
|
||||
bool takeOwnership) {
|
||||
int idx = attachmentPointIndex(attachment);
|
||||
|
||||
if (m_attachPoints[idx].target != target ||
|
||||
m_attachPoints[idx].name != name ||
|
||||
m_attachPoints[idx].obj.Ptr() != obj.Ptr()) {
|
||||
m_attachPoints[idx].obj.Ptr() != obj.Ptr() ||
|
||||
m_attachPoints[idx].owned != takeOwnership) {
|
||||
|
||||
detachObject(idx);
|
||||
|
||||
m_attachPoints[idx].target = target;
|
||||
m_attachPoints[idx].name = name;
|
||||
m_attachPoints[idx].obj = obj;
|
||||
m_attachPoints[idx].owned = takeOwnership;
|
||||
|
||||
if (target == GL_RENDERBUFFER_OES && obj.Ptr() != NULL) {
|
||||
RenderbufferData *rbData = (RenderbufferData *)obj.Ptr();
|
||||
rbData->attachedFB = m_fbName;
|
||||
rbData->attachedPoint = attachment;
|
||||
}
|
||||
|
||||
m_dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +91,7 @@ int FramebufferData::attachmentPointIndex(GLenum attachment)
|
||||
case GL_DEPTH_ATTACHMENT_OES:
|
||||
return 1;
|
||||
case GL_STENCIL_ATTACHMENT_OES:
|
||||
return 3;
|
||||
return 2;
|
||||
default:
|
||||
return MAX_ATTACH_POINTS;
|
||||
}
|
||||
@@ -97,7 +103,109 @@ void FramebufferData::detachObject(int idx) {
|
||||
rbData->attachedFB = 0;
|
||||
rbData->attachedPoint = 0;
|
||||
}
|
||||
|
||||
if(m_attachPoints[idx].owned)
|
||||
{
|
||||
switch(m_attachPoints[idx].target)
|
||||
{
|
||||
case GL_RENDERBUFFER_OES:
|
||||
GLEScontext::dispatcher().glDeleteRenderbuffersEXT(1, &(m_attachPoints[idx].name));
|
||||
break;
|
||||
case GL_TEXTURE_2D:
|
||||
GLEScontext::dispatcher().glDeleteTextures(1, &(m_attachPoints[idx].name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_attachPoints[idx].target = 0;
|
||||
m_attachPoints[idx].name = 0;
|
||||
m_attachPoints[idx].obj = ObjectDataPtr(NULL);
|
||||
m_attachPoints[idx].owned = false;
|
||||
}
|
||||
|
||||
void FramebufferData::validate(GLEScontext* ctx)
|
||||
{
|
||||
if(!getAttachment(GL_COLOR_ATTACHMENT0_OES, NULL, NULL))
|
||||
{
|
||||
// GLES does not require the framebuffer to have a color attachment.
|
||||
// OpenGL does. Therefore, if no color is attached, create a dummy
|
||||
// color texture and attach it.
|
||||
// This dummy color texture will is owned by the FramebufferObject,
|
||||
// and will be released by it when its object is detached.
|
||||
|
||||
GLint type = GL_NONE;
|
||||
GLint name = 0;
|
||||
|
||||
ctx->dispatcher().glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT_OES, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type);
|
||||
if(type != GL_NONE)
|
||||
{
|
||||
ctx->dispatcher().glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT_OES, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->dispatcher().glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT_OES, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type);
|
||||
if(type != GL_NONE)
|
||||
{
|
||||
ctx->dispatcher().glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT_OES, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &name);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No color, depth or stencil attachments - do nothing
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Find the existing attachment(s) dimensions
|
||||
GLint width = 0;
|
||||
GLint height = 0;
|
||||
|
||||
if(type == GL_RENDERBUFFER)
|
||||
{
|
||||
GLint prev;
|
||||
ctx->dispatcher().glGetIntegerv(GL_RENDERBUFFER_BINDING, &prev);
|
||||
ctx->dispatcher().glBindRenderbufferEXT(GL_RENDERBUFFER, name);
|
||||
ctx->dispatcher().glGetRenderbufferParameterivEXT(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width);
|
||||
ctx->dispatcher().glGetRenderbufferParameterivEXT(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height);
|
||||
ctx->dispatcher().glBindRenderbufferEXT(GL_RENDERBUFFER, prev);
|
||||
}
|
||||
else if(type == GL_TEXTURE)
|
||||
{
|
||||
GLint prev;
|
||||
ctx->dispatcher().glGetIntegerv(GL_TEXTURE_BINDING_2D, &prev);
|
||||
ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, name);
|
||||
ctx->dispatcher().glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
|
||||
ctx->dispatcher().glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
|
||||
ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, prev);
|
||||
}
|
||||
|
||||
// Create the color attachment and attch it
|
||||
unsigned int tex = ctx->shareGroup()->genGlobalName(TEXTURE);
|
||||
GLint prev;
|
||||
ctx->dispatcher().glGetIntegerv(GL_TEXTURE_BINDING_2D, &prev);
|
||||
ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, tex);
|
||||
|
||||
ctx->dispatcher().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
|
||||
ctx->dispatcher().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
|
||||
ctx->dispatcher().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
|
||||
ctx->dispatcher().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
|
||||
ctx->dispatcher().glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
ctx->dispatcher().glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tex, 0);
|
||||
setAttachment(GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tex, ObjectDataPtr(NULL), true);
|
||||
|
||||
ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, prev);
|
||||
}
|
||||
|
||||
if(m_dirty)
|
||||
{
|
||||
// This is a workaround for a bug found in several OpenGL
|
||||
// drivers (e.g. ATI's) - after the framebuffer attachments
|
||||
// have changed, and before the next draw, unbind and rebind
|
||||
// the framebuffer to sort things out.
|
||||
ctx->dispatcher().glBindFramebufferEXT(GL_FRAMEBUFFER,0);
|
||||
ctx->dispatcher().glBindFramebufferEXT(GL_FRAMEBUFFER,ctx->shareGroup()->getGlobalName(FRAMEBUFFER,m_fbName));
|
||||
|
||||
m_dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <GLES/glext.h>
|
||||
#include <GLcommon/GLESvalidate.h>
|
||||
#include <GLcommon/TextureUtils.h>
|
||||
#include <GLcommon/FramebufferData.h>
|
||||
#include <strings.h>
|
||||
|
||||
//decleration
|
||||
@@ -676,3 +677,17 @@ ObjectLocalName GLEScontext::getDefaultTextureName(GLenum target) {
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
void GLEScontext::drawValidate(void)
|
||||
{
|
||||
if(m_framebuffer == 0)
|
||||
return;
|
||||
|
||||
ObjectDataPtr fbObj = m_shareGroup->getObjectData(FRAMEBUFFER,m_framebuffer);
|
||||
if (fbObj.Ptr() == NULL)
|
||||
return;
|
||||
|
||||
FramebufferData *fbData = (FramebufferData *)fbObj.Ptr();
|
||||
|
||||
fbData->validate(this);
|
||||
}
|
||||
|
||||
@@ -53,6 +53,13 @@ NameSpace::genName(ObjectLocalName p_localName, bool genGlobal, bool genLocal)
|
||||
return localName;
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
NameSpace::genGlobalName(void)
|
||||
{
|
||||
return m_globalNameSpace->genName(m_type);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
NameSpace::getGlobalName(ObjectLocalName p_localName)
|
||||
{
|
||||
@@ -190,6 +197,18 @@ ShareGroup::genName(NamedObjectType p_type, ObjectLocalName p_localName, bool ge
|
||||
return localName;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
ShareGroup::genGlobalName(NamedObjectType p_type)
|
||||
{
|
||||
if (p_type >= NUM_OBJECT_TYPES) return 0;
|
||||
|
||||
mutex_lock(&m_lock);
|
||||
unsigned int name = m_nameSpace[p_type]->genGlobalName();
|
||||
mutex_unlock(&m_lock);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
ShareGroup::getGlobalName(NamedObjectType p_type, ObjectLocalName p_localName)
|
||||
{
|
||||
@@ -389,3 +408,4 @@ void *ObjectNameManager::getGlobalContext()
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,12 +45,15 @@ public:
|
||||
void setAttachment(GLenum attachment,
|
||||
GLenum target,
|
||||
GLuint name,
|
||||
ObjectDataPtr obj);
|
||||
ObjectDataPtr obj,
|
||||
bool takeOwnership = false);
|
||||
|
||||
GLuint getAttachment(GLenum attachment,
|
||||
GLenum *outTarget,
|
||||
ObjectDataPtr *outObj);
|
||||
|
||||
void validate(class GLEScontext* ctx);
|
||||
|
||||
private:
|
||||
inline int attachmentPointIndex(GLenum attachment);
|
||||
void detachObject(int idx);
|
||||
@@ -58,10 +61,12 @@ private:
|
||||
private:
|
||||
GLuint m_fbName;
|
||||
struct attachPoint {
|
||||
GLenum target;
|
||||
GLuint name;
|
||||
GLenum target; // OGL if owned, GLES otherwise
|
||||
GLuint name; // OGL if owned, GLES otherwise
|
||||
ObjectDataPtr obj;
|
||||
bool owned;
|
||||
} m_attachPoints[MAX_ATTACH_POINTS+1];
|
||||
bool m_dirty;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -135,6 +135,7 @@ public:
|
||||
virtual GLSupport* getCaps(){return &s_glSupport;};
|
||||
virtual ~GLEScontext();
|
||||
virtual int getMaxTexUnits() = 0;
|
||||
virtual void drawValidate(void);
|
||||
|
||||
void setRenderbufferBinding(GLuint rb) { m_renderbuffer = rb; }
|
||||
GLuint getRenderbufferBinding() const { return m_renderbuffer; }
|
||||
|
||||
@@ -80,6 +80,11 @@ private:
|
||||
//
|
||||
ObjectLocalName genName(ObjectLocalName p_localName, bool genGlobal, bool genLocal);
|
||||
|
||||
// genGlobalName() - This function creates a global name
|
||||
// with no associated local name, for the
|
||||
// translator internal use.
|
||||
unsigned int genGlobalName(void);
|
||||
|
||||
//
|
||||
// getGlobalName - returns the global name of an object or 0 if the object
|
||||
// does not exist.
|
||||
@@ -150,6 +155,11 @@ public:
|
||||
//
|
||||
ObjectLocalName genName(NamedObjectType p_type, ObjectLocalName p_localName = 0, bool genLocal= false);
|
||||
|
||||
// genGlobalName() - This function creates a global name
|
||||
// with no associated local name, for the
|
||||
// translator internal use.
|
||||
unsigned int genGlobalName(NamedObjectType p_type);
|
||||
|
||||
//
|
||||
// getGlobalName - retrieves the "global" name of an object or 0 if the
|
||||
// object does not exist.
|
||||
|
||||
Reference in New Issue
Block a user