Commit dde7f446 by Nicolas Capens Committed by Nicolas Capens

Eliminate GL resource manager.

Bug 18591036 Change-Id: I436c8cc4b30d41010db7ab4b10be0c74217b9f15 Reviewed-on: https://swiftshader-review.googlesource.com/1550Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 53fae3e9
...@@ -16,9 +16,6 @@ class Context ...@@ -16,9 +16,6 @@ class Context
public: public:
virtual void destroy() = 0; virtual void destroy() = 0;
virtual void makeCurrent(Surface *surface) = 0; virtual void makeCurrent(Surface *surface) = 0;
virtual void bindTexImage(Surface *surface) = 0;
virtual EGLenum validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel) = 0;
virtual Image *createSharedImage(EGLenum target, GLuint name, GLuint textureLevel) = 0;
virtual int getClientVersion() = 0; virtual int getClientVersion() = 0;
}; };
} }
......
...@@ -89,12 +89,6 @@ void Surface::release() ...@@ -89,12 +89,6 @@ void Surface::release()
mDepthStencil = NULL; mDepthStencil = NULL;
} }
if(mTexture)
{
mTexture->releaseTexImage();
mTexture = NULL;
}
if(backBuffer) if(backBuffer)
{ {
backBuffer->release(); backBuffer->release();
......
...@@ -6,7 +6,6 @@ namespace egl ...@@ -6,7 +6,6 @@ namespace egl
class Texture2D class Texture2D
{ {
public: public:
virtual void releaseTexImage() = 0;
}; };
} }
......
...@@ -629,103 +629,6 @@ EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLi ...@@ -629,103 +629,6 @@ EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLi
return EGL_FALSE; return EGL_FALSE;
} }
EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
try
{
egl::Display *display = static_cast<egl::Display*>(dpy);
egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
if(!validateSurface(display, eglSurface))
{
return EGL_FALSE;
}
if(buffer != EGL_BACK_BUFFER)
{
return error(EGL_BAD_PARAMETER, EGL_FALSE);
}
if(surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
{
return error(EGL_BAD_SURFACE, EGL_FALSE);
}
if(eglSurface->getBoundTexture())
{
return error(EGL_BAD_ACCESS, EGL_FALSE);
}
if(eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
{
return error(EGL_BAD_MATCH, EGL_FALSE);
}
egl::Context *context = static_cast<egl::Context*>(egl::getCurrentContext());
if(context)
{
context->bindTexImage(eglSurface);
}
return success(EGL_TRUE);
}
catch(std::bad_alloc&)
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
try
{
egl::Display *display = static_cast<egl::Display*>(dpy);
egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
if(!validateSurface(display, eglSurface))
{
return EGL_FALSE;
}
if(buffer != EGL_BACK_BUFFER)
{
return error(EGL_BAD_PARAMETER, EGL_FALSE);
}
if(surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
{
return error(EGL_BAD_SURFACE, EGL_FALSE);
}
if(eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
{
return error(EGL_BAD_MATCH, EGL_FALSE);
}
egl::Texture2D *texture = eglSurface->getBoundTexture();
if(texture)
{
texture->releaseTexImage();
}
return success(EGL_TRUE);
}
catch(std::bad_alloc&)
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval) EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval)
{ {
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval); TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval);
...@@ -1078,149 +981,15 @@ EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNat ...@@ -1078,149 +981,15 @@ EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNat
return EGL_FALSE; return EGL_FALSE;
} }
EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
{
try
{
egl::Display *display = static_cast<egl::Display*>(dpy);
egl::Context *context = static_cast<egl::Context*>(ctx);
if(!validateDisplay(display))
{
return error(EGL_BAD_DISPLAY, EGL_NO_IMAGE_KHR);
}
if(context != EGL_NO_CONTEXT && !display->isValidContext(context))
{
return error(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
}
EGLenum imagePreserved = EGL_FALSE;
GLuint textureLevel = 0;
if(attrib_list)
{
for(const EGLint *attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
{
if(attribute[0] == EGL_IMAGE_PRESERVED_KHR)
{
imagePreserved = attribute[1];
}
else if(attribute[0] == EGL_GL_TEXTURE_LEVEL_KHR)
{
textureLevel = attribute[1];
}
else
{
return error(EGL_BAD_ATTRIBUTE, EGL_NO_IMAGE_KHR);
}
}
}
GLuint name = reinterpret_cast<intptr_t>(buffer);
if(name == 0)
{
return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
}
EGLenum validationResult = context->validateSharedImage(target, name, textureLevel);
if(validationResult != EGL_SUCCESS)
{
return error(validationResult, EGL_NO_IMAGE_KHR);
}
egl::Image *image = context->createSharedImage(target, name, textureLevel);
if(!image)
{
return error(EGL_BAD_MATCH, EGL_NO_IMAGE_KHR);
}
if(image->getMultiSampleDepth() > 1)
{
return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
}
return success((EGLImageKHR)image);
}
catch(std::bad_alloc&)
{
return error(EGL_BAD_ALLOC, EGL_NO_IMAGE_KHR);
}
return EGL_NO_IMAGE_KHR;
}
EGLBoolean EGLAPIENTRY eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
{
try
{
egl::Display *display = static_cast<egl::Display*>(dpy);
if(!validateDisplay(display))
{
return error(EGL_BAD_DISPLAY, EGL_FALSE);
}
if(!image)
{
return error(EGL_BAD_PARAMETER, EGL_FALSE);
}
egl::Image *glImage = static_cast<egl::Image*>(image);
glImage->release();
return success(EGL_TRUE);
}
catch(std::bad_alloc&)
{
return error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
}
__eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname) __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname)
{ {
TRACE("(const char *procname = \"%s\")", procname); TRACE("(const char *procname = \"%s\")", procname);
try
{
struct Extension
{
const char *name;
__eglMustCastToProperFunctionPointerType address;
};
static const Extension eglExtensions[] =
{
#define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
EXTENSION(eglCreateImageKHR),
EXTENSION(eglDestroyImageKHR),
#undef EXTENSION
};
for(int ext = 0; ext < sizeof(eglExtensions) / sizeof(Extension); ext++)
{
if(strcmp(procname, eglExtensions[ext].name) == 0)
{
return (__eglMustCastToProperFunctionPointerType)eglExtensions[ext].address;
}
}
if(rad::getProcAddress != 0) if(rad::getProcAddress != 0)
{ {
__eglMustCastToProperFunctionPointerType proc = rad::getProcAddress(procname); __eglMustCastToProperFunctionPointerType proc = rad::getProcAddress(procname);
if(proc) return proc; if(proc) return proc;
} }
}
catch(std::bad_alloc&)
{
return error(EGL_BAD_ALLOC, (__eglMustCastToProperFunctionPointerType)NULL);
}
return NULL; return NULL;
} }
......
LIBRARY libEGL LIBRARY libEGL
EXPORTS EXPORTS
eglBindAPI @14 eglBindAPI @14
eglBindTexImage @20
eglChooseConfig @7 eglChooseConfig @7
eglCopyBuffers @33 eglCopyBuffers @33
eglCreateContext @23 eglCreateContext @23
...@@ -25,7 +24,6 @@ EXPORTS ...@@ -25,7 +24,6 @@ EXPORTS
eglQueryContext @29 eglQueryContext @29
eglQueryString @5 eglQueryString @5
eglQuerySurface @13 eglQuerySurface @13
eglReleaseTexImage @21
eglReleaseThread @17 eglReleaseThread @17
eglSurfaceAttrib @19 eglSurfaceAttrib @19
eglSwapBuffers @32 eglSwapBuffers @32
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "main.h" #include "main.h"
#include "mathutil.h" #include "mathutil.h"
#include "utilities.h" #include "utilities.h"
#include "ResourceManager.h"
#include "Buffer.h" #include "Buffer.h"
#include "Fence.h" #include "Fence.h"
#include "Framebuffer.h" #include "Framebuffer.h"
...@@ -39,11 +38,10 @@ ...@@ -39,11 +38,10 @@
namespace es2 namespace es2
{ {
Device *Context::device = 0;
Context::Context(const egl::Config *config, const Context *shareContext) : mConfig(config) Context::Context(const egl::Config *config, const Context *shareContext) : mConfig(config)
{ {
device = getDevice(); sw::Context *context = new sw::Context();
device = new es2::Device(context);
mFenceHandleAllocator.setBaseHandle(0); mFenceHandleAllocator.setBaseHandle(0);
...@@ -115,39 +113,17 @@ Context::Context(const egl::Config *config, const Context *shareContext) : mConf ...@@ -115,39 +113,17 @@ Context::Context(const egl::Config *config, const Context *shareContext) : mConf
mState.colorMaskAlpha = true; mState.colorMaskAlpha = true;
mState.depthMask = true; mState.depthMask = true;
if(shareContext != NULL)
{
mResourceManager = shareContext->mResourceManager;
mResourceManager->addRef();
}
else
{
mResourceManager = new ResourceManager();
}
// [OpenGL ES 2.0.24] section 3.7 page 83:
// In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
// and cube map texture state vectors respectively associated with them.
// In order that access to these initial textures not be lost, they are treated as texture
// objects all of whose names are 0.
mTexture2DZero.set(new Texture2D(0));
mTextureCubeMapZero.set(new TextureCubeMap(0));
mTextureExternalZero.set(new TextureExternal(0));
mState.activeSampler = 0; mState.activeSampler = 0;
mState.elementArrayBuffer = 0; mState.elementArrayBuffer = 0;
bindTextureCubeMap(0);
bindTexture2D(0);
bindReadFramebuffer(0);
bindDrawFramebuffer(0);
bindRenderbuffer(0);
mState.currentProgram = 0;
mState.packAlignment = 4; mState.packAlignment = 4;
mState.unpackAlignment = 4; mState.unpackAlignment = 4;
mState.program = 0;
mState.colorBuffer = 0;
mState.depthBuffer = 0;
mState.stencilBuffer = 0;
mVertexDataManager = NULL; mVertexDataManager = NULL;
mIndexDataManager = NULL; mIndexDataManager = NULL;
...@@ -164,61 +140,8 @@ Context::Context(const egl::Config *config, const Context *shareContext) : mConf ...@@ -164,61 +140,8 @@ Context::Context(const egl::Config *config, const Context *shareContext) : mConf
Context::~Context() Context::~Context()
{ {
if(mState.currentProgram != 0)
{
Program *programObject = mResourceManager->getProgram(mState.currentProgram);
if(programObject)
{
programObject->release();
}
mState.currentProgram = 0;
}
while(!mFramebufferMap.empty())
{
deleteFramebuffer(mFramebufferMap.begin()->first);
}
while(!mFenceMap.empty())
{
deleteFence(mFenceMap.begin()->first);
}
while(!mQueryMap.empty())
{
deleteQuery(mQueryMap.begin()->first);
}
for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
{
for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
{
mState.samplerTexture[type][sampler].set(NULL);
}
}
for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
mState.vertexAttribute[i].buffer = 0;
}
for(int i = 0; i < QUERY_TYPE_COUNT; i++)
{
mState.activeQuery[i].set(NULL);
}
//mState.arrayBuffer.set(NULL);
//mState.elementArrayBuffer.set(NULL);
//mState.renderbuffer.set(NULL);
mTexture2DZero.set(NULL);
mTextureCubeMapZero.set(NULL);
mTextureExternalZero.set(NULL);
delete mVertexDataManager; delete mVertexDataManager;
delete mIndexDataManager; delete mIndexDataManager;
mResourceManager->release();
} }
void Context::makeCurrent(egl::Surface *surface) void Context::makeCurrent(egl::Surface *surface)
...@@ -241,26 +164,6 @@ void Context::makeCurrent(egl::Surface *surface) ...@@ -241,26 +164,6 @@ void Context::makeCurrent(egl::Surface *surface)
mHasBeenCurrent = true; mHasBeenCurrent = true;
} }
// Wrap the existing resources into GL objects and assign them to the '0' names
egl::Image *defaultRenderTarget = surface->getRenderTarget();
egl::Image *depthStencil = surface->getDepthStencil();
Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
setFramebufferZero(framebufferZero);
if(defaultRenderTarget)
{
defaultRenderTarget->release();
}
if(depthStencil)
{
depthStencil->release();
}
markAllStateDirty(); markAllStateDirty();
} }
...@@ -648,21 +551,6 @@ void Context::setActiveSampler(unsigned int active) ...@@ -648,21 +551,6 @@ void Context::setActiveSampler(unsigned int active)
mState.activeSampler = active; mState.activeSampler = active;
} }
GLuint Context::getReadFramebufferHandle() const
{
return mState.readFramebuffer;
}
GLuint Context::getDrawFramebufferHandle() const
{
return mState.drawFramebuffer;
}
GLuint Context::getRenderbufferHandle() const
{
return mState.renderbuffer.id();
}
GLuint Context::getActiveQuery(GLenum target) const GLuint Context::getActiveQuery(GLenum target) const
{ {
Query *queryObject = NULL; Query *queryObject = NULL;
...@@ -733,614 +621,204 @@ GLint Context::getUnpackAlignment() const ...@@ -733,614 +621,204 @@ GLint Context::getUnpackAlignment() const
return mState.unpackAlignment; return mState.unpackAlignment;
} }
GLuint Context::createProgram() void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
{
return mResourceManager->createProgram();
}
GLuint Context::createShader(GLenum type)
{
return mResourceManager->createShader(type);
}
GLuint Context::createTexture()
{
return mResourceManager->createTexture();
}
GLuint Context::createRenderbuffer()
{
return mResourceManager->createRenderbuffer();
}
// Returns an unused framebuffer name
GLuint Context::createFramebuffer()
{ {
GLuint handle = mFramebufferHandleAllocator.allocate(); Renderbuffer *renderbufferObject = mState.renderbuffer.get();
renderbufferObject->setStorage(renderbuffer);
mFramebufferMap[handle] = NULL;
return handle;
} }
GLuint Context::createFence() // Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
bool Context::applyRenderTarget()
{ {
GLuint handle = mFenceHandleAllocator.allocate(); egl::Image *renderTarget = mState.colorBuffer;//framebuffer->getRenderTarget();
device->setRenderTarget(renderTarget);
//if(renderTarget) renderTarget->release();
mFenceMap[handle] = new Fence; egl::Image *depthStencil = mState.depthBuffer;//framebuffer->getDepthStencil();
device->setDepthStencilSurface(depthStencil);
//if(depthStencil) depthStencil->release();
return handle; Viewport viewport;
} float zNear = clamp01(mState.zNear);
float zFar = clamp01(mState.zFar);
// Returns an unused query name viewport.x0 = mState.viewportX;
GLuint Context::createQuery() viewport.y0 = mState.viewportY;
{ viewport.width = mState.viewportWidth;
GLuint handle = mQueryHandleAllocator.allocate(); viewport.height = mState.viewportHeight;
viewport.minZ = zNear;
viewport.maxZ = zFar;
mQueryMap[handle] = NULL; device->setViewport(viewport);
return handle; if(mState.scissorTest)
} {
sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight};
scissor.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
void Context::deleteShader(GLuint shader) device->setScissorRect(scissor);
{ device->setScissorEnable(true);
mResourceManager->deleteShader(shader); }
} else
{
device->setScissorEnable(false);
}
void Context::deleteProgram(GLuint program) Program *program = mState.program;
{
mResourceManager->deleteProgram(program);
}
void Context::deleteTexture(GLuint texture) if(program)
{
if(mResourceManager->getTexture(texture))
{ {
detachTexture(texture); GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};
program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]);
program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]);
program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]);
} }
mResourceManager->deleteTexture(texture); return true;
} }
void Context::deleteRenderbuffer(GLuint renderbuffer) // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
void Context::applyState(GLenum drawMode)
{ {
if(mResourceManager->getRenderbuffer(renderbuffer)) if(mState.cullFace)
{
device->setCullMode(rad2sw::ConvertCullMode(mState.cullMode, mState.frontFace));
}
else
{ {
detachRenderbuffer(renderbuffer); device->setCullMode(sw::CULL_NONE);
} }
mResourceManager->deleteRenderbuffer(renderbuffer); if(mDepthStateDirty)
} {
if(mState.depthTest)
{
device->setDepthBufferEnable(true);
device->setDepthCompare(rad2sw::ConvertDepthComparison(mState.depthFunc));
}
else
{
device->setDepthBufferEnable(false);
}
void Context::deleteFramebuffer(GLuint framebuffer) mDepthStateDirty = false;
{ }
FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
if(framebufferObject != mFramebufferMap.end()) if(mBlendStateDirty)
{
if(mState.blend)
{ {
detachFramebuffer(framebuffer); device->setAlphaBlendEnable(true);
device->setSeparateAlphaBlendEnable(true);
mFramebufferHandleAllocator.release(framebufferObject->first); device->setBlendConstant(rad2sw::ConvertColor(mState.blendColor));
delete framebufferObject->second;
mFramebufferMap.erase(framebufferObject);
}
}
void Context::deleteFence(GLuint fence) device->setSourceBlendFactor(rad2sw::ConvertBlendFunc(mState.sourceBlendRGB));
{ device->setDestBlendFactor(rad2sw::ConvertBlendFunc(mState.destBlendRGB));
FenceMap::iterator fenceObject = mFenceMap.find(fence); device->setBlendOperation(rad2sw::ConvertBlendOp(mState.blendEquationRGB));
if(fenceObject != mFenceMap.end()) device->setSourceBlendFactorAlpha(rad2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
device->setDestBlendFactorAlpha(rad2sw::ConvertBlendFunc(mState.destBlendAlpha));
device->setBlendOperationAlpha(rad2sw::ConvertBlendOp(mState.blendEquationAlpha));
}
else
{ {
mFenceHandleAllocator.release(fenceObject->first); device->setAlphaBlendEnable(false);
delete fenceObject->second;
mFenceMap.erase(fenceObject);
} }
}
void Context::deleteQuery(GLuint query) mBlendStateDirty = false;
{ }
QueryMap::iterator queryObject = mQueryMap.find(query);
if(queryObject != mQueryMap.end()) if(mStencilStateDirty || mFrontFaceDirty)
{ {
mQueryHandleAllocator.release(queryObject->first); if(mState.stencilTest && mState.stencilBuffer)
if(queryObject->second)
{ {
queryObject->second->release(); device->setStencilEnable(true);
} device->setTwoSidedStencil(true);
mQueryMap.erase(queryObject); if(mState.stencilWritemask != mState.stencilBackWritemask ||
mState.stencilRef != mState.stencilBackRef ||
mState.stencilMask != mState.stencilBackMask)
{
ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL.");
return error(GL_INVALID_OPERATION);
} }
}
Shader *Context::getShader(GLuint handle) // get the maximum size of the stencil ref
{ egl::Image *stencilbuffer = mState.stencilBuffer;
return mResourceManager->getShader(handle); GLuint maxStencil = (1 << sw2rad::GetStencilSize(stencilbuffer->getInternalFormat())) - 1;
}
Program *Context::getProgram(GLuint handle)
{
return mResourceManager->getProgram(handle);
}
Texture *Context::getTexture(GLuint handle) if(mState.frontFace == GL_CCW)
{ {
return mResourceManager->getTexture(handle); device->setStencilWriteMask(mState.stencilWritemask);
} device->setStencilCompare(rad2sw::ConvertStencilComparison(mState.stencilFunc));
Renderbuffer *Context::getRenderbuffer(GLuint handle) device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
{ device->setStencilMask(mState.stencilMask);
return mResourceManager->getRenderbuffer(handle);
}
Framebuffer *Context::getReadFramebuffer() device->setStencilFailOperation(rad2sw::ConvertStencilOp(mState.stencilFail));
{ device->setStencilZFailOperation(rad2sw::ConvertStencilOp(mState.stencilPassDepthFail));
return getFramebuffer(mState.readFramebuffer); device->setStencilPassOperation(rad2sw::ConvertStencilOp(mState.stencilPassDepthPass));
}
Framebuffer *Context::getDrawFramebuffer() device->setStencilWriteMaskCCW(mState.stencilBackWritemask);
{ device->setStencilCompareCCW(rad2sw::ConvertStencilComparison(mState.stencilBackFunc));
return getFramebuffer(mState.drawFramebuffer);
}
void Context::bindTexture2D(GLuint texture) device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
{ device->setStencilMaskCCW(mState.stencilBackMask);
mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
mState.samplerTexture[TEXTURE_2D][mState.activeSampler].set(getTexture(texture)); device->setStencilFailOperationCCW(rad2sw::ConvertStencilOp(mState.stencilBackFail));
} device->setStencilZFailOperationCCW(rad2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
device->setStencilPassOperationCCW(rad2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
}
else
{
device->setStencilWriteMaskCCW(mState.stencilWritemask);
device->setStencilCompareCCW(rad2sw::ConvertStencilComparison(mState.stencilFunc));
void Context::bindTextureCubeMap(GLuint texture) device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
{ device->setStencilMaskCCW(mState.stencilMask);
mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].set(getTexture(texture)); device->setStencilFailOperationCCW(rad2sw::ConvertStencilOp(mState.stencilFail));
} device->setStencilZFailOperationCCW(rad2sw::ConvertStencilOp(mState.stencilPassDepthFail));
device->setStencilPassOperationCCW(rad2sw::ConvertStencilOp(mState.stencilPassDepthPass));
void Context::bindTextureExternal(GLuint texture) device->setStencilWriteMask(mState.stencilBackWritemask);
{ device->setStencilCompare(rad2sw::ConvertStencilComparison(mState.stencilBackFunc));
mResourceManager->checkTextureAllocation(texture, TEXTURE_EXTERNAL);
mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].set(getTexture(texture)); device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
} device->setStencilMask(mState.stencilBackMask);
void Context::bindReadFramebuffer(GLuint framebuffer) device->setStencilFailOperation(rad2sw::ConvertStencilOp(mState.stencilBackFail));
{ device->setStencilZFailOperation(rad2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
if(!getFramebuffer(framebuffer)) device->setStencilPassOperation(rad2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
{
mFramebufferMap[framebuffer] = new Framebuffer();
} }
}
mState.readFramebuffer = framebuffer; else
}
void Context::bindDrawFramebuffer(GLuint framebuffer)
{
if(!getFramebuffer(framebuffer))
{ {
mFramebufferMap[framebuffer] = new Framebuffer(); device->setStencilEnable(false);
} }
mState.drawFramebuffer = framebuffer; mStencilStateDirty = false;
} mFrontFaceDirty = false;
}
void Context::bindRenderbuffer(GLuint renderbuffer)
{
mState.renderbuffer.set(getRenderbuffer(renderbuffer));
}
void Context::useProgram(GLuint program)
{
GLuint priorProgram = mState.currentProgram;
mState.currentProgram = program; // Must switch before trying to delete, otherwise it only gets flagged.
if(priorProgram != program) if(mMaskStateDirty)
{ {
Program *newProgram = mResourceManager->getProgram(program); device->setColorWriteMask(0, rad2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
Program *oldProgram = mResourceManager->getProgram(priorProgram); device->setDepthWriteEnable(mState.depthMask);
if(newProgram) mMaskStateDirty = false;
{
newProgram->addRef();
} }
if(oldProgram) if(mPolygonOffsetStateDirty)
{
oldProgram->release();
}
}
}
void Context::beginQuery(GLenum target, GLuint query)
{
// From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
// of zero, if the active query object name for <target> is non-zero (for the
// targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
// the active query for either target is non-zero), if <id> is the name of an
// existing query object whose type does not match <target>, or if <id> is the
// active query object name for any query type, the error INVALID_OPERATION is
// generated.
// Ensure no other queries are active
// NOTE: If other queries than occlusion are supported, we will need to check
// separately that:
// a) The query ID passed is not the current active query for any target/type
// b) There are no active queries for the requested target (and in the case
// of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
// no query may be active for either if glBeginQuery targets either.
for(int i = 0; i < QUERY_TYPE_COUNT; i++)
{
if(mState.activeQuery[i].get() != NULL)
{
return error(GL_INVALID_OPERATION);
}
}
QueryType qType;
switch(target)
{
case GL_ANY_SAMPLES_PASSED_EXT:
qType = QUERY_ANY_SAMPLES_PASSED;
break;
case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
break;
default:
ASSERT(false);
}
Query *queryObject = getQuery(query, true, target);
// Check that name was obtained with glGenQueries
if(!queryObject)
{
return error(GL_INVALID_OPERATION);
}
// Check for type mismatch
if(queryObject->getType() != target)
{
return error(GL_INVALID_OPERATION);
}
// Set query as active for specified target
mState.activeQuery[qType].set(queryObject);
// Begin query
queryObject->begin();
}
void Context::endQuery(GLenum target)
{
QueryType qType;
switch(target)
{
case GL_ANY_SAMPLES_PASSED_EXT:
qType = QUERY_ANY_SAMPLES_PASSED;
break;
case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
break;
default:
ASSERT(false);
}
Query *queryObject = mState.activeQuery[qType].get();
if(queryObject == NULL)
{
return error(GL_INVALID_OPERATION);
}
queryObject->end();
mState.activeQuery[qType].set(NULL);
}
void Context::setFramebufferZero(Framebuffer *buffer)
{
delete mFramebufferMap[0];
mFramebufferMap[0] = buffer;
}
void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
{
Renderbuffer *renderbufferObject = mState.renderbuffer.get();
renderbufferObject->setStorage(renderbuffer);
}
Framebuffer *Context::getFramebuffer(unsigned int handle)
{
FramebufferMap::iterator framebuffer = mFramebufferMap.find(handle);
if(framebuffer == mFramebufferMap.end())
{
return NULL;
}
else
{
return framebuffer->second;
}
}
Fence *Context::getFence(unsigned int handle)
{
FenceMap::iterator fence = mFenceMap.find(handle);
if(fence == mFenceMap.end())
{
return NULL;
}
else
{
return fence->second;
}
}
Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
{
QueryMap::iterator query = mQueryMap.find(handle);
if(query == mQueryMap.end())
{
return NULL;
}
else
{
if(!query->second && create)
{
query->second = new Query(handle, type);
query->second->addRef();
}
return query->second;
}
}
Program *Context::getCurrentProgram()
{
return mState.program;
//return mResourceManager->getProgram(mState.currentProgram);
}
Texture2D *Context::getTexture2D()
{
return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
}
TextureCubeMap *Context::getTextureCubeMap()
{
return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
}
TextureExternal *Context::getTextureExternal()
{
return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL));
}
Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)
{
GLuint texid = mState.samplerTexture[type][sampler].id();
if(texid == 0) // Special case: 0 refers to different initial textures based on the target
{
switch (type)
{
case TEXTURE_2D: return mTexture2DZero.get();
case TEXTURE_CUBE: return mTextureCubeMapZero.get();
case TEXTURE_EXTERNAL: return mTextureExternalZero.get();
default: UNREACHABLE();
}
}
return mState.samplerTexture[type][sampler].get();
}
// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
bool Context::applyRenderTarget()
{
Framebuffer *framebuffer = getDrawFramebuffer();
int width, height, samples;
if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE)
{
return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
}
egl::Image *renderTarget = mState.colorBuffer;//framebuffer->getRenderTarget();
device->setRenderTarget(renderTarget);
//if(renderTarget) renderTarget->release();
egl::Image *depthStencil = mState.depthBuffer;//framebuffer->getDepthStencil();
device->setDepthStencilSurface(depthStencil);
//if(depthStencil) depthStencil->release();
Viewport viewport;
float zNear = clamp01(mState.zNear);
float zFar = clamp01(mState.zFar);
viewport.x0 = mState.viewportX;
viewport.y0 = mState.viewportY;
viewport.width = mState.viewportWidth;
viewport.height = mState.viewportHeight;
viewport.minZ = zNear;
viewport.maxZ = zFar;
device->setViewport(viewport);
if(mState.scissorTest)
{
sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight};
scissor.clip(0, 0, width, height);
device->setScissorRect(scissor);
device->setScissorEnable(true);
}
else
{
device->setScissorEnable(false);
}
Program *program = getCurrentProgram();
if(program)
{
GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};
program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]);
program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]);
program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]);
}
return true;
}
// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
void Context::applyState(GLenum drawMode)
{
Framebuffer *framebuffer = getDrawFramebuffer();
if(mState.cullFace)
{
device->setCullMode(rad2sw::ConvertCullMode(mState.cullMode, mState.frontFace));
}
else
{
device->setCullMode(sw::CULL_NONE);
}
if(mDepthStateDirty)
{
if(mState.depthTest)
{
device->setDepthBufferEnable(true);
device->setDepthCompare(rad2sw::ConvertDepthComparison(mState.depthFunc));
}
else
{
device->setDepthBufferEnable(false);
}
mDepthStateDirty = false;
}
if(mBlendStateDirty)
{
if(mState.blend)
{
device->setAlphaBlendEnable(true);
device->setSeparateAlphaBlendEnable(true);
device->setBlendConstant(rad2sw::ConvertColor(mState.blendColor));
device->setSourceBlendFactor(rad2sw::ConvertBlendFunc(mState.sourceBlendRGB));
device->setDestBlendFactor(rad2sw::ConvertBlendFunc(mState.destBlendRGB));
device->setBlendOperation(rad2sw::ConvertBlendOp(mState.blendEquationRGB));
device->setSourceBlendFactorAlpha(rad2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
device->setDestBlendFactorAlpha(rad2sw::ConvertBlendFunc(mState.destBlendAlpha));
device->setBlendOperationAlpha(rad2sw::ConvertBlendOp(mState.blendEquationAlpha));
}
else
{
device->setAlphaBlendEnable(false);
}
mBlendStateDirty = false;
}
if(mStencilStateDirty || mFrontFaceDirty)
{
if(mState.stencilTest && framebuffer->hasStencil())
{
device->setStencilEnable(true);
device->setTwoSidedStencil(true);
if(mState.stencilWritemask != mState.stencilBackWritemask ||
mState.stencilRef != mState.stencilBackRef ||
mState.stencilMask != mState.stencilBackMask)
{
ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL.");
return error(GL_INVALID_OPERATION);
}
// get the maximum size of the stencil ref
Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
if(mState.frontFace == GL_CCW)
{
device->setStencilWriteMask(mState.stencilWritemask);
device->setStencilCompare(rad2sw::ConvertStencilComparison(mState.stencilFunc));
device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
device->setStencilMask(mState.stencilMask);
device->setStencilFailOperation(rad2sw::ConvertStencilOp(mState.stencilFail));
device->setStencilZFailOperation(rad2sw::ConvertStencilOp(mState.stencilPassDepthFail));
device->setStencilPassOperation(rad2sw::ConvertStencilOp(mState.stencilPassDepthPass));
device->setStencilWriteMaskCCW(mState.stencilBackWritemask);
device->setStencilCompareCCW(rad2sw::ConvertStencilComparison(mState.stencilBackFunc));
device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
device->setStencilMaskCCW(mState.stencilBackMask);
device->setStencilFailOperationCCW(rad2sw::ConvertStencilOp(mState.stencilBackFail));
device->setStencilZFailOperationCCW(rad2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
device->setStencilPassOperationCCW(rad2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
}
else
{
device->setStencilWriteMaskCCW(mState.stencilWritemask);
device->setStencilCompareCCW(rad2sw::ConvertStencilComparison(mState.stencilFunc));
device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
device->setStencilMaskCCW(mState.stencilMask);
device->setStencilFailOperationCCW(rad2sw::ConvertStencilOp(mState.stencilFail));
device->setStencilZFailOperationCCW(rad2sw::ConvertStencilOp(mState.stencilPassDepthFail));
device->setStencilPassOperationCCW(rad2sw::ConvertStencilOp(mState.stencilPassDepthPass));
device->setStencilWriteMask(mState.stencilBackWritemask);
device->setStencilCompare(rad2sw::ConvertStencilComparison(mState.stencilBackFunc));
device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
device->setStencilMask(mState.stencilBackMask);
device->setStencilFailOperation(rad2sw::ConvertStencilOp(mState.stencilBackFail));
device->setStencilZFailOperation(rad2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
device->setStencilPassOperation(rad2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
}
}
else
{
device->setStencilEnable(false);
}
mStencilStateDirty = false;
mFrontFaceDirty = false;
}
if(mMaskStateDirty)
{
device->setColorWriteMask(0, rad2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
device->setDepthWriteEnable(mState.depthMask);
mMaskStateDirty = false;
}
if(mPolygonOffsetStateDirty)
{ {
if(mState.polygonOffsetFill) if(mState.polygonOffsetFill)
{ {
Renderbuffer *depthbuffer = framebuffer->getDepthbuffer(); egl::Image *depthbuffer = mState.depthBuffer;
if(depthbuffer) if(depthbuffer)
{ {
device->setSlopeDepthBias(mState.polygonOffsetFactor); device->setSlopeDepthBias(mState.polygonOffsetFactor);
float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize())); float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(sw2rad::GetDepthSize(depthbuffer->getInternalFormat())));
device->setDepthBias(depthBias); device->setDepthBias(depthBias);
} }
} }
...@@ -1369,8 +847,9 @@ void Context::applyState(GLenum drawMode) ...@@ -1369,8 +847,9 @@ void Context::applyState(GLenum drawMode)
unsigned int mask = 0; unsigned int mask = 0;
if(mState.sampleCoverageValue != 0) if(mState.sampleCoverageValue != 0)
{ {
int width, height, samples; int width = mState.colorBuffer->getWidth();
framebuffer->completeness(width, height, samples); int height = mState.colorBuffer->getHeight();
int samples = mState.colorBuffer->getMultiSampleDepth();
float threshold = 0.5f; float threshold = 0.5f;
...@@ -1419,7 +898,7 @@ GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count) ...@@ -1419,7 +898,7 @@ GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count)
return err; return err;
} }
Program *program = getCurrentProgram(); Program *program = mState.program;
device->resetInputStreams(false); device->resetInputStreams(false);
...@@ -1466,7 +945,7 @@ GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode ...@@ -1466,7 +945,7 @@ GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode
// Applies the shaders and shader constants // Applies the shaders and shader constants
void Context::applyShaders() void Context::applyShaders()
{ {
Program *programObject = getCurrentProgram(); Program *programObject = mState.program;
sw::VertexShader *vertexShader = programObject->getVertexShader(); sw::VertexShader *vertexShader = programObject->getVertexShader();
sw::PixelShader *pixelShader = programObject->getPixelShader(); sw::PixelShader *pixelShader = programObject->getPixelShader();
...@@ -1482,66 +961,9 @@ void Context::applyShaders() ...@@ -1482,66 +961,9 @@ void Context::applyShaders()
programObject->applyUniforms(); programObject->applyUniforms();
} }
void Context::applyTextures()
{
applyTextures(sw::SAMPLER_PIXEL);
applyTextures(sw::SAMPLER_VERTEX);
}
void Context::applyTextures(sw::SamplerType samplerType)
{
Program *programObject = getCurrentProgram();
int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS; // Range of samplers of given sampler type
for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++)
{
int textureUnit = programObject->getSamplerMapping(samplerType, samplerIndex); // OpenGL texture image unit index
if(textureUnit != -1)
{
TextureType textureType = programObject->getSamplerTextureType(samplerType, samplerIndex);
Texture *texture = getSamplerTexture(textureUnit, textureType);
if(texture->isSamplerComplete())
{
GLenum wrapS = texture->getWrapS();
GLenum wrapT = texture->getWrapT();
GLenum texFilter = texture->getMinFilter();
GLenum magFilter = texture->getMagFilter();
GLfloat maxAnisotropy = texture->getMaxAnisotropy();
device->setAddressingModeU(samplerType, samplerIndex, rad2sw::ConvertTextureWrap(wrapS));
device->setAddressingModeV(samplerType, samplerIndex, rad2sw::ConvertTextureWrap(wrapT));
sw::FilterType minFilter;
sw::MipmapType mipFilter;
rad2sw::ConvertMinFilter(texFilter, &minFilter, &mipFilter, maxAnisotropy);
// ASSERT(minFilter == rad2sw::ConvertMagFilter(magFilter));
device->setTextureFilter(samplerType, samplerIndex, minFilter);
// device->setTextureFilter(samplerType, samplerIndex, rad2sw::ConvertMagFilter(magFilter));
device->setMipmapFilter(samplerType, samplerIndex, mipFilter);
device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy);
applyTexture(samplerType, samplerIndex, texture);
}
else
{
applyTexture(samplerType, samplerIndex, 0);
}
}
else
{
applyTexture(samplerType, samplerIndex, NULL);
}
}
}
void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture) void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture)
{ {
//Program *program = getCurrentProgram(); //Program *program = mState.program;
int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index; int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index;
bool textureUsed = true; bool textureUsed = true;
...@@ -1612,298 +1034,37 @@ void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture ...@@ -1612,298 +1034,37 @@ void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture
{ {
for(int face = 0; face < 6; face++) for(int face = 0; face < 6; face++)
{ {
TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture); TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture);
for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++)
{
int surfaceLevel = mipmapLevel;
if(surfaceLevel < 0)
{
surfaceLevel = 0;
}
else if(surfaceLevel >= levelCount)
{
surfaceLevel = levelCount - 1;
}
egl::Image *surface = cubeTexture->getImage(face, surfaceLevel);
device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
}
}
}
else UNIMPLEMENTED();
}
else
{
device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);
}
}
void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
{
Framebuffer *framebuffer = getReadFramebuffer();
int framebufferWidth, framebufferHeight, framebufferSamples;
if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE)
{
return error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
if(getReadFramebufferHandle() != 0 && framebufferSamples != 0)
{
return error(GL_INVALID_OPERATION);
}
GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment);
// Sized query sanity check
if(bufSize)
{
int requiredSize = outputPitch * height;
if(requiredSize > *bufSize)
{
return error(GL_INVALID_OPERATION);
}
}
egl::Image *renderTarget = framebuffer->getRenderTarget();
if(!renderTarget)
{
return error(GL_OUT_OF_MEMORY);
}
sw::Rect rect = {x, y, x + width, y + height};
rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY);
unsigned char *dest = (unsigned char*)pixels;
unsigned short *dest16 = (unsigned short*)pixels;
int inputPitch = (int)renderTarget->getPitch();
for(int j = 0; j < rect.y1 - rect.y0; j++)
{
if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
{
// Fast path for EXT_read_format_bgra, given an RGBA source buffer
// Note that buffers with no alpha go through the slow path below
memcpy(dest + j * outputPitch, source + j * inputPitch, (rect.x1 - rect.x0) * 4);
}
else
{
for(int i = 0; i < rect.x1 - rect.x0; i++)
{
float r;
float g;
float b;
float a;
switch(renderTarget->getInternalFormat())
{
case sw::FORMAT_R5G6B5:
{
unsigned short rgb = *(unsigned short*)(source + 2 * i + j * inputPitch);
a = 1.0f;
b = (rgb & 0x001F) * (1.0f / 0x001F);
g = (rgb & 0x07E0) * (1.0f / 0x07E0);
r = (rgb & 0xF800) * (1.0f / 0xF800);
}
break;
case sw::FORMAT_A1R5G5B5:
{
unsigned short argb = *(unsigned short*)(source + 2 * i + j * inputPitch);
a = (argb & 0x8000) ? 1.0f : 0.0f;
b = (argb & 0x001F) * (1.0f / 0x001F);
g = (argb & 0x03E0) * (1.0f / 0x03E0);
r = (argb & 0x7C00) * (1.0f / 0x7C00);
}
break;
case sw::FORMAT_A8R8G8B8:
{
unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
a = (argb & 0xFF000000) * (1.0f / 0xFF000000);
b = (argb & 0x000000FF) * (1.0f / 0x000000FF);
g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);
r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);
}
break;
case sw::FORMAT_X8R8G8B8:
{
unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * inputPitch);
a = 1.0f;
b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);
g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);
r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);
}
break;
case sw::FORMAT_A2R10G10B10:
{
unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
a = (argb & 0xC0000000) * (1.0f / 0xC0000000);
b = (argb & 0x000003FF) * (1.0f / 0x000003FF);
g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);
r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);
}
break;
case sw::FORMAT_A32B32G32R32F:
{
r = *((float*)(source + 16 * i + j * inputPitch) + 0);
g = *((float*)(source + 16 * i + j * inputPitch) + 1);
b = *((float*)(source + 16 * i + j * inputPitch) + 2);
a = *((float*)(source + 16 * i + j * inputPitch) + 3);
}
break;
case sw::FORMAT_A16B16G16R16F:
{
r = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 0);
g = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 1);
b = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 2);
a = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 3);
}
break;
default:
UNIMPLEMENTED(); // FIXME
UNREACHABLE();
}
switch(format)
{
case GL_RGBA:
switch(type)
{
case GL_UNSIGNED_BYTE:
dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f);
dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f);
dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
break;
default: UNREACHABLE();
}
break;
case GL_BGRA_EXT:
switch(type)
{
case GL_UNSIGNED_BYTE:
dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * b + 0.5f);
dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * r + 0.5f);
dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
break;
case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
// this type is packed as follows:
// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
// --------------------------------------------------------------------------------
// | 4th | 3rd | 2nd | 1st component |
// --------------------------------------------------------------------------------
// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
dest16[i + j * outputPitch / sizeof(unsigned short)] =
((unsigned short)(15 * a + 0.5f) << 12)|
((unsigned short)(15 * r + 0.5f) << 8) |
((unsigned short)(15 * g + 0.5f) << 4) |
((unsigned short)(15 * b + 0.5f) << 0);
break;
case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
// this type is packed as follows:
// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
// --------------------------------------------------------------------------------
// | 4th | 3rd | 2nd | 1st component |
// --------------------------------------------------------------------------------
// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
dest16[i + j * outputPitch / sizeof(unsigned short)] =
((unsigned short)( a + 0.5f) << 15) |
((unsigned short)(31 * r + 0.5f) << 10) |
((unsigned short)(31 * g + 0.5f) << 5) |
((unsigned short)(31 * b + 0.5f) << 0);
break;
default: UNREACHABLE();
}
break;
case GL_RGB: // IMPLEMENTATION_COLOR_READ_FORMAT
switch(type)
{
case GL_UNSIGNED_SHORT_5_6_5: // IMPLEMENTATION_COLOR_READ_TYPE
dest16[i + j * outputPitch / sizeof(unsigned short)] =
((unsigned short)(31 * b + 0.5f) << 0) |
((unsigned short)(63 * g + 0.5f) << 5) |
((unsigned short)(31 * r + 0.5f) << 11);
break;
default: UNREACHABLE();
}
break;
default: UNREACHABLE();
}
}
}
}
renderTarget->unlock();
renderTarget->release();
}
void Context::clear(GLbitfield mask)
{
Framebuffer *framebuffer = getDrawFramebuffer();
if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
return error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
if(!applyRenderTarget())
{
return;
}
unsigned int color = (unorm<8>(mState.colorClearValue.alpha) << 24) |
(unorm<8>(mState.colorClearValue.red) << 16) |
(unorm<8>(mState.colorClearValue.green) << 8) |
(unorm<8>(mState.colorClearValue.blue) << 0);
float depth = clamp01(mState.depthClearValue);
int stencil = mState.stencilClearValue & 0x000000FF;
if(mask & GL_COLOR_BUFFER_BIT) for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++)
{ {
unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) | int surfaceLevel = mipmapLevel;
(mState.colorMaskGreen ? 0x2 : 0) |
(mState.colorMaskBlue ? 0x4 : 0) |
(mState.colorMaskAlpha ? 0x8 : 0);
if(rgbaMask != 0) if(surfaceLevel < 0)
{ {
device->clearColor(color, rgbaMask); surfaceLevel = 0;
} }
else if(surfaceLevel >= levelCount)
{
surfaceLevel = levelCount - 1;
} }
if(mask & GL_DEPTH_BUFFER_BIT) egl::Image *surface = cubeTexture->getImage(face, surfaceLevel);
{ device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
if(mState.depthMask != 0)
{
device->clearDepth(depth);
} }
} }
if(mask & GL_STENCIL_BUFFER_BIT)
{
if(mState.stencilWritemask != 0)
{
device->clearStencil(stencil, mState.stencilWritemask);
} }
else UNIMPLEMENTED();
}
else
{
device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);
} }
} }
void Context::drawArrays(GLenum mode, GLint first, GLsizei count) void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
{ {
if(!mState.currentProgram) if(!mState.program)
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -1933,9 +1094,8 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count) ...@@ -1933,9 +1094,8 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
} }
applyShaders(); applyShaders();
applyTextures();
if(!getCurrentProgram()->validateSamplers(false)) if(!mState.program->validateSamplers(false))
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -1948,7 +1108,7 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count) ...@@ -1948,7 +1108,7 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
{ {
if(!mState.currentProgram && !mState.program) if(!mState.program)
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -1993,7 +1153,7 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void * ...@@ -1993,7 +1153,7 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *
applyShaders(); applyShaders();
//applyTextures(); //applyTextures();
if(!getCurrentProgram()->validateSamplers(false)) if(!mState.program->validateSamplers(false))
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -2096,89 +1256,6 @@ int Context::getSupportedMultiSampleDepth(sw::Format format, int requested) ...@@ -2096,89 +1256,6 @@ int Context::getSupportedMultiSampleDepth(sw::Format format, int requested)
return 4; return 4;
} }
void Context::detachTexture(GLuint texture)
{
// [OpenGL ES 2.0.24] section 3.8 page 84:
// If a texture object is deleted, it is as if all texture units which are bound to that texture object are
// rebound to texture object zero
for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
{
for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
{
if(mState.samplerTexture[type][sampler].id() == texture)
{
mState.samplerTexture[type][sampler].set(NULL);
}
}
}
// [OpenGL ES 2.0.24] section 4.4 page 112:
// If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
// as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
// image was attached in the currently bound framebuffer.
Framebuffer *readFramebuffer = getReadFramebuffer();
Framebuffer *drawFramebuffer = getDrawFramebuffer();
if(readFramebuffer)
{
readFramebuffer->detachTexture(texture);
}
if(drawFramebuffer && drawFramebuffer != readFramebuffer)
{
drawFramebuffer->detachTexture(texture);
}
}
void Context::detachFramebuffer(GLuint framebuffer)
{
// [OpenGL ES 2.0.24] section 4.4 page 107:
// If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
// BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
if(mState.readFramebuffer == framebuffer)
{
bindReadFramebuffer(0);
}
if(mState.drawFramebuffer == framebuffer)
{
bindDrawFramebuffer(0);
}
}
void Context::detachRenderbuffer(GLuint renderbuffer)
{
// [OpenGL ES 2.0.24] section 4.4 page 109:
// If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
// had been executed with the target RENDERBUFFER and name of zero.
if(mState.renderbuffer.id() == renderbuffer)
{
bindRenderbuffer(0);
}
// [OpenGL ES 2.0.24] section 4.4 page 111:
// If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
// then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
// point to which this image was attached in the currently bound framebuffer.
Framebuffer *readFramebuffer = getReadFramebuffer();
Framebuffer *drawFramebuffer = getDrawFramebuffer();
if(readFramebuffer)
{
readFramebuffer->detachRenderbuffer(renderbuffer);
}
if(drawFramebuffer && drawFramebuffer != readFramebuffer)
{
drawFramebuffer->detachRenderbuffer(renderbuffer);
}
}
bool Context::cullSkipsDraw(GLenum drawMode) bool Context::cullSkipsDraw(GLenum drawMode)
{ {
return mState.cullFace && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode); return mState.cullFace && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
...@@ -2203,396 +1280,8 @@ bool Context::isTriangleMode(GLenum drawMode) ...@@ -2203,396 +1280,8 @@ bool Context::isTriangleMode(GLenum drawMode)
return false; return false;
} }
void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask)
{
Framebuffer *readFramebuffer = getReadFramebuffer();
Framebuffer *drawFramebuffer = getDrawFramebuffer();
int readBufferWidth, readBufferHeight, readBufferSamples;
int drawBufferWidth, drawBufferHeight, drawBufferSamples;
if(!readFramebuffer || readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE ||
!drawFramebuffer || drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE)
{
return error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
if(drawBufferSamples > 1)
{
return error(GL_INVALID_OPERATION);
}
sw::Rect sourceRect;
sw::Rect destRect;
if(srcX0 < srcX1)
{
sourceRect.x0 = srcX0;
sourceRect.x1 = srcX1;
destRect.x0 = dstX0;
destRect.x1 = dstX1;
}
else
{
sourceRect.x0 = srcX1;
destRect.x0 = dstX1;
sourceRect.x1 = srcX0;
destRect.x1 = dstX0;
}
if(srcY0 < srcY1)
{
sourceRect.y0 = srcY0;
destRect.y0 = dstY0;
sourceRect.y1 = srcY1;
destRect.y1 = dstY1;
}
else
{
sourceRect.y0 = srcY1;
destRect.y0 = dstY1;
sourceRect.y1 = srcY0;
destRect.y1 = dstY0;
}
sw::Rect sourceScissoredRect = sourceRect;
sw::Rect destScissoredRect = destRect;
if(mState.scissorTest) // Only write to parts of the destination framebuffer which pass the scissor test
{
if(destRect.x0 < mState.scissorX)
{
int xDiff = mState.scissorX - destRect.x0;
destScissoredRect.x0 = mState.scissorX;
sourceScissoredRect.x0 += xDiff;
}
if(destRect.x1 > mState.scissorX + mState.scissorWidth)
{
int xDiff = destRect.x1 - (mState.scissorX + mState.scissorWidth);
destScissoredRect.x1 = mState.scissorX + mState.scissorWidth;
sourceScissoredRect.x1 -= xDiff;
}
if(destRect.y0 < mState.scissorY)
{
int yDiff = mState.scissorY - destRect.y0;
destScissoredRect.y0 = mState.scissorY;
sourceScissoredRect.y0 += yDiff;
}
if(destRect.y1 > mState.scissorY + mState.scissorHeight)
{
int yDiff = destRect.y1 - (mState.scissorY + mState.scissorHeight);
destScissoredRect.y1 = mState.scissorY + mState.scissorHeight;
sourceScissoredRect.y1 -= yDiff;
}
}
sw::Rect sourceTrimmedRect = sourceScissoredRect;
sw::Rect destTrimmedRect = destScissoredRect;
// The source & destination rectangles also may need to be trimmed if they fall out of the bounds of
// the actual draw and read surfaces.
if(sourceTrimmedRect.x0 < 0)
{
int xDiff = 0 - sourceTrimmedRect.x0;
sourceTrimmedRect.x0 = 0;
destTrimmedRect.x0 += xDiff;
}
if(sourceTrimmedRect.x1 > readBufferWidth)
{
int xDiff = sourceTrimmedRect.x1 - readBufferWidth;
sourceTrimmedRect.x1 = readBufferWidth;
destTrimmedRect.x1 -= xDiff;
}
if(sourceTrimmedRect.y0 < 0)
{
int yDiff = 0 - sourceTrimmedRect.y0;
sourceTrimmedRect.y0 = 0;
destTrimmedRect.y0 += yDiff;
}
if(sourceTrimmedRect.y1 > readBufferHeight)
{
int yDiff = sourceTrimmedRect.y1 - readBufferHeight;
sourceTrimmedRect.y1 = readBufferHeight;
destTrimmedRect.y1 -= yDiff;
}
if(destTrimmedRect.x0 < 0)
{
int xDiff = 0 - destTrimmedRect.x0;
destTrimmedRect.x0 = 0;
sourceTrimmedRect.x0 += xDiff;
}
if(destTrimmedRect.x1 > drawBufferWidth)
{
int xDiff = destTrimmedRect.x1 - drawBufferWidth;
destTrimmedRect.x1 = drawBufferWidth;
sourceTrimmedRect.x1 -= xDiff;
}
if(destTrimmedRect.y0 < 0)
{
int yDiff = 0 - destTrimmedRect.y0;
destTrimmedRect.y0 = 0;
sourceTrimmedRect.y0 += yDiff;
}
if(destTrimmedRect.y1 > drawBufferHeight)
{
int yDiff = destTrimmedRect.y1 - drawBufferHeight;
destTrimmedRect.y1 = drawBufferHeight;
sourceTrimmedRect.y1 -= yDiff;
}
bool partialBufferCopy = false;
if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight ||
sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth ||
destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight ||
destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth ||
sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0)
{
partialBufferCopy = true;
}
bool blitRenderTarget = false;
bool blitDepthStencil = false;
if(mask & GL_COLOR_BUFFER_BIT)
{
const bool validReadType = readFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
readFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
const bool validDrawType = drawFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
drawFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
if(!validReadType || !validDrawType ||
readFramebuffer->getColorbuffer()->getInternalFormat() != drawFramebuffer->getColorbuffer()->getInternalFormat())
{
ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation");
return error(GL_INVALID_OPERATION);
}
if(partialBufferCopy && readBufferSamples > 1)
{
return error(GL_INVALID_OPERATION);
}
blitRenderTarget = true;
}
if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
{
Renderbuffer *readDSBuffer = NULL;
Renderbuffer *drawDSBuffer = NULL;
// We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have
// both a depth and stencil buffer, it will be the same buffer.
if(mask & GL_DEPTH_BUFFER_BIT)
{
if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
{
if(readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() ||
readFramebuffer->getDepthbuffer()->getInternalFormat() != drawFramebuffer->getDepthbuffer()->getInternalFormat())
{
return error(GL_INVALID_OPERATION);
}
blitDepthStencil = true;
readDSBuffer = readFramebuffer->getDepthbuffer();
drawDSBuffer = drawFramebuffer->getDepthbuffer();
}
}
if(mask & GL_STENCIL_BUFFER_BIT)
{
if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
{
if(readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() ||
readFramebuffer->getStencilbuffer()->getInternalFormat() != drawFramebuffer->getStencilbuffer()->getInternalFormat())
{
return error(GL_INVALID_OPERATION);
}
blitDepthStencil = true;
readDSBuffer = readFramebuffer->getStencilbuffer();
drawDSBuffer = drawFramebuffer->getStencilbuffer();
}
}
if(partialBufferCopy)
{
ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
return error(GL_INVALID_OPERATION); // Only whole-buffer copies are permitted
}
if((drawDSBuffer && drawDSBuffer->getSamples() > 1) ||
(readDSBuffer && readDSBuffer->getSamples() > 1))
{
return error(GL_INVALID_OPERATION);
}
}
if(blitRenderTarget || blitDepthStencil)
{
if(blitRenderTarget)
{
egl::Image *readRenderTarget = readFramebuffer->getRenderTarget();
egl::Image *drawRenderTarget = drawFramebuffer->getRenderTarget();
bool success = device->stretchRect(readRenderTarget, &sourceRect, drawRenderTarget, &destRect, false);
readRenderTarget->release();
drawRenderTarget->release();
if(!success)
{
ERR("BlitFramebufferANGLE failed.");
return;
}
}
if(blitDepthStencil)
{
bool success = device->stretchRect(readFramebuffer->getDepthStencil(), NULL, drawFramebuffer->getDepthStencil(), NULL, false);
if(!success)
{
ERR("BlitFramebufferANGLE failed.");
return;
}
}
}
}
void Context::bindTexImage(egl::Surface *surface)
{
es2::Texture2D *textureObject = getTexture2D();
if(textureObject)
{
textureObject->bindTexImage(surface);
}
}
EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
{
GLenum textureTarget = GL_NONE;
switch(target)
{
case EGL_GL_TEXTURE_2D_KHR:
textureTarget = GL_TEXTURE_2D;
break;
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
textureTarget = GL_TEXTURE_CUBE_MAP;
break;
case EGL_GL_RENDERBUFFER_KHR:
break;
default:
return EGL_BAD_PARAMETER;
}
if(textureLevel >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
{
return EGL_BAD_MATCH;
}
if(textureTarget != GL_NONE)
{
es2::Texture *texture = getTexture(name);
if(!texture || texture->getTarget() != textureTarget)
{
return EGL_BAD_PARAMETER;
}
if(texture->isShared(textureTarget, textureLevel)) // Bound to an EGLSurface or already an EGLImage sibling
{
return EGL_BAD_ACCESS;
}
if(textureLevel != 0 && !texture->isSamplerComplete())
{
return EGL_BAD_PARAMETER;
}
if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1))
{
return EGL_BAD_PARAMETER;
}
}
else if(target == EGL_GL_RENDERBUFFER_KHR)
{
es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
if(!renderbuffer)
{
return EGL_BAD_PARAMETER;
}
if(renderbuffer->isShared()) // Already an EGLImage sibling
{
return EGL_BAD_ACCESS;
}
}
else UNREACHABLE();
return EGL_SUCCESS;
}
egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
{
GLenum textureTarget = GL_NONE;
switch(target)
{
case EGL_GL_TEXTURE_2D_KHR: textureTarget = GL_TEXTURE_2D; break;
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break;
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break;
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break;
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break;
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break;
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break;
}
if(textureTarget != GL_NONE)
{
es2::Texture *texture = getTexture(name);
return texture->createSharedImage(textureTarget, textureLevel);
}
else if(target == EGL_GL_RENDERBUFFER_KHR)
{
es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
return renderbuffer->createSharedImage();
}
else UNREACHABLE();
return 0;
}
Device *Context::getDevice() Device *Context::getDevice()
{ {
if(!device)
{
sw::Context *context = new sw::Context();
device = new es2::Device(context);
}
return device; return device;
} }
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#define LIBGLESV2_CONTEXT_H_ #define LIBGLESV2_CONTEXT_H_
#include "libEGL/Context.hpp" #include "libEGL/Context.hpp"
#include "ResourceManager.h"
#include "HandleAllocator.h" #include "HandleAllocator.h"
#include "RefCountObject.h" #include "RefCountObject.h"
#include "Image.hpp" #include "Image.hpp"
...@@ -216,14 +215,13 @@ struct State ...@@ -216,14 +215,13 @@ struct State
GLuint readFramebuffer; GLuint readFramebuffer;
GLuint drawFramebuffer; GLuint drawFramebuffer;
BindingPointer<Renderbuffer> renderbuffer; BindingPointer<Renderbuffer> renderbuffer;
GLuint currentProgram;
Program *program; Program *program;
egl::Image *colorBuffer; egl::Image *colorBuffer;
egl::Image *depthBuffer; egl::Image *depthBuffer;
egl::Image *stencilBuffer;
VertexAttribute vertexAttribute[MAX_VERTEX_ATTRIBS]; VertexAttribute vertexAttribute[MAX_VERTEX_ATTRIBS];
BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][MAX_COMBINED_TEXTURE_IMAGE_UNITS];
BindingPointer<Query> activeQuery[QUERY_TYPE_COUNT]; BindingPointer<Query> activeQuery[QUERY_TYPE_COUNT];
GLint unpackAlignment; GLint unpackAlignment;
...@@ -300,10 +298,6 @@ public: ...@@ -300,10 +298,6 @@ public:
void setActiveSampler(unsigned int active); void setActiveSampler(unsigned int active);
GLuint getReadFramebufferHandle() const;
GLuint getDrawFramebufferHandle() const;
GLuint getRenderbufferHandle() const;
GLuint getActiveQuery(GLenum target) const; GLuint getActiveQuery(GLenum target) const;
void setEnableVertexAttribArray(unsigned int attribNum, bool enabled); void setEnableVertexAttribArray(unsigned int attribNum, bool enabled);
...@@ -319,63 +313,8 @@ public: ...@@ -319,63 +313,8 @@ public:
void setPackAlignment(GLint alignment); void setPackAlignment(GLint alignment);
GLint getPackAlignment() const; GLint getPackAlignment() const;
// These create and destroy methods are merely pass-throughs to
// ResourceManager, which owns these object types
GLuint createShader(GLenum type);
GLuint createProgram();
GLuint createTexture();
GLuint createRenderbuffer();
void deleteShader(GLuint shader);
void deleteProgram(GLuint program);
void deleteTexture(GLuint texture);
void deleteRenderbuffer(GLuint renderbuffer);
// Framebuffers are owned by the Context, so these methods do not pass through
GLuint createFramebuffer();
void deleteFramebuffer(GLuint framebuffer);
// Fences are owned by the Context
GLuint createFence();
void deleteFence(GLuint fence);
// Queries are owned by the Context
GLuint createQuery();
void deleteQuery(GLuint query);
void bindTexture2D(GLuint texture);
void bindTextureCubeMap(GLuint texture);
void bindTextureExternal(GLuint texture);
void bindReadFramebuffer(GLuint framebuffer);
void bindDrawFramebuffer(GLuint framebuffer);
void bindRenderbuffer(GLuint renderbuffer);
void useProgram(GLuint program);
void beginQuery(GLenum target, GLuint query);
void endQuery(GLenum target);
void setFramebufferZero(Framebuffer *framebuffer);
void setRenderbufferStorage(RenderbufferStorage *renderbuffer); void setRenderbufferStorage(RenderbufferStorage *renderbuffer);
Fence *getFence(GLuint handle);
Shader *getShader(GLuint handle);
Program *getProgram(GLuint handle);
virtual Texture *getTexture(GLuint handle);
Framebuffer *getFramebuffer(GLuint handle);
virtual Renderbuffer *getRenderbuffer(GLuint handle);
Query *getQuery(GLuint handle, bool create, GLenum type);
Program *getCurrentProgram();
Texture2D *getTexture2D();
TextureCubeMap *getTextureCubeMap();
TextureExternal *getTextureExternal();
Texture *getSamplerTexture(unsigned int sampler, TextureType type);
Framebuffer *getReadFramebuffer();
Framebuffer *getDrawFramebuffer();
void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);
void clear(GLbitfield mask);
void drawArrays(GLenum mode, GLint first, GLsizei count); void drawArrays(GLenum mode, GLint first, GLsizei count);
void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices); void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
void finish(); void finish();
...@@ -391,14 +330,6 @@ public: ...@@ -391,14 +330,6 @@ public:
static int getSupportedMultiSampleDepth(sw::Format format, int requested); static int getSupportedMultiSampleDepth(sw::Format format, int requested);
void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask);
virtual void bindTexImage(egl::Surface *surface);
virtual EGLenum validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel);
virtual egl::Image *createSharedImage(EGLenum target, GLuint name, GLuint textureLevel);
Device *getDevice(); Device *getDevice();
public: public:
...@@ -409,14 +340,8 @@ public: ...@@ -409,14 +340,8 @@ public:
GLenum applyVertexBuffer(GLint base, GLint first, GLsizei count); GLenum applyVertexBuffer(GLint base, GLint first, GLsizei count);
GLenum applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); GLenum applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
void applyShaders(); void applyShaders();
void applyTextures();
void applyTextures(sw::SamplerType type);
void applyTexture(sw::SamplerType type, int sampler, Texture *texture); void applyTexture(sw::SamplerType type, int sampler, Texture *texture);
void detachTexture(GLuint texture);
void detachFramebuffer(GLuint framebuffer);
void detachRenderbuffer(GLuint renderbuffer);
bool cullSkipsDraw(GLenum drawMode); bool cullSkipsDraw(GLenum drawMode);
bool isTriangleMode(GLenum drawMode); bool isTriangleMode(GLenum drawMode);
...@@ -424,10 +349,6 @@ public: ...@@ -424,10 +349,6 @@ public:
State mState; State mState;
BindingPointer<Texture2D> mTexture2DZero;
BindingPointer<TextureCubeMap> mTextureCubeMapZero;
BindingPointer<TextureExternal> mTextureExternalZero;
typedef std::map<GLint, Framebuffer*> FramebufferMap; typedef std::map<GLint, Framebuffer*> FramebufferMap;
FramebufferMap mFramebufferMap; FramebufferMap mFramebufferMap;
HandleAllocator mFramebufferHandleAllocator; HandleAllocator mFramebufferHandleAllocator;
...@@ -465,9 +386,7 @@ public: ...@@ -465,9 +386,7 @@ public:
bool mFrontFaceDirty; bool mFrontFaceDirty;
bool mDitherStateDirty; bool mDitherStateDirty;
ResourceManager *mResourceManager; Device *device;
static Device *device;
}; };
} }
......
...@@ -47,11 +47,11 @@ Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const ...@@ -47,11 +47,11 @@ Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const
} }
else if(type == GL_RENDERBUFFER) else if(type == GL_RENDERBUFFER)
{ {
buffer = context->getRenderbuffer(handle); //buffer = context->getRenderbuffer(handle);
} }
else if(IsTextureTarget(type)) else if(IsTextureTarget(type))
{ {
buffer = context->getTexture(handle)->getRenderbuffer(type); //buffer = context->getTexture(handle)->getRenderbuffer(type);
} }
else else
{ {
......
...@@ -53,7 +53,7 @@ namespace es2 ...@@ -53,7 +53,7 @@ namespace es2
{ {
if(parentTexture) if(parentTexture)
{ {
parentTexture->addRef(); return parentTexture->addRef();
} }
sw::atomicIncrement(&referenceCount); sw::atomicIncrement(&referenceCount);
...@@ -63,7 +63,7 @@ namespace es2 ...@@ -63,7 +63,7 @@ namespace es2
{ {
if(parentTexture) if(parentTexture)
{ {
parentTexture->release(); return parentTexture->release();
} }
if(referenceCount > 0) if(referenceCount > 0)
......
...@@ -70,7 +70,7 @@ namespace es2 ...@@ -70,7 +70,7 @@ namespace es2
{ {
} }
Program::Program(ResourceManager *manager, GLuint handle) : resourceManager(manager), handle(handle), serial(issueSerial()) Program::Program(GLuint handle) : handle(handle), serial(issueSerial())
{ {
device = getDevice(); device = getDevice();
...@@ -1965,9 +1965,9 @@ namespace es2 ...@@ -1965,9 +1965,9 @@ namespace es2
{ {
referenceCount--; referenceCount--;
if(referenceCount == 0 && orphaned) if(referenceCount == 0)
{ {
resourceManager->deleteProgram(handle); delete this;
} }
} }
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
namespace es2 namespace es2
{ {
class Device; class Device;
class ResourceManager;
class FragmentShader; class FragmentShader;
class VertexShader; class VertexShader;
...@@ -64,10 +63,20 @@ namespace es2 ...@@ -64,10 +63,20 @@ namespace es2
unsigned int index; unsigned int index;
}; };
enum TextureType
{
TEXTURE_2D,
TEXTURE_CUBE,
TEXTURE_EXTERNAL,
TEXTURE_TYPE_COUNT,
TEXTURE_UNKNOWN
};
class Program class Program
{ {
public: public:
Program(ResourceManager *manager, GLuint handle); Program(GLuint handle);
~Program(); ~Program();
...@@ -199,7 +208,6 @@ namespace es2 ...@@ -199,7 +208,6 @@ namespace es2
static unsigned int currentSerial; static unsigned int currentSerial;
ResourceManager *resourceManager;
const GLuint handle; const GLuint handle;
}; };
} }
......
// SwiftShader Software Renderer
//
// Copyright(c) 2005-2012 TransGaming Inc.
//
// All rights reserved. No part of this software may be copied, distributed, transmitted,
// transcribed, stored in a retrieval system, translated into any human or computer
// language by any means, or disclosed to third parties without the explicit written
// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
// or implied, including but not limited to any patent rights, are granted to you.
//
// ResourceManager.cpp: Implements the ResourceManager class, which tracks and
// retrieves objects which may be shared by multiple Contexts.
#include "ResourceManager.h"
#include "Buffer.h"
#include "Program.h"
#include "Renderbuffer.h"
#include "Shader.h"
#include "Texture.h"
namespace es2
{
ResourceManager::ResourceManager()
{
mRefCount = 1;
}
ResourceManager::~ResourceManager()
{
while(!mProgramMap.empty())
{
deleteProgram(mProgramMap.begin()->first);
}
while(!mShaderMap.empty())
{
deleteShader(mShaderMap.begin()->first);
}
while(!mRenderbufferMap.empty())
{
deleteRenderbuffer(mRenderbufferMap.begin()->first);
}
while(!mTextureMap.empty())
{
deleteTexture(mTextureMap.begin()->first);
}
}
void ResourceManager::addRef()
{
mRefCount++;
}
void ResourceManager::release()
{
if(--mRefCount == 0)
{
delete this;
}
}
// Returns an unused shader/program name
GLuint ResourceManager::createShader(GLenum type)
{
GLuint handle = mProgramShaderHandleAllocator.allocate();
if(type == GL_VERTEX_SHADER)
{
mShaderMap[handle] = new VertexShader(this, handle);
}
else if(type == GL_FRAGMENT_SHADER)
{
mShaderMap[handle] = new FragmentShader(this, handle);
}
else UNREACHABLE();
return handle;
}
// Returns an unused program/shader name
GLuint ResourceManager::createProgram()
{
GLuint handle = mProgramShaderHandleAllocator.allocate();
mProgramMap[handle] = new Program(this, handle);
return handle;
}
// Returns an unused texture name
GLuint ResourceManager::createTexture()
{
GLuint handle = mTextureHandleAllocator.allocate();
mTextureMap[handle] = NULL;
return handle;
}
// Returns an unused renderbuffer name
GLuint ResourceManager::createRenderbuffer()
{
GLuint handle = mRenderbufferHandleAllocator.allocate();
mRenderbufferMap[handle] = NULL;
return handle;
}
void ResourceManager::deleteShader(GLuint shader)
{
ShaderMap::iterator shaderObject = mShaderMap.find(shader);
if(shaderObject != mShaderMap.end())
{
if(shaderObject->second->getRefCount() == 0)
{
mProgramShaderHandleAllocator.release(shaderObject->first);
delete shaderObject->second;
mShaderMap.erase(shaderObject);
}
else
{
shaderObject->second->flagForDeletion();
}
}
}
void ResourceManager::deleteProgram(GLuint program)
{
ProgramMap::iterator programObject = mProgramMap.find(program);
if(programObject != mProgramMap.end())
{
if(programObject->second->getRefCount() == 0)
{
mProgramShaderHandleAllocator.release(programObject->first);
delete programObject->second;
mProgramMap.erase(programObject);
}
else
{
programObject->second->flagForDeletion();
}
}
}
void ResourceManager::deleteTexture(GLuint texture)
{
TextureMap::iterator textureObject = mTextureMap.find(texture);
if(textureObject != mTextureMap.end())
{
mTextureHandleAllocator.release(textureObject->first);
if(textureObject->second) textureObject->second->release();
mTextureMap.erase(textureObject);
}
}
void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
{
RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
if(renderbufferObject != mRenderbufferMap.end())
{
mRenderbufferHandleAllocator.release(renderbufferObject->first);
if(renderbufferObject->second) renderbufferObject->second->release();
mRenderbufferMap.erase(renderbufferObject);
}
}
Shader *ResourceManager::getShader(unsigned int handle)
{
ShaderMap::iterator shader = mShaderMap.find(handle);
if(shader == mShaderMap.end())
{
return NULL;
}
else
{
return shader->second;
}
}
Texture *ResourceManager::getTexture(unsigned int handle)
{
if(handle == 0) return NULL;
TextureMap::iterator texture = mTextureMap.find(handle);
if(texture == mTextureMap.end())
{
return NULL;
}
else
{
return texture->second;
}
}
Program *ResourceManager::getProgram(unsigned int handle)
{
ProgramMap::iterator program = mProgramMap.find(handle);
if(program == mProgramMap.end())
{
return NULL;
}
else
{
return program->second;
}
}
Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
{
RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
if(renderbuffer == mRenderbufferMap.end())
{
return NULL;
}
else
{
if (!renderbuffer->second)
{
Renderbuffer *renderbufferObject = new Renderbuffer(handle, new Colorbuffer(0, 0, GL_RGBA4_OES, 0));
mRenderbufferMap[handle] = renderbufferObject;
renderbufferObject->addRef();
}
return renderbuffer->second;
}
}
void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
{
mRenderbufferMap[handle] = buffer;
}
void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
{
if(!getTexture(texture) && texture != 0)
{
Texture *textureObject;
if(type == TEXTURE_2D)
{
textureObject = new Texture2D(texture);
}
else if(type == TEXTURE_CUBE)
{
textureObject = new TextureCubeMap(texture);
}
else if(type == TEXTURE_EXTERNAL)
{
textureObject = new TextureExternal(texture);
}
else
{
UNREACHABLE();
return;
}
mTextureMap[texture] = textureObject;
textureObject->addRef();
}
}
}
// SwiftShader Software Renderer
//
// Copyright(c) 2005-2012 TransGaming Inc.
//
// All rights reserved. No part of this software may be copied, distributed, transmitted,
// transcribed, stored in a retrieval system, translated into any human or computer
// language by any means, or disclosed to third parties without the explicit written
// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
// or implied, including but not limited to any patent rights, are granted to you.
//
// ResourceManager.h : Defines the ResourceManager class, which tracks objects
// shared by multiple GL contexts.
#ifndef LIBGLESV2_RESOURCEMANAGER_H_
#define LIBGLESV2_RESOURCEMANAGER_H_
#include "HandleAllocator.h"
#define GL_APICALL
#include <GLES2/gl2.h>
#include <map>
namespace es2
{
class Shader;
class Program;
class Texture;
class Renderbuffer;
enum TextureType
{
TEXTURE_2D,
TEXTURE_CUBE,
TEXTURE_EXTERNAL,
TEXTURE_TYPE_COUNT,
TEXTURE_UNKNOWN
};
class ResourceManager
{
public:
ResourceManager();
~ResourceManager();
void addRef();
void release();
GLuint createBuffer();
GLuint createShader(GLenum type);
GLuint createProgram();
GLuint createTexture();
GLuint createRenderbuffer();
void deleteShader(GLuint shader);
void deleteProgram(GLuint program);
void deleteTexture(GLuint texture);
void deleteRenderbuffer(GLuint renderbuffer);
Shader *getShader(GLuint handle);
Program *getProgram(GLuint handle);
Texture *getTexture(GLuint handle);
Renderbuffer *getRenderbuffer(GLuint handle);
void setRenderbuffer(GLuint handle, Renderbuffer *renderbuffer);
void checkTextureAllocation(GLuint texture, TextureType type);
private:
std::size_t mRefCount;
typedef std::map<GLint, Shader*> ShaderMap;
ShaderMap mShaderMap;
typedef std::map<GLint, Program*> ProgramMap;
ProgramMap mProgramMap;
HandleAllocator mProgramShaderHandleAllocator;
typedef std::map<GLint, Texture*> TextureMap;
TextureMap mTextureMap;
HandleAllocator mTextureHandleAllocator;
typedef std::map<GLint, Renderbuffer*> RenderbufferMap;
RenderbufferMap mRenderbufferMap;
HandleAllocator mRenderbufferHandleAllocator;
};
}
#endif // LIBGLESV2_RESOURCEMANAGER_H_
...@@ -26,7 +26,7 @@ namespace es2 ...@@ -26,7 +26,7 @@ namespace es2
{ {
bool Shader::compilerInitialized = false; bool Shader::compilerInitialized = false;
Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mResourceManager(manager) Shader::Shader(GLuint handle) : mHandle(handle)
{ {
mSource = NULL; mSource = NULL;
mInfoLog = NULL; mInfoLog = NULL;
...@@ -216,9 +216,9 @@ void Shader::release() ...@@ -216,9 +216,9 @@ void Shader::release()
{ {
mRefCount--; mRefCount--;
if(mRefCount == 0 && mDeleteStatus) if(mRefCount == 0)
{ {
mResourceManager->deleteShader(mHandle); delete this;
} }
} }
...@@ -361,7 +361,7 @@ bool Shader::compareVarying(const Varying &x, const Varying &y) ...@@ -361,7 +361,7 @@ bool Shader::compareVarying(const Varying &x, const Varying &y)
return false; return false;
} }
VertexShader::VertexShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle) VertexShader::VertexShader(GLuint handle) : Shader(handle)
{ {
vertexShader = 0; vertexShader = 0;
} }
...@@ -447,7 +447,7 @@ sw::VertexShader *VertexShader::getVertexShader() const ...@@ -447,7 +447,7 @@ sw::VertexShader *VertexShader::getVertexShader() const
return vertexShader; return vertexShader;
} }
FragmentShader::FragmentShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle) FragmentShader::FragmentShader(GLuint handle) : Shader(handle)
{ {
pixelShader = 0; pixelShader = 0;
} }
......
...@@ -17,8 +17,6 @@ ...@@ -17,8 +17,6 @@
#ifndef LIBGLESV2_SHADER_H_ #ifndef LIBGLESV2_SHADER_H_
#define LIBGLESV2_SHADER_H_ #define LIBGLESV2_SHADER_H_
#include "ResourceManager.h"
#include "compiler/TranslatorASM.h" #include "compiler/TranslatorASM.h"
#define GL_APICALL #define GL_APICALL
...@@ -67,7 +65,7 @@ class Shader ...@@ -67,7 +65,7 @@ class Shader
friend class sh::OutputASM; friend class sh::OutputASM;
public: public:
Shader(ResourceManager *manager, GLuint handle); Shader(GLuint handle);
virtual ~Shader(); virtual ~Shader();
...@@ -115,8 +113,6 @@ private: ...@@ -115,8 +113,6 @@ private:
const GLuint mHandle; const GLuint mHandle;
unsigned int mRefCount; // Number of program objects this shader is attached to unsigned int mRefCount; // Number of program objects this shader is attached to
bool mDeleteStatus; // Flag to indicate that the shader can be deleted when no longer in use bool mDeleteStatus; // Flag to indicate that the shader can be deleted when no longer in use
ResourceManager *mResourceManager;
}; };
class VertexShader : public Shader class VertexShader : public Shader
...@@ -124,7 +120,7 @@ class VertexShader : public Shader ...@@ -124,7 +120,7 @@ class VertexShader : public Shader
friend class Program; friend class Program;
public: public:
VertexShader(ResourceManager *manager, GLuint handle); VertexShader(GLuint handle);
~VertexShader(); ~VertexShader();
...@@ -142,7 +138,7 @@ private: ...@@ -142,7 +138,7 @@ private:
class FragmentShader : public Shader class FragmentShader : public Shader
{ {
public: public:
FragmentShader(ResourceManager *manager, GLuint handle); FragmentShader(GLuint handle);
~FragmentShader(); ~FragmentShader();
......
...@@ -404,50 +404,6 @@ void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum form ...@@ -404,50 +404,6 @@ void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum form
Texture::setImage(format, type, unpackAlignment, pixels, image[level]); Texture::setImage(format, type, unpackAlignment, pixels, image[level]);
} }
void Texture2D::bindTexImage(egl::Surface *surface)
{
GLenum format;
switch(surface->getInternalFormat())
{
case sw::FORMAT_A8R8G8B8:
format = GL_RGBA;
break;
case sw::FORMAT_X8R8G8B8:
format = GL_RGB;
break;
default:
UNIMPLEMENTED();
return;
}
for(int level = 0; level < MIPMAP_LEVELS; level++)
{
if(image[level])
{
image[level]->unbind();
image[level] = 0;
}
}
image[0] = surface->getRenderTarget();
mSurface = surface;
mSurface->setBoundTexture(this);
}
void Texture2D::releaseTexImage()
{
for(int level = 0; level < MIPMAP_LEVELS; level++)
{
if(image[level])
{
image[level]->unbind();
image[level] = 0;
}
}
}
void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels) void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
{ {
if(image[level]) if(image[level])
......
...@@ -139,8 +139,6 @@ public: ...@@ -139,8 +139,6 @@ public:
virtual bool isSamplerComplete() const; virtual bool isSamplerComplete() const;
virtual bool isCompressed(GLenum target, GLint level) const; virtual bool isCompressed(GLenum target, GLint level) const;
virtual bool isDepth(GLenum target, GLint level) const; virtual bool isDepth(GLenum target, GLint level) const;
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
virtual void generateMipmaps(); virtual void generateMipmaps();
......
...@@ -33,7 +33,7 @@ VertexDataManager::~VertexDataManager() ...@@ -33,7 +33,7 @@ VertexDataManager::~VertexDataManager()
GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated) GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated)
{ {
const VertexAttributeArray &attribs = mContext->getVertexAttributes(); const VertexAttributeArray &attribs = mContext->getVertexAttributes();
Program *program = mContext->getCurrentProgram(); Program *program = mContext->mState.program;
// Perform the vertex data translations // Perform the vertex data translations
for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
......
...@@ -322,7 +322,8 @@ class Program : public Object ...@@ -322,7 +322,8 @@ class Program : public Object
public: public:
Program(Device *device) : Object(device) Program(Device *device) : Object(device)
{ {
program = new es2::Program(nullptr, 0); program = new es2::Program(0);
program->addRef();
} }
virtual ~Program() virtual ~Program()
...@@ -829,6 +830,7 @@ public: ...@@ -829,6 +830,7 @@ public:
} }
image->unlock(); image->unlock();
image->release();
} }
Buffer *buffer; Buffer *buffer;
...@@ -1391,8 +1393,10 @@ void RADAPIENTRY radProgramSource(RADprogram program, RADprogramFormat format, R ...@@ -1391,8 +1393,10 @@ void RADAPIENTRY radProgramSource(RADprogram program, RADprogramFormat format, R
GLint vertexLength = strlen(vertexSource); GLint vertexLength = strlen(vertexSource);
GLint fragmentLength = strlen(fragmentSource); GLint fragmentLength = strlen(fragmentSource);
es2::VertexShader *vertexShader = new es2::VertexShader(nullptr, 0); es2::VertexShader *vertexShader = new es2::VertexShader(0);
es2::FragmentShader *fragmentShader = new es2::FragmentShader(nullptr, 0); vertexShader->addRef();
es2::FragmentShader *fragmentShader = new es2::FragmentShader(0);
fragmentShader->addRef();
vertexShader->setSource(1, &vertexSource, &vertexLength); vertexShader->setSource(1, &vertexSource, &vertexLength);
fragmentShader->setSource(1, &fragmentSource, &fragmentLength); fragmentShader->setSource(1, &fragmentSource, &fragmentLength);
...@@ -1572,7 +1576,9 @@ RADrenderTargetHandle RADAPIENTRY radGetTextureRenderTargetHandle(RADtexture tex ...@@ -1572,7 +1576,9 @@ RADrenderTargetHandle RADAPIENTRY radGetTextureRenderTargetHandle(RADtexture tex
default: default:
UNREACHABLE(); UNREACHABLE();
} }
return reinterpret_cast<RADrenderTargetHandle>(radTexture->texture->getRenderTarget(glTarget, level)); egl::Image *image = radTexture->texture->getRenderTarget(glTarget, level);
image->release(); // FIXME: Handles are weak pointers
return reinterpret_cast<RADrenderTargetHandle>(image);
} }
RADsampler RADAPIENTRY radCreateSampler(RADdevice device) RADsampler RADAPIENTRY radCreateSampler(RADdevice device)
......
...@@ -175,7 +175,6 @@ copy "$(OutDir)libRAD.dll" "$(ProjectDir)..\..\..\lib\$(Configuration)\"</Comman ...@@ -175,7 +175,6 @@ copy "$(OutDir)libRAD.dll" "$(ProjectDir)..\..\..\lib\$(Configuration)\"</Comman
<ClCompile Include="Query.cpp" /> <ClCompile Include="Query.cpp" />
<ClCompile Include="RefCountObject.cpp" /> <ClCompile Include="RefCountObject.cpp" />
<ClCompile Include="Renderbuffer.cpp" /> <ClCompile Include="Renderbuffer.cpp" />
<ClCompile Include="ResourceManager.cpp" />
<ClCompile Include="Shader.cpp" /> <ClCompile Include="Shader.cpp" />
<ClCompile Include="Texture.cpp" /> <ClCompile Include="Texture.cpp" />
<ClCompile Include="utilities.cpp" /> <ClCompile Include="utilities.cpp" />
...@@ -201,7 +200,6 @@ copy "$(OutDir)libRAD.dll" "$(ProjectDir)..\..\..\lib\$(Configuration)\"</Comman ...@@ -201,7 +200,6 @@ copy "$(OutDir)libRAD.dll" "$(ProjectDir)..\..\..\lib\$(Configuration)\"</Comman
<ClInclude Include="RefCountObject.h" /> <ClInclude Include="RefCountObject.h" />
<ClInclude Include="Renderbuffer.h" /> <ClInclude Include="Renderbuffer.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
<ClInclude Include="ResourceManager.h" />
<ClInclude Include="Shader.h" /> <ClInclude Include="Shader.h" />
<ClInclude Include="Texture.h" /> <ClInclude Include="Texture.h" />
<ClInclude Include="utilities.h" /> <ClInclude Include="utilities.h" />
......
...@@ -47,9 +47,6 @@ ...@@ -47,9 +47,6 @@
<ClCompile Include="Renderbuffer.cpp"> <ClCompile Include="Renderbuffer.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="ResourceManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Shader.cpp"> <ClCompile Include="Shader.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
...@@ -109,9 +106,6 @@ ...@@ -109,9 +106,6 @@
<ClInclude Include="resource.h"> <ClInclude Include="resource.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="ResourceManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Shader.h"> <ClInclude Include="Shader.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment