mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-02 06:44:45 +00:00
softgpu: Fix incorrect depth buffer write base address.
softgpu: Implement framebuffer pixel formats different than RGBA8888. softgpu: Move texel decoding functions to a separate header.
This commit is contained in:
parent
b2d4df2ddf
commit
a013aad6f1
@ -163,6 +163,7 @@
|
||||
<ClInclude Include="Math3D.h" />
|
||||
<ClInclude Include="Null\NullGpu.h" />
|
||||
<ClInclude Include="Software\Clipper.h" />
|
||||
<ClInclude Include="Software\Colors.h" />
|
||||
<ClInclude Include="Software\Lighting.h" />
|
||||
<ClInclude Include="Software\Rasterizer.h" />
|
||||
<ClInclude Include="Software\SoftGpu.h" />
|
||||
|
@ -68,6 +68,9 @@
|
||||
<ClInclude Include="GLES\TextureScaler.h">
|
||||
<Filter>GLES</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Software\Colors.h">
|
||||
<Filter>Software</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Software\Clipper.h">
|
||||
<Filter>Software</Filter>
|
||||
</ClInclude>
|
||||
|
@ -211,6 +211,7 @@ struct GPUgstate
|
||||
float tgenMatrix[12];
|
||||
float boneMatrix[12 * 8]; // Eight bone matrices.
|
||||
|
||||
GEBufferFormat FrameBufFormat() const { return static_cast<GEBufferFormat>(framebufpixformat & 3); }
|
||||
int FrameBufStride() const { return fbwidth&0x7C0; }
|
||||
int DepthBufStride() const { return fbwidth&0x7C0; }
|
||||
|
||||
|
104
GPU/Software/Colors.h
Normal file
104
GPU/Software/Colors.h
Normal file
@ -0,0 +1,104 @@
|
||||
// Copyright (c) 2013- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CommonTypes.h"
|
||||
|
||||
static inline u32 DecodeRGBA4444(u16 src)
|
||||
{
|
||||
u8 r = (src>>12) & 0x0F;
|
||||
u8 g = (src>>8) & 0x0F;
|
||||
u8 b = (src>>4) & 0x0F;
|
||||
u8 a = (src>>0) & 0x0F;
|
||||
r = (r << 4) | r;
|
||||
g = (g << 4) | g;
|
||||
b = (b << 4) | b;
|
||||
a = (a << 4) | a;
|
||||
return (a << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
|
||||
static inline u32 DecodeRGBA5551(u16 src)
|
||||
{
|
||||
u8 r = src & 0x1F;
|
||||
u8 g = (src >> 5) & 0x1F;
|
||||
u8 b = (src >> 10) & 0x1F;
|
||||
u8 a = (src >> 15) & 0x1;
|
||||
r = (r << 3) | (r >> 2);
|
||||
g = (g << 3) | (g >> 2);
|
||||
b = (b << 3) | (b >> 2);
|
||||
a = (a) ? 0xff : 0;
|
||||
return (a << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
|
||||
static inline u32 DecodeRGB565(u16 src)
|
||||
{
|
||||
u8 r = src & 0x1F;
|
||||
u8 g = (src >> 5) & 0x3F;
|
||||
u8 b = (src >> 11) & 0x1F;
|
||||
u8 a = 0xFF;
|
||||
r = (r << 3) | (r >> 2);
|
||||
g = (g << 2) | (g >> 4);
|
||||
b = (b << 3) | (b >> 2);
|
||||
return (a << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
|
||||
static inline u32 DecodeRGBA8888(u32 src)
|
||||
{
|
||||
u8 r = src & 0xFF;
|
||||
u8 g = (src >> 8) & 0xFF;
|
||||
u8 b = (src >> 16) & 0xFF;
|
||||
u8 a = (src >> 24) & 0xFF;
|
||||
return (a << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
|
||||
static inline u16 RGBA8888To565(u32 value)
|
||||
{
|
||||
u8 r = value & 0xFF;
|
||||
u8 g = (value >> 8) & 0xFF;
|
||||
u8 b = (value >> 16) & 0xFF;
|
||||
r >>= 3;
|
||||
g >>= 2;
|
||||
b >>= 3;
|
||||
return (u16)r | ((u16)g << 5) | ((u16)b << 11);
|
||||
}
|
||||
|
||||
static inline u16 RGBA8888To5551(u32 value)
|
||||
{
|
||||
u8 r = value & 0xFF;
|
||||
u8 g = (value >> 8) & 0xFF;
|
||||
u8 b = (value >> 16) & 0xFF;
|
||||
u8 a = (value >> 24) & 0xFF;
|
||||
r >>= 3;
|
||||
g >>= 3;
|
||||
b >>= 3;
|
||||
a >>= 7;
|
||||
return (u16)r | ((u16)g << 5) | ((u16)b << 10) | ((u16)a << 15);
|
||||
}
|
||||
|
||||
static inline u16 RGBA8888To4444(u32 value)
|
||||
{
|
||||
u8 r = value & 0xFF;
|
||||
u8 g = (value >> 8) & 0xFF;
|
||||
u8 b = (value >> 16) & 0xFF;
|
||||
u8 a = (value >> 24) & 0xFF;
|
||||
r >>= 4;
|
||||
g >>= 4;
|
||||
b >>= 4;
|
||||
a >>= 4;
|
||||
return (u16)r | ((u16)g << 4) | ((u16)b << 8) | ((u16)a << 12);
|
||||
}
|
@ -19,6 +19,7 @@
|
||||
#include "../GPUState.h"
|
||||
|
||||
#include "Rasterizer.h"
|
||||
#include "Colors.h"
|
||||
|
||||
extern u8* fb;
|
||||
extern u8* depthbuf;
|
||||
@ -53,53 +54,6 @@ static inline int GetPixelDataOffset(unsigned int texel_size_bits, unsigned int
|
||||
return tile_idx * tile_size_bits/8 + ((u % (tile_size_bits / texel_size_bits)));
|
||||
}
|
||||
|
||||
static inline u32 DecodeRGBA4444(u16 src)
|
||||
{
|
||||
u8 r = src & 0x0F;
|
||||
u8 g = (src>>4) & 0x0F;
|
||||
u8 b = (src>>8) & 0x0F;
|
||||
u8 a = (src>>12) & 0x0F;
|
||||
r = (r << 4) | r;
|
||||
g = (g << 4) | g;
|
||||
b = (b << 4) | b;
|
||||
a = (a << 4) | a;
|
||||
return (a << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
|
||||
static inline u32 DecodeRGBA5551(u16 src)
|
||||
{
|
||||
u8 r = src & 0x1F;
|
||||
u8 g = (src >> 5) & 0x1F;
|
||||
u8 b = (src >> 10) & 0x1F;
|
||||
u8 a = (src >> 15) & 0x1;
|
||||
r = (r << 3) | (r >> 2);
|
||||
g = (g << 3) | (g >> 2);
|
||||
b = (b << 3) | (b >> 2);
|
||||
a = (a) ? 0xff : 0;
|
||||
return (a << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
|
||||
static inline u32 DecodeRGB565(u16 src)
|
||||
{
|
||||
u8 r = src & 0x1F;
|
||||
u8 g = (src >> 5) & 0x3F;
|
||||
u8 b = (src >> 11) & 0x1F;
|
||||
u8 a = 0xFF;
|
||||
r = (r << 3) | (r >> 2);
|
||||
g = (g << 2) | (g >> 4);
|
||||
b = (b << 3) | (b >> 2);
|
||||
return (a << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
|
||||
static inline u32 DecodeRGBA8888(u32 src)
|
||||
{
|
||||
u8 r = src & 0xFF;
|
||||
u8 g = (src >> 8) & 0xFF;
|
||||
u8 b = (src >> 16) & 0xFF;
|
||||
u8 a = (src >> 24) & 0xFF;
|
||||
return (a << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
|
||||
static inline u32 LookupColor(unsigned int index, unsigned int level)
|
||||
{
|
||||
const bool mipmapShareClut = (gstate.texmode & 0x100) == 0;
|
||||
@ -199,13 +153,41 @@ static inline u32 SampleNearest(int level, float s, float t)
|
||||
// NOTE: These likely aren't endian safe
|
||||
static inline u32 GetPixelColor(int x, int y)
|
||||
{
|
||||
// TODO: Fix for other pixel formats!
|
||||
return *(u32*)&fb[4*x + 4*y*gstate.FrameBufStride()];
|
||||
switch (gstate.FrameBufFormat()) {
|
||||
case GE_FORMAT_565:
|
||||
return DecodeRGB565(*(u16*)&fb[4*x + 4*y*gstate.FrameBufStride()]);
|
||||
|
||||
case GE_FORMAT_5551:
|
||||
return DecodeRGBA5551(*(u16*)&fb[4*x + 4*y*gstate.FrameBufStride()]);
|
||||
|
||||
case GE_FORMAT_4444:
|
||||
return DecodeRGBA4444(*(u16*)&fb[4*x + 4*y*gstate.FrameBufStride()]);
|
||||
|
||||
case GE_FORMAT_8888:
|
||||
return *(u32*)&fb[4*x + 4*y*gstate.FrameBufStride()];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void SetPixelColor(int x, int y, u32 value)
|
||||
{
|
||||
*(u32*)&fb[4*x + 4*y*gstate.FrameBufStride()] = value;
|
||||
switch (gstate.FrameBufFormat()) {
|
||||
case GE_FORMAT_565:
|
||||
*(u16*)&fb[4*x + 4*y*gstate.FrameBufStride()] = RGBA8888To565(value);
|
||||
break;
|
||||
|
||||
case GE_FORMAT_5551:
|
||||
*(u16*)&fb[4*x + 4*y*gstate.FrameBufStride()] = RGBA8888To5551(value);
|
||||
break;
|
||||
|
||||
case GE_FORMAT_4444:
|
||||
*(u16*)&fb[4*x + 4*y*gstate.FrameBufStride()] = RGBA8888To4444(value);
|
||||
break;
|
||||
|
||||
case GE_FORMAT_8888:
|
||||
*(u32*)&fb[4*x + 4*y*gstate.FrameBufStride()] = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 GetPixelDepth(int x, int y)
|
||||
@ -220,11 +202,13 @@ static inline void SetPixelDepth(int x, int y, u16 value)
|
||||
|
||||
static inline u8 GetPixelStencil(int x, int y)
|
||||
{
|
||||
// TODO: Fix for other pixel formats ?
|
||||
return (((*(u32*)&fb[4*x + 4*y*gstate.FrameBufStride()]) & 0x80000000) != 0) ? 0xFF : 0;
|
||||
}
|
||||
|
||||
static inline void SetPixelStencil(int x, int y, u8 value)
|
||||
{
|
||||
// TODO: Fix for other pixel formats ?
|
||||
*(u32*)&fb[4*x + 4*y*gstate.FrameBufStride()] = (*(u32*)&fb[4*x + 4*y*gstate.FrameBufStride()] & ~0x80000000) | ((value&0x80)<<24);
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "SoftGpu.h"
|
||||
#include "TransformUnit.h"
|
||||
#include "Colors.h"
|
||||
|
||||
static GLuint temp_texture = 0;
|
||||
|
||||
@ -156,7 +157,29 @@ void CopyToCurrentFboFromRam(u8* data, int srcwidth, int srcheight, int dstwidth
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, temp_texture);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)srcwidth, (GLsizei)srcheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
if (gstate.FrameBufFormat() == GE_FORMAT_8888) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)srcwidth, (GLsizei)srcheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
} else {
|
||||
// TODO: This should probably be converted in a shader instead..
|
||||
// TODO: Do something less brain damaged to manage this buffer...
|
||||
u32* buf = new u32[srcwidth*srcheight];
|
||||
for (int y = 0; y < srcheight; ++y) {
|
||||
for (int x = 0; x < srcwidth; ++x) {
|
||||
u16 src = *(u16*)&fb[4*x + 4*y*gstate.FrameBufStride()];
|
||||
|
||||
if (gstate.FrameBufFormat() == GE_FORMAT_565)
|
||||
buf[x+y*srcwidth] = DecodeRGB565(src);
|
||||
else if (gstate.FrameBufFormat() == GE_FORMAT_5551)
|
||||
buf[x+y*srcwidth] = DecodeRGBA5551(src);
|
||||
else if (gstate.FrameBufFormat() == GE_FORMAT_4444)
|
||||
buf[x+y*srcwidth] = DecodeRGBA4444(src);
|
||||
}
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)srcwidth, (GLsizei)srcheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
|
||||
|
||||
delete[] buf;
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
@ -255,7 +278,6 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff)
|
||||
|
||||
if (type != GE_PRIM_TRIANGLES && type != GE_PRIM_TRIANGLE_STRIP && type != GE_PRIM_RECTANGLES)
|
||||
break;
|
||||
|
||||
// ERROR_LOG(G3D, "DL DrawPrim type: %s count: %i vaddr= %08x, iaddr= %08x", type<7 ? types[type] : "INVALID", count, gstate_c.vertexAddr, gstate_c.indexAddr);
|
||||
|
||||
void *verts = Memory::GetPointer(gstate_c.vertexAddr);
|
||||
@ -542,7 +564,7 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff)
|
||||
case GE_CMD_ZBUFPTR:
|
||||
{
|
||||
u32 ptr = op & 0xFFE000;
|
||||
depthbuf = Memory::GetPointer(0x44000000 | (gstate.fbptr & 0xFFE000) | ((gstate.fbwidth & 0xFF0000) << 8));
|
||||
depthbuf = Memory::GetPointer(0x44000000 | (gstate.zbptr & 0xFFE000) | ((gstate.zbwidth & 0xFF0000) << 8));
|
||||
DEBUG_LOG(G3D,"Zbuf Ptr: %06x", ptr);
|
||||
}
|
||||
break;
|
||||
@ -550,7 +572,7 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff)
|
||||
case GE_CMD_ZBUFWIDTH:
|
||||
{
|
||||
u32 w = data & 0xFFFFFF;
|
||||
depthbuf = Memory::GetPointer(0x44000000 | (gstate.fbptr & 0xFFE000) | ((gstate.fbwidth & 0xFF0000) << 8));
|
||||
depthbuf = Memory::GetPointer(0x44000000 | (gstate.zbptr & 0xFFE000) | ((gstate.zbwidth & 0xFF0000) << 8));
|
||||
DEBUG_LOG(G3D,"Zbuf Width: %i", w);
|
||||
}
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user