Implements generateMipmap for CPU-side textures

TRAC #22350 Author: Shannon Woods Signed-off-by: Jamie Madill Signed-off-by: Daniel Koch git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1763 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent c8cd7f61
......@@ -15,6 +15,7 @@
#include "libGLESv2/main.h"
#include "libGLESv2/mathutil.h"
#include "libGLESv2/renderer/renderer11_utils.h"
#include "libGLESv2/renderer/generatemip.h"
namespace rx
{
......@@ -40,6 +41,69 @@ Image11 *Image11::makeImage11(Image *img)
return static_cast<rx::Image11*>(img);
}
void Image11::generateMipmap(Image11 *dest, Image11 *src)
{
ASSERT(src->getDXGIFormat() == dest->getDXGIFormat());
ASSERT(src->getWidth() == 1 || src->getWidth() / 2 == dest->getWidth());
ASSERT(src->getHeight() == 1 || src->getHeight() / 2 == dest->getHeight());
D3D11_MAPPED_SUBRESOURCE destMapped, srcMapped;
dest->map(&destMapped);
src->map(&srcMapped);
const unsigned char *sourceData = reinterpret_cast<const unsigned char*>(srcMapped.pData);
unsigned char *destData = reinterpret_cast<unsigned char*>(destMapped.pData);
if (sourceData && destData)
{
switch (src->getDXGIFormat())
{
case DXGI_FORMAT_R8G8B8A8_UNORM:
case DXGI_FORMAT_B8G8R8A8_UNORM:
GenerateMip<R8G8B8A8>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
break;
case DXGI_FORMAT_A8_UNORM:
GenerateMip<A8>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
break;
case DXGI_FORMAT_R8_UNORM:
GenerateMip<R8>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
break;
case DXGI_FORMAT_R32G32B32A32_FLOAT:
GenerateMip<A32B32G32R32F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
break;
case DXGI_FORMAT_R32G32B32_FLOAT:
GenerateMip<R32G32B32F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
break;
case DXGI_FORMAT_R16G16B16A16_FLOAT:
GenerateMip<A16B16G16R16F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
break;
case DXGI_FORMAT_R8G8_UNORM:
GenerateMip<R8G8>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
break;
case DXGI_FORMAT_R16_FLOAT:
GenerateMip<R16F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
break;
case DXGI_FORMAT_R16G16_FLOAT:
GenerateMip<R16G16F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
break;
case DXGI_FORMAT_R32_FLOAT:
GenerateMip<R32F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
break;
case DXGI_FORMAT_R32G32_FLOAT:
GenerateMip<R32G32F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
break;
default:
UNREACHABLE();
break;
}
dest->unmap();
src->unmap();
}
dest->markDirty();
}
bool Image11::isDirty() const
{
return (mStagingTexture && mDirty);
......
......@@ -36,6 +36,8 @@ class Image11 : public Image
static Image11 *makeImage11(Image *img);
static void generateMipmap(Image11 *dest, Image11 *src);
virtual bool isDirty() const;
ID3D11Texture2D *getStagingTexture();
......@@ -54,15 +56,16 @@ class Image11 : public Image
virtual void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
protected:
HRESULT map(D3D11_MAPPED_SUBRESOURCE *map);
void unmap();
private:
DISALLOW_COPY_AND_ASSIGN(Image11);
void createStagingTexture();
bool updateStagingTexture(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
HRESULT map(D3D11_MAPPED_SUBRESOURCE *map);
void unmap();
Renderer11 *mRenderer;
DXGI_FORMAT mDXGIFormat;
......
......@@ -2414,9 +2414,9 @@ Image *Renderer11::createImage()
void Renderer11::generateMipmap(Image *dest, Image *src)
{
// TODO
UNIMPLEMENTED();
return;
Image11 *dest11 = Image11::makeImage11(dest);
Image11 *src11 = Image11::makeImage11(src);
Image11::generateMipmap(dest11, src11);
}
TextureStorage *Renderer11::createTextureStorage2D(SwapChain *swapChain)
......
......@@ -24,6 +24,9 @@ struct L8
}
};
typedef L8 R8; // R8 type is functionally equivalent for mip purposes
typedef L8 A8; // A8 type is functionally equivalent for mip purposes
struct A8L8
{
unsigned char L;
......@@ -35,6 +38,8 @@ struct A8L8
}
};
typedef A8L8 R8G8; // R8G8 type is functionally equivalent for mip purposes
struct A8R8G8B8
{
unsigned char B;
......@@ -48,6 +53,8 @@ struct A8R8G8B8
}
};
typedef A8R8G8B8 R8G8B8A8; // R8G8B8A8 type is functionally equivalent for mip purposes
struct A16B16G16R16F
{
unsigned short R;
......@@ -64,6 +71,28 @@ struct A16B16G16R16F
}
};
struct R16F
{
unsigned short R;
static void average(R16F *dst, const R16F *src1, const R16F *src2)
{
dst->R = gl::float32ToFloat16((gl::float16ToFloat32(src1->R) + gl::float16ToFloat32(src2->R)) * 0.5f);
}
};
struct R16G16F
{
unsigned short R;
unsigned short G;
static void average(R16G16F *dst, const R16G16F *src1, const R16G16F *src2)
{
dst->R = gl::float32ToFloat16((gl::float16ToFloat32(src1->R) + gl::float16ToFloat32(src2->R)) * 0.5f);
dst->G = gl::float32ToFloat16((gl::float16ToFloat32(src1->G) + gl::float16ToFloat32(src2->G)) * 0.5f);
}
};
struct A32B32G32R32F
{
float R;
......@@ -80,6 +109,42 @@ struct A32B32G32R32F
}
};
struct R32F
{
float R;
static void average(R32F *dst, const R32F *src1, const R32F *src2)
{
dst->R = (src1->R + src2->R) * 0.5f;
}
};
struct R32G32F
{
float R;
float G;
static void average(R32G32F *dst, const R32G32F *src1, const R32G32F *src2)
{
dst->R = (src1->R + src2->R) * 0.5f;
dst->G = (src1->G + src2->G) * 0.5f;
}
};
struct R32G32B32F
{
float R;
float G;
float B;
static void average(R32G32B32F *dst, const R32G32B32F *src1, const R32G32B32F *src2)
{
dst->R = (src1->R + src2->R) * 0.5f;
dst->G = (src1->G + src2->G) * 0.5f;
dst->B = (src1->B + src2->B) * 0.5f;
}
};
template <typename T>
static void GenerateMip(unsigned int sourceWidth, unsigned int sourceHeight,
const unsigned char *sourceData, int sourcePitch,
......
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