Commit 1beb1db8 by Jamie Madill

Enable unpack buffer support for initializing 2D textures in TexImage2D.

TRAC #23843 Signed-off-by: Geoff Lang Signed-off-by: Shannon Woods
parent efb2a6ff
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#include "libGLESv2/renderer/Renderer.h" #include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/renderer/TextureStorage.h" #include "libGLESv2/renderer/TextureStorage.h"
#include "libEGL/Surface.h" #include "libEGL/Surface.h"
#include "libGLESv2/Buffer.h"
#include "libGLESv2/renderer/BufferStorage.h"
namespace gl namespace gl
{ {
...@@ -273,13 +275,46 @@ void Texture::setImage(const PixelUnpackState &unpack, GLenum type, const void * ...@@ -273,13 +275,46 @@ void Texture::setImage(const PixelUnpackState &unpack, GLenum type, const void *
{ {
// We no longer need the "GLenum format" parameter to TexImage to determine what data format "pixels" contains. // We no longer need the "GLenum format" parameter to TexImage to determine what data format "pixels" contains.
// From our image internal format we know how many channels to expect, and "type" gives the format of pixel's components. // From our image internal format we know how many channels to expect, and "type" gives the format of pixel's components.
if (pixels != NULL) const void *pixelData = pixels;
if (unpack.pixelBuffer.id() != 0)
{
// Do a CPU readback here, if we have an unpack buffer bound and the fast GPU path is not supported
Buffer *pixelBuffer = unpack.pixelBuffer.get();
ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels);
const void *bufferData = pixelBuffer->getStorage()->getData();
pixelData = static_cast<const unsigned char *>(bufferData) + offset;
}
if (pixelData != NULL)
{ {
image->loadData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), unpack.alignment, type, pixels); image->loadData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), unpack.alignment, type, pixelData);
mDirtyImages = true; mDirtyImages = true;
} }
} }
bool Texture::fastUnpackPixels(const PixelUnpackState &unpack, const void *pixels, const Box &destArea,
GLenum sizedInternalFormat, GLenum type, GLint level)
{
if (destArea.width <= 0 && destArea.height <= 0 && destArea.depth <= 0)
{
return true;
}
// In order to perform the fast copy through the shader, we must have the right format, and be able
// to create a render target.
if (IsFastCopyBufferToTextureSupported(sizedInternalFormat, mRenderer->getCurrentClientVersion()))
{
unsigned int offset = reinterpret_cast<unsigned int>(pixels);
rx::RenderTarget *destRenderTarget = getStorage(true)->getStorageInstance()->getRenderTarget(level);
return mRenderer->fastCopyBufferToTexture(unpack, offset, destRenderTarget, sizedInternalFormat, type, destArea);
}
// Return false if we do not support fast unpack
return false;
}
void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, rx::Image *image) void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, rx::Image *image)
{ {
if (pixels != NULL) if (pixels != NULL)
...@@ -470,7 +505,18 @@ void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLint inter ...@@ -470,7 +505,18 @@ void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLint inter
: GetSizedInternalFormat(format, type, clientVersion); : GetSizedInternalFormat(format, type, clientVersion);
redefineImage(level, sizedInternalFormat, width, height); redefineImage(level, sizedInternalFormat, width, height);
// Attempt a fast gpu copy of the pixel data to the surface
// If we want to support rendering (which is necessary for GPU unpack buffers), level 0 must be complete
Box destArea(0, 0, 0, getWidth(level), getHeight(level), 1);
if (unpack.pixelBuffer.id() != 0 && isLevelComplete(0) && fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, level))
{
// Ensure we don't overwrite our newly initialized data
mImageArray[level]->markClean();
}
else
{
Texture::setImage(unpack, type, pixels, mImageArray[level]); Texture::setImage(unpack, type, pixels, mImageArray[level]);
}
} }
void Texture2D::bindTexImage(egl::Surface *surface) void Texture2D::bindTexImage(egl::Surface *surface)
......
...@@ -113,6 +113,8 @@ class Texture : public RefCountObject ...@@ -113,6 +113,8 @@ class Texture : public RefCountObject
void setCompressedImage(GLsizei imageSize, const void *pixels, rx::Image *image); void setCompressedImage(GLsizei imageSize, const void *pixels, rx::Image *image);
bool subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, bool subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLsizei imageSize, const void *pixels, rx::Image *image); GLenum format, GLsizei imageSize, const void *pixels, rx::Image *image);
bool fastUnpackPixels(const PixelUnpackState &unpack, const void *pixels, const Box &destArea,
GLenum sizedInternalFormat, GLenum type, GLint level);
GLint creationLevels(GLsizei width, GLsizei height, GLsizei depth) const; GLint creationLevels(GLsizei width, GLsizei height, GLsizei depth) const;
GLint creationLevels(GLsizei width, GLsizei height) const; GLint creationLevels(GLsizei width, GLsizei height) const;
......
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