Commit 1dcea2a7 authored by hybrid's avatar hybrid

Fix memory access in d3dx mipmap generation. Thanks to hellflip for the hint.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4618 dfc29bdd-3216-0410-991c-e03cc46cb475
parent bca9c67a
...@@ -396,11 +396,13 @@ bool CD3D8Texture::createMipMaps(u32 level) ...@@ -396,11 +396,13 @@ bool CD3D8Texture::createMipMaps(u32 level)
{ {
if (upperDesc.Format == D3DFMT_A1R5G5B5) if (upperDesc.Format == D3DFMT_A1R5G5B5)
copy16BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits, copy16BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits,
upperDesc.Width, upperDesc.Height,
lowerDesc.Width, lowerDesc.Height, lowerDesc.Width, lowerDesc.Height,
upperlr.Pitch, lowerlr.Pitch); upperlr.Pitch, lowerlr.Pitch);
else else
if (upperDesc.Format == D3DFMT_A8R8G8B8) if (upperDesc.Format == D3DFMT_A8R8G8B8)
copy32BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits, copy32BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits,
upperDesc.Width, upperDesc.Height,
lowerDesc.Width, lowerDesc.Height, lowerDesc.Width, lowerDesc.Height,
upperlr.Pitch, lowerlr.Pitch); upperlr.Pitch, lowerlr.Pitch);
else else
...@@ -452,65 +454,77 @@ ECOLOR_FORMAT CD3D8Texture::getColorFormatFromD3DFormat(D3DFORMAT format) ...@@ -452,65 +454,77 @@ ECOLOR_FORMAT CD3D8Texture::getColorFormatFromD3DFormat(D3DFORMAT format)
void CD3D8Texture::copy16BitMipMap(char* src, char* tgt, void CD3D8Texture::copy16BitMipMap(char* src, char* tgt,
s32 width, s32 height, const s32 srcWidth, const s32 srcHeight,
s32 pitchsrc, s32 pitchtgt) const const s32 width, const s32 height,
const s32 pitchsrc, const s32 pitchtgt) const
{ {
u16 c; const s32 dy_max = (srcHeight==1?1:2);
const s32 dx_max = (srcWidth==1?1:2);
for (int x=0; x<width; ++x) const s32 blockcount= dx_max*dy_max;
for (s32 y=0; y<height; ++y)
{ {
for (int y=0; y<height; ++y) for (s32 x=0; x<width; ++x)
{ {
s32 a=0, r=0, g=0, b=0; u32 a=0, r=0, g=0, b=0;
for (s32 dy=0; dy<dy_max; ++dy)
for (int dx=0; dx<2; ++dx)
{ {
for (int dy=0; dy<2; ++dy) const s32 tgy = (y*2)+dy;
for (s32 dx=0; dx<dx_max; ++dx)
{ {
int tgx = (x*2)+dx; const s32 tgx = (x*2)+dx;
int tgy = (y*2)+dy;
c = *(u16*)((void*)&src[(tgx*2)+(tgy*pitchsrc)]); SColor c;
if (ColorFormat == ECF_A1R5G5B5)
c = A1R5G5B5toA8R8G8B8(*(u16*)(&src[(tgx*2)+(tgy*pitchsrc)]));
else
c = R5G6B5toA8R8G8B8(*(u16*)(&src[(tgx*2)+(tgy*pitchsrc)]));
a += getAlpha(c); a += c.getAlpha();
r += getRed(c); r += c.getRed();
g += getGreen(c); g += c.getGreen();
b += getBlue(c); b += c.getBlue();
} }
} }
a /= 4; a /= blockcount;
r /= 4; r /= blockcount;
g /= 4; g /= blockcount;
b /= 4; b /= blockcount;
c = ((a & 0x1) <<15) | ((r & 0x1F)<<10) | ((g & 0x1F)<<5) | (b & 0x1F); u16 c;
*(u16*)((void*)&tgt[(x*2)+(y*pitchtgt)]) = c; if (ColorFormat == ECF_A1R5G5B5)
c = RGBA16(r,g,b,a);
else
c = A8R8G8B8toR5G6B5(SColor(a,r,g,b).color);
*(u16*)(&tgt[(x*2)+(y*pitchtgt)]) = c;
} }
} }
} }
void CD3D8Texture::copy32BitMipMap(char* src, char* tgt, void CD3D8Texture::copy32BitMipMap(char* src, char* tgt,
s32 width, s32 height, const s32 srcWidth, const s32 srcHeight,
s32 pitchsrc, s32 pitchtgt) const const s32 width, const s32 height,
const s32 pitchsrc, const s32 pitchtgt) const
{ {
SColor c; const s32 dy_max = (srcHeight==1?1:2);
const s32 dx_max = (srcWidth==1?1:2);
for (int x=0; x<width; ++x) const s32 blockcount= dx_max*dy_max;
for (s32 y=0; y<height; ++y)
{ {
for (int y=0; y<height; ++y) for (s32 x=0; x<width; ++x)
{ {
s32 a=0, r=0, g=0, b=0; u32 a=0, r=0, g=0, b=0;
SColor c;
for (int dx=0; dx<2; ++dx) for (s32 dy=0; dy<dy_max; ++dy)
{ {
for (int dy=0; dy<2; ++dy) const s32 tgy = (y*2)+dy;
for (s32 dx=0; dx<dx_max; ++dx)
{ {
int tgx = (x*2)+dx; const s32 tgx = (x*2)+dx;
int tgy = (y*2)+dy;
c = *(u32*)((void*)&src[(tgx<<2)+(tgy*pitchsrc)]); c = *(u32*)(&src[(tgx*4)+(tgy*pitchsrc)]);
a += c.getAlpha(); a += c.getAlpha();
r += c.getRed(); r += c.getRed();
...@@ -519,13 +533,13 @@ void CD3D8Texture::copy32BitMipMap(char* src, char* tgt, ...@@ -519,13 +533,13 @@ void CD3D8Texture::copy32BitMipMap(char* src, char* tgt,
} }
} }
a >>= 2; a /= blockcount;
r >>= 2; r /= blockcount;
g >>= 2; g /= blockcount;
b >>= 2; b /= blockcount;
c = ((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff); c.set(a, r, g, b);
*(u32*)((void*)&tgt[(x*4)+(y*pitchtgt)]) = c.color; *(u32*)(&tgt[(x*4)+(y*pitchtgt)]) = c.color;
} }
} }
} }
......
...@@ -91,10 +91,15 @@ private: ...@@ -91,10 +91,15 @@ private:
bool createMipMaps(u32 level=1); bool createMipMaps(u32 level=1);
void copy16BitMipMap(char* src, char* tgt, void copy16BitMipMap(char* src, char* tgt,
s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const; const s32 srcWidth, const s32 srcHeight,
const s32 width, const s32 height,
const s32 pitchsrc, const s32 pitchtgt) const;
//! Helper function for mipmap generation.
void copy32BitMipMap(char* src, char* tgt, void copy32BitMipMap(char* src, char* tgt,
s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const; const s32 srcWidth, const s32 srcHeight,
const s32 width, const s32 height,
const s32 pitchsrc, const s32 pitchtgt) const;
IDirect3DDevice8* Device; IDirect3DDevice8* Device;
IDirect3DTexture8* Texture; IDirect3DTexture8* Texture;
......
...@@ -255,11 +255,13 @@ bool CD3D9Texture::createMipMaps(u32 level) ...@@ -255,11 +255,13 @@ bool CD3D9Texture::createMipMaps(u32 level)
{ {
if ((upperDesc.Format == D3DFMT_A1R5G5B5) || (upperDesc.Format == D3DFMT_R5G6B5)) if ((upperDesc.Format == D3DFMT_A1R5G5B5) || (upperDesc.Format == D3DFMT_R5G6B5))
copy16BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits, copy16BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits,
upperDesc.Width, upperDesc.Height,
lowerDesc.Width, lowerDesc.Height, lowerDesc.Width, lowerDesc.Height,
upperlr.Pitch, lowerlr.Pitch); upperlr.Pitch, lowerlr.Pitch);
else else
if (upperDesc.Format == D3DFMT_A8R8G8B8) if (upperDesc.Format == D3DFMT_A8R8G8B8)
copy32BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits, copy32BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits,
upperDesc.Width, upperDesc.Height,
lowerDesc.Width, lowerDesc.Height, lowerDesc.Width, lowerDesc.Height,
upperlr.Pitch, lowerlr.Pitch); upperlr.Pitch, lowerlr.Pitch);
else else
...@@ -581,19 +583,22 @@ bool CD3D9Texture::hasMipMaps() const ...@@ -581,19 +583,22 @@ bool CD3D9Texture::hasMipMaps() const
void CD3D9Texture::copy16BitMipMap(char* src, char* tgt, void CD3D9Texture::copy16BitMipMap(char* src, char* tgt,
s32 width, s32 height, const s32 srcWidth, const s32 srcHeight,
s32 pitchsrc, s32 pitchtgt) const const s32 width, const s32 height,
const s32 pitchsrc, const s32 pitchtgt) const
{ {
const s32 dy_max = (srcHeight==1?1:2);
const s32 dx_max = (srcWidth==1?1:2);
const s32 blockcount= dx_max*dy_max;
for (s32 y=0; y<height; ++y) for (s32 y=0; y<height; ++y)
{ {
for (s32 x=0; x<width; ++x) for (s32 x=0; x<width; ++x)
{ {
u32 a=0, r=0, g=0, b=0; u32 a=0, r=0, g=0, b=0;
for (s32 dy=0; dy<dy_max; ++dy)
for (s32 dy=0; dy<2; ++dy)
{ {
const s32 tgy = (y*2)+dy; const s32 tgy = (y*2)+dy;
for (s32 dx=0; dx<2; ++dx) for (s32 dx=0; dx<dx_max; ++dx)
{ {
const s32 tgx = (x*2)+dx; const s32 tgx = (x*2)+dx;
...@@ -610,10 +615,10 @@ void CD3D9Texture::copy16BitMipMap(char* src, char* tgt, ...@@ -610,10 +615,10 @@ void CD3D9Texture::copy16BitMipMap(char* src, char* tgt,
} }
} }
a /= 4; a /= blockcount;
r /= 4; r /= blockcount;
g /= 4; g /= blockcount;
b /= 4; b /= blockcount;
u16 c; u16 c;
if (ColorFormat == ECF_A1R5G5B5) if (ColorFormat == ECF_A1R5G5B5)
...@@ -627,9 +632,13 @@ void CD3D9Texture::copy16BitMipMap(char* src, char* tgt, ...@@ -627,9 +632,13 @@ void CD3D9Texture::copy16BitMipMap(char* src, char* tgt,
void CD3D9Texture::copy32BitMipMap(char* src, char* tgt, void CD3D9Texture::copy32BitMipMap(char* src, char* tgt,
s32 width, s32 height, const s32 srcWidth, const s32 srcHeight,
s32 pitchsrc, s32 pitchtgt) const const s32 width, const s32 height,
const s32 pitchsrc, const s32 pitchtgt) const
{ {
const s32 dy_max = (srcHeight==1?1:2);
const s32 dx_max = (srcWidth==1?1:2);
const s32 blockcount= dx_max*dy_max;
for (s32 y=0; y<height; ++y) for (s32 y=0; y<height; ++y)
{ {
for (s32 x=0; x<width; ++x) for (s32 x=0; x<width; ++x)
...@@ -637,10 +646,10 @@ void CD3D9Texture::copy32BitMipMap(char* src, char* tgt, ...@@ -637,10 +646,10 @@ void CD3D9Texture::copy32BitMipMap(char* src, char* tgt,
u32 a=0, r=0, g=0, b=0; u32 a=0, r=0, g=0, b=0;
SColor c; SColor c;
for (s32 dy=0; dy<2; ++dy) for (s32 dy=0; dy<dy_max; ++dy)
{ {
const s32 tgy = (y*2)+dy; const s32 tgy = (y*2)+dy;
for (s32 dx=0; dx<2; ++dx) for (s32 dx=0; dx<dx_max; ++dx)
{ {
const s32 tgx = (x*2)+dx; const s32 tgx = (x*2)+dx;
...@@ -653,10 +662,10 @@ void CD3D9Texture::copy32BitMipMap(char* src, char* tgt, ...@@ -653,10 +662,10 @@ void CD3D9Texture::copy32BitMipMap(char* src, char* tgt,
} }
} }
a /= 4; a /= blockcount;
r /= 4; r /= blockcount;
g /= 4; g /= blockcount;
b /= 4; b /= blockcount;
c.set(a, r, g, b); c.set(a, r, g, b);
*(u32*)(&tgt[(x*4)+(y*pitchtgt)]) = c.color; *(u32*)(&tgt[(x*4)+(y*pitchtgt)]) = c.color;
......
...@@ -94,11 +94,15 @@ private: ...@@ -94,11 +94,15 @@ private:
//! Helper function for mipmap generation. //! Helper function for mipmap generation.
void copy16BitMipMap(char* src, char* tgt, void copy16BitMipMap(char* src, char* tgt,
s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const; const s32 srcWidth, const s32 srcHeight,
const s32 width, const s32 height,
const s32 pitchsrc, const s32 pitchtgt) const;
//! Helper function for mipmap generation. //! Helper function for mipmap generation.
void copy32BitMipMap(char* src, char* tgt, void copy32BitMipMap(char* src, char* tgt,
s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const; const s32 srcWidth, const s32 srcHeight,
const s32 width, const s32 height,
const s32 pitchsrc, const s32 pitchtgt) const;
//! set Pitch based on the d3d format //! set Pitch based on the d3d format
void setPitch(D3DFORMAT d3dformat); void setPitch(D3DFORMAT d3dformat);
......
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