Commit bfa23b3f by Nicolas Capens Committed by Nicolas Capens

Separate image depth and samples count.

Previously, multisampled images used the 'depth' member of 3D images or 2D arrays as the number of samples. This caused rendering to a layer of a 2D array to be interpreted as rendering to a multisampled render target. This change adds a 'samples' member which is orthogonal to 'depth'. Note that write operations put the same color into each of the samples, while read operations (still) assume multisampled images have been resolved into the first slice. Change-Id: Ib33a0cf8194e19fcbb569b0c257ba1e1bd9c4821 Reviewed-on: https://swiftshader-review.googlesource.com/14808Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 7f72df96
...@@ -2660,7 +2660,7 @@ namespace D3D9 ...@@ -2660,7 +2660,7 @@ namespace D3D9
void *bitmap = cursorSurface->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC); void *bitmap = cursorSurface->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
delete cursor; delete cursor;
cursor = sw::Surface::create(nullptr, width, height, 1, 0, sw::FORMAT_A8R8G8B8, false, false); cursor = sw::Surface::create(nullptr, width, height, 1, 0, 1, sw::FORMAT_A8R8G8B8, false, false);
void *buffer = cursor->lockExternal(0, 0, 0, sw::LOCK_DISCARD, sw::PUBLIC); void *buffer = cursor->lockExternal(0, 0, 0, sw::LOCK_DISCARD, sw::PUBLIC);
memcpy(buffer, bitmap, width * height * sizeof(unsigned int)); memcpy(buffer, bitmap, width * height * sizeof(unsigned int));
......
...@@ -77,7 +77,7 @@ namespace D3D9 ...@@ -77,7 +77,7 @@ namespace D3D9
} }
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) 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) : Direct3DResource9(device, D3DRTYPE_SURFACE, pool, memoryUsage(width, height, multiSample, quality, format)), Surface(getParentResource(container), width, height, 1, 0, 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)
{ {
parentTexture = dynamic_cast<Direct3DBaseTexture9*>(container); parentTexture = dynamic_cast<Direct3DBaseTexture9*>(container);
} }
...@@ -411,8 +411,8 @@ namespace D3D9 ...@@ -411,8 +411,8 @@ namespace D3D9
return Surface::bytes(translateFormat(format)); return Surface::bytes(translateFormat(format));
} }
unsigned int Direct3DSurface9::memoryUsage(int width, int height, D3DFORMAT format) unsigned int Direct3DSurface9::memoryUsage(int width, int height, D3DMULTISAMPLE_TYPE multiSample, unsigned int quality, D3DFORMAT format)
{ {
return Surface::size(width, height, 1, 0, translateFormat(format)); return Surface::size(width, height, 1, 0, sampleCount(multiSample, quality), translateFormat(format));
} }
} }
...@@ -64,7 +64,7 @@ namespace D3D9 ...@@ -64,7 +64,7 @@ namespace D3D9
static int bytes(D3DFORMAT format); static int bytes(D3DFORMAT format);
private: private:
static unsigned int memoryUsage(int width, int height, D3DFORMAT format); static unsigned int memoryUsage(int width, int height, D3DMULTISAMPLE_TYPE multiSample, unsigned int quality, D3DFORMAT format);
// Creation parameters // Creation parameters
Unknown *const container; Unknown *const container;
......
...@@ -31,7 +31,7 @@ namespace D3D9 ...@@ -31,7 +31,7 @@ namespace D3D9
} }
Direct3DVolume9::Direct3DVolume9(Direct3DDevice9 *device, Direct3DVolumeTexture9 *container, int width, int height, int depth, D3DFORMAT format, D3DPOOL pool, unsigned long 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) : device(device), Surface(container->getResource(), width, height, depth, 0, 1, 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 = new Direct3DResource9(device, D3DRTYPE_VOLUME, pool, memoryUsage(width, height, depth, format));
resource->bind(); resource->bind();
...@@ -230,6 +230,6 @@ namespace D3D9 ...@@ -230,6 +230,6 @@ namespace D3D9
unsigned int Direct3DVolume9::memoryUsage(int width, int height, int depth, D3DFORMAT format) unsigned int Direct3DVolume9::memoryUsage(int width, int height, int depth, D3DFORMAT format)
{ {
return Surface::size(width, height, depth, 0, translateFormat(format)); return Surface::size(width, height, depth, 0, 1, translateFormat(format));
} }
} }
...@@ -52,7 +52,7 @@ class [[clang::lto_visibility_public]] Image : public sw::Surface, public gl::Ob ...@@ -52,7 +52,7 @@ class [[clang::lto_visibility_public]] Image : public sw::Surface, public gl::Ob
protected: protected:
// 2D texture image // 2D texture image
Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type) Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
: sw::Surface(parentTexture->getResource(), width, height, 1, 0, SelectInternalFormat(format, type), true, true), : sw::Surface(parentTexture->getResource(), width, height, 1, 0, 1, SelectInternalFormat(format, type), true, true),
width(width), height(height), format(format), type(type), internalFormat(SelectInternalFormat(format, type)), depth(1), width(width), height(height), format(format), type(type), internalFormat(SelectInternalFormat(format, type)), depth(1),
parentTexture(parentTexture) parentTexture(parentTexture)
{ {
...@@ -63,7 +63,7 @@ protected: ...@@ -63,7 +63,7 @@ protected:
// 3D/Cube texture image // 3D/Cube texture image
Image(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, int border, GLenum format, GLenum type) 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), : sw::Surface(parentTexture->getResource(), width, height, depth, border, 1, SelectInternalFormat(format, type), true, true),
width(width), height(height), format(format), type(type), internalFormat(SelectInternalFormat(format, type)), depth(depth), width(width), height(height), format(format), type(type), internalFormat(SelectInternalFormat(format, type)), depth(depth),
parentTexture(parentTexture) parentTexture(parentTexture)
{ {
...@@ -74,7 +74,7 @@ protected: ...@@ -74,7 +74,7 @@ protected:
// Native EGL image // Native EGL image
Image(GLsizei width, GLsizei height, GLenum format, GLenum type, int pitchP) Image(GLsizei width, GLsizei height, GLenum format, GLenum type, int pitchP)
: sw::Surface(nullptr, width, height, 1, 0, SelectInternalFormat(format, type), true, true, pitchP), : sw::Surface(nullptr, width, height, 1, 0, 1, SelectInternalFormat(format, type), true, true, pitchP),
width(width), height(height), format(format), type(type), internalFormat(SelectInternalFormat(format, type)), depth(1), width(width), height(height), format(format), type(type), internalFormat(SelectInternalFormat(format, type)), depth(1),
parentTexture(nullptr) parentTexture(nullptr)
{ {
...@@ -84,8 +84,9 @@ protected: ...@@ -84,8 +84,9 @@ protected:
// Render target // Render target
Image(GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable) Image(GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable)
: sw::Surface(nullptr, width, height, multiSampleDepth, 0, internalFormat, lockable, true), : sw::Surface(nullptr, width, height, 1, 0, multiSampleDepth, internalFormat, lockable, true),
width(width), height(height), format(0 /*GL_NONE*/), type(0 /*GL_NONE*/), internalFormat(internalFormat), depth(multiSampleDepth), width(width), height(height), format(0 /*GL_NONE*/), type(0 /*GL_NONE*/), internalFormat(internalFormat),
depth(multiSampleDepth),
parentTexture(nullptr) parentTexture(nullptr)
{ {
shared = false; shared = false;
......
...@@ -39,14 +39,14 @@ namespace gl ...@@ -39,14 +39,14 @@ namespace gl
Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type) Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
: parentTexture(parentTexture), width(width), height(height), format(format), type(type) : parentTexture(parentTexture), width(width), height(height), format(format), type(type)
, internalFormat(selectInternalFormat(format, type)), multiSampleDepth(1) , internalFormat(selectInternalFormat(format, type)), multiSampleDepth(1)
, sw::Surface(getParentResource(parentTexture), width, height, 1, 0, selectInternalFormat(format, type), true, true) , sw::Surface(getParentResource(parentTexture), width, height, 1, 0, 1, selectInternalFormat(format, type), true, true)
{ {
referenceCount = 1; referenceCount = 1;
} }
Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable, bool renderTarget) 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) : 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, 0, internalFormat, lockable, renderTarget) , sw::Surface(getParentResource(parentTexture), width, height, 1, 0, multiSampleDepth, internalFormat, lockable, renderTarget)
{ {
referenceCount = 1; referenceCount = 1;
} }
......
...@@ -836,17 +836,18 @@ namespace es2 ...@@ -836,17 +836,18 @@ namespace es2
unsigned int destPitch = dest->getInternalPitchB(); unsigned int destPitch = dest->getInternalPitchB();
unsigned int bytes = dWidth * Surface::bytes(source->getInternalFormat()); unsigned int bytes = dWidth * Surface::bytes(source->getInternalFormat());
for(int z = 0; z < dDepth; ++z) for(int z = 0; z < dDepth; z++)
{ {
unsigned char *sourceBytes = (unsigned char*)source->lockInternal(0, 0, z, LOCK_READONLY, PUBLIC); unsigned char *sourceBytes = (unsigned char*)source->lockInternal(0, 0, z, LOCK_READONLY, PUBLIC);
unsigned char *destBytes = (unsigned char*)dest->lockInternal(0, 0, z, LOCK_READWRITE, PUBLIC); unsigned char *destBytes = (unsigned char*)dest->lockInternal(0, 0, z, LOCK_READWRITE, PUBLIC);
for(int y = 0; y < dHeight; ++y)
for(int y = 0; y < dHeight; y++)
{ {
memcpy(destBytes, sourceBytes, bytes); memcpy(destBytes, sourceBytes, bytes);
if(alpha0xFF) if(alpha0xFF)
{ {
for(int x = 0; x < dWidth; ++x) for(int x = 0; x < dWidth; x++)
{ {
destBytes[4 * x + 3] = 0xFF; destBytes[4 * x + 3] = 0xFF;
} }
...@@ -855,11 +856,11 @@ namespace es2 ...@@ -855,11 +856,11 @@ namespace es2
sourceBytes += sourcePitch; sourceBytes += sourcePitch;
destBytes += destPitch; destBytes += destPitch;
} }
}
source->unlockInternal(); source->unlockInternal();
dest->unlockInternal(); dest->unlockInternal();
} }
}
else else
{ {
blit3D(source, dest); blit3D(source, dest);
......
...@@ -30,7 +30,7 @@ namespace sw ...@@ -30,7 +30,7 @@ namespace sw
delete blitCache; delete blitCache;
} }
void Blitter::clear(void* pixel, sw::Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask) void Blitter::clear(void *pixel, sw::Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask)
{ {
if(fastClear(pixel, format, dest, dRect, rgbaMask)) if(fastClear(pixel, format, dest, dRect, rgbaMask))
{ {
...@@ -44,7 +44,7 @@ namespace sw ...@@ -44,7 +44,7 @@ namespace sw
delete color; delete color;
} }
bool Blitter::fastClear(void* pixel, sw::Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask) bool Blitter::fastClear(void *pixel, sw::Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask)
{ {
if(format != FORMAT_A32B32G32R32F) if(format != FORMAT_A32B32G32R32F)
{ {
...@@ -99,7 +99,11 @@ namespace sw ...@@ -99,7 +99,11 @@ namespace sw
return false; return false;
} }
uint8_t *d = (uint8_t*)dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, sw::LOCK_WRITEONLY, sw::PUBLIC); uint8_t *slice = (uint8_t*)dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, sw::LOCK_WRITEONLY, sw::PUBLIC);
for(int j = 0; j < dest->getSamples(); j++)
{
uint8_t *d = slice;
switch(Surface::bytes(dest->getFormat())) switch(Surface::bytes(dest->getFormat()))
{ {
...@@ -121,6 +125,9 @@ namespace sw ...@@ -121,6 +125,9 @@ namespace sw
assert(false); assert(false);
} }
slice += dest->getInternalSliceB();
}
dest->unlockInternal(); dest->unlockInternal();
return true; return true;
...@@ -1201,6 +1208,7 @@ namespace sw ...@@ -1201,6 +1208,7 @@ namespace sw
For(Int i = x0d, i < x1d, i++) For(Int i = x0d, i < x1d, i++)
{ {
Pointer<Byte> d = destLine + (dstQuadLayout ? (((j & Int(1)) << 1) + (i * 2) - (i & Int(1))) : RValue<Int>(i)) * dstBytes; Pointer<Byte> d = destLine + (dstQuadLayout ? (((j & Int(1)) << 1) + (i * 2) - (i & Int(1))) : RValue<Int>(i)) * dstBytes;
if(hasConstantColorI) if(hasConstantColorI)
{ {
if(!write(constantColorI, d, state.destFormat, state.options)) if(!write(constantColorI, d, state.destFormat, state.options))
...@@ -1281,10 +1289,20 @@ namespace sw ...@@ -1281,10 +1289,20 @@ namespace sw
(c10 * ix + c11 * fx) * fy; (c10 * ix + c11 * fx) * fy;
} }
if(!ApplyScaleAndClamp(color, state) || !write(color, d, state.destFormat, state.options)) if(!ApplyScaleAndClamp(color, state))
{ {
return nullptr; return nullptr;
} }
for(int s = 0; s < state.destSamples; s++)
{
if(!write(color, d, state.destFormat, state.options))
{
return nullptr;
}
d += *Pointer<Int>(blit + OFFSET(BlitData,dSliceB));
}
} }
if(!hasConstantColorI && !hasConstantColorF) { x += w; } if(!hasConstantColorI && !hasConstantColorF) { x += w; }
...@@ -1322,6 +1340,7 @@ namespace sw ...@@ -1322,6 +1340,7 @@ namespace sw
state.sourceFormat = isStencil ? source->getStencilFormat() : source->getFormat(useSourceInternal); state.sourceFormat = isStencil ? source->getStencilFormat() : source->getFormat(useSourceInternal);
state.destFormat = isStencil ? dest->getStencilFormat() : dest->getFormat(useDestInternal); state.destFormat = isStencil ? dest->getStencilFormat() : dest->getFormat(useDestInternal);
state.destSamples = dest->getSamples();
state.options = options; state.options = options;
criticalSection.lock(); criticalSection.lock();
...@@ -1355,6 +1374,7 @@ namespace sw ...@@ -1355,6 +1374,7 @@ namespace sw
dest->lock(0, 0, destRect.slice, isRGBA ? (isEntireDest ? sw::LOCK_DISCARD : sw::LOCK_WRITEONLY) : sw::LOCK_READWRITE, sw::PUBLIC, useDestInternal); dest->lock(0, 0, destRect.slice, isRGBA ? (isEntireDest ? sw::LOCK_DISCARD : sw::LOCK_WRITEONLY) : sw::LOCK_READWRITE, sw::PUBLIC, useDestInternal);
data.sPitchB = isStencil ? source->getStencilPitchB() : source->getPitchB(useSourceInternal); data.sPitchB = isStencil ? source->getStencilPitchB() : source->getPitchB(useSourceInternal);
data.dPitchB = isStencil ? dest->getStencilPitchB() : dest->getPitchB(useDestInternal); data.dPitchB = isStencil ? dest->getStencilPitchB() : dest->getPitchB(useDestInternal);
data.dSliceB = isStencil ? dest->getStencilSliceB() : dest->getSliceB(useDestInternal);
data.w = sRect.width() / dRect.width(); data.w = sRect.width() / dRect.width();
data.h = sRect.height() / dRect.height(); data.h = sRect.height() / dRect.height();
......
...@@ -47,6 +47,7 @@ namespace sw ...@@ -47,6 +47,7 @@ namespace sw
Format sourceFormat; Format sourceFormat;
Format destFormat; Format destFormat;
int destSamples;
Blitter::Options options; Blitter::Options options;
}; };
...@@ -56,6 +57,7 @@ namespace sw ...@@ -56,6 +57,7 @@ namespace sw
void *dest; void *dest;
int sPitchB; int sPitchB;
int dPitchB; int dPitchB;
int dSliceB;
float x0; float x0;
float y0; float y0;
...@@ -75,12 +77,12 @@ namespace sw ...@@ -75,12 +77,12 @@ namespace sw
Blitter(); Blitter();
virtual ~Blitter(); virtual ~Blitter();
void clear(void* pixel, sw::Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask); void clear(void *pixel, sw::Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask);
void blit(Surface *source, const SliceRectF &sRect, Surface *dest, const SliceRect &dRect, bool filter, bool isStencil = false); void blit(Surface *source, const SliceRectF &sRect, Surface *dest, const SliceRect &dRect, bool filter, bool isStencil = false);
void blit3D(Surface *source, Surface *dest); void blit3D(Surface *source, Surface *dest);
private: private:
bool fastClear(void* pixel, sw::Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask); bool fastClear(void *pixel, sw::Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask);
bool read(Float4 &color, Pointer<Byte> element, Format format); bool read(Float4 &color, Pointer<Byte> element, Format format);
bool write(Float4 &color, Pointer<Byte> element, Format format, const Blitter::Options& options); bool write(Float4 &color, Pointer<Byte> element, Format format, const Blitter::Options& options);
......
...@@ -606,7 +606,8 @@ namespace sw ...@@ -606,7 +606,8 @@ namespace sw
if(draw->renderTarget[index]) if(draw->renderTarget[index])
{ {
data->colorBuffer[index] = (unsigned int*)context->renderTarget[index]->lockInternal(0, 0, q * ms, LOCK_READWRITE, MANAGED); data->colorBuffer[index] = (unsigned int*)context->renderTarget[index]->lockInternal(0, 0, 0, LOCK_READWRITE, MANAGED);
data->colorBuffer[index] += q * ms * context->renderTarget[index]->getSliceB(true);
data->colorPitchB[index] = context->renderTarget[index]->getInternalPitchB(); data->colorPitchB[index] = context->renderTarget[index]->getInternalPitchB();
data->colorSliceB[index] = context->renderTarget[index]->getInternalSliceB(); data->colorSliceB[index] = context->renderTarget[index]->getInternalSliceB();
} }
...@@ -617,14 +618,16 @@ namespace sw ...@@ -617,14 +618,16 @@ namespace sw
if(draw->depthBuffer) if(draw->depthBuffer)
{ {
data->depthBuffer = (float*)context->depthBuffer->lockInternal(0, 0, q * ms, LOCK_READWRITE, MANAGED); data->depthBuffer = (float*)context->depthBuffer->lockInternal(0, 0, 0, LOCK_READWRITE, MANAGED);
data->depthBuffer += q * ms * context->depthBuffer->getSliceB(true);
data->depthPitchB = context->depthBuffer->getInternalPitchB(); data->depthPitchB = context->depthBuffer->getInternalPitchB();
data->depthSliceB = context->depthBuffer->getInternalSliceB(); data->depthSliceB = context->depthBuffer->getInternalSliceB();
} }
if(draw->stencilBuffer) if(draw->stencilBuffer)
{ {
data->stencilBuffer = (unsigned char*)context->stencilBuffer->lockStencil(0, 0, q * ms, MANAGED); data->stencilBuffer = (unsigned char*)context->stencilBuffer->lockStencil(0, 0, 0, MANAGED);
data->stencilBuffer += q * ms * context->stencilBuffer->getSliceB(true);
data->stencilPitchB = context->stencilBuffer->getStencilPitchB(); data->stencilPitchB = context->stencilBuffer->getStencilPitchB();
data->stencilSliceB = context->stencilBuffer->getStencilSliceB(); data->stencilSliceB = context->stencilBuffer->getStencilSliceB();
} }
...@@ -673,13 +676,7 @@ namespace sw ...@@ -673,13 +676,7 @@ namespace sw
void Renderer::clear(void *value, Format format, Surface *dest, const Rect &clearRect, unsigned int rgbaMask) void Renderer::clear(void *value, Format format, Surface *dest, const Rect &clearRect, unsigned int rgbaMask)
{ {
SliceRect rect = clearRect; blitter->clear(value, format, dest, clearRect, rgbaMask);
int samples = dest->getDepth();
for(rect.slice = 0; rect.slice < samples; rect.slice++)
{
blitter->clear(value, format, dest, rect, rgbaMask);
}
} }
void Renderer::blit(Surface *source, const SliceRectF &sRect, Surface *dest, const SliceRect &dRect, bool filter, bool isStencil) void Renderer::blit(Surface *source, const SliceRectF &sRect, Surface *dest, const SliceRect &dRect, bool filter, bool isStencil)
......
...@@ -44,16 +44,24 @@ namespace sw ...@@ -44,16 +44,24 @@ namespace sw
void Surface::Buffer::write(int x, int y, int z, const Color<float> &color) void Surface::Buffer::write(int x, int y, int z, const Color<float> &color)
{ {
void *element = (unsigned char*)buffer + (x + border) * bytes + (y + border) * pitchB + z * sliceB; byte *element = (byte*)buffer + (x + border) * bytes + (y + border) * pitchB + z * samples * sliceB;
for(int i = 0; i < samples; i++)
{
write(element, color); write(element, color);
element += sliceB;
}
} }
void Surface::Buffer::write(int x, int y, const Color<float> &color) void Surface::Buffer::write(int x, int y, const Color<float> &color)
{ {
void *element = (unsigned char*)buffer + (x + border) * bytes + (y + border) * pitchB; byte *element = (byte*)buffer + (x + border) * bytes + (y + border) * pitchB;
for(int i = 0; i < samples; i++)
{
write(element, color); write(element, color);
element += sliceB;
}
} }
inline void Surface::Buffer::write(void *element, const Color<float> &color) inline void Surface::Buffer::write(void *element, const Color<float> &color)
...@@ -365,7 +373,7 @@ namespace sw ...@@ -365,7 +373,7 @@ namespace sw
Color<float> Surface::Buffer::read(int x, int y, int z) const Color<float> Surface::Buffer::read(int x, int y, int z) const
{ {
void *element = (unsigned char*)buffer + (x + border) * bytes + (y + border) * pitchB + z * sliceB; void *element = (unsigned char*)buffer + (x + border) * bytes + (y + border) * pitchB + z * samples * sliceB;
return read(element); return read(element);
} }
...@@ -1039,7 +1047,7 @@ namespace sw ...@@ -1039,7 +1047,7 @@ namespace sw
return c000 + c100 + c010 + c110 + c001 + c101 + c011 + c111; return c000 + c100 + c010 + c110 + c001 + c101 + c011 + c111;
} }
Color<float> Surface::Buffer::sample(float x, float y) const Color<float> Surface::Buffer::sample(float x, float y, int layer) const
{ {
x -= 0.5f; x -= 0.5f;
y -= 0.5f; y -= 0.5f;
...@@ -1050,10 +1058,10 @@ namespace sw ...@@ -1050,10 +1058,10 @@ namespace sw
int y0 = clamp((int)y, 0, height - 1); int y0 = clamp((int)y, 0, height - 1);
int y1 = (y0 + 1 >= height) ? y0 : y0 + 1; int y1 = (y0 + 1 >= height) ? y0 : y0 + 1;
Color<float> c00 = read(x0, y0); Color<float> c00 = read(x0, y0, layer);
Color<float> c10 = read(x1, y0); Color<float> c10 = read(x1, y0, layer);
Color<float> c01 = read(x0, y1); Color<float> c01 = read(x0, y1, layer);
Color<float> c11 = read(x1, y1); Color<float> c11 = read(x1, y1, layer);
float fx = x - x0; float fx = x - x0;
float fy = y - y0; float fy = y - y0;
...@@ -1156,11 +1164,11 @@ namespace sw ...@@ -1156,11 +1164,11 @@ namespace sw
case FORMAT_ATI2: case FORMAT_ATI2:
return (unsigned char*)buffer + 16 * (x / 4) + (y / 4) * pitchB + z * sliceB; return (unsigned char*)buffer + 16 * (x / 4) + (y / 4) * pitchB + z * sliceB;
default: default:
return (unsigned char*)buffer + x * bytes + y * pitchB + z * sliceB; return (unsigned char*)buffer + x * bytes + y * pitchB + z * samples * sliceB;
} }
} }
return 0; return nullptr;
} }
void Surface::Buffer::unlockRect() void Surface::Buffer::unlockRect()
...@@ -1173,8 +1181,8 @@ namespace sw ...@@ -1173,8 +1181,8 @@ namespace sw
public: public:
SurfaceImplementation(int width, int height, int depth, Format format, void *pixels, int pitch, int slice) SurfaceImplementation(int width, int height, int depth, Format format, void *pixels, int pitch, int slice)
: Surface(width, height, depth, format, pixels, pitch, slice) {} : Surface(width, height, depth, format, pixels, pitch, slice) {}
SurfaceImplementation(Resource *texture, int width, int height, int depth, int border, Format format, bool lockable, bool renderTarget, int pitchP = 0) SurfaceImplementation(Resource *texture, int width, int height, int depth, int border, int samples, Format format, bool lockable, bool renderTarget, int pitchP = 0)
: Surface(texture, width, height, depth, border, format, lockable, renderTarget, pitchP) {} : Surface(texture, width, height, depth, border, samples, format, lockable, renderTarget, pitchP) {}
~SurfaceImplementation() override {}; ~SurfaceImplementation() override {};
void *lockInternal(int x, int y, int z, Lock lock, Accessor client) override void *lockInternal(int x, int y, int z, Lock lock, Accessor client) override
...@@ -1193,9 +1201,9 @@ namespace sw ...@@ -1193,9 +1201,9 @@ namespace sw
return new SurfaceImplementation(width, height, depth, format, pixels, pitch, slice); return new SurfaceImplementation(width, height, depth, format, pixels, pitch, slice);
} }
Surface *Surface::create(Resource *texture, int width, int height, int depth, int border, Format format, bool lockable, bool renderTarget, int pitchPprovided) Surface *Surface::create(Resource *texture, int width, int height, int depth, int border, int samples, Format format, bool lockable, bool renderTarget, int pitchPprovided)
{ {
return new SurfaceImplementation(texture, width, height, depth, border, format, lockable, renderTarget, pitchPprovided); return new SurfaceImplementation(texture, width, height, depth, border, samples, format, lockable, renderTarget, pitchPprovided);
} }
Surface::Surface(int width, int height, int depth, Format format, void *pixels, int pitch, int slice) : lockable(true), renderTarget(false) Surface::Surface(int width, int height, int depth, Format format, void *pixels, int pitch, int slice) : lockable(true), renderTarget(false)
...@@ -1209,6 +1217,7 @@ namespace sw ...@@ -1209,6 +1217,7 @@ namespace sw
external.width = width; external.width = width;
external.height = height; external.height = height;
external.depth = depth; external.depth = depth;
external.samples = 1;
external.format = format; external.format = format;
external.bytes = bytes(external.format); external.bytes = bytes(external.format);
external.pitchB = pitch; external.pitchB = pitch;
...@@ -1223,6 +1232,7 @@ namespace sw ...@@ -1223,6 +1232,7 @@ namespace sw
internal.width = width; internal.width = width;
internal.height = height; internal.height = height;
internal.depth = depth; internal.depth = depth;
internal.samples = 1;
internal.format = selectInternalFormat(format); internal.format = selectInternalFormat(format);
internal.bytes = bytes(internal.format); internal.bytes = bytes(internal.format);
internal.pitchB = pitchB(internal.width, 0, internal.format, false); internal.pitchB = pitchB(internal.width, 0, internal.format, false);
...@@ -1237,6 +1247,7 @@ namespace sw ...@@ -1237,6 +1247,7 @@ namespace sw
stencil.width = width; stencil.width = width;
stencil.height = height; stencil.height = height;
stencil.depth = depth; stencil.depth = depth;
stencil.samples = 1;
stencil.format = isStencil(format) ? FORMAT_S8 : FORMAT_NULL; stencil.format = isStencil(format) ? FORMAT_S8 : FORMAT_NULL;
stencil.bytes = bytes(stencil.format); stencil.bytes = bytes(stencil.format);
stencil.pitchB = pitchB(stencil.width, 0, stencil.format, false); stencil.pitchB = pitchB(stencil.width, 0, stencil.format, false);
...@@ -1251,17 +1262,19 @@ namespace sw ...@@ -1251,17 +1262,19 @@ namespace sw
paletteUsed = 0; paletteUsed = 0;
} }
Surface::Surface(Resource *texture, int width, int height, int depth, int border, Format format, bool lockable, bool renderTarget, int pitchPprovided) : lockable(lockable), renderTarget(renderTarget) Surface::Surface(Resource *texture, int width, int height, int depth, int border, int samples, Format format, bool lockable, bool renderTarget, int pitchPprovided) : lockable(lockable), renderTarget(renderTarget)
{ {
resource = texture ? texture : new Resource(0); resource = texture ? texture : new Resource(0);
hasParent = texture != nullptr; hasParent = texture != nullptr;
ownExternal = true; ownExternal = true;
depth = max(1, depth); depth = max(1, depth);
samples = max(1, samples);
external.buffer = nullptr; external.buffer = nullptr;
external.width = width; external.width = width;
external.height = height; external.height = height;
external.depth = depth; external.depth = depth;
external.samples = (short)samples;
external.format = format; external.format = format;
external.bytes = bytes(external.format); external.bytes = bytes(external.format);
external.pitchB = pitchB(external.width, 0, external.format, renderTarget && !texture); external.pitchB = pitchB(external.width, 0, external.format, renderTarget && !texture);
...@@ -1276,13 +1289,14 @@ namespace sw ...@@ -1276,13 +1289,14 @@ namespace sw
internal.width = width; internal.width = width;
internal.height = height; internal.height = height;
internal.depth = depth; internal.depth = depth;
internal.samples = (short)samples;
internal.format = selectInternalFormat(format); internal.format = selectInternalFormat(format);
internal.bytes = bytes(internal.format); internal.bytes = bytes(internal.format);
internal.pitchB = !pitchPprovided ? pitchB(internal.width, border, internal.format, renderTarget) : pitchPprovided * internal.bytes; internal.pitchB = !pitchPprovided ? pitchB(internal.width, border, internal.format, renderTarget) : pitchPprovided * internal.bytes;
internal.pitchP = !pitchPprovided ? pitchP(internal.width, border, internal.format, renderTarget) : pitchPprovided; internal.pitchP = !pitchPprovided ? pitchP(internal.width, border, internal.format, renderTarget) : pitchPprovided;
internal.sliceB = sliceB(internal.width, internal.height, border, internal.format, renderTarget); internal.sliceB = sliceB(internal.width, internal.height, border, internal.format, renderTarget);
internal.sliceP = sliceP(internal.width, internal.height, border, internal.format, renderTarget); internal.sliceP = sliceP(internal.width, internal.height, border, internal.format, renderTarget);
internal.border = border; internal.border = (short)border;
internal.lock = LOCK_UNLOCKED; internal.lock = LOCK_UNLOCKED;
internal.dirty = false; internal.dirty = false;
...@@ -1290,6 +1304,7 @@ namespace sw ...@@ -1290,6 +1304,7 @@ namespace sw
stencil.width = width; stencil.width = width;
stencil.height = height; stencil.height = height;
stencil.depth = depth; stencil.depth = depth;
stencil.samples = (short)samples;
stencil.format = isStencil(format) ? FORMAT_S8 : FORMAT_NULL; stencil.format = isStencil(format) ? FORMAT_S8 : FORMAT_NULL;
stencil.bytes = bytes(stencil.format); stencil.bytes = bytes(stencil.format);
stencil.pitchB = pitchB(stencil.width, 0, stencil.format, renderTarget); stencil.pitchB = pitchB(stencil.width, 0, stencil.format, renderTarget);
...@@ -1344,7 +1359,7 @@ namespace sw ...@@ -1344,7 +1359,7 @@ namespace sw
} }
else else
{ {
external.buffer = allocateBuffer(external.width, external.height, external.depth, external.border, external.format); external.buffer = allocateBuffer(external.width, external.height, external.depth, external.border, external.samples, external.format);
} }
} }
...@@ -1396,7 +1411,7 @@ namespace sw ...@@ -1396,7 +1411,7 @@ namespace sw
} }
else else
{ {
internal.buffer = allocateBuffer(internal.width, internal.height, internal.depth, internal.border, internal.format); internal.buffer = allocateBuffer(internal.width, internal.height, internal.depth, internal.border, internal.samples, internal.format);
} }
} }
...@@ -1471,7 +1486,7 @@ namespace sw ...@@ -1471,7 +1486,7 @@ namespace sw
if(!stencil.buffer) if(!stencil.buffer)
{ {
stencil.buffer = allocateBuffer(stencil.width, stencil.height, stencil.depth, stencil.border, stencil.format); stencil.buffer = allocateBuffer(stencil.width, stencil.height, stencil.depth, stencil.border, stencil.samples, stencil.format);
} }
return stencil.lockRect(x, y, front, LOCK_READWRITE); // FIXME return stencil.lockRect(x, y, front, LOCK_READWRITE); // FIXME
...@@ -1931,17 +1946,21 @@ namespace sw ...@@ -1931,17 +1946,21 @@ namespace sw
unsigned char *sourceSlice = (unsigned char*)source.lockRect(0, 0, 0, sw::LOCK_READONLY); unsigned char *sourceSlice = (unsigned char*)source.lockRect(0, 0, 0, sw::LOCK_READONLY);
unsigned char *destinationSlice = (unsigned char*)destination.lockRect(0, 0, 0, sw::LOCK_WRITEONLY); unsigned char *destinationSlice = (unsigned char*)destination.lockRect(0, 0, 0, sw::LOCK_WRITEONLY);
for(int z = 0; z < destination.depth && z < source.depth; z++) int depth = min(destination.depth, source.depth);
int height = min(destination.height, source.height);
int width = min(destination.width, source.width);
for(int z = 0; z < depth; z++)
{ {
unsigned char *sourceRow = sourceSlice; unsigned char *sourceRow = sourceSlice;
unsigned char *destinationRow = destinationSlice; unsigned char *destinationRow = destinationSlice;
for(int y = 0; y < destination.height && y < source.height; y++) for(int y = 0; y < height; y++)
{ {
unsigned char *sourceElement = sourceRow; unsigned char *sourceElement = sourceRow;
unsigned char *destinationElement = destinationRow; unsigned char *destinationElement = destinationRow;
for(int x = 0; x < destination.width && x < source.width; x++) for(int x = 0; x < width; x++)
{ {
unsigned int b = sourceElement[0]; unsigned int b = sourceElement[0];
unsigned int g = sourceElement[1]; unsigned int g = sourceElement[1];
...@@ -1970,17 +1989,21 @@ namespace sw ...@@ -1970,17 +1989,21 @@ namespace sw
unsigned char *sourceSlice = (unsigned char*)source.lockRect(0, 0, 0, sw::LOCK_READONLY); unsigned char *sourceSlice = (unsigned char*)source.lockRect(0, 0, 0, sw::LOCK_READONLY);
unsigned char *destinationSlice = (unsigned char*)destination.lockRect(0, 0, 0, sw::LOCK_WRITEONLY); unsigned char *destinationSlice = (unsigned char*)destination.lockRect(0, 0, 0, sw::LOCK_WRITEONLY);
for(int z = 0; z < destination.depth && z < source.depth; z++) int depth = min(destination.depth, source.depth);
int height = min(destination.height, source.height);
int width = min(destination.width, source.width);
for(int z = 0; z < depth; z++)
{ {
unsigned char *sourceRow = sourceSlice; unsigned char *sourceRow = sourceSlice;
unsigned char *destinationRow = destinationSlice; unsigned char *destinationRow = destinationSlice;
for(int y = 0; y < destination.height && y < source.height; y++) for(int y = 0; y < height; y++)
{ {
unsigned char *sourceElement = sourceRow; unsigned char *sourceElement = sourceRow;
unsigned char *destinationElement = destinationRow; unsigned char *destinationElement = destinationRow;
for(int x = 0; x < destination.width && x < source.width; x++) for(int x = 0; x < width; x++)
{ {
unsigned int xrgb = *(unsigned short*)sourceElement; unsigned int xrgb = *(unsigned short*)sourceElement;
...@@ -2011,17 +2034,21 @@ namespace sw ...@@ -2011,17 +2034,21 @@ namespace sw
unsigned char *sourceSlice = (unsigned char*)source.lockRect(0, 0, 0, sw::LOCK_READONLY); unsigned char *sourceSlice = (unsigned char*)source.lockRect(0, 0, 0, sw::LOCK_READONLY);
unsigned char *destinationSlice = (unsigned char*)destination.lockRect(0, 0, 0, sw::LOCK_WRITEONLY); unsigned char *destinationSlice = (unsigned char*)destination.lockRect(0, 0, 0, sw::LOCK_WRITEONLY);
for(int z = 0; z < destination.depth && z < source.depth; z++) int depth = min(destination.depth, source.depth);
int height = min(destination.height, source.height);
int width = min(destination.width, source.width);
for(int z = 0; z < depth; z++)
{ {
unsigned char *sourceRow = sourceSlice; unsigned char *sourceRow = sourceSlice;
unsigned char *destinationRow = destinationSlice; unsigned char *destinationRow = destinationSlice;
for(int y = 0; y < destination.height && y < source.height; y++) for(int y = 0; y < height; y++)
{ {
unsigned char *sourceElement = sourceRow; unsigned char *sourceElement = sourceRow;
unsigned char *destinationElement = destinationRow; unsigned char *destinationElement = destinationRow;
for(int x = 0; x < destination.width && x < source.width; x++) for(int x = 0; x < width; x++)
{ {
unsigned int argb = *(unsigned short*)sourceElement; unsigned int argb = *(unsigned short*)sourceElement;
...@@ -2053,17 +2080,21 @@ namespace sw ...@@ -2053,17 +2080,21 @@ namespace sw
unsigned char *sourceSlice = (unsigned char*)source.lockRect(0, 0, 0, sw::LOCK_READONLY); unsigned char *sourceSlice = (unsigned char*)source.lockRect(0, 0, 0, sw::LOCK_READONLY);
unsigned char *destinationSlice = (unsigned char*)destination.lockRect(0, 0, 0, sw::LOCK_WRITEONLY); unsigned char *destinationSlice = (unsigned char*)destination.lockRect(0, 0, 0, sw::LOCK_WRITEONLY);
for(int z = 0; z < destination.depth && z < source.depth; z++) int depth = min(destination.depth, source.depth);
int height = min(destination.height, source.height);
int width = min(destination.width, source.width);
for(int z = 0; z < depth; z++)
{ {
unsigned char *sourceRow = sourceSlice; unsigned char *sourceRow = sourceSlice;
unsigned char *destinationRow = destinationSlice; unsigned char *destinationRow = destinationSlice;
for(int y = 0; y < destination.height && y < source.height; y++) for(int y = 0; y < height; y++)
{ {
unsigned char *sourceElement = sourceRow; unsigned char *sourceElement = sourceRow;
unsigned char *destinationElement = destinationRow; unsigned char *destinationElement = destinationRow;
for(int x = 0; x < destination.width && x < source.width; x++) for(int x = 0; x < width; x++)
{ {
unsigned int xrgb = *(unsigned short*)sourceElement; unsigned int xrgb = *(unsigned short*)sourceElement;
...@@ -2094,17 +2125,21 @@ namespace sw ...@@ -2094,17 +2125,21 @@ namespace sw
unsigned char *sourceSlice = (unsigned char*)source.lockRect(0, 0, 0, sw::LOCK_READONLY); unsigned char *sourceSlice = (unsigned char*)source.lockRect(0, 0, 0, sw::LOCK_READONLY);
unsigned char *destinationSlice = (unsigned char*)destination.lockRect(0, 0, 0, sw::LOCK_WRITEONLY); unsigned char *destinationSlice = (unsigned char*)destination.lockRect(0, 0, 0, sw::LOCK_WRITEONLY);
for(int z = 0; z < destination.depth && z < source.depth; z++) int depth = min(destination.depth, source.depth);
int height = min(destination.height, source.height);
int width = min(destination.width, source.width);
for(int z = 0; z < depth; z++)
{ {
unsigned char *sourceRow = sourceSlice; unsigned char *sourceRow = sourceSlice;
unsigned char *destinationRow = destinationSlice; unsigned char *destinationRow = destinationSlice;
for(int y = 0; y < destination.height && y < source.height; y++) for(int y = 0; y < height; y++)
{ {
unsigned char *sourceElement = sourceRow; unsigned char *sourceElement = sourceRow;
unsigned char *destinationElement = destinationRow; unsigned char *destinationElement = destinationRow;
for(int x = 0; x < destination.width && x < source.width; x++) for(int x = 0; x < width; x++)
{ {
unsigned int argb = *(unsigned short*)sourceElement; unsigned int argb = *(unsigned short*)sourceElement;
...@@ -2136,17 +2171,21 @@ namespace sw ...@@ -2136,17 +2171,21 @@ namespace sw
unsigned char *sourceSlice = (unsigned char*)source.lockRect(0, 0, 0, sw::LOCK_READONLY); unsigned char *sourceSlice = (unsigned char*)source.lockRect(0, 0, 0, sw::LOCK_READONLY);
unsigned char *destinationSlice = (unsigned char*)destination.lockRect(0, 0, 0, sw::LOCK_WRITEONLY); unsigned char *destinationSlice = (unsigned char*)destination.lockRect(0, 0, 0, sw::LOCK_WRITEONLY);
for(int z = 0; z < destination.depth && z < source.depth; z++) int depth = min(destination.depth, source.depth);
int height = min(destination.height, source.height);
int width = min(destination.width, source.width);
for(int z = 0; z < depth; z++)
{ {
unsigned char *sourceRow = sourceSlice; unsigned char *sourceRow = sourceSlice;
unsigned char *destinationRow = destinationSlice; unsigned char *destinationRow = destinationSlice;
for(int y = 0; y < destination.height && y < source.height; y++) for(int y = 0; y < height; y++)
{ {
unsigned char *sourceElement = sourceRow; unsigned char *sourceElement = sourceRow;
unsigned char *destinationElement = destinationRow; unsigned char *destinationElement = destinationRow;
for(int x = 0; x < destination.width && x < source.width; x++) for(int x = 0; x < width; x++)
{ {
unsigned int abgr = palette[*(unsigned char*)sourceElement]; unsigned int abgr = palette[*(unsigned char*)sourceElement];
...@@ -2581,7 +2620,7 @@ namespace sw ...@@ -2581,7 +2620,7 @@ namespace sw
{ {
} }
unsigned int Surface::size(int width, int height, int depth, int border, Format format) unsigned int Surface::size(int width, int height, int depth, int border, int samples, Format format)
{ {
width += 2 * border; width += 2 * border;
height += 2 * border; height += 2 * border;
...@@ -2667,7 +2706,7 @@ namespace sw ...@@ -2667,7 +2706,7 @@ namespace sw
return YSize + 2 * CSize; return YSize + 2 * CSize;
} }
default: default:
return bytes(format) * width * height * depth; return bytes(format) * width * height * depth * samples;
} }
} }
...@@ -3184,7 +3223,7 @@ namespace sw ...@@ -3184,7 +3223,7 @@ namespace sw
return 1; return 1;
} }
void *Surface::allocateBuffer(int width, int height, int depth, int border, Format format) void *Surface::allocateBuffer(int width, int height, int depth, int border, int samples, Format format)
{ {
// Render targets require 2x2 quads // Render targets require 2x2 quads
int width2 = (width + 1) & ~1; int width2 = (width + 1) & ~1;
...@@ -3193,7 +3232,7 @@ namespace sw ...@@ -3193,7 +3232,7 @@ namespace sw
// FIXME: Unpacking byte4 to short4 in the sampler currently involves reading 8 bytes, // FIXME: Unpacking byte4 to short4 in the sampler currently involves reading 8 bytes,
// and stencil operations also read 8 bytes per four 8-bit stencil values, // and stencil operations also read 8 bytes per four 8-bit stencil values,
// so we have to allocate 4 extra bytes to avoid buffer overruns. // so we have to allocate 4 extra bytes to avoid buffer overruns.
return allocate(size(width2, height2, depth, border, format) + 4); return allocate(size(width2, height2, depth, border, samples, format) + 4);
} }
void Surface::memfill4(void *buffer, int pattern, int bytes) void Surface::memfill4(void *buffer, int pattern, int bytes)
...@@ -3308,7 +3347,7 @@ namespace sw ...@@ -3308,7 +3347,7 @@ namespace sw
{ {
float *target = (float*)lockInternal(0, 0, 0, lock, PUBLIC) + x0 + width2 * y0; float *target = (float*)lockInternal(0, 0, 0, lock, PUBLIC) + x0 + width2 * y0;
for(int z = 0; z < internal.depth; z++) for(int z = 0; z < internal.samples; z++)
{ {
for(int y = y0; y < y1; y++) for(int y = y0; y < y1; y++)
{ {
...@@ -3333,7 +3372,7 @@ namespace sw ...@@ -3333,7 +3372,7 @@ namespace sw
int evenX0 = ((x0 + 1) & ~1) * 2; int evenX0 = ((x0 + 1) & ~1) * 2;
int evenBytes = (oddX1 - evenX0) * sizeof(float); int evenBytes = (oddX1 - evenX0) * sizeof(float);
for(int z = 0; z < internal.depth; z++) for(int z = 0; z < internal.samples; z++)
{ {
for(int y = y0; y < y1; y++) for(int y = y0; y < y1; y++)
{ {
...@@ -3437,7 +3476,7 @@ namespace sw ...@@ -3437,7 +3476,7 @@ namespace sw
char *buffer = (char*)lockStencil(0, 0, 0, PUBLIC); char *buffer = (char*)lockStencil(0, 0, 0, PUBLIC);
// Stencil buffers are assumed to use quad layout // Stencil buffers are assumed to use quad layout
for(int z = 0; z < stencil.depth; z++) for(int z = 0; z < stencil.samples; z++)
{ {
for(int y = y0; y < y1; y++) for(int y = y0; y < y1; y++)
{ {
...@@ -3534,7 +3573,7 @@ namespace sw ...@@ -3534,7 +3573,7 @@ namespace sw
} }
} }
void Surface::copyInternal(const Surface* source, int x, int y, float srcX, float srcY, bool filter) void Surface::copyInternal(const Surface *source, int x, int y, float srcX, float srcY, bool filter)
{ {
ASSERT(internal.lock != LOCK_UNLOCKED && source && source->internal.lock != LOCK_UNLOCKED); ASSERT(internal.lock != LOCK_UNLOCKED && source && source->internal.lock != LOCK_UNLOCKED);
...@@ -3542,17 +3581,17 @@ namespace sw ...@@ -3542,17 +3581,17 @@ namespace sw
if(!filter) if(!filter)
{ {
color = source->internal.read((int)srcX, (int)srcY); color = source->internal.read((int)srcX, (int)srcY, 0);
} }
else // Bilinear filtering else // Bilinear filtering
{ {
color = source->internal.sample(srcX, srcY); color = source->internal.sample(srcX, srcY, 0);
} }
internal.write(x, y, color); internal.write(x, y, color);
} }
void Surface::copyInternal(const Surface* source, int x, int y, int z, float srcX, float srcY, float srcZ, bool filter) void Surface::copyInternal(const Surface *source, int x, int y, int z, float srcX, float srcY, float srcZ, bool filter)
{ {
ASSERT(internal.lock != LOCK_UNLOCKED && source && source->internal.lock != LOCK_UNLOCKED); ASSERT(internal.lock != LOCK_UNLOCKED && source && source->internal.lock != LOCK_UNLOCKED);
...@@ -3688,7 +3727,8 @@ namespace sw ...@@ -3688,7 +3727,8 @@ namespace sw
external.depth == internal.depth && external.depth == internal.depth &&
external.pitchB == internal.pitchB && external.pitchB == internal.pitchB &&
external.sliceB == internal.sliceB && external.sliceB == internal.sliceB &&
external.border == internal.border; external.border == internal.border &&
external.samples == internal.samples;
} }
Format Surface::selectInternalFormat(Format format) const Format Surface::selectInternalFormat(Format format) const
...@@ -3947,11 +3987,13 @@ namespace sw ...@@ -3947,11 +3987,13 @@ namespace sw
void Surface::resolve() void Surface::resolve()
{ {
if(internal.depth <= 1 || !internal.dirty || !renderTarget || internal.format == FORMAT_NULL) if(internal.samples <= 1 || !internal.dirty || !renderTarget || internal.format == FORMAT_NULL)
{ {
return; return;
} }
ASSERT(internal.depth == 1); // Unimplemented
void *source = internal.lockRect(0, 0, 0, LOCK_READWRITE); void *source = internal.lockRect(0, 0, 0, LOCK_READWRITE);
int width = internal.width; int width = internal.width;
...@@ -3983,7 +4025,7 @@ namespace sw ...@@ -3983,7 +4025,7 @@ namespace sw
#if defined(__i386__) || defined(__x86_64__) #if defined(__i386__) || defined(__x86_64__)
if(CPUID::supportsSSE2() && (width % 4) == 0) if(CPUID::supportsSSE2() && (width % 4) == 0)
{ {
if(internal.depth == 2) if(internal.samples == 2)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4001,7 +4043,7 @@ namespace sw ...@@ -4001,7 +4043,7 @@ namespace sw
source1 += pitch; source1 += pitch;
} }
} }
else if(internal.depth == 4) else if(internal.samples == 4)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4025,7 +4067,7 @@ namespace sw ...@@ -4025,7 +4067,7 @@ namespace sw
source3 += pitch; source3 += pitch;
} }
} }
else if(internal.depth == 8) else if(internal.samples == 8)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4061,7 +4103,7 @@ namespace sw ...@@ -4061,7 +4103,7 @@ namespace sw
source7 += pitch; source7 += pitch;
} }
} }
else if(internal.depth == 16) else if(internal.samples == 16)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4128,7 +4170,7 @@ namespace sw ...@@ -4128,7 +4170,7 @@ namespace sw
{ {
#define AVERAGE(x, y) (((x) & (y)) + ((((x) ^ (y)) >> 1) & 0x7F7F7F7F) + (((x) ^ (y)) & 0x01010101)) #define AVERAGE(x, y) (((x) & (y)) + ((((x) ^ (y)) >> 1) & 0x7F7F7F7F) + (((x) ^ (y)) & 0x01010101))
if(internal.depth == 2) if(internal.samples == 2)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4146,7 +4188,7 @@ namespace sw ...@@ -4146,7 +4188,7 @@ namespace sw
source1 += pitch; source1 += pitch;
} }
} }
else if(internal.depth == 4) else if(internal.samples == 4)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4170,7 +4212,7 @@ namespace sw ...@@ -4170,7 +4212,7 @@ namespace sw
source3 += pitch; source3 += pitch;
} }
} }
else if(internal.depth == 8) else if(internal.samples == 8)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4206,7 +4248,7 @@ namespace sw ...@@ -4206,7 +4248,7 @@ namespace sw
source7 += pitch; source7 += pitch;
} }
} }
else if(internal.depth == 16) else if(internal.samples == 16)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4277,7 +4319,7 @@ namespace sw ...@@ -4277,7 +4319,7 @@ namespace sw
#if defined(__i386__) || defined(__x86_64__) #if defined(__i386__) || defined(__x86_64__)
if(CPUID::supportsSSE2() && (width % 4) == 0) if(CPUID::supportsSSE2() && (width % 4) == 0)
{ {
if(internal.depth == 2) if(internal.samples == 2)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4295,7 +4337,7 @@ namespace sw ...@@ -4295,7 +4337,7 @@ namespace sw
source1 += pitch; source1 += pitch;
} }
} }
else if(internal.depth == 4) else if(internal.samples == 4)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4319,7 +4361,7 @@ namespace sw ...@@ -4319,7 +4361,7 @@ namespace sw
source3 += pitch; source3 += pitch;
} }
} }
else if(internal.depth == 8) else if(internal.samples == 8)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4355,7 +4397,7 @@ namespace sw ...@@ -4355,7 +4397,7 @@ namespace sw
source7 += pitch; source7 += pitch;
} }
} }
else if(internal.depth == 16) else if(internal.samples == 16)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4422,7 +4464,7 @@ namespace sw ...@@ -4422,7 +4464,7 @@ namespace sw
{ {
#define AVERAGE(x, y) (((x) & (y)) + ((((x) ^ (y)) >> 1) & 0x7FFF7FFF) + (((x) ^ (y)) & 0x00010001)) #define AVERAGE(x, y) (((x) & (y)) + ((((x) ^ (y)) >> 1) & 0x7FFF7FFF) + (((x) ^ (y)) & 0x00010001))
if(internal.depth == 2) if(internal.samples == 2)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4440,7 +4482,7 @@ namespace sw ...@@ -4440,7 +4482,7 @@ namespace sw
source1 += pitch; source1 += pitch;
} }
} }
else if(internal.depth == 4) else if(internal.samples == 4)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4464,7 +4506,7 @@ namespace sw ...@@ -4464,7 +4506,7 @@ namespace sw
source3 += pitch; source3 += pitch;
} }
} }
else if(internal.depth == 8) else if(internal.samples == 8)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4500,7 +4542,7 @@ namespace sw ...@@ -4500,7 +4542,7 @@ namespace sw
source7 += pitch; source7 += pitch;
} }
} }
else if(internal.depth == 16) else if(internal.samples == 16)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4570,7 +4612,7 @@ namespace sw ...@@ -4570,7 +4612,7 @@ namespace sw
#if defined(__i386__) || defined(__x86_64__) #if defined(__i386__) || defined(__x86_64__)
if(CPUID::supportsSSE2() && (width % 2) == 0) if(CPUID::supportsSSE2() && (width % 2) == 0)
{ {
if(internal.depth == 2) if(internal.samples == 2)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4588,7 +4630,7 @@ namespace sw ...@@ -4588,7 +4630,7 @@ namespace sw
source1 += pitch; source1 += pitch;
} }
} }
else if(internal.depth == 4) else if(internal.samples == 4)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4612,7 +4654,7 @@ namespace sw ...@@ -4612,7 +4654,7 @@ namespace sw
source3 += pitch; source3 += pitch;
} }
} }
else if(internal.depth == 8) else if(internal.samples == 8)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4648,7 +4690,7 @@ namespace sw ...@@ -4648,7 +4690,7 @@ namespace sw
source7 += pitch; source7 += pitch;
} }
} }
else if(internal.depth == 16) else if(internal.samples == 16)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4715,7 +4757,7 @@ namespace sw ...@@ -4715,7 +4757,7 @@ namespace sw
{ {
#define AVERAGE(x, y) (((x) & (y)) + ((((x) ^ (y)) >> 1) & 0x7FFF7FFF) + (((x) ^ (y)) & 0x00010001)) #define AVERAGE(x, y) (((x) & (y)) + ((((x) ^ (y)) >> 1) & 0x7FFF7FFF) + (((x) ^ (y)) & 0x00010001))
if(internal.depth == 2) if(internal.samples == 2)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4733,7 +4775,7 @@ namespace sw ...@@ -4733,7 +4775,7 @@ namespace sw
source1 += pitch; source1 += pitch;
} }
} }
else if(internal.depth == 4) else if(internal.samples == 4)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4757,7 +4799,7 @@ namespace sw ...@@ -4757,7 +4799,7 @@ namespace sw
source3 += pitch; source3 += pitch;
} }
} }
else if(internal.depth == 8) else if(internal.samples == 8)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4793,7 +4835,7 @@ namespace sw ...@@ -4793,7 +4835,7 @@ namespace sw
source7 += pitch; source7 += pitch;
} }
} }
else if(internal.depth == 16) else if(internal.samples == 16)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4863,7 +4905,7 @@ namespace sw ...@@ -4863,7 +4905,7 @@ namespace sw
#if defined(__i386__) || defined(__x86_64__) #if defined(__i386__) || defined(__x86_64__)
if(CPUID::supportsSSE() && (width % 4) == 0) if(CPUID::supportsSSE() && (width % 4) == 0)
{ {
if(internal.depth == 2) if(internal.samples == 2)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4882,7 +4924,7 @@ namespace sw ...@@ -4882,7 +4924,7 @@ namespace sw
source1 += pitch; source1 += pitch;
} }
} }
else if(internal.depth == 4) else if(internal.samples == 4)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4907,7 +4949,7 @@ namespace sw ...@@ -4907,7 +4949,7 @@ namespace sw
source3 += pitch; source3 += pitch;
} }
} }
else if(internal.depth == 8) else if(internal.samples == 8)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -4944,7 +4986,7 @@ namespace sw ...@@ -4944,7 +4986,7 @@ namespace sw
source7 += pitch; source7 += pitch;
} }
} }
else if(internal.depth == 16) else if(internal.samples == 16)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5010,7 +5052,7 @@ namespace sw ...@@ -5010,7 +5052,7 @@ namespace sw
else else
#endif #endif
{ {
if(internal.depth == 2) if(internal.samples == 2)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5029,7 +5071,7 @@ namespace sw ...@@ -5029,7 +5071,7 @@ namespace sw
source1 += pitch; source1 += pitch;
} }
} }
else if(internal.depth == 4) else if(internal.samples == 4)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5054,7 +5096,7 @@ namespace sw ...@@ -5054,7 +5096,7 @@ namespace sw
source3 += pitch; source3 += pitch;
} }
} }
else if(internal.depth == 8) else if(internal.samples == 8)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5091,7 +5133,7 @@ namespace sw ...@@ -5091,7 +5133,7 @@ namespace sw
source7 += pitch; source7 += pitch;
} }
} }
else if(internal.depth == 16) else if(internal.samples == 16)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5160,7 +5202,7 @@ namespace sw ...@@ -5160,7 +5202,7 @@ namespace sw
#if defined(__i386__) || defined(__x86_64__) #if defined(__i386__) || defined(__x86_64__)
if(CPUID::supportsSSE() && (width % 2) == 0) if(CPUID::supportsSSE() && (width % 2) == 0)
{ {
if(internal.depth == 2) if(internal.samples == 2)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5179,7 +5221,7 @@ namespace sw ...@@ -5179,7 +5221,7 @@ namespace sw
source1 += pitch; source1 += pitch;
} }
} }
else if(internal.depth == 4) else if(internal.samples == 4)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5204,7 +5246,7 @@ namespace sw ...@@ -5204,7 +5246,7 @@ namespace sw
source3 += pitch; source3 += pitch;
} }
} }
else if(internal.depth == 8) else if(internal.samples == 8)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5241,7 +5283,7 @@ namespace sw ...@@ -5241,7 +5283,7 @@ namespace sw
source7 += pitch; source7 += pitch;
} }
} }
else if(internal.depth == 16) else if(internal.samples == 16)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5307,7 +5349,7 @@ namespace sw ...@@ -5307,7 +5349,7 @@ namespace sw
else else
#endif #endif
{ {
if(internal.depth == 2) if(internal.samples == 2)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5326,7 +5368,7 @@ namespace sw ...@@ -5326,7 +5368,7 @@ namespace sw
source1 += pitch; source1 += pitch;
} }
} }
else if(internal.depth == 4) else if(internal.samples == 4)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5351,7 +5393,7 @@ namespace sw ...@@ -5351,7 +5393,7 @@ namespace sw
source3 += pitch; source3 += pitch;
} }
} }
else if(internal.depth == 8) else if(internal.samples == 8)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5388,7 +5430,7 @@ namespace sw ...@@ -5388,7 +5430,7 @@ namespace sw
source7 += pitch; source7 += pitch;
} }
} }
else if(internal.depth == 16) else if(internal.samples == 16)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5457,7 +5499,7 @@ namespace sw ...@@ -5457,7 +5499,7 @@ namespace sw
#if defined(__i386__) || defined(__x86_64__) #if defined(__i386__) || defined(__x86_64__)
if(CPUID::supportsSSE()) if(CPUID::supportsSSE())
{ {
if(internal.depth == 2) if(internal.samples == 2)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5476,7 +5518,7 @@ namespace sw ...@@ -5476,7 +5518,7 @@ namespace sw
source1 += pitch; source1 += pitch;
} }
} }
else if(internal.depth == 4) else if(internal.samples == 4)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5501,7 +5543,7 @@ namespace sw ...@@ -5501,7 +5543,7 @@ namespace sw
source3 += pitch; source3 += pitch;
} }
} }
else if(internal.depth == 8) else if(internal.samples == 8)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5538,7 +5580,7 @@ namespace sw ...@@ -5538,7 +5580,7 @@ namespace sw
source7 += pitch; source7 += pitch;
} }
} }
else if(internal.depth == 16) else if(internal.samples == 16)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5604,7 +5646,7 @@ namespace sw ...@@ -5604,7 +5646,7 @@ namespace sw
else else
#endif #endif
{ {
if(internal.depth == 2) if(internal.samples == 2)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5623,7 +5665,7 @@ namespace sw ...@@ -5623,7 +5665,7 @@ namespace sw
source1 += pitch; source1 += pitch;
} }
} }
else if(internal.depth == 4) else if(internal.samples == 4)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5648,7 +5690,7 @@ namespace sw ...@@ -5648,7 +5690,7 @@ namespace sw
source3 += pitch; source3 += pitch;
} }
} }
else if(internal.depth == 8) else if(internal.samples == 8)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5685,7 +5727,7 @@ namespace sw ...@@ -5685,7 +5727,7 @@ namespace sw
source7 += pitch; source7 += pitch;
} }
} }
else if(internal.depth == 16) else if(internal.samples == 16)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5754,7 +5796,7 @@ namespace sw ...@@ -5754,7 +5796,7 @@ namespace sw
#if defined(__i386__) || defined(__x86_64__) #if defined(__i386__) || defined(__x86_64__)
if(CPUID::supportsSSE2() && (width % 8) == 0) if(CPUID::supportsSSE2() && (width % 8) == 0)
{ {
if(internal.depth == 2) if(internal.samples == 2)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5783,7 +5825,7 @@ namespace sw ...@@ -5783,7 +5825,7 @@ namespace sw
source1 += pitch; source1 += pitch;
} }
} }
else if(internal.depth == 4) else if(internal.samples == 4)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5824,7 +5866,7 @@ namespace sw ...@@ -5824,7 +5866,7 @@ namespace sw
source3 += pitch; source3 += pitch;
} }
} }
else if(internal.depth == 8) else if(internal.samples == 8)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -5889,7 +5931,7 @@ namespace sw ...@@ -5889,7 +5931,7 @@ namespace sw
source7 += pitch; source7 += pitch;
} }
} }
else if(internal.depth == 16) else if(internal.samples == 16)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -6009,7 +6051,7 @@ namespace sw ...@@ -6009,7 +6051,7 @@ namespace sw
{ {
#define AVERAGE(x, y) (((x) & (y)) + ((((x) ^ (y)) >> 1) & 0x7BEF) + (((x) ^ (y)) & 0x0821)) #define AVERAGE(x, y) (((x) & (y)) + ((((x) ^ (y)) >> 1) & 0x7BEF) + (((x) ^ (y)) & 0x0821))
if(internal.depth == 2) if(internal.samples == 2)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -6027,7 +6069,7 @@ namespace sw ...@@ -6027,7 +6069,7 @@ namespace sw
source1 += pitch; source1 += pitch;
} }
} }
else if(internal.depth == 4) else if(internal.samples == 4)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -6051,7 +6093,7 @@ namespace sw ...@@ -6051,7 +6093,7 @@ namespace sw
source3 += pitch; source3 += pitch;
} }
} }
else if(internal.depth == 8) else if(internal.samples == 8)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
...@@ -6087,7 +6129,7 @@ namespace sw ...@@ -6087,7 +6129,7 @@ namespace sw
source7 += pitch; source7 += pitch;
} }
} }
else if(internal.depth == 16) else if(internal.samples == 16)
{ {
for(int y = 0; y < height; y++) for(int y = 0; y < height; y++)
{ {
......
...@@ -48,7 +48,7 @@ namespace sw ...@@ -48,7 +48,7 @@ namespace sw
typedef RectT<int> Rect; typedef RectT<int> Rect;
typedef RectT<float> RectF; typedef RectT<float> RectF;
template <typename T> struct SliceRectT : public RectT<T> template<typename T> struct SliceRectT : public RectT<T>
{ {
SliceRectT() : slice(0) {} SliceRectT() : slice(0) {}
SliceRectT(const RectT<T>& rect) : RectT<T>(rect), slice(0) {} SliceRectT(const RectT<T>& rect) : RectT<T>(rect), slice(0) {}
...@@ -237,7 +237,9 @@ namespace sw ...@@ -237,7 +237,9 @@ namespace sw
private: private:
struct Buffer struct Buffer
{ {
public: friend Surface;
private:
void write(int x, int y, int z, const Color<float> &color); void write(int x, int y, int z, const Color<float> &color);
void write(int x, int y, const Color<float> &color); void write(int x, int y, const Color<float> &color);
void write(void *element, const Color<float> &color); void write(void *element, const Color<float> &color);
...@@ -245,7 +247,7 @@ namespace sw ...@@ -245,7 +247,7 @@ namespace sw
Color<float> read(int x, int y) const; Color<float> read(int x, int y) const;
Color<float> read(void *element) const; Color<float> read(void *element) const;
Color<float> sample(float x, float y, float z) const; Color<float> sample(float x, float y, float z) const;
Color<float> sample(float x, float y) const; Color<float> sample(float x, float y, int layer) const;
void *lockRect(int x, int y, int z, Lock lock); void *lockRect(int x, int y, int z, Lock lock);
void unlockRect(); void unlockRect();
...@@ -254,12 +256,15 @@ namespace sw ...@@ -254,12 +256,15 @@ namespace sw
int width; int width;
int height; int height;
int depth; int depth;
short border;
short samples;
int bytes; int bytes;
int pitchB; int pitchB;
int pitchP; int pitchP;
int sliceB; int sliceB;
int sliceP; int sliceP;
int border;
Format format; Format format;
AtomicInt lock; AtomicInt lock;
...@@ -268,11 +273,11 @@ namespace sw ...@@ -268,11 +273,11 @@ namespace sw
protected: protected:
Surface(int width, int height, int depth, Format format, void *pixels, int pitch, int slice); Surface(int width, int height, int depth, Format format, void *pixels, int pitch, int slice);
Surface(Resource *texture, int width, int height, int depth, int border, Format format, bool lockable, bool renderTarget, int pitchP = 0); Surface(Resource *texture, int width, int height, int depth, int border, int samples, Format format, bool lockable, bool renderTarget, int pitchP = 0);
public: public:
static Surface *create(int width, int height, int depth, Format format, void *pixels, int pitch, int slice); 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, int border, Format format, bool lockable, bool renderTarget, int pitchP = 0); static Surface *create(Resource *texture, int width, int height, int depth, int border, int samples, Format format, bool lockable, bool renderTarget, int pitchP = 0);
virtual ~Surface() = 0; virtual ~Surface() = 0;
...@@ -313,6 +318,7 @@ namespace sw ...@@ -313,6 +318,7 @@ namespace sw
void sync(); // Wait for lock(s) to be released. void sync(); // Wait for lock(s) to be released.
inline bool isUnlocked() const; // Only reliable after sync(). inline bool isUnlocked() const; // Only reliable after sync().
inline int getSamples() const;
inline int getMultiSampleCount() const; inline int getMultiSampleCount() const;
inline int getSuperSampleCount() const; inline int getSuperSampleCount() const;
...@@ -351,7 +357,7 @@ namespace sw ...@@ -351,7 +357,7 @@ namespace sw
static int pitchP(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 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 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 unsigned int size(int width, int height, int depth, int border, int samples, Format format); // FIXME: slice * depth
static bool isStencil(Format format); static bool isStencil(Format format);
static bool isDepth(Format format); static bool isDepth(Format format);
...@@ -474,7 +480,7 @@ namespace sw ...@@ -474,7 +480,7 @@ namespace sw
static void update(Buffer &destination, Buffer &source); static void update(Buffer &destination, Buffer &source);
static void genericUpdate(Buffer &destination, Buffer &source); static void genericUpdate(Buffer &destination, Buffer &source);
static void *allocateBuffer(int width, int height, int depth, int border, Format format); static void *allocateBuffer(int width, int height, int depth, int border, int samples, Format format);
static void memfill4(void *buffer, int pattern, int bytes); static void memfill4(void *buffer, int pattern, int bytes);
bool identicalFormats() const; bool identicalFormats() const;
...@@ -625,14 +631,19 @@ namespace sw ...@@ -625,14 +631,19 @@ namespace sw
return stencil.sliceB; return stencil.sliceB;
} }
int Surface::getSamples() const
{
return internal.samples;
}
int Surface::getMultiSampleCount() const int Surface::getMultiSampleCount() const
{ {
return sw::min(internal.depth, 4); return sw::min((int)internal.samples, 4);
} }
int Surface::getSuperSampleCount() const int Surface::getSuperSampleCount() const
{ {
return internal.depth > 4 ? internal.depth / 4 : 1; return internal.samples > 4 ? internal.samples / 4 : 1;
} }
bool Surface::isUnlocked() const bool Surface::isUnlocked() 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