Commit e9233fb7 by Alexis Hetu Committed by Alexis Hétu

Adding multisampling to texture3D test

Required adding X and Y flipping to blitter. Change-Id: Icaac4045ae9419296112464d7ccdde7babb76eb3 Reviewed-on: https://swiftshader-review.googlesource.com/2180Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent 82cd6d82
...@@ -2877,38 +2877,54 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -2877,38 +2877,54 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
sw::SliceRect sourceRect; sw::SliceRect sourceRect;
sw::SliceRect destRect; sw::SliceRect destRect;
bool flipX = (srcX0 < srcX1) ^ (dstX0 < dstX1);
bool flipy = (srcY0 < srcY1) ^ (dstY0 < dstY1);
if(srcX0 < srcX1) if(srcX0 < srcX1)
{ {
sourceRect.x0 = srcX0; sourceRect.x0 = srcX0;
sourceRect.x1 = srcX1; sourceRect.x1 = srcX1;
destRect.x0 = dstX0;
destRect.x1 = dstX1;
} }
else else
{ {
sourceRect.x0 = srcX1; sourceRect.x0 = srcX1;
destRect.x0 = dstX1;
sourceRect.x1 = srcX0; sourceRect.x1 = srcX0;
destRect.x1 = dstX0;
} }
if(dstX0 < dstX1)
{
destRect.x0 = dstX0;
destRect.x1 = dstX1;
}
else
{
destRect.x0 = dstX1;
destRect.x1 = dstX0;
}
if(srcY0 < srcY1) if(srcY0 < srcY1)
{ {
sourceRect.y0 = srcY0; sourceRect.y0 = srcY0;
destRect.y0 = dstY0;
sourceRect.y1 = srcY1; sourceRect.y1 = srcY1;
destRect.y1 = dstY1;
} }
else else
{ {
sourceRect.y0 = srcY1; sourceRect.y0 = srcY1;
destRect.y0 = dstY1;
sourceRect.y1 = srcY0; sourceRect.y1 = srcY0;
destRect.y1 = dstY0;
} }
sw::Rect sourceScissoredRect = sourceRect; if(dstY0 < dstY1)
{
destRect.y0 = dstY0;
destRect.y1 = dstY1;
}
else
{
destRect.y0 = dstY1;
destRect.y1 = dstY0;
}
sw::Rect sourceScissoredRect = sourceRect;
sw::Rect destScissoredRect = destRect; sw::Rect destScissoredRect = destRect;
if(mState.scissorTest) // Only write to parts of the destination framebuffer which pass the scissor test if(mState.scissorTest) // Only write to parts of the destination framebuffer which pass the scissor test
...@@ -3023,10 +3039,8 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -3023,10 +3039,8 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
readFramebuffer->getColorbufferType() == GL_RENDERBUFFER; readFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
const bool validDrawType = drawFramebuffer->getColorbufferType() == GL_TEXTURE_2D || const bool validDrawType = drawFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
drawFramebuffer->getColorbufferType() == GL_RENDERBUFFER; drawFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
if(!validReadType || !validDrawType || 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); return error(GL_INVALID_OPERATION);
} }
...@@ -3050,8 +3064,7 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -3050,8 +3064,7 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
{ {
if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer()) if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
{ {
if(readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() || if(readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType())
readFramebuffer->getDepthbuffer()->getInternalFormat() != drawFramebuffer->getDepthbuffer()->getInternalFormat())
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -3066,8 +3079,7 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -3066,8 +3079,7 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
{ {
if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer()) if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
{ {
if(readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() || if(readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType())
readFramebuffer->getStencilbuffer()->getInternalFormat() != drawFramebuffer->getStencilbuffer()->getInternalFormat())
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -3098,6 +3110,15 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -3098,6 +3110,15 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
egl::Image *readRenderTarget = readFramebuffer->getRenderTarget(); egl::Image *readRenderTarget = readFramebuffer->getRenderTarget();
egl::Image *drawRenderTarget = drawFramebuffer->getRenderTarget(); egl::Image *drawRenderTarget = drawFramebuffer->getRenderTarget();
if(flipX)
{
swap(destRect.x0, destRect.x1);
}
if(flipy)
{
swap(destRect.y0, destRect.y1);
}
bool success = device->stretchRect(readRenderTarget, &sourceRect, drawRenderTarget, &destRect, false); bool success = device->stretchRect(readRenderTarget, &sourceRect, drawRenderTarget, &destRect, false);
readRenderTarget->release(); readRenderTarget->release();
...@@ -3105,7 +3126,7 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -3105,7 +3126,7 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
if(!success) if(!success)
{ {
ERR("BlitFramebufferANGLE failed."); ERR("BlitFramebuffer failed.");
return; return;
} }
} }
...@@ -3116,7 +3137,7 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -3116,7 +3137,7 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
if(!success) if(!success)
{ {
ERR("BlitFramebufferANGLE failed."); ERR("BlitFramebuffer failed.");
return; return;
} }
} }
......
...@@ -470,9 +470,58 @@ namespace es2 ...@@ -470,9 +470,58 @@ namespace es2
this->viewport = viewport; this->viewport = viewport;
} }
void Device::copyBuffer(sw::byte *sourceBuffer, sw::byte *destBuffer, unsigned int width, unsigned int height, unsigned int sourcePitch, unsigned int destPitch, unsigned int bytes, bool flipX, bool flipY)
{
unsigned int widthB = width * bytes;
unsigned int widthMaxB = widthB - 1;
if(flipX)
{
if(flipY)
{
sourceBuffer += (height - 1) * sourcePitch;
for(unsigned int y = 0; y < height; ++y, sourceBuffer -= sourcePitch, destBuffer += destPitch)
{
for(unsigned int x = 0; x < widthB; ++x)
{
destBuffer[x] = sourceBuffer[widthMaxB - x];
}
}
}
else
{
for(unsigned int y = 0; y < height; ++y, sourceBuffer += sourcePitch, destBuffer += destPitch)
{
for(unsigned int x = 0; x < widthB; ++x)
{
destBuffer[x] = sourceBuffer[widthMaxB - x];
}
}
}
}
else
{
if(flipY)
{
sourceBuffer += (height - 1) * sourcePitch;
for(unsigned int y = 0; y < height; ++y, sourceBuffer -= sourcePitch, destBuffer += destPitch)
{
memcpy(destBuffer, sourceBuffer, widthB);
}
}
else
{
for(unsigned int y = 0; y < height; ++y, sourceBuffer += sourcePitch, destBuffer += destPitch)
{
memcpy(destBuffer, sourceBuffer, widthB);
}
}
}
}
bool Device::stretchRect(egl::Image *source, const sw::SliceRect *sourceRect, egl::Image *dest, const sw::SliceRect *destRect, bool filter) bool Device::stretchRect(egl::Image *source, const sw::SliceRect *sourceRect, egl::Image *dest, const sw::SliceRect *destRect, bool filter)
{ {
if(!source || !dest || !validRectangle(sourceRect, source) || !validRectangle(destRect, dest)) if(!source || !dest)
{ {
ERR("Invalid parameters"); ERR("Invalid parameters");
return false; return false;
...@@ -483,12 +532,40 @@ namespace es2 ...@@ -483,12 +532,40 @@ namespace es2
int dWidth = dest->getExternalWidth(); int dWidth = dest->getExternalWidth();
int dHeight = dest->getExternalHeight(); int dHeight = dest->getExternalHeight();
bool flipX = false;
bool flipY = false;
if(sourceRect && destRect)
{
flipX = (sourceRect->x0 < sourceRect->x1) ^ (destRect->x0 < destRect->x1);
flipY = (sourceRect->y0 < sourceRect->y1) ^ (destRect->y0 < destRect->y1);
}
else if(sourceRect)
{
flipX = (sourceRect->x0 > sourceRect->x1);
flipY = (sourceRect->y0 > sourceRect->y1);
}
else if(destRect)
{
flipX = (destRect->x0 > destRect->x1);
flipY = (destRect->y0 > destRect->y1);
}
SliceRect sRect; SliceRect sRect;
SliceRect dRect; SliceRect dRect;
if(sourceRect) if(sourceRect)
{ {
sRect = *sourceRect; sRect = *sourceRect;
if(sRect.x0 > sRect.x1)
{
swap(sRect.x0, sRect.x1);
}
if(sRect.y0 > sRect.y1)
{
swap(sRect.y0, sRect.y1);
}
} }
else else
{ {
...@@ -501,6 +578,16 @@ namespace es2 ...@@ -501,6 +578,16 @@ namespace es2
if(destRect) if(destRect)
{ {
dRect = *destRect; dRect = *destRect;
if(dRect.x0 > dRect.x1)
{
swap(dRect.x0, dRect.x1);
}
if(dRect.y0 > dRect.y1)
{
swap(dRect.y0, dRect.y1);
}
} }
else else
{ {
...@@ -510,6 +597,12 @@ namespace es2 ...@@ -510,6 +597,12 @@ namespace es2
dRect.x1 = dWidth; dRect.x1 = dWidth;
} }
if(!validRectangle(&sRect, source) || !validRectangle(&dRect, dest))
{
ERR("Invalid parameters");
return false;
}
bool scaling = (sRect.x1 - sRect.x0 != dRect.x1 - dRect.x0) || (sRect.y1 - sRect.y0 != dRect.y1 - dRect.y0); bool scaling = (sRect.x1 - sRect.x0 != dRect.x1 - dRect.x0) || (sRect.y1 - sRect.y0 != dRect.y1 - dRect.y0);
bool equalFormats = source->getInternalFormat() == dest->getInternalFormat(); bool equalFormats = source->getInternalFormat() == dest->getInternalFormat();
bool depthStencil = Image::isDepth(source->getInternalFormat()) || Image::isStencil(source->getInternalFormat()); bool depthStencil = Image::isDepth(source->getInternalFormat()) || Image::isStencil(source->getInternalFormat());
...@@ -529,17 +622,7 @@ namespace es2 ...@@ -529,17 +622,7 @@ namespace es2
sw::byte *sourceBuffer = (sw::byte*)source->lockInternal(0, 0, sourceRect->slice, LOCK_READONLY, PUBLIC); sw::byte *sourceBuffer = (sw::byte*)source->lockInternal(0, 0, sourceRect->slice, LOCK_READONLY, PUBLIC);
sw::byte *destBuffer = (sw::byte*)dest->lockInternal(0, 0, destRect->slice, LOCK_DISCARD, PUBLIC); sw::byte *destBuffer = (sw::byte*)dest->lockInternal(0, 0, destRect->slice, LOCK_DISCARD, PUBLIC);
unsigned int width = source->getInternalWidth(); copyBuffer(sourceBuffer, destBuffer, source->getInternalWidth(), source->getInternalHeight(), source->getInternalPitchB(), dest->getInternalPitchB(), Image::bytes(source->getInternalFormat()), flipX, flipY);
unsigned int height = source->getInternalHeight();
unsigned int pitch = source->getInternalPitchB();
for(unsigned int y = 0; y < height; y++)
{
memcpy(destBuffer, sourceBuffer, pitch); // FIXME: Only copy width * bytes
sourceBuffer += pitch;
destBuffer += pitch;
}
source->unlockInternal(); source->unlockInternal();
dest->unlockInternal(); dest->unlockInternal();
...@@ -550,17 +633,7 @@ namespace es2 ...@@ -550,17 +633,7 @@ namespace es2
sw::byte *sourceBuffer = (sw::byte*)source->lockStencil(0, PUBLIC); sw::byte *sourceBuffer = (sw::byte*)source->lockStencil(0, PUBLIC);
sw::byte *destBuffer = (sw::byte*)dest->lockStencil(0, PUBLIC); sw::byte *destBuffer = (sw::byte*)dest->lockStencil(0, PUBLIC);
unsigned int width = source->getInternalWidth(); copyBuffer(sourceBuffer, destBuffer, source->getInternalWidth(), source->getInternalHeight(), source->getInternalPitchB(), dest->getInternalPitchB(), Image::bytes(source->getInternalFormat()), flipX, flipY);
unsigned int height = source->getInternalHeight();
unsigned int pitch = source->getStencilPitchB();
for(unsigned int y = 0; y < height; y++)
{
memcpy(destBuffer, sourceBuffer, pitch); // FIXME: Only copy width * bytes
sourceBuffer += pitch;
destBuffer += pitch;
}
source->unlockStencil(); source->unlockStencil();
dest->unlockStencil(); dest->unlockStencil();
...@@ -575,22 +648,18 @@ namespace es2 ...@@ -575,22 +648,18 @@ namespace es2
unsigned int width = dRect.x1 - dRect.x0; unsigned int width = dRect.x1 - dRect.x0;
unsigned int height = dRect.y1 - dRect.y0; unsigned int height = dRect.y1 - dRect.y0;
unsigned int bytes = width * Image::bytes(source->getInternalFormat());
for(unsigned int y = 0; y < height; y++) copyBuffer(sourceBytes, destBytes, width, height, sourcePitch, destPitch, Image::bytes(source->getInternalFormat()), flipX, flipY);
{
memcpy(destBytes, sourceBytes, bytes);
if(alpha0xFF) if(alpha0xFF)
{
for(unsigned int y = 0; y < height; ++y, destBytes += destPitch)
{ {
for(unsigned int x = 0; x < width; x++) for(unsigned int x = 0; x < width; ++x)
{ {
destBytes[4 * x + 3] = 0xFF; destBytes[4 * x + 3] = 0xFF;
} }
} }
sourceBytes += sourcePitch;
destBytes += destPitch;
} }
source->unlockInternal(); source->unlockInternal();
...@@ -598,6 +667,14 @@ namespace es2 ...@@ -598,6 +667,14 @@ namespace es2
} }
else else
{ {
if(flipX)
{
swap(dRect.x0, dRect.x1);
}
if(flipY)
{
swap(dRect.y0, dRect.y1);
}
blit(source, sRect, dest, dRect, scaling && filter); blit(source, sRect, dest, dRect, scaling && filter);
} }
......
...@@ -81,6 +81,8 @@ namespace es2 ...@@ -81,6 +81,8 @@ namespace es2
bool validRectangle(const sw::Rect *rect, egl::Image *surface); bool validRectangle(const sw::Rect *rect, egl::Image *surface);
void copyBuffer(sw::byte *sourceBuffer, sw::byte *destBuffer, unsigned int width, unsigned int height, unsigned int sourcePitch, unsigned int destPitch, unsigned int bytes, bool flipX, bool flipY);
Viewport viewport; Viewport viewport;
sw::Rect scissorRect; sw::Rect scissorRect;
bool scissorEnable; bool scissorEnable;
......
...@@ -2974,6 +2974,7 @@ const GLubyte* GL_APIENTRY glGetString(GLenum name) ...@@ -2974,6 +2974,7 @@ const GLubyte* GL_APIENTRY glGetString(GLenum name)
"GL_EXT_texture_filter_anisotropic " "GL_EXT_texture_filter_anisotropic "
"GL_EXT_texture_format_BGRA8888 " "GL_EXT_texture_format_BGRA8888 "
"GL_ANGLE_framebuffer_blit " "GL_ANGLE_framebuffer_blit "
"GL_NV_framebuffer_blit "
"GL_ANGLE_framebuffer_multisample " "GL_ANGLE_framebuffer_multisample "
#if (S3TC_SUPPORT) #if (S3TC_SUPPORT)
"GL_ANGLE_texture_compression_dxt3 " "GL_ANGLE_texture_compression_dxt3 "
...@@ -5129,8 +5130,7 @@ void GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height) ...@@ -5129,8 +5130,7 @@ void GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
} }
} }
void GL_APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, void GL_APIENTRY glBlitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
GLbitfield mask, GLenum filter)
{ {
TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, " TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
"GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, " "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
...@@ -5150,12 +5150,6 @@ void GL_APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, G ...@@ -5150,12 +5150,6 @@ void GL_APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, G
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
{
ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
return error(GL_INVALID_OPERATION);
}
es2::Context *context = es2::getContext(); es2::Context *context = es2::getContext();
if(context) if(context)
...@@ -5170,6 +5164,18 @@ void GL_APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, G ...@@ -5170,6 +5164,18 @@ void GL_APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, G
} }
} }
void GL_APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter)
{
if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
{
ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
return error(GL_INVALID_OPERATION);
}
glBlitFramebufferNV(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
}
void GL_APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, void GL_APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type, const GLvoid* pixels) GLint border, GLenum format, GLenum type, const GLvoid* pixels)
{ {
...@@ -5614,6 +5620,7 @@ __eglMustCastToProperFunctionPointerType glGetProcAddress(const char *procname) ...@@ -5614,6 +5620,7 @@ __eglMustCastToProperFunctionPointerType glGetProcAddress(const char *procname)
EXTENSION(glTexImage3DOES), EXTENSION(glTexImage3DOES),
EXTENSION(glBlitFramebufferANGLE), EXTENSION(glBlitFramebufferANGLE),
EXTENSION(glBlitFramebufferNV),
EXTENSION(glRenderbufferStorageMultisampleANGLE), EXTENSION(glRenderbufferStorageMultisampleANGLE),
EXTENSION(glDeleteFencesNV), EXTENSION(glDeleteFencesNV),
EXTENSION(glGenFencesNV), EXTENSION(glGenFencesNV),
......
...@@ -51,6 +51,14 @@ inline T clamp(T x, MIN min, MAX max) ...@@ -51,6 +51,14 @@ inline T clamp(T x, MIN min, MAX max)
return x < min ? min : (x > max ? max : x); return x < min ? min : (x > max ? max : x);
} }
template<class T>
inline void swap(T &a, T &b)
{
T t = a;
a = b;
b = t;
}
inline float clamp01(float x) inline float clamp01(float x)
{ {
return clamp(x, 0.0f, 1.0f); return clamp(x, 0.0f, 1.0f);
......
...@@ -26,24 +26,42 @@ namespace sw ...@@ -26,24 +26,42 @@ namespace sw
delete blitCache; delete blitCache;
} }
void Blitter::blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter) void Blitter::blit(Surface *source, const SliceRect &sourceRect, Surface *dest, const SliceRect &destRect, bool filter)
{ {
if(blitReactor(source, sRect, dest, dRect, filter)) if(blitReactor(source, sourceRect, dest, destRect, filter))
{ {
return; return;
} }
SliceRect sRect = sourceRect;
SliceRect dRect = destRect;
bool flipX = destRect.x0 > destRect.x1;
bool flipY = destRect.y0 > destRect.y1;
if(flipX)
{
swap(dRect.x0, dRect.x1);
swap(sRect.x0, sRect.x1);
}
if(flipY)
{
swap(dRect.y0, dRect.y1);
swap(sRect.y0, sRect.y1);
}
source->lockInternal(sRect.x0, sRect.y0, sRect.slice, sw::LOCK_READONLY, sw::PUBLIC); source->lockInternal(sRect.x0, sRect.y0, sRect.slice, sw::LOCK_READONLY, sw::PUBLIC);
dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, sw::LOCK_WRITEONLY, sw::PUBLIC); dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, sw::LOCK_WRITEONLY, sw::PUBLIC);
float w = 1.0f / (dRect.x1 - dRect.x0) * (sRect.x1 - sRect.x0); float w = 1.0f / (dRect.x1 - dRect.x0) * (sRect.x1 - sRect.x0);
float h = 1.0f / (dRect.y1 - dRect.y0) * (sRect.y1 - sRect.y0); float h = 1.0f / (dRect.y1 - dRect.y0) * (sRect.y1 - sRect.y0);
const float xStart = (float)sRect.x0 + 0.5f * w;
float y = (float)sRect.y0 + 0.5f * h; float y = (float)sRect.y0 + 0.5f * h;
for(int j = dRect.y0; j < dRect.y1; j++) for(int j = dRect.y0; j < dRect.y1; j++)
{ {
float x = (float)sRect.x0 + 0.5f * w; float x = xStart;
for(int i = dRect.x0; i < dRect.x1; i++) for(int i = dRect.x0; i < dRect.x1; i++)
{ {
...@@ -115,8 +133,21 @@ namespace sw ...@@ -115,8 +133,21 @@ namespace sw
return true; return true;
} }
bool Blitter::blitReactor(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter) bool Blitter::blitReactor(Surface *source, const SliceRect &sourceRect, Surface *dest, const SliceRect &destRect, bool filter)
{ {
Rect dRect = destRect;
Rect sRect = sourceRect;
if(destRect.x0 > destRect.x1)
{
swap(dRect.x0, dRect.x1);
swap(sRect.x0, sRect.x1);
}
if(destRect.y0 > destRect.y1)
{
swap(dRect.y0, dRect.y1);
swap(sRect.y0, sRect.y1);
}
BlitState state; BlitState state;
state.sourceFormat = source->getInternalFormat(); state.sourceFormat = source->getInternalFormat();
...@@ -154,6 +185,7 @@ namespace sw ...@@ -154,6 +185,7 @@ namespace sw
For(Int j = y0d, j < y1d, j++) For(Int j = y0d, j < y1d, j++)
{ {
Float x = x0; Float x = x0;
Pointer<Byte> destLine = dest + j * dPitchB;
For(Int i = x0d, i < x1d, i++) For(Int i = x0d, i < x1d, i++)
{ {
...@@ -262,7 +294,7 @@ namespace sw ...@@ -262,7 +294,7 @@ namespace sw
Surface::isUnsignedComponent(state.destFormat, 3) ? 0.0f : -1.0f)); Surface::isUnsignedComponent(state.destFormat, 3) ? 0.0f : -1.0f));
} }
Pointer<Byte> d = dest + j * dPitchB + i * Surface::bytes(state.destFormat); Pointer<Byte> d = destLine + i * Surface::bytes(state.destFormat);
switch(state.destFormat) switch(state.destFormat)
{ {
...@@ -321,8 +353,8 @@ namespace sw ...@@ -321,8 +353,8 @@ namespace sw
BlitData data; BlitData data;
data.source = source->lockInternal(0, 0, sRect.slice, sw::LOCK_READONLY, sw::PUBLIC); data.source = source->lockInternal(0, 0, sourceRect.slice, sw::LOCK_READONLY, sw::PUBLIC);
data.dest = dest->lockInternal(0, 0, dRect.slice, sw::LOCK_WRITEONLY, sw::PUBLIC); data.dest = dest->lockInternal(0, 0, destRect.slice, sw::LOCK_WRITEONLY, sw::PUBLIC);
data.sPitchB = source->getInternalPitchB(); data.sPitchB = source->getInternalPitchB();
data.dPitchB = dest->getInternalPitchB(); data.dPitchB = dest->getInternalPitchB();
......
...@@ -94,7 +94,7 @@ class OGLES2ColourGrading : public PVRShell ...@@ -94,7 +94,7 @@ class OGLES2ColourGrading : public PVRShell
{ {
eMultisampleExtension_None, eMultisampleExtension_None,
eMultisampleExtension_IMG, eMultisampleExtension_IMG,
eMultisampleExtension_EXT eMultisampleExtension_ANGLE
}; };
// Print3D object // Print3D object
...@@ -179,6 +179,9 @@ class OGLES2ColourGrading : public PVRShell ...@@ -179,6 +179,9 @@ class OGLES2ColourGrading : public PVRShell
bool m_bMultisampledSupported; bool m_bMultisampledSupported;
EMultisampleExtension m_eMultisampleMode; EMultisampleExtension m_eMultisampleMode;
bool m_flipX;
bool m_flipY;
public: public:
OGLES2ColourGrading() : OGLES2ColourGrading() :
m_uiMaskTexture(0), m_uiMaskTexture(0),
...@@ -203,7 +206,9 @@ public: ...@@ -203,7 +206,9 @@ public:
m_uiColourBufferMultisampled(0), m_uiColourBufferMultisampled(0),
m_ulStartTime(0), m_ulStartTime(0),
m_bDiscard(false), m_bDiscard(false),
m_bMultisampledSupported(false) m_bMultisampledSupported(false),
m_flipX(false),
m_flipY(false)
{ {
} }
...@@ -494,9 +499,9 @@ bool OGLES2ColourGrading::CreateFBO() ...@@ -494,9 +499,9 @@ bool OGLES2ColourGrading::CreateFBO()
{ {
// Figure out if the platform supports either EXT or IMG extension // Figure out if the platform supports either EXT or IMG extension
m_eMultisampleMode = eMultisampleExtension_IMG; m_eMultisampleMode = eMultisampleExtension_IMG;
if(m_Extensions.glFramebufferTexture2DMultisampleEXT && m_Extensions.glRenderbufferStorageMultisampleEXT) if(m_Extensions.glRenderbufferStorageMultisampleANGLE)
{ {
m_eMultisampleMode = eMultisampleExtension_EXT; m_eMultisampleMode = eMultisampleExtension_ANGLE;
} }
GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0 }; GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0 };
...@@ -553,17 +558,17 @@ bool OGLES2ColourGrading::CreateFBO() ...@@ -553,17 +558,17 @@ bool OGLES2ColourGrading::CreateFBO()
glGenRenderbuffers(1, &m_uiDepthBufferMultisampled); glGenRenderbuffers(1, &m_uiDepthBufferMultisampled);
glBindRenderbuffer(GL_RENDERBUFFER, m_uiDepthBufferMultisampled); glBindRenderbuffer(GL_RENDERBUFFER, m_uiDepthBufferMultisampled);
if(m_eMultisampleMode == eMultisampleExtension_EXT) if(m_eMultisampleMode == eMultisampleExtension_ANGLE)
m_Extensions.glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT16, PVRShellGet(prefWidth), PVRShellGet(prefHeight)); m_Extensions.glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT16, PVRShellGet(prefWidth), PVRShellGet(prefHeight));
else else
m_Extensions.glRenderbufferStorageMultisampleIMG(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT16, PVRShellGet(prefWidth), PVRShellGet(prefHeight)); m_Extensions.glRenderbufferStorageMultisampleIMG(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT16, PVRShellGet(prefWidth), PVRShellGet(prefHeight));
glGenRenderbuffers(1, &m_uiColourBufferMultisampled); glGenRenderbuffers(1, &m_uiColourBufferMultisampled);
glBindRenderbuffer(GL_RENDERBUFFER, m_uiColourBufferMultisampled); glBindRenderbuffer(GL_RENDERBUFFER, m_uiColourBufferMultisampled);
if(m_eMultisampleMode == eMultisampleExtension_EXT) if(m_eMultisampleMode == eMultisampleExtension_ANGLE)
m_Extensions.glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, GL_RGB, PVRShellGet(prefWidth), PVRShellGet(prefHeight)); m_Extensions.glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, samples, GL_RGB8_OES, PVRShellGet(prefWidth), PVRShellGet(prefHeight));
else else
m_Extensions.glRenderbufferStorageMultisampleIMG(GL_RENDERBUFFER, samples, GL_RGB, PVRShellGet(prefWidth), PVRShellGet(prefHeight)); m_Extensions.glRenderbufferStorageMultisampleIMG(GL_RENDERBUFFER, samples, GL_RGB8_OES, PVRShellGet(prefWidth), PVRShellGet(prefHeight));
glBindRenderbuffer(GL_RENDERBUFFER, 0); glBindRenderbuffer(GL_RENDERBUFFER, 0);
...@@ -650,7 +655,7 @@ bool OGLES2ColourGrading::InitView() ...@@ -650,7 +655,7 @@ bool OGLES2ColourGrading::InitView()
// Create a multisampled FBO if the required extension is supported // Create a multisampled FBO if the required extension is supported
m_eMultisampleMode = eMultisampleExtension_None; m_eMultisampleMode = eMultisampleExtension_None;
m_bMultisampledSupported = false; m_bMultisampledSupported = false;
m_bMultisampledSupported |= CPVRTgles2Ext::IsGLExtensionSupported("GL_EXT_multisampled_render_to_texture"); m_bMultisampledSupported |= CPVRTgles2Ext::IsGLExtensionSupported("GL_ANGLE_framebuffer_multisample");
m_bMultisampledSupported |= CPVRTgles2Ext::IsGLExtensionSupported("GL_IMG_multisampled_render_to_texture"); m_bMultisampledSupported |= CPVRTgles2Ext::IsGLExtensionSupported("GL_IMG_multisampled_render_to_texture");
// Create FBOs // Create FBOs
...@@ -770,7 +775,15 @@ bool OGLES2ColourGrading::RenderScene() ...@@ -770,7 +775,15 @@ bool OGLES2ColourGrading::RenderScene()
if(m_iCurrentLUT < eA) if(m_iCurrentLUT < eA)
m_iCurrentLUT = eB; m_iCurrentLUT = eB;
} }
else if(PVRShellIsKeyPressed(PVRShellKeyNameUP))
{
m_flipX = !m_flipX;
}
else if(PVRShellIsKeyPressed(PVRShellKeyNameDOWN))
{
m_flipY = !m_flipY;
}
// Render to our texture // Render to our texture
{ {
// Bind our FBO // Bind our FBO
...@@ -852,8 +865,13 @@ bool OGLES2ColourGrading::RenderScene() ...@@ -852,8 +865,13 @@ bool OGLES2ColourGrading::RenderScene()
{ {
glBindFramebuffer(GL_READ_FRAMEBUFFER_NV, m_uiFBOMultisampled); glBindFramebuffer(GL_READ_FRAMEBUFFER_NV, m_uiFBOMultisampled);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER_NV, m_uiFBO); glBindFramebuffer(GL_DRAW_FRAMEBUFFER_NV, m_uiFBO);
return false; // FIXME: fix the multisampling path by adding a blit function below int w = PVRShellGet(prefWidth);
//glBlitFramebuffer(0, 0, PVRShellGet(prefWidth), PVRShellGet(prefHeight), 0, 0, PVRShellGet(prefWidth), PVRShellGet(prefHeight), GL_COLOR_BUFFER_BIT, GL_NEAREST); int h = PVRShellGet(prefHeight);
int destX0 = m_flipX ? w : 0;
int destX1 = m_flipX ? 0 : w;
int destY0 = m_flipY ? h : 0;
int destY1 = m_flipY ? 0 : h;
m_Extensions.glBlitFramebufferNV(0, 0, w, h, destX0, destY0, destX1, destY1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
} }
// We are done with rendering to our FBO so switch back to the back buffer. // We are done with rendering to our FBO so switch back to the back buffer.
......
...@@ -51,8 +51,8 @@ void CPVRTgles2Ext::LoadExtensions() ...@@ -51,8 +51,8 @@ void CPVRTgles2Ext::LoadExtensions()
glEndQueryEXT = 0; glEndQueryEXT = 0;
glGetQueryivEXT = 0; glGetQueryivEXT = 0;
glGetQueryObjectuivEXT = 0; glGetQueryObjectuivEXT = 0;
glRenderbufferStorageMultisampleEXT = 0; glRenderbufferStorageMultisampleANGLE = 0;
glFramebufferTexture2DMultisampleEXT = 0; glBlitFramebufferNV = 0;
glTexImage3DOES = 0; glTexImage3DOES = 0;
glTexSubImage3DOES = 0; glTexSubImage3DOES = 0;
glCopyTexSubImage3DOES = 0; glCopyTexSubImage3DOES = 0;
...@@ -100,22 +100,27 @@ void CPVRTgles2Ext::LoadExtensions() ...@@ -100,22 +100,27 @@ void CPVRTgles2Ext::LoadExtensions()
glFramebufferTexture2DMultisampleIMG = (PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMG) PVRGetProcAddress(glFramebufferTexture2DMultisampleIMG); glFramebufferTexture2DMultisampleIMG = (PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMG) PVRGetProcAddress(glFramebufferTexture2DMultisampleIMG);
} }
/* GL_EXT_multisampled_render_to_texture */ /* GL_ANGLE_framebuffer_multisample */
if (strstr((char *)pszGLExtensions, "GL_EXT_multisampled_render_to_texture")) if (strstr((char *)pszGLExtensions, "GL_ANGLE_framebuffer_multisample"))
{ {
glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXT) PVRGetProcAddress(glRenderbufferStorageMultisampleEXT); glRenderbufferStorageMultisampleANGLE = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC)PVRGetProcAddress(glRenderbufferStorageMultisampleANGLE);
glFramebufferTexture2DMultisampleEXT = (PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXT) PVRGetProcAddress(glFramebufferTexture2DMultisampleEXT);
} }
/* GL_NV_framebuffer_blit */
if (strstr((char *)pszGLExtensions, "GL_NV_framebuffer_blit"))
{
glBlitFramebufferNV = (PFNGLBLITFRAMEBUFFERNVPROC) PVRGetProcAddress(glBlitFramebufferNV);
}
/* GL_OES_texture_3D */ /* GL_OES_texture_3D */
if(strstr((char *)pszGLExtensions, "GL_OES_texture_3D")) if(strstr((char *)pszGLExtensions, "GL_OES_texture_3D"))
{ {
glTexImage3DOES = (PFNGLTEXIMAGE3DOES)PVRGetProcAddress(glTexImage3DOES); glTexImage3DOES = (PFNGLTEXIMAGE3DOES) PVRGetProcAddress(glTexImage3DOES);
glTexSubImage3DOES = (PFNGLTEXSUBIMAGE3DOES)PVRGetProcAddress(glTexSubImage3DOES); glTexSubImage3DOES = (PFNGLTEXSUBIMAGE3DOES) PVRGetProcAddress(glTexSubImage3DOES);
glCopyTexSubImage3DOES = (PFNGLCOPYTEXSUBIMAGE3DOES)PVRGetProcAddress(glCopyTexSubImage3DOES); glCopyTexSubImage3DOES = (PFNGLCOPYTEXSUBIMAGE3DOES) PVRGetProcAddress(glCopyTexSubImage3DOES);
glCompressedTexImage3DOES = (PFNGLCOMPRESSEDTEXIMAGE3DOES)PVRGetProcAddress(glCompressedTexImage3DOES); glCompressedTexImage3DOES = (PFNGLCOMPRESSEDTEXIMAGE3DOES) PVRGetProcAddress(glCompressedTexImage3DOES);
glCompressedTexSubImage3DOES = (PFNGLCOMPRESSEDTEXSUBIMAGE3DOES)PVRGetProcAddress(glCompressedTexSubImage3DOES); glCompressedTexSubImage3DOES = (PFNGLCOMPRESSEDTEXSUBIMAGE3DOES) PVRGetProcAddress(glCompressedTexSubImage3DOES);
glFramebufferTexture3DOES = (PFNGLFRAMEBUFFERTEXTURE3DOES)PVRGetProcAddress(glFramebufferTexture3DOES); glFramebufferTexture3DOES = (PFNGLFRAMEBUFFERTEXTURE3DOES) PVRGetProcAddress(glFramebufferTexture3DOES);
} }
/* GL_EXT_draw_buffers */ /* GL_EXT_draw_buffers */
......
...@@ -103,8 +103,9 @@ public: ...@@ -103,8 +103,9 @@ public:
typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMG) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMG) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMG) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMG) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXT) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXT) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERNVPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DOES) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels); typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DOES) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DOES) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels); typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DOES) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels);
...@@ -165,15 +166,23 @@ public: ...@@ -165,15 +166,23 @@ public:
PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMG glFramebufferTexture2DMultisampleIMG; PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMG glFramebufferTexture2DMultisampleIMG;
// GL_EXT_multisampled_render_to_texture // GL_EXT_multisampled_render_to_texture
#if !defined(GL_EXT_multisampled_render_to_texture) #if !defined(GL_ANGLE_framebuffer_multisample)
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C #define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB
#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 #define GL_MAX_SAMPLES_ANGLE 0x8D57
#define GL_MAX_SAMPLES_EXT 0x8D57
#endif #endif
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXT glRenderbufferStorageMultisampleEXT; PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC glRenderbufferStorageMultisampleANGLE;
PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXT glFramebufferTexture2DMultisampleEXT;
// GL_NV_framebuffer_blit
#if !defined(GL_NV_framebuffer_blit)
#define GL_READ_FRAMEBUFFER_NV 0x8CA8
#define GL_DRAW_FRAMEBUFFER_NV 0x8CA9
#define GL_DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6
#define GL_READ_FRAMEBUFFER_BINDING_NV 0x8CAA
#endif
PFNGLBLITFRAMEBUFFERNVPROC glBlitFramebufferNV;
// GL_OES_texture_3D // GL_OES_texture_3D
#if !defined(GL_OES_texture_3D) #if !defined(GL_OES_texture_3D)
...@@ -185,7 +194,6 @@ public: ...@@ -185,7 +194,6 @@ public:
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4
#endif #endif
PFNGLTEXIMAGE3DOES glTexImage3DOES; PFNGLTEXIMAGE3DOES glTexImage3DOES;
PFNGLTEXSUBIMAGE3DOES glTexSubImage3DOES; PFNGLTEXSUBIMAGE3DOES glTexSubImage3DOES;
PFNGLCOPYTEXSUBIMAGE3DOES glCopyTexSubImage3DOES; PFNGLCOPYTEXSUBIMAGE3DOES glCopyTexSubImage3DOES;
......
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