Commit f68510dd by Alexis Hetu Committed by Alexis Hétu

First simplest 3D mipmap implementation

Bug 19126833 Change-Id: Idd67457542deb1408812bce2c796b275a7b19f0e Reviewed-on: https://swiftshader-review.googlesource.com/2420Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent 55a2cbc6
...@@ -681,6 +681,70 @@ namespace es2 ...@@ -681,6 +681,70 @@ namespace es2
return true; return true;
} }
bool Device::stretchCube(egl::Image *source, egl::Image *dest)
{
if(!source || !dest || Image::isDepth(source->getInternalFormat()) || Image::isStencil(source->getInternalFormat()))
{
ERR("Invalid parameters");
return false;
}
int sWidth = source->getExternalWidth();
int sHeight = source->getExternalHeight();
int sDepth = source->getExternalDepth();
int dWidth = dest->getExternalWidth();
int dHeight = dest->getExternalHeight();
int dDepth = dest->getExternalDepth();
bool scaling = (sWidth != dWidth) || (sHeight != dHeight) || (sDepth != dDepth);
bool equalFormats = source->getInternalFormat() == dest->getInternalFormat();
bool alpha0xFF = false;
if((source->getInternalFormat() == FORMAT_A8R8G8B8 && dest->getInternalFormat() == FORMAT_X8R8G8B8) ||
(source->getInternalFormat() == FORMAT_X8R8G8B8 && dest->getInternalFormat() == FORMAT_A8R8G8B8))
{
equalFormats = true;
alpha0xFF = true;
}
if(!scaling && equalFormats)
{
unsigned int sourcePitch = source->getInternalPitchB();
unsigned int destPitch = dest->getInternalPitchB();
unsigned int bytes = dWidth * Image::bytes(source->getInternalFormat());
for(int z = 0; z < dDepth; ++z)
{
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);
for(int y = 0; y < dHeight; ++y)
{
memcpy(destBytes, sourceBytes, bytes);
if(alpha0xFF)
{
for(int x = 0; x < dWidth; ++x)
{
destBytes[4 * x + 3] = 0xFF;
}
}
sourceBytes += sourcePitch;
destBytes += destPitch;
}
}
source->unlockInternal();
dest->unlockInternal();
}
else
{
blit3D(source, dest);
}
return true;
}
bool Device::bindResources() bool Device::bindResources()
{ {
if(!bindViewport()) if(!bindViewport())
......
...@@ -70,6 +70,7 @@ namespace es2 ...@@ -70,6 +70,7 @@ namespace es2
virtual void setViewport(const Viewport &viewport); virtual void setViewport(const Viewport &viewport);
virtual bool stretchRect(egl::Image *sourceSurface, const sw::SliceRect *sourceRect, egl::Image *destSurface, const sw::SliceRect *destRect, bool filter); virtual bool stretchRect(egl::Image *sourceSurface, const sw::SliceRect *sourceRect, egl::Image *destSurface, const sw::SliceRect *destRect, bool filter);
virtual bool stretchCube(egl::Image *sourceSurface, egl::Image *destSurface);
virtual void finish(); virtual void finish();
private: private:
......
...@@ -1723,7 +1723,29 @@ bool Texture3D::isDepth(GLenum target, GLint level) const ...@@ -1723,7 +1723,29 @@ bool Texture3D::isDepth(GLenum target, GLint level) const
void Texture3D::generateMipmaps() void Texture3D::generateMipmaps()
{ {
UNIMPLEMENTED(); if(!image[0])
{
return; // FIXME: error?
}
unsigned int q = log2(std::max(std::max(image[0]->getWidth(), image[0]->getHeight()), image[0]->getDepth()));
for(unsigned int i = 1; i <= q; i++)
{
if(image[i])
{
image[i]->unbind(this);
}
image[i] = new Image(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());
if(!image[i])
{
return error(GL_OUT_OF_MEMORY);
}
getDevice()->stretchCube(image[i - 1], image[i]);
}
} }
egl::Image *Texture3D::getImage(unsigned int level) egl::Image *Texture3D::getImage(unsigned int level)
......
...@@ -53,8 +53,8 @@ namespace sw ...@@ -53,8 +53,8 @@ namespace sw
source->lockInternal(sRect.x0, sRect.y0, sRect.slice, sw::LOCK_READONLY, sw::PUBLIC); source->lockInternal(sRect.x0, sRect.y0, sRect.slice, sw::LOCK_READONLY, sw::PUBLIC);
dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, sw::LOCK_WRITEONLY, sw::PUBLIC); dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, sw::LOCK_WRITEONLY, sw::PUBLIC);
float w = 1.0f / (dRect.x1 - dRect.x0) * (sRect.x1 - sRect.x0); float w = static_cast<float>(sRect.x1 - sRect.x0) / static_cast<float>(dRect.x1 - dRect.x0);
float h = 1.0f / (dRect.y1 - dRect.y0) * (sRect.y1 - sRect.y0); float h = static_cast<float>(sRect.y1 - sRect.y0) / static_cast<float>(dRect.y1 - dRect.y0);
const float xStart = (float)sRect.x0 + 0.5f * w; const float xStart = (float)sRect.x0 + 0.5f * w;
float y = (float)sRect.y0 + 0.5f * h; float y = (float)sRect.y0 + 0.5f * h;
...@@ -88,6 +88,36 @@ namespace sw ...@@ -88,6 +88,36 @@ namespace sw
dest->unlockInternal(); dest->unlockInternal();
} }
void Blitter::blit3D(Surface *source, Surface *dest)
{
source->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
dest->lockInternal(0, 0, 0, sw::LOCK_WRITEONLY, sw::PUBLIC);
float w = static_cast<float>(source->getExternalWidth()) / static_cast<float>(dest->getExternalWidth());
float h = static_cast<float>(source->getExternalHeight()) / static_cast<float>(dest->getExternalHeight());
float d = static_cast<float>(source->getExternalDepth()) / static_cast<float>(dest->getExternalDepth());
float z = 0.5f * d;
for(int k = 0; k < dest->getExternalDepth(); ++k)
{
float y = 0.5f * h;
for(int j = 0; j < dest->getExternalHeight(); ++j)
{
float x = 0.5f * w;
for(int i = 0; i < dest->getExternalWidth(); ++i)
{
dest->writeInternal(i, j, k, source->sampleInternal(x, y, z));
x += w;
}
y += h;
}
z += d;
}
source->unlockInternal();
dest->unlockInternal();
}
bool Blitter::read(Float4 &c, Pointer<Byte> element, Format format) bool Blitter::read(Float4 &c, Pointer<Byte> element, Format format)
{ {
c = Float4(1.0f, 1.0f, 1.0f, 1.0f); c = Float4(1.0f, 1.0f, 1.0f, 1.0f);
......
...@@ -28,6 +28,7 @@ namespace sw ...@@ -28,6 +28,7 @@ namespace sw
virtual ~Blitter(); virtual ~Blitter();
void blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter); void blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter);
void blit3D(Surface *source, Surface *dest);
private: private:
bool read(Float4 &color, Pointer<Byte> element, Format format); bool read(Float4 &color, Pointer<Byte> element, Format format);
......
...@@ -190,6 +190,11 @@ namespace sw ...@@ -190,6 +190,11 @@ namespace sw
blitter.blit(source, sRect, dest, dRect, filter); blitter.blit(source, sRect, dest, dRect, filter);
} }
void Renderer::blit3D(Surface *source, Surface *dest)
{
blitter.blit3D(source, dest);
}
void Renderer::draw(DrawType drawType, unsigned int indexOffset, unsigned int count, bool update) void Renderer::draw(DrawType drawType, unsigned int indexOffset, unsigned int count, bool update)
{ {
#ifndef NDEBUG #ifndef NDEBUG
......
...@@ -271,6 +271,7 @@ namespace sw ...@@ -271,6 +271,7 @@ namespace sw
virtual ~Renderer(); virtual ~Renderer();
virtual void blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter); virtual void blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter);
virtual void blit3D(Surface *source, Surface *dest);
virtual void draw(DrawType drawType, unsigned int indexOffset, unsigned int count, bool update = true); virtual void draw(DrawType drawType, unsigned int indexOffset, unsigned int count, bool update = true);
virtual void setIndexBuffer(Resource *indexBuffer); virtual void setIndexBuffer(Resource *indexBuffer);
......
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