Commit 7ce51fcf by Nicolas Capens Committed by Nicolas Capens

Move the EGL shared image creation implementation to the context.

BUG=18110152 Change-Id: I21aece83756f033f579f11c0fb2e9e3d21f93703 Reviewed-on: https://swiftshader-review.googlesource.com/1262Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent eef2c973
#ifndef egl_Context_hpp #ifndef egl_Context_hpp
#define egl_Context_hpp #define egl_Context_hpp
#define EGLAPI
#include <EGL/egl.h>
#define GL_API
#include <GLES/gl.h>
namespace gl
{
class Image;
}
namespace egl namespace egl
{ {
class Surface; class Surface;
...@@ -10,6 +20,8 @@ class Context ...@@ -10,6 +20,8 @@ class Context
public: public:
virtual void destroy() = 0; virtual void destroy() = 0;
virtual void bindTexImage(Surface *surface) = 0; virtual void bindTexImage(Surface *surface) = 0;
virtual EGLenum validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel) = 0;
virtual gl::Image *createSharedImage(EGLenum target, GLuint name, GLuint textureLevel) = 0;
}; };
} }
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include "Display.h" #include "Display.h"
#include "main.h" #include "main.h"
#include "libGLESv2/mathutil.h"
#include "libGLESv2/Device.hpp" #include "libGLESv2/Device.hpp"
#include "libEGL/Surface.h" #include "libEGL/Surface.h"
#include "libEGL/Context.hpp" #include "libEGL/Context.hpp"
......
...@@ -312,7 +312,7 @@ bool Surface::checkForResize() ...@@ -312,7 +312,7 @@ bool Surface::checkForResize()
if(static_cast<egl::Surface*>(getCurrentDrawSurface()) == this) if(static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
{ {
gl::makeCurrent(static_cast<gl::Context*>(getCurrentContext()), static_cast<egl::Display*>(getCurrentDisplay()), this); gl::makeCurrent(static_cast<egl::Context*>(getCurrentContext()), static_cast<egl::Display*>(getCurrentDisplay()), this);
} }
return true; return true;
......
...@@ -15,8 +15,8 @@ ...@@ -15,8 +15,8 @@
#include "Display.h" #include "Display.h"
#include "Surface.h" #include "Surface.h"
#include "Texture2D.hpp" #include "Texture2D.hpp"
#include "libGLESv2/Context.h" #include "Context.hpp"
#include "libGLESv2/Texture.h" #include "libGLESv2/Image.hpp"
#include "common/debug.h" #include "common/debug.h"
#include "Common/Version.h" #include "Common/Version.h"
...@@ -845,7 +845,7 @@ EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurfac ...@@ -845,7 +845,7 @@ EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurfac
try try
{ {
egl::Display *display = static_cast<egl::Display*>(dpy); egl::Display *display = static_cast<egl::Display*>(dpy);
gl::Context *context = static_cast<gl::Context*>(ctx); egl::Context *context = static_cast<egl::Context*>(ctx);
if(ctx != EGL_NO_CONTEXT && !validateContext(display, context)) if(ctx != EGL_NO_CONTEXT && !validateContext(display, context))
{ {
...@@ -953,7 +953,7 @@ EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint at ...@@ -953,7 +953,7 @@ EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint at
try try
{ {
egl::Display *display = static_cast<egl::Display*>(dpy); egl::Display *display = static_cast<egl::Display*>(dpy);
gl::Context *context = static_cast<gl::Context*>(ctx); egl::Context *context = static_cast<egl::Context*>(ctx);
if(!validateContext(display, context)) if(!validateContext(display, context))
{ {
...@@ -1070,7 +1070,7 @@ EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenu ...@@ -1070,7 +1070,7 @@ EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenu
try try
{ {
egl::Display *display = static_cast<egl::Display*>(dpy); egl::Display *display = static_cast<egl::Display*>(dpy);
gl::Context *context = static_cast<gl::Context*>(ctx); egl::Context *context = static_cast<egl::Context*>(ctx);
if(!validateDisplay(display)) if(!validateDisplay(display))
{ {
...@@ -1082,27 +1082,6 @@ EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenu ...@@ -1082,27 +1082,6 @@ EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenu
return error(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR); return error(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
} }
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 error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
}
EGLenum imagePreserved = EGL_FALSE; EGLenum imagePreserved = EGL_FALSE;
GLuint textureLevel = 0; GLuint textureLevel = 0;
if(attrib_list) if(attrib_list)
...@@ -1124,11 +1103,6 @@ EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenu ...@@ -1124,11 +1103,6 @@ EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenu
} }
} }
if(textureLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
{
return error(EGL_BAD_MATCH, EGL_NO_IMAGE_KHR);
}
GLuint name = reinterpret_cast<intptr_t>(buffer); GLuint name = reinterpret_cast<intptr_t>(buffer);
if(name == 0) if(name == 0)
...@@ -1136,51 +1110,14 @@ EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenu ...@@ -1136,51 +1110,14 @@ EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenu
return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
} }
gl::Image *image = 0; EGLenum validationResult = context->validateSharedImage(target, name, textureLevel);
if(textureTarget != GL_NONE)
{
gl::Texture *texture = context->getTexture(name);
if(!texture || texture->getTarget() != textureTarget)
{
return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
}
if(texture->isShared(textureTarget, textureLevel)) // Bound to an EGLSurface or already an EGLImage sibling
{
return error(EGL_BAD_ACCESS, EGL_NO_IMAGE_KHR);
}
if(textureLevel != 0 && !texture->isSamplerComplete())
{
return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
}
if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1))
{
return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
}
image = texture->createSharedImage(textureTarget, textureLevel);
}
else if(target == EGL_GL_RENDERBUFFER_KHR)
{
gl::Renderbuffer *renderbuffer = context->getRenderbuffer(name);
if(!renderbuffer)
{
return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
}
if(renderbuffer->isShared()) // Already an EGLImage sibling if(validationResult != EGL_SUCCESS)
{ {
return error(EGL_BAD_ACCESS, EGL_NO_IMAGE_KHR); return error(validationResult, EGL_NO_IMAGE_KHR);
} }
image = renderbuffer->createSharedImage(); gl::Image *image = context->createSharedImage(target, name, textureLevel);
}
else UNREACHABLE();
if(!image) if(!image)
{ {
......
...@@ -91,7 +91,7 @@ CONSTRUCTOR static bool eglAttachProcess() ...@@ -91,7 +91,7 @@ CONSTRUCTOR static bool eglAttachProcess()
libGLESv2 = loadLibrary(libGLESv2_lib); libGLESv2 = loadLibrary(libGLESv2_lib);
gl::createDevice = (gl::Device*(*)())getProcAddress(libGLESv2, "createDevice"); gl::createDevice = (gl::Device*(*)())getProcAddress(libGLESv2, "createDevice");
gl::createContext = (egl::Context *(*)(const egl::Config*, const egl::Context*))getProcAddress(libGLESv2, "glCreateContext"); gl::createContext = (egl::Context *(*)(const egl::Config*, const egl::Context*))getProcAddress(libGLESv2, "glCreateContext");
gl::makeCurrent = (void (*)(gl::Context*, egl::Display*, egl::Surface*))getProcAddress(libGLESv2, "glMakeCurrent"); gl::makeCurrent = (void (*)(egl::Context*, egl::Display*, egl::Surface*))getProcAddress(libGLESv2, "glMakeCurrent");
gl::getProcAddress = (__eglMustCastToProperFunctionPointerType (*)(const char*))getProcAddress(libGLESv2, "glGetProcAddress"); gl::getProcAddress = (__eglMustCastToProperFunctionPointerType (*)(const char*))getProcAddress(libGLESv2, "glGetProcAddress");
gl::createBackBuffer = (gl::Image *(*)(int, int, const egl::Config*))getProcAddress(libGLESv2, "createBackBuffer"); gl::createBackBuffer = (gl::Image *(*)(int, int, const egl::Config*))getProcAddress(libGLESv2, "createBackBuffer");
gl::createFrameBuffer = (sw::FrameBuffer *(*)(EGLNativeDisplayType, EGLNativeWindowType, int, int))getProcAddress(libGLESv2, "createFrameBuffer"); gl::createFrameBuffer = (sw::FrameBuffer *(*)(EGLNativeDisplayType, EGLNativeWindowType, int, int))getProcAddress(libGLESv2, "createFrameBuffer");
...@@ -263,8 +263,8 @@ namespace gl ...@@ -263,8 +263,8 @@ namespace gl
Device *(*createDevice)() = 0; Device *(*createDevice)() = 0;
egl::Context *(*createContext)(const egl::Config *config, const egl::Context *shareContext) = 0; egl::Context *(*createContext)(const egl::Config *config, const egl::Context *shareContext) = 0;
void (*bindTexImage)(egl::Surface *surface) = 0; void (*bindTexImage)(egl::Surface *surface) = 0;
void (*makeCurrent)(Context *context, egl::Display *display, egl::Surface *surface) = 0; void (*makeCurrent)(egl::Context *context, egl::Display *display, egl::Surface *surface) = 0;
Context *(*getCurrentContext)() = 0; egl::Context *(*getCurrentContext)() = 0;
__eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname) = 0; __eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname) = 0;
Image *(*createBackBuffer)(int width, int height, const egl::Config *config) = 0; Image *(*createBackBuffer)(int width, int height, const egl::Config *config) = 0;
sw::FrameBuffer *(*createFrameBuffer)(EGLNativeDisplayType display, EGLNativeWindowType window, int width, int height) = 0; sw::FrameBuffer *(*createFrameBuffer)(EGLNativeDisplayType display, EGLNativeWindowType window, int width, int height) = 0;
......
...@@ -84,12 +84,11 @@ namespace sw ...@@ -84,12 +84,11 @@ namespace sw
namespace gl namespace gl
{ {
class Device; class Device;
class Context;
class Image; class Image;
extern Device *(*createDevice)(); extern Device *(*createDevice)();
extern egl::Context *(*createContext)(const egl::Config *config, const egl::Context *shareContext); extern egl::Context *(*createContext)(const egl::Config *config, const egl::Context *shareContext);
extern void (*makeCurrent)(Context *context, egl::Display *display, egl::Surface *surface); extern void (*makeCurrent)(egl::Context *context, egl::Display *display, egl::Surface *surface);
extern __eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname); extern __eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname);
extern Image *(*createBackBuffer)(int width, int height, const egl::Config *config); extern Image *(*createBackBuffer)(int width, int height, const egl::Config *config);
extern sw::FrameBuffer *(*createFrameBuffer)(EGLNativeDisplayType display, EGLNativeWindowType window, int width, int height); extern sw::FrameBuffer *(*createFrameBuffer)(EGLNativeDisplayType display, EGLNativeWindowType window, int width, int height);
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
#include "libEGL/Surface.h" #include "libEGL/Surface.h"
#include "Common/Half.hpp" #include "Common/Half.hpp"
#include <EGL/eglext.h>
#undef near #undef near
#undef far #undef far
...@@ -2226,6 +2228,85 @@ void Context::bindTexImage(egl::Surface *surface) ...@@ -2226,6 +2228,85 @@ void Context::bindTexImage(egl::Surface *surface)
} }
} }
EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
{
switch(target)
{
case EGL_GL_TEXTURE_2D_KHR:
break;
case EGL_GL_RENDERBUFFER_KHR:
break;
default:
return EGL_BAD_PARAMETER;
}
if(textureLevel >= IMPLEMENTATION_MAX_TEXTURE_LEVELS)
{
return EGL_BAD_MATCH;
}
if(target == EGL_GL_TEXTURE_2D_KHR)
{
Texture *texture = getTexture(name);
if(!texture || texture->getTarget() != target)
{
return EGL_BAD_PARAMETER;
}
if(texture->isShared(GL_TEXTURE_2D, 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)
{
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;
}
Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
{
if(target == EGL_GL_TEXTURE_2D_KHR)
{
gl::Texture *texture = getTexture(name);
return texture->createSharedImage(GL_TEXTURE_2D, textureLevel);
}
else if(target == EGL_GL_RENDERBUFFER_KHR)
{
gl::Renderbuffer *renderbuffer = getRenderbuffer(name);
return renderbuffer->createSharedImage();
}
else UNREACHABLE();
return 0;
}
} }
// Exported functions for use by EGL // Exported functions for use by EGL
......
...@@ -368,6 +368,8 @@ public: ...@@ -368,6 +368,8 @@ public:
static int getSupportedMultiSampleDepth(sw::Format format, int requested); static int getSupportedMultiSampleDepth(sw::Format format, int requested);
virtual void bindTexImage(egl::Surface *surface); virtual void bindTexImage(egl::Surface *surface);
virtual EGLenum validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel);
virtual Image *createSharedImage(EGLenum target, GLuint name, GLuint textureLevel);
private: private:
virtual ~Context(); virtual ~Context();
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include "libEGL/Surface.h" #include "libEGL/Surface.h"
#include "Common/Half.hpp" #include "Common/Half.hpp"
#include <EGL/eglext.h>
#undef near #undef near
#undef far #undef far
...@@ -3039,6 +3041,109 @@ void Context::bindTexImage(egl::Surface *surface) ...@@ -3039,6 +3041,109 @@ void Context::bindTexImage(egl::Surface *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 >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
{
return EGL_BAD_MATCH;
}
if(textureTarget != GL_NONE)
{
gl::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)
{
gl::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;
}
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)
{
gl::Texture *texture = getTexture(name);
return texture->createSharedImage(textureTarget, textureLevel);
}
else if(target == EGL_GL_RENDERBUFFER_KHR)
{
gl::Renderbuffer *renderbuffer = getRenderbuffer(name);
return renderbuffer->createSharedImage();
}
else UNREACHABLE();
return 0;
}
} }
// Exported functions for use by EGL // Exported functions for use by EGL
......
...@@ -420,6 +420,8 @@ public: ...@@ -420,6 +420,8 @@ public:
GLbitfield mask); GLbitfield mask);
virtual void bindTexImage(egl::Surface *surface); virtual void bindTexImage(egl::Surface *surface);
virtual EGLenum validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel);
virtual gl::Image *createSharedImage(EGLenum target, GLuint name, GLuint textureLevel);
private: private:
virtual ~Context(); virtual ~Context();
......
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