fixup! fixed the deswizzling logic. Patch by @yuriks

This commit is contained in:
Subv 2015-08-16 20:41:54 -05:00
parent 1e5a32fce3
commit 3b6c037ba2
2 changed files with 58 additions and 20 deletions

View File

@ -849,21 +849,25 @@ void RasterizerOpenGL::ReloadColorBuffer() {
std::unique_ptr<u8[]> temp_fb_color_buffer(new u8[fb_color_texture.width * fb_color_texture.height * bytes_per_pixel]); std::unique_ptr<u8[]> temp_fb_color_buffer(new u8[fb_color_texture.width * fb_color_texture.height * bytes_per_pixel]);
// Directly copy pixels. The OpenGL internal formats match the 3DS ones, so no conversion is necessary. // Directly copy pixels. The OpenGL internal formats match the 3DS ones, so no conversion is necessary.
using VideoCore::CopyTextureAndUntile;
switch (bytes_per_pixel) { switch (bytes_per_pixel) {
case 4: case 4:
VideoCore::CopyTextureAndTile<u32>((u32*)temp_fb_color_buffer.get(), (u32*)color_buffer, fb_color_texture.width, fb_color_texture.height); CopyTextureAndUntile<u32>(reinterpret_cast<u32*>(temp_fb_color_buffer.get()),
reinterpret_cast<u32*>(color_buffer),
fb_color_texture.width, fb_color_texture.height);
break; break;
case 3: case 3:
VideoCore::CopyTextureAndTile<u24_be>((u24_be*)temp_fb_color_buffer.get(), (u24_be*)color_buffer, fb_color_texture.width, fb_color_texture.height); CopyTextureAndUntile<u24_be>(reinterpret_cast<u24_be*>(temp_fb_color_buffer.get()),
reinterpret_cast<u24_be*>(color_buffer),
fb_color_texture.width, fb_color_texture.height);
break; break;
case 2: case 2:
VideoCore::CopyTextureAndTile<u16>((u16*)temp_fb_color_buffer.get(), (u16*)color_buffer, fb_color_texture.width, fb_color_texture.height); CopyTextureAndUntile<u16>(reinterpret_cast<u16*>(temp_fb_color_buffer.get()),
break; reinterpret_cast<u16*>(color_buffer),
case 1: fb_color_texture.width, fb_color_texture.height);
VideoCore::CopyTextureAndTile<u8>(temp_fb_color_buffer.get(), color_buffer, fb_color_texture.width, fb_color_texture.height);
break; break;
default: default:
LOG_ERROR(Render_OpenGL, "Unimplemented pixel size %u bytes per pixel", bytes_per_pixel); UNREACHABLE();
} }
state.texture_units[0].texture_2d = fb_color_texture.texture.handle; state.texture_units[0].texture_2d = fb_color_texture.texture.handle;
@ -968,21 +972,25 @@ void RasterizerOpenGL::CommitColorBuffer() {
state.Apply(); state.Apply();
// Directly copy pixels. The OpenGL internal formats match the 3DS ones, so no conversion is necessary. // Directly copy pixels. The OpenGL internal formats match the 3DS ones, so no conversion is necessary.
using VideoCore::CopyTextureAndTile;
switch (bytes_per_pixel) { switch (bytes_per_pixel) {
case 4: case 4:
VideoCore::CopyTextureAndTile<u32>((u32*)color_buffer, (u32*)temp_gl_color_buffer.get(), fb_color_texture.width, fb_color_texture.height); CopyTextureAndTile<u32>(reinterpret_cast<u32*>(color_buffer),
reinterpret_cast<u32*>(temp_gl_color_buffer.get()),
fb_color_texture.width, fb_color_texture.height);
break; break;
case 3: case 3:
VideoCore::CopyTextureAndTile<u24_be>((u24_be*)color_buffer, (u24_be*)temp_gl_color_buffer.get(), fb_color_texture.width, fb_color_texture.height); CopyTextureAndTile<u24_be>(reinterpret_cast<u24_be*>(color_buffer),
reinterpret_cast<u24_be*>(temp_gl_color_buffer.get()),
fb_color_texture.width, fb_color_texture.height);
break; break;
case 2: case 2:
VideoCore::CopyTextureAndTile<u16>((u16*)color_buffer, (u16*)temp_gl_color_buffer.get(), fb_color_texture.width, fb_color_texture.height); CopyTextureAndTile<u16>(reinterpret_cast<u16*>(color_buffer),
break; reinterpret_cast<u16*>(temp_gl_color_buffer.get()),
case 1: fb_color_texture.width, fb_color_texture.height);
VideoCore::CopyTextureAndTile<u8>(color_buffer, temp_gl_color_buffer.get(), fb_color_texture.width, fb_color_texture.height);
break; break;
default: default:
LOG_ERROR(Render_OpenGL, "Unimplemented pixel size %u bytes per pixel", bytes_per_pixel); UNREACHABLE();
} }
} }
} }

View File

@ -57,13 +57,15 @@ static inline u32 MortonInterleave(u32 x, u32 y) {
} }
/** /**
* Copies the texture data from the source address to the destination address, * Copies the texture data from the source address to the destination address, applying a
* applying a Morton-order transformation while copying. * Morton-order transformation while copying.
*
* @param T Type of the source and destination pointers, the swizzling process depends on the size
* of this parameter.
* @param dst Pointer to which the texture will be copied. * @param dst Pointer to which the texture will be copied.
* @param src Pointer to the source texture data. * @param src Pointer to the source texture data.
* @param width Width of the texture, should be a multiple of 8. * @param width Width of the texture, should be a multiple of 8.
* @param height Height of the texture, should be a multiple of 8. * @param height Height of the texture, should be a multiple of 8.
* @param T Type of the source and destination pointers, the swizzling process depends on the size of this parameter.
*/ */
template<typename T> template<typename T>
static inline void CopyTextureAndTile(T* dst, const T* src, unsigned int width, unsigned int height) { static inline void CopyTextureAndTile(T* dst, const T* src, unsigned int width, unsigned int height) {
@ -83,6 +85,34 @@ static inline void CopyTextureAndTile(T* dst, const T* src, unsigned int width,
} }
} }
/**
* Copies texture data while undoing the transformation applied by `CopyTextureAndTile`.
*
* @param T Type of the source and destination pointers, the swizzling process depends on the size
* of this parameter.
* @param dst Pointer to which the texture will be copied.
* @param src Pointer to the source texture data.
* @param width Width of the texture, should be a multiple of 8.
* @param height Height of the texture, should be a multiple of 8.
*/
template<typename T>
static inline void CopyTextureAndUntile(T* dst, const T* src, unsigned int width, unsigned int height) {
for (unsigned int y = 0; y + 8 <= height; y += 8) {
for (unsigned int x = 0; x + 8 <= width; x += 8) {
T* line = &dst[y * width + x];
for (unsigned int yy = 0; yy < 8; ++yy) {
for (unsigned int xx = 0; xx < 8; ++xx) {
line[xx] = src[morton_lut[yy * 8 + xx]];
}
line += width;
}
src += 8 * 8;
}
}
}
/** /**
* Calculates the offset of the position of the pixel in Morton order * Calculates the offset of the position of the pixel in Morton order
*/ */