Commit 9c6d5222 by Alexis Hetu Committed by Nicolas Capens

Add support for borders around textures.

Borders are required to support seamless cubemap sampling. Subsequent patches will fill the borders with pixels from adjacent cube faces. The border is expressed in pixels and is added on all edges, resulting in an image of dimensions (width + 2 * border) x (height + 2 * border). The surface still exposes dimensions of width x height through the API and points to the same pixel when locked. Change-Id: I06d5121267ce1a2c50e628490d8690de71bfeb08 Reviewed-on: https://swiftshader-review.googlesource.com/8208Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent f8b827ef
......@@ -227,7 +227,7 @@ namespace D3D8
desc->Type = D3DRTYPE_SURFACE;
desc->Height = height;
desc->Width = width;
desc->Size = size(getWidth(), getHeight(), getDepth(), getExternalFormat());
desc->Size = size(getWidth(), getHeight(), getDepth(), 0, getExternalFormat());
desc->MultiSampleType = multiSample;
desc->Usage = usage;
......@@ -285,6 +285,6 @@ namespace D3D8
unsigned int Direct3DSurface8::memoryUsage(int width, int height, D3DFORMAT format)
{
return Surface::size(width, height, 1, translateFormat(format));
return Surface::size(width, height, 1, 0, translateFormat(format));
}
}
......@@ -144,8 +144,8 @@ namespace D3D8
return INVALIDCALL();
}
lockedVolume->RowPitch = pitchB(getWidth(), getExternalFormat(), false);
lockedVolume->SlicePitch = sliceB(getWidth(), getHeight(), getExternalFormat(), false);
lockedVolume->RowPitch = pitchB(getWidth(), 0, getExternalFormat(), false);
lockedVolume->SlicePitch = sliceB(getWidth(), getHeight(), 0, getExternalFormat(), false);
sw::Lock lock = sw::LOCK_READWRITE;
......@@ -194,6 +194,6 @@ namespace D3D8
unsigned int Direct3DVolume8::memoryUsage(int width, int height, int depth, D3DFORMAT format)
{
return Surface::size(width, height, depth, translateFormat(format));
return Surface::size(width, height, depth, 0, translateFormat(format));
}
}
......@@ -2660,7 +2660,7 @@ namespace D3D9
void *bitmap = cursorSurface->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
delete cursor;
cursor = sw::Surface::create(0, width, height, 1, sw::FORMAT_A8R8G8B8, false, false);
cursor = sw::Surface::create(nullptr, width, height, 1, 0, sw::FORMAT_A8R8G8B8, false, false);
void *buffer = cursor->lockExternal(0, 0, 0, sw::LOCK_DISCARD, sw::PUBLIC);
memcpy(buffer, bitmap, width * height * sizeof(unsigned int));
......@@ -2674,7 +2674,7 @@ namespace D3D9
}
else
{
sw::FrameBuffer::setCursorImage(0);
sw::FrameBuffer::setCursorImage(nullptr);
}
sw::FrameBuffer::setCursorOrigin(x0, y0);
......
......@@ -76,7 +76,8 @@ namespace D3D9
return (pool != D3DPOOL_DEFAULT) || (usage & D3DUSAGE_DYNAMIC) || lockableOverride;
}
Direct3DSurface9::Direct3DSurface9(Direct3DDevice9 *device, Unknown *container, int width, int height, D3DFORMAT format, D3DPOOL pool, D3DMULTISAMPLE_TYPE multiSample, unsigned int quality, bool lockableOverride, unsigned long usage) : Direct3DResource9(device, D3DRTYPE_SURFACE, pool, memoryUsage(width, height, format)), Surface(getParentResource(container), width, height, sampleCount(multiSample, quality), translateFormat(format), isLockable(pool, usage, lockableOverride), (usage & D3DUSAGE_RENDERTARGET) || (usage & D3DUSAGE_DEPTHSTENCIL)), container(container), width(width), height(height), format(format), pool(pool), multiSample(multiSample), quality(quality), lockable(isLockable(pool, usage, lockableOverride)), usage(usage)
Direct3DSurface9::Direct3DSurface9(Direct3DDevice9 *device, Unknown *container, int width, int height, D3DFORMAT format, D3DPOOL pool, D3DMULTISAMPLE_TYPE multiSample, unsigned int quality, bool lockableOverride, unsigned long usage)
: Direct3DResource9(device, D3DRTYPE_SURFACE, pool, memoryUsage(width, height, format)), Surface(getParentResource(container), width, height, sampleCount(multiSample, quality), 0, translateFormat(format), isLockable(pool, usage, lockableOverride), (usage & D3DUSAGE_RENDERTARGET) || (usage & D3DUSAGE_DEPTHSTENCIL)), container(container), width(width), height(height), format(format), pool(pool), multiSample(multiSample), quality(quality), lockable(isLockable(pool, usage, lockableOverride)), usage(usage)
{
parentTexture = dynamic_cast<Direct3DBaseTexture9*>(container);
}
......@@ -412,6 +413,6 @@ namespace D3D9
unsigned int Direct3DSurface9::memoryUsage(int width, int height, D3DFORMAT format)
{
return Surface::size(width, height, 1, translateFormat(format));
return Surface::size(width, height, 1, 0, translateFormat(format));
}
}
......@@ -30,7 +30,8 @@ namespace D3D9
return (pool != D3DPOOL_DEFAULT) || (usage & D3DUSAGE_DYNAMIC);
}
Direct3DVolume9::Direct3DVolume9(Direct3DDevice9 *device, Direct3DVolumeTexture9 *container, int width, int height, int depth, D3DFORMAT format, D3DPOOL pool, unsigned long usage) : device(device), Surface(container->getResource(), width, height, depth, translateFormat(format), isLockable(pool, usage), false), container(container), width(width), height(height), depth(depth), format(format), pool(pool), lockable(isLockable(pool, usage)), usage(usage)
Direct3DVolume9::Direct3DVolume9(Direct3DDevice9 *device, Direct3DVolumeTexture9 *container, int width, int height, int depth, D3DFORMAT format, D3DPOOL pool, unsigned long usage)
: device(device), Surface(container->getResource(), width, height, depth, 0, translateFormat(format), isLockable(pool, usage), false), container(container), width(width), height(height), depth(depth), format(format), pool(pool), lockable(isLockable(pool, usage)), usage(usage)
{
resource = new Direct3DResource9(device, D3DRTYPE_VOLUME, pool, memoryUsage(width, height, depth, format));
resource->bind();
......@@ -229,6 +230,6 @@ namespace D3D9
unsigned int Direct3DVolume9::memoryUsage(int width, int height, int depth, D3DFORMAT format)
{
return Surface::size(width, height, depth, translateFormat(format));
return Surface::size(width, height, depth, 0, translateFormat(format));
}
}
......@@ -1232,8 +1232,8 @@ namespace egl
public:
ImageImplementation(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
: Image(parentTexture, width, height, format, type) {}
ImageImplementation(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type)
: Image(parentTexture, width, height, depth, format, type) {}
ImageImplementation(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, int border, GLenum format, GLenum type)
: Image(parentTexture, width, height, depth, border, format, type) {}
ImageImplementation(GLsizei width, GLsizei height, GLenum format, GLenum type, int pitchP)
: Image(width, height, format, type, pitchP) {}
ImageImplementation(GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable)
......@@ -1265,9 +1265,9 @@ namespace egl
return new ImageImplementation(parentTexture, width, height, format, type);
}
Image *Image::create(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type)
Image *Image::create(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, int border, GLenum format, GLenum type)
{
return new ImageImplementation(parentTexture, width, height, depth, format, type);
return new ImageImplementation(parentTexture, width, height, depth, border, format, type);
}
Image *Image::create(GLsizei width, GLsizei height, GLenum format, GLenum type, int pitchP)
......
......@@ -52,7 +52,7 @@ class [[clang::lto_visibility_public]] Image : public sw::Surface, public gl::Ob
protected:
// 2D texture image
Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
: sw::Surface(parentTexture->getResource(), width, height, 1, SelectInternalFormat(format, type), true, true),
: sw::Surface(parentTexture->getResource(), width, height, 1, 0, SelectInternalFormat(format, type), true, true),
width(width), height(height), format(format), type(type), internalFormat(SelectInternalFormat(format, type)), depth(1),
parentTexture(parentTexture)
{
......@@ -61,9 +61,9 @@ protected:
parentTexture->addRef();
}
// 3D texture image
Image(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type)
: sw::Surface(parentTexture->getResource(), width, height, depth, SelectInternalFormat(format, type), true, true),
// 3D/Cube texture image
Image(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, int border, GLenum format, GLenum type)
: sw::Surface(parentTexture->getResource(), width, height, depth, border, SelectInternalFormat(format, type), true, true),
width(width), height(height), format(format), type(type), internalFormat(SelectInternalFormat(format, type)), depth(depth),
parentTexture(parentTexture)
{
......@@ -74,7 +74,7 @@ protected:
// Native EGL image
Image(GLsizei width, GLsizei height, GLenum format, GLenum type, int pitchP)
: sw::Surface(nullptr, width, height, 1, SelectInternalFormat(format, type), true, true, pitchP),
: sw::Surface(nullptr, width, height, 1, 0, SelectInternalFormat(format, type), true, true, pitchP),
width(width), height(height), format(format), type(type), internalFormat(SelectInternalFormat(format, type)), depth(1),
parentTexture(nullptr)
{
......@@ -84,7 +84,7 @@ protected:
// Render target
Image(GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable)
: sw::Surface(nullptr, width, height, multiSampleDepth, internalFormat, lockable, true),
: sw::Surface(nullptr, width, height, multiSampleDepth, 0, internalFormat, lockable, true),
width(width), height(height), format(0 /*GL_NONE*/), type(0 /*GL_NONE*/), internalFormat(internalFormat), depth(multiSampleDepth),
parentTexture(nullptr)
{
......@@ -96,8 +96,8 @@ public:
// 2D texture image
static Image *create(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type);
// 3D texture image
static Image *create(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type);
// 3D/Cube texture image
static Image *create(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, int border, GLenum format, GLenum type);
// Native EGL image
static Image *create(GLsizei width, GLsizei height, GLenum format, GLenum type, int pitchP);
......
......@@ -39,14 +39,14 @@ namespace gl
Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
: parentTexture(parentTexture), width(width), height(height), format(format), type(type)
, internalFormat(selectInternalFormat(format, type)), multiSampleDepth(1)
, sw::Surface(getParentResource(parentTexture), width, height, 1, selectInternalFormat(format, type), true, true)
, sw::Surface(getParentResource(parentTexture), width, height, 1, 0, selectInternalFormat(format, type), true, true)
{
referenceCount = 1;
}
Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable, bool renderTarget)
: parentTexture(parentTexture), width(width), height(height), internalFormat(internalFormat), format(0 /*GL_NONE*/), type(0 /*GL_NONE*/), multiSampleDepth(multiSampleDepth)
, sw::Surface(getParentResource(parentTexture), width, height, multiSampleDepth, internalFormat, lockable, renderTarget)
, sw::Surface(getParentResource(parentTexture), width, height, multiSampleDepth, 0, internalFormat, lockable, renderTarget)
{
referenceCount = 1;
}
......
......@@ -1128,7 +1128,8 @@ void TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum forma
}
GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
image[face][level] = egl::Image::create(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);
int border = (egl::getClientVersion() >= 3) ? 1 : 0;
image[face][level] = egl::Image::create(this, width, height, 1, border, sizedInternalFormat, GL_UNSIGNED_BYTE);
if(!image[face][level])
{
......@@ -1269,7 +1270,8 @@ void TextureCubeMap::setImage(egl::Context *context, GLenum target, GLint level,
image[face][level]->release();
}
image[face][level] = egl::Image::create(this, width, height, format, type);
int border = (egl::getClientVersion() >= 3) ? 1 : 0;
image[face][level] = egl::Image::create(this, width, height, 1, border, format, type);
if(!image[face][level])
{
......@@ -1297,7 +1299,8 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint
}
GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
image[face][level] = egl::Image::create(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);
int border = (egl::getClientVersion() >= 3) ? 1 : 0;
image[face][level] = egl::Image::create(this, width, height, 1, border, sizedInternalFormat, GL_UNSIGNED_BYTE);
if(!image[face][level])
{
......@@ -1391,7 +1394,8 @@ void TextureCubeMap::generateMipmaps()
image[f][i]->release();
}
image[f][i] = egl::Image::create(this, std::max(image[0][0]->getWidth() >> i, 1), std::max(image[0][0]->getHeight() >> i, 1), image[0][0]->getFormat(), image[0][0]->getType());
int border = (egl::getClientVersion() >= 3) ? 1 : 0;
image[f][i] = egl::Image::create(this, std::max(image[0][0]->getWidth() >> i, 1), std::max(image[0][0]->getHeight() >> i, 1), 1, border, image[0][0]->getFormat(), image[0][0]->getType());
if(!image[f][i])
{
......@@ -1592,7 +1596,7 @@ void Texture3D::setImage(egl::Context *context, GLint level, GLsizei width, GLsi
image[level]->release();
}
image[level] = egl::Image::create(this, width, height, depth, format, type);
image[level] = egl::Image::create(this, width, height, depth, 0, format, type);
if(!image[level])
{
......@@ -1615,7 +1619,7 @@ void Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GL
}
GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
image[level] = egl::Image::create(this, width, height, depth, sizedInternalFormat, GL_UNSIGNED_BYTE);
image[level] = egl::Image::create(this, width, height, depth, 0, sizedInternalFormat, GL_UNSIGNED_BYTE);
if(!image[level])
{
......@@ -1651,7 +1655,7 @@ void Texture3D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLint z,
}
GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
image[level] = egl::Image::create(this, width, height, depth, sizedInternalFormat, GL_UNSIGNED_BYTE);
image[level] = egl::Image::create(this, width, height, depth, 0, sizedInternalFormat, GL_UNSIGNED_BYTE);
if(!image[level])
{
......@@ -1829,7 +1833,7 @@ void Texture3D::generateMipmaps()
image[i]->release();
}
image[i] = egl::Image::create(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), std::max(image[0]->getDepth() >> i, 1), image[0]->getFormat(), image[0]->getType());
image[i] = egl::Image::create(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), std::max(image[0]->getDepth() >> i, 1), 0, image[0]->getFormat(), image[0]->getType());
if(!image[i])
{
......@@ -1928,7 +1932,7 @@ void Texture2DArray::generateMipmaps()
GLsizei w = std::max(image[0]->getWidth() >> i, 1);
GLsizei h = std::max(image[0]->getHeight() >> i, 1);
image[i] = egl::Image::create(this, w, h, depth, image[0]->getFormat(), image[0]->getType());
image[i] = egl::Image::create(this, w, h, depth, 0, image[0]->getFormat(), image[0]->getType());
if(!image[i])
{
......
......@@ -244,6 +244,7 @@ namespace sw
int pitchP;
int sliceB;
int sliceP;
int border;
Format format;
AtomicInt lock;
......@@ -252,11 +253,11 @@ namespace sw
protected:
Surface(int width, int height, int depth, Format format, void *pixels, int pitch, int slice);
Surface(Resource *texture, int width, int height, int depth, Format format, bool lockable, bool renderTarget, int pitchP = 0);
Surface(Resource *texture, int width, int height, int depth, int border, Format format, bool lockable, bool renderTarget, int pitchP = 0);
public:
static Surface *create(int width, int height, int depth, Format format, void *pixels, int pitch, int slice);
static Surface *create(Resource *texture, int width, int height, int depth, Format format, bool lockable, bool renderTarget, int pitchP = 0);
static Surface *create(Resource *texture, int width, int height, int depth, int border, Format format, bool lockable, bool renderTarget, int pitchP = 0);
virtual ~Surface() = 0;
......@@ -265,6 +266,7 @@ namespace sw
inline int getWidth() const;
inline int getHeight() const;
inline int getDepth() const;
inline int getBorder() const;
inline Format getFormat(bool internal = false) const;
inline int getPitchB(bool internal = false) const;
inline int getPitchP(bool internal = false) const;
......@@ -326,11 +328,11 @@ namespace sw
Resource *getResource();
static int bytes(Format format);
static int pitchB(int width, Format format, bool target);
static int pitchP(int width, Format format, bool target);
static int sliceB(int width, int height, Format format, bool target);
static int sliceP(int width, int height, Format format, bool target);
static unsigned int size(int width, int height, int depth, Format format); // FIXME: slice * depth
static int pitchB(int width, int border, Format format, bool target);
static int pitchP(int width, int border, Format format, bool target);
static int sliceB(int width, int height, int border, Format format, bool target);
static int sliceP(int width, int height, int border, Format format, bool target);
static unsigned int size(int width, int height, int depth, int border, Format format); // FIXME: slice * depth
static bool isStencil(Format format);
static bool isDepth(Format format);
......@@ -433,27 +435,27 @@ namespace sw
};
};
static void decodeR8G8B8(Buffer &destination, const Buffer &source);
static void decodeX1R5G5B5(Buffer &destination, const Buffer &source);
static void decodeA1R5G5B5(Buffer &destination, const Buffer &source);
static void decodeX4R4G4B4(Buffer &destination, const Buffer &source);
static void decodeA4R4G4B4(Buffer &destination, const Buffer &source);
static void decodeP8(Buffer &destination, const Buffer &source);
static void decodeR8G8B8(Buffer &destination, Buffer &source);
static void decodeX1R5G5B5(Buffer &destination, Buffer &source);
static void decodeA1R5G5B5(Buffer &destination, Buffer &source);
static void decodeX4R4G4B4(Buffer &destination, Buffer &source);
static void decodeA4R4G4B4(Buffer &destination, Buffer &source);
static void decodeP8(Buffer &destination, Buffer &source);
#if S3TC_SUPPORT
static void decodeDXT1(Buffer &internal, const Buffer &external);
static void decodeDXT3(Buffer &internal, const Buffer &external);
static void decodeDXT5(Buffer &internal, const Buffer &external);
static void decodeDXT1(Buffer &internal, Buffer &external);
static void decodeDXT3(Buffer &internal, Buffer &external);
static void decodeDXT5(Buffer &internal, Buffer &external);
#endif
static void decodeATI1(Buffer &internal, const Buffer &external);
static void decodeATI2(Buffer &internal, const Buffer &external);
static void decodeEAC(Buffer &internal, const Buffer &external, int nbChannels, bool isSigned);
static void decodeETC2(Buffer &internal, const Buffer &external, int nbAlphaBits, bool isSRGB);
static void decodeASTC(Buffer &internal, const Buffer &external, int xSize, int ySize, int zSize, bool isSRGB);
static void decodeATI1(Buffer &internal, Buffer &external);
static void decodeATI2(Buffer &internal, Buffer &external);
static void decodeEAC(Buffer &internal, Buffer &external, int nbChannels, bool isSigned);
static void decodeETC2(Buffer &internal, Buffer &external, int nbAlphaBits, bool isSRGB);
static void decodeASTC(Buffer &internal, Buffer &external, int xSize, int ySize, int zSize, bool isSRGB);
static void update(Buffer &destination, Buffer &source);
static void genericUpdate(Buffer &destination, Buffer &source);
static void *allocateBuffer(int width, int height, int depth, Format format);
static void *allocateBuffer(int width, int height, int depth, int border, Format format);
static void memfill4(void *buffer, int pattern, int bytes);
bool identicalFormats() const;
......@@ -509,6 +511,11 @@ namespace sw
return external.depth;
}
int Surface::getBorder() const
{
return internal.border;
}
Format Surface::getFormat(bool internal) const
{
return internal ? getInternalFormat() : getExternalFormat();
......
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