mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
Centralize color conversion functions in Common/ColorConv.
This commit is contained in:
parent
41001637ce
commit
2623a48b4a
@ -326,6 +326,8 @@ add_library(Common STATIC
|
||||
${CommonExtra}
|
||||
Common/ChunkFile.cpp
|
||||
Common/ChunkFile.h
|
||||
Common/ColorConv.cpp
|
||||
Common/ColorConv.h
|
||||
Common/ConsoleListener.cpp
|
||||
Common/ConsoleListener.h
|
||||
Common/Crypto/md5.cpp
|
||||
|
271
Common/ColorConv.cpp
Normal file
271
Common/ColorConv.cpp
Normal file
@ -0,0 +1,271 @@
|
||||
// Copyright (C) 2015 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/.
|
||||
|
||||
#include "ColorConv.h"
|
||||
#include "CommonTypes.h"
|
||||
|
||||
inline u16 RGBA8888toRGB565(u32 px) {
|
||||
return ((px >> 3) & 0x001F) | ((px >> 5) & 0x07E0) | ((px >> 8) & 0xF800);
|
||||
}
|
||||
|
||||
inline u16 RGBA8888toRGBA4444(u32 px) {
|
||||
return ((px >> 4) & 0x000F) | ((px >> 8) & 0x00F0) | ((px >> 12) & 0x0F00) | ((px >> 16) & 0xF000);
|
||||
}
|
||||
|
||||
inline u16 RGBA8888toRGBA5551(u32 px) {
|
||||
return ((px >> 3) & 0x001F) | ((px >> 6) & 0x03E0) | ((px >> 9) & 0x7C00) | ((px >> 16) & 0x8000);
|
||||
}
|
||||
|
||||
inline u16 BGRA8888toRGB565(u32 px) {
|
||||
return ((px >> 19) & 0x001F) | ((px >> 5) & 0x07E0) | ((px << 8) & 0xF800);
|
||||
}
|
||||
|
||||
inline u16 BGRA8888toRGBA4444(u32 px) {
|
||||
return ((px >> 20) & 0x000F) | ((px >> 8) & 0x00F0) | ((px << 4) & 0x0F00) | ((px >> 16) & 0xF000);
|
||||
}
|
||||
|
||||
inline u32 RGBA2BGRA(u32 src) {
|
||||
const u32 r = (src & 0x000000FF) << 16;
|
||||
const u32 ga = src & 0xFF00FF00;
|
||||
const u32 b = (src & 0x00FF0000) >> 16;
|
||||
return r | ga | b;
|
||||
}
|
||||
|
||||
// convert 4444 image to 8888, parallelizable
|
||||
void convert4444(u16* data, u32* out, int width, int l, int u) {
|
||||
for (int y = l; y < u; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
u32 val = data[y*width + x];
|
||||
u32 r = ((val >> 12) & 0xF) * 17;
|
||||
u32 g = ((val >> 8) & 0xF) * 17;
|
||||
u32 b = ((val >> 4) & 0xF) * 17;
|
||||
u32 a = ((val >> 0) & 0xF) * 17;
|
||||
out[y*width + x] = (a << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// convert 565 image to 8888, parallelizable
|
||||
void convert565(u16* data, u32* out, int width, int l, int u) {
|
||||
for (int y = l; y < u; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
u32 val = data[y*width + x];
|
||||
u32 r = Convert5To8((val >> 11) & 0x1F);
|
||||
u32 g = Convert6To8((val >> 5) & 0x3F);
|
||||
u32 b = Convert5To8((val) & 0x1F);
|
||||
out[y*width + x] = (0xFF << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// convert 5551 image to 8888, parallelizable
|
||||
void convert5551(u16* data, u32* out, int width, int l, int u) {
|
||||
for (int y = l; y < u; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
u32 val = data[y*width + x];
|
||||
u32 r = Convert5To8((val >> 11) & 0x1F);
|
||||
u32 g = Convert5To8((val >> 6) & 0x1F);
|
||||
u32 b = Convert5To8((val >> 1) & 0x1F);
|
||||
u32 a = (val & 0x1) * 255;
|
||||
out[y*width + x] = (a << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertBGRA8888ToRGB565(u16 *dst, const u32 *src, const u32 numPixels) {
|
||||
for (u32 x = 0; x < numPixels; ++x) {
|
||||
dst[x] = BGRA8888toRGB565(src[x]);
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertRGBA8888ToRGB565(u16 *dst, const u32 *src, const u32 numPixels) {
|
||||
for (u32 x = 0; x < numPixels; ++x) {
|
||||
dst[x] = RGBA8888toRGB565(src[x]);
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertBGRA8888ToRGBA4444(u16 *dst, const u32 *src, const u32 numPixels) {
|
||||
for (u32 x = 0; x < numPixels; ++x) {
|
||||
dst[x] = BGRA8888toRGBA4444(src[x]);
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertRGBA8888ToRGBA4444(u16 *dst, const u32 *src, const u32 numPixels) {
|
||||
for (u32 x = 0; x < numPixels; ++x) {
|
||||
dst[x] = RGBA8888toRGBA4444(src[x]);
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertBGRA8888ToRGBA8888(u32 *dst, const u32 *src, const u32 numPixels) {
|
||||
#ifdef _M_SSE
|
||||
const __m128i maskGA = _mm_set1_epi32(0xFF00FF00);
|
||||
|
||||
const __m128i *srcp = (const __m128i *)src;
|
||||
__m128i *dstp = (__m128i *)dst;
|
||||
u32 sseChunks = numPixels / 4;
|
||||
if (((intptr_t)src & 0xF) || ((intptr_t)dst & 0xF)) {
|
||||
sseChunks = 0;
|
||||
}
|
||||
for (u32 i = 0; i < sseChunks; ++i) {
|
||||
__m128i c = _mm_load_si128(&srcp[i]);
|
||||
__m128i rb = _mm_andnot_si128(maskGA, c);
|
||||
c = _mm_and_si128(c, maskGA);
|
||||
|
||||
__m128i b = _mm_srli_epi32(rb, 16);
|
||||
__m128i r = _mm_slli_epi32(rb, 16);
|
||||
c = _mm_or_si128(_mm_or_si128(c, r), b);
|
||||
_mm_store_si128(&dstp[i], c);
|
||||
}
|
||||
// The remainder starts right after those done via SSE.
|
||||
u32 i = sseChunks * 4;
|
||||
#else
|
||||
u32 i = 0;
|
||||
#endif
|
||||
for (; i < numPixels; i++) {
|
||||
const u32 c = src[i];
|
||||
dst[i] = ((c >> 16) & 0x000000FF) |
|
||||
((c >> 0) & 0xFF00FF00) |
|
||||
((c << 16) & 0x00FF0000);
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertRGBA8888ToRGBA5551(u16 *dst, const u32 *src, const u32 numPixels) {
|
||||
#if _M_SSE >= 0x401
|
||||
const __m128i maskAG = _mm_set1_epi32(0x8000F800);
|
||||
const __m128i maskRB = _mm_set1_epi32(0x00F800F8);
|
||||
const __m128i mask = _mm_set1_epi32(0x0000FFFF);
|
||||
|
||||
const __m128i *srcp = (const __m128i *)src;
|
||||
__m128i *dstp = (__m128i *)dst;
|
||||
u32 sseChunks = (numPixels / 4) & ~1;
|
||||
// SSE 4.1 required for _mm_packus_epi32.
|
||||
if (((intptr_t)src & 0xF) || ((intptr_t)dst & 0xF) || !cpu_info.bSSE4_1) {
|
||||
sseChunks = 0;
|
||||
}
|
||||
for (u32 i = 0; i < sseChunks; i += 2) {
|
||||
__m128i c1 = _mm_load_si128(&srcp[i + 0]);
|
||||
__m128i c2 = _mm_load_si128(&srcp[i + 1]);
|
||||
__m128i ag, rb;
|
||||
|
||||
ag = _mm_and_si128(c1, maskAG);
|
||||
ag = _mm_or_si128(_mm_srli_epi32(ag, 16), _mm_srli_epi32(ag, 6));
|
||||
rb = _mm_and_si128(c1, maskRB);
|
||||
rb = _mm_or_si128(_mm_srli_epi32(rb, 3), _mm_srli_epi32(rb, 9));
|
||||
c1 = _mm_and_si128(_mm_or_si128(ag, rb), mask);
|
||||
|
||||
ag = _mm_and_si128(c2, maskAG);
|
||||
ag = _mm_or_si128(_mm_srli_epi32(ag, 16), _mm_srli_epi32(ag, 6));
|
||||
rb = _mm_and_si128(c2, maskRB);
|
||||
rb = _mm_or_si128(_mm_srli_epi32(rb, 3), _mm_srli_epi32(rb, 9));
|
||||
c2 = _mm_and_si128(_mm_or_si128(ag, rb), mask);
|
||||
|
||||
_mm_store_si128(&dstp[i / 2], _mm_packus_epi32(c1, c2));
|
||||
}
|
||||
// The remainder starts right after those done via SSE.
|
||||
u32 i = sseChunks * 4;
|
||||
#else
|
||||
u32 i = 0;
|
||||
#endif
|
||||
for (; i < numPixels; i++) {
|
||||
dst[i] = RGBA8888toRGBA5551(src[i]);
|
||||
}
|
||||
}
|
||||
|
||||
inline u16 BGRA8888toRGBA5551(u32 px) {
|
||||
return ((px >> 19) & 0x001F) | ((px >> 6) & 0x03E0) | ((px << 7) & 0x7C00) | ((px >> 16) & 0x8000);
|
||||
}
|
||||
|
||||
void ConvertBGRA8888ToRGBA5551(u16 *dst, const u32 *src, const u32 numPixels) {
|
||||
#if _M_SSE >= 0x401
|
||||
const __m128i maskAG = _mm_set1_epi32(0x8000F800);
|
||||
const __m128i maskRB = _mm_set1_epi32(0x00F800F8);
|
||||
const __m128i mask = _mm_set1_epi32(0x0000FFFF);
|
||||
|
||||
const __m128i *srcp = (const __m128i *)src;
|
||||
__m128i *dstp = (__m128i *)dst;
|
||||
u32 sseChunks = (numPixels / 4) & ~1;
|
||||
// SSE 4.1 required for _mm_packus_epi32.
|
||||
if (((intptr_t)src & 0xF) || ((intptr_t)dst & 0xF) || !cpu_info.bSSE4_1) {
|
||||
sseChunks = 0;
|
||||
}
|
||||
for (u32 i = 0; i < sseChunks; i += 2) {
|
||||
__m128i c1 = _mm_load_si128(&srcp[i + 0]);
|
||||
__m128i c2 = _mm_load_si128(&srcp[i + 1]);
|
||||
__m128i ag, rb;
|
||||
|
||||
ag = _mm_and_si128(c1, maskAG);
|
||||
ag = _mm_or_si128(_mm_srli_epi32(ag, 16), _mm_srli_epi32(ag, 6));
|
||||
rb = _mm_and_si128(c1, maskRB);
|
||||
rb = _mm_or_si128(_mm_srli_epi32(rb, 19), _mm_slli_epi32(rb, 7));
|
||||
c1 = _mm_and_si128(_mm_or_si128(ag, rb), mask);
|
||||
|
||||
ag = _mm_and_si128(c2, maskAG);
|
||||
ag = _mm_or_si128(_mm_srli_epi32(ag, 16), _mm_srli_epi32(ag, 6));
|
||||
rb = _mm_and_si128(c2, maskRB);
|
||||
rb = _mm_or_si128(_mm_srli_epi32(rb, 19), _mm_slli_epi32(rb, 7));
|
||||
c2 = _mm_and_si128(_mm_or_si128(ag, rb), mask);
|
||||
|
||||
_mm_store_si128(&dstp[i / 2], _mm_packus_epi32(c1, c2));
|
||||
}
|
||||
// The remainder starts right after those done via SSE.
|
||||
u32 i = sseChunks * 4;
|
||||
#else
|
||||
u32 i = 0;
|
||||
#endif
|
||||
for (; i < numPixels; i++) {
|
||||
dst[i] = BGRA8888toRGBA5551(src[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertRGB565ToRGBA888F(u32 *dst32, const u16 *src, int numPixels) {
|
||||
u8 *dst = (u8 *)dst32;
|
||||
for (int x = 0; x < numPixels; x++) {
|
||||
u16 col = src[x];
|
||||
dst[x * 4] = Convert5To8((col)& 0x1f);
|
||||
dst[x * 4 + 1] = Convert6To8((col >> 5) & 0x3f);
|
||||
dst[x * 4 + 2] = Convert5To8((col >> 11) & 0x1f);
|
||||
dst[x * 4 + 3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertRGBA5551ToRGBA8888(u32 *dst32, const u16 *src, int numPixels) {
|
||||
u8 *dst = (u8 *)dst32;
|
||||
for (int x = 0; x < numPixels; x++) {
|
||||
u16 col = src[x];
|
||||
dst[x * 4] = Convert5To8((col)& 0x1f);
|
||||
dst[x * 4 + 1] = Convert5To8((col >> 5) & 0x1f);
|
||||
dst[x * 4 + 2] = Convert5To8((col >> 10) & 0x1f);
|
||||
dst[x * 4 + 3] = (col >> 15) ? 255 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertRGBA4444ToRGBA8888(u32 *dst32, const u16 *src, int numPixels) {
|
||||
u8 *dst = (u8 *)dst32;
|
||||
for (int x = 0; x < numPixels; x++) {
|
||||
u16 col = src[x];
|
||||
dst[x * 4] = Convert4To8((col >> 8) & 0xf);
|
||||
dst[x * 4 + 1] = Convert4To8((col >> 4) & 0xf);
|
||||
dst[x * 4 + 2] = Convert4To8(col & 0xf);
|
||||
dst[x * 4 + 3] = Convert4To8(col >> 12);
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertBGRA8888ToRGBA8888(u32 *dst, const u32 *src, int numPixels) {
|
||||
for (int x = 0; x < numPixels; x++) {
|
||||
dst[x] = RGBA2BGRA(src[x]);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013- PPSSPP Project.
|
||||
// Copyright (C) 2015 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
|
||||
@ -15,12 +15,36 @@
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "CommonTypes.h"
|
||||
|
||||
static inline u32 DecodeRGBA4444(u16 src)
|
||||
{
|
||||
inline u8 Convert4To8(u8 v) {
|
||||
// Swizzle bits: 00001234 -> 12341234
|
||||
return (v << 4) | (v);
|
||||
}
|
||||
|
||||
inline u8 Convert5To8(u8 v) {
|
||||
// Swizzle bits: 00012345 -> 12345123
|
||||
return (v << 3) | (v >> 2);
|
||||
}
|
||||
|
||||
inline u8 Convert6To8(u8 v) {
|
||||
// Swizzle bits: 00123456 -> 12345612
|
||||
return (v << 2) | (v >> 4);
|
||||
}
|
||||
|
||||
// convert 4444 image to 8888
|
||||
void convert4444(u16* data, u32* out, int width, int l, int u);
|
||||
|
||||
// convert 565 image to 8888
|
||||
void convert565(u16* data, u32* out, int width, int l, int u);
|
||||
|
||||
// convert 5551 image to 8888
|
||||
void convert5551(u16* data, u32* out, int width, int l, int u);
|
||||
|
||||
inline u32 DecodeRGBA4444(u16 src) {
|
||||
const u32 r = (src & 0x000F) << 0;
|
||||
const u32 g = (src & 0x00F0) << 4;
|
||||
const u32 b = (src & 0x0F00) << 8;
|
||||
@ -30,8 +54,7 @@ static inline u32 DecodeRGBA4444(u16 src)
|
||||
return c | (c << 4);
|
||||
}
|
||||
|
||||
static inline u32 DecodeRGBA5551(u16 src)
|
||||
{
|
||||
inline u32 DecodeRGBA5551(u16 src) {
|
||||
u8 r = Convert5To8((src >> 0) & 0x1F);
|
||||
u8 g = Convert5To8((src >> 5) & 0x1F);
|
||||
u8 b = Convert5To8((src >> 10) & 0x1F);
|
||||
@ -40,8 +63,7 @@ static inline u32 DecodeRGBA5551(u16 src)
|
||||
return (a << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
|
||||
static inline u32 DecodeRGB565(u16 src)
|
||||
{
|
||||
inline u32 DecodeRGB565(u16 src) {
|
||||
u8 r = Convert5To8((src >> 0) & 0x1F);
|
||||
u8 g = Convert6To8((src >> 5) & 0x3F);
|
||||
u8 b = Convert5To8((src >> 11) & 0x1F);
|
||||
@ -49,8 +71,7 @@ static inline u32 DecodeRGB565(u16 src)
|
||||
return (a << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
|
||||
static inline u32 DecodeRGBA8888(u32 src)
|
||||
{
|
||||
inline u32 DecodeRGBA8888(u32 src) {
|
||||
#if 1
|
||||
return src;
|
||||
#else
|
||||
@ -63,8 +84,7 @@ static inline u32 DecodeRGBA8888(u32 src)
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline u16 RGBA8888To565(u32 value)
|
||||
{
|
||||
inline u16 RGBA8888To565(u32 value) {
|
||||
u8 r = value & 0xFF;
|
||||
u8 g = (value >> 8) & 0xFF;
|
||||
u8 b = (value >> 16) & 0xFF;
|
||||
@ -74,8 +94,7 @@ static inline u16 RGBA8888To565(u32 value)
|
||||
return (u16)r | ((u16)g << 5) | ((u16)b << 11);
|
||||
}
|
||||
|
||||
static inline u16 RGBA8888To5551(u32 value)
|
||||
{
|
||||
inline u16 RGBA8888To5551(u32 value) {
|
||||
u8 r = value & 0xFF;
|
||||
u8 g = (value >> 8) & 0xFF;
|
||||
u8 b = (value >> 16) & 0xFF;
|
||||
@ -87,12 +106,25 @@ static inline u16 RGBA8888To5551(u32 value)
|
||||
return (u16)r | ((u16)g << 5) | ((u16)b << 10) | ((u16)a << 15);
|
||||
}
|
||||
|
||||
static inline u16 RGBA8888To4444(u32 value)
|
||||
{
|
||||
static inline u16 RGBA8888To4444(u32 value) {
|
||||
const u32 c = value >> 4;
|
||||
const u16 r = (c >> 0) & 0x000F;
|
||||
const u16 g = (c >> 4) & 0x00F0;
|
||||
const u16 b = (c >> 8) & 0x0F00;
|
||||
const u16 r = (c >> 0) & 0x000F;
|
||||
const u16 g = (c >> 4) & 0x00F0;
|
||||
const u16 b = (c >> 8) & 0x0F00;
|
||||
const u16 a = (c >> 12) & 0xF000;
|
||||
return r | g | b | a;
|
||||
}
|
||||
|
||||
void ConvertBGRA8888ToRGB565(u16 *dst, const u32 *src, const u32 numPixels);
|
||||
void ConvertRGBA8888ToRGB565(u16 *dst, const u32 *src, const u32 numPixels);
|
||||
void ConvertBGRA8888ToRGBA4444(u16 *dst, const u32 *src, const u32 numPixels);
|
||||
void ConvertRGBA8888ToRGBA4444(u16 *dst, const u32 *src, const u32 numPixels);
|
||||
void ConvertBGRA8888ToRGBA8888(u32 *dst, const u32 *src, const u32 numPixels);
|
||||
void ConvertRGBA8888ToRGBA5551(u16 *dst, const u32 *src, const u32 numPixels);
|
||||
void ConvertBGRA8888ToRGBA5551(u16 *dst, const u32 *src, const u32 numPixels);
|
||||
|
||||
void ConvertRGB565ToRGBA888F(u32 *dst, const u16 *src, int numPixels);
|
||||
void ConvertRGBA5551ToRGBA8888(u32 *dst, const u16 *src, int numPixels);
|
||||
void ConvertRGBA4444ToRGBA8888(u32 *dst, const u16 *src, int numPixels);
|
||||
|
||||
void ConvertBGRA8888ToRGBA8888(u32 *dst, const u32 *src, int numPixels);
|
@ -194,6 +194,7 @@
|
||||
<ClInclude Include="BitSet.h" />
|
||||
<ClInclude Include="ChunkFile.h" />
|
||||
<ClInclude Include="CodeBlock.h" />
|
||||
<ClInclude Include="ColorConv.h" />
|
||||
<ClInclude Include="Common.h" />
|
||||
<ClInclude Include="CommonFuncs.h" />
|
||||
<ClInclude Include="CommonTypes.h" />
|
||||
@ -240,6 +241,7 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ChunkFile.cpp" />
|
||||
<ClCompile Include="ColorConv.cpp" />
|
||||
<ClCompile Include="ConsoleListener.cpp" />
|
||||
<ClCompile Include="CPUDetect.cpp" />
|
||||
<ClCompile Include="Crypto\md5.cpp" />
|
||||
|
@ -7,6 +7,7 @@
|
||||
<ClInclude Include="Atomic_GCC.h" />
|
||||
<ClInclude Include="Atomic_Win32.h" />
|
||||
<ClInclude Include="ChunkFile.h" />
|
||||
<ClInclude Include="ColorConv.h" />
|
||||
<ClInclude Include="Common.h" />
|
||||
<ClInclude Include="CommonFuncs.h" />
|
||||
<ClInclude Include="CommonTypes.h" />
|
||||
@ -49,6 +50,7 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp" />
|
||||
<ClCompile Include="ABI.cpp" />
|
||||
<ClCompile Include="ColorConv.cpp" />
|
||||
<ClCompile Include="ConsoleListener.cpp" />
|
||||
<ClCompile Include="CPUDetect.cpp" />
|
||||
<ClCompile Include="FileUtil.cpp" />
|
||||
@ -88,4 +90,4 @@
|
||||
<UniqueIdentifier>{1b593f03-7b28-4707-9228-4981796f5589}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
@ -23,6 +23,7 @@
|
||||
#endif
|
||||
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/ColorConv.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/Screenshot.h"
|
||||
#include "GPU/Common/GPUDebugInterface.h"
|
||||
@ -48,8 +49,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool put_buf(const void *buf, int len) override
|
||||
{
|
||||
bool put_buf(const void *buf, int len) override {
|
||||
if (fp_) {
|
||||
if (fwrite(buf, len, 1, fp_) != 1) {
|
||||
fclose(fp_);
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
#include "ext/xxhash.h"
|
||||
#include "Common/CPUDetect.h"
|
||||
#include "Common/ColorConv.h"
|
||||
|
||||
#include "GPU/Common/TextureDecoder.h"
|
||||
// NEON is in a separate file so that it can be compiled with a runtime check.
|
||||
#include "GPU/Common/TextureDecoderNEON.h"
|
||||
@ -327,128 +329,3 @@ void DecodeDXT5Block(u32 *dst, const DXT5Block *src, int pitch) {
|
||||
dst += pitch;
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertBGRA8888ToRGBA8888(u32 *dst, const u32 *src, const u32 numPixels) {
|
||||
#ifdef _M_SSE
|
||||
const __m128i maskGA = _mm_set1_epi32(0xFF00FF00);
|
||||
|
||||
const __m128i *srcp = (const __m128i *)src;
|
||||
__m128i *dstp = (__m128i *)dst;
|
||||
u32 sseChunks = numPixels / 4;
|
||||
if (((intptr_t)src & 0xF) || ((intptr_t)dst & 0xF)) {
|
||||
sseChunks = 0;
|
||||
}
|
||||
for (u32 i = 0; i < sseChunks; ++i) {
|
||||
__m128i c = _mm_load_si128(&srcp[i]);
|
||||
__m128i rb = _mm_andnot_si128(maskGA, c);
|
||||
c = _mm_and_si128(c, maskGA);
|
||||
|
||||
__m128i b = _mm_srli_epi32(rb, 16);
|
||||
__m128i r = _mm_slli_epi32(rb, 16);
|
||||
c = _mm_or_si128(_mm_or_si128(c, r), b);
|
||||
_mm_store_si128(&dstp[i], c);
|
||||
}
|
||||
// The remainder starts right after those done via SSE.
|
||||
u32 i = sseChunks * 4;
|
||||
#else
|
||||
u32 i = 0;
|
||||
#endif
|
||||
for (; i < numPixels; i++) {
|
||||
const u32 c = src[i];
|
||||
dst[i] = ((c >> 16) & 0x000000FF) |
|
||||
((c >> 0) & 0xFF00FF00) |
|
||||
((c << 16) & 0x00FF0000);
|
||||
}
|
||||
}
|
||||
|
||||
inline u16 RGBA8888toRGBA5551(u32 px) {
|
||||
return ((px >> 3) & 0x001F) | ((px >> 6) & 0x03E0) | ((px >> 9) & 0x7C00) | ((px >> 16) & 0x8000);
|
||||
}
|
||||
|
||||
void ConvertRGBA8888ToRGBA5551(u16 *dst, const u32 *src, const u32 numPixels) {
|
||||
#if _M_SSE >= 0x401
|
||||
const __m128i maskAG = _mm_set1_epi32(0x8000F800);
|
||||
const __m128i maskRB = _mm_set1_epi32(0x00F800F8);
|
||||
const __m128i mask = _mm_set1_epi32(0x0000FFFF);
|
||||
|
||||
const __m128i *srcp = (const __m128i *)src;
|
||||
__m128i *dstp = (__m128i *)dst;
|
||||
u32 sseChunks = (numPixels / 4) & ~1;
|
||||
// SSE 4.1 required for _mm_packus_epi32.
|
||||
if (((intptr_t)src & 0xF) || ((intptr_t)dst & 0xF) || !cpu_info.bSSE4_1) {
|
||||
sseChunks = 0;
|
||||
}
|
||||
for (u32 i = 0; i < sseChunks; i += 2) {
|
||||
__m128i c1 = _mm_load_si128(&srcp[i + 0]);
|
||||
__m128i c2 = _mm_load_si128(&srcp[i + 1]);
|
||||
__m128i ag, rb;
|
||||
|
||||
ag = _mm_and_si128(c1, maskAG);
|
||||
ag = _mm_or_si128(_mm_srli_epi32(ag, 16), _mm_srli_epi32(ag, 6));
|
||||
rb = _mm_and_si128(c1, maskRB);
|
||||
rb = _mm_or_si128(_mm_srli_epi32(rb, 3), _mm_srli_epi32(rb, 9));
|
||||
c1 = _mm_and_si128(_mm_or_si128(ag, rb), mask);
|
||||
|
||||
ag = _mm_and_si128(c2, maskAG);
|
||||
ag = _mm_or_si128(_mm_srli_epi32(ag, 16), _mm_srli_epi32(ag, 6));
|
||||
rb = _mm_and_si128(c2, maskRB);
|
||||
rb = _mm_or_si128(_mm_srli_epi32(rb, 3), _mm_srli_epi32(rb, 9));
|
||||
c2 = _mm_and_si128(_mm_or_si128(ag, rb), mask);
|
||||
|
||||
_mm_store_si128(&dstp[i / 2], _mm_packus_epi32(c1, c2));
|
||||
}
|
||||
// The remainder starts right after those done via SSE.
|
||||
u32 i = sseChunks * 4;
|
||||
#else
|
||||
u32 i = 0;
|
||||
#endif
|
||||
for (; i < numPixels; i++) {
|
||||
dst[i] = RGBA8888toRGBA5551(src[i]);
|
||||
}
|
||||
}
|
||||
|
||||
inline u16 BGRA8888toRGBA5551(u32 px) {
|
||||
return ((px >> 19) & 0x001F) | ((px >> 6) & 0x03E0) | ((px << 7) & 0x7C00) | ((px >> 16) & 0x8000);
|
||||
}
|
||||
|
||||
void ConvertBGRA8888ToRGBA5551(u16 *dst, const u32 *src, const u32 numPixels) {
|
||||
#if _M_SSE >= 0x401
|
||||
const __m128i maskAG = _mm_set1_epi32(0x8000F800);
|
||||
const __m128i maskRB = _mm_set1_epi32(0x00F800F8);
|
||||
const __m128i mask = _mm_set1_epi32(0x0000FFFF);
|
||||
|
||||
const __m128i *srcp = (const __m128i *)src;
|
||||
__m128i *dstp = (__m128i *)dst;
|
||||
u32 sseChunks = (numPixels / 4) & ~1;
|
||||
// SSE 4.1 required for _mm_packus_epi32.
|
||||
if (((intptr_t)src & 0xF) || ((intptr_t)dst & 0xF) || !cpu_info.bSSE4_1) {
|
||||
sseChunks = 0;
|
||||
}
|
||||
for (u32 i = 0; i < sseChunks; i += 2) {
|
||||
__m128i c1 = _mm_load_si128(&srcp[i + 0]);
|
||||
__m128i c2 = _mm_load_si128(&srcp[i + 1]);
|
||||
__m128i ag, rb;
|
||||
|
||||
ag = _mm_and_si128(c1, maskAG);
|
||||
ag = _mm_or_si128(_mm_srli_epi32(ag, 16), _mm_srli_epi32(ag, 6));
|
||||
rb = _mm_and_si128(c1, maskRB);
|
||||
rb = _mm_or_si128(_mm_srli_epi32(rb, 19), _mm_slli_epi32(rb, 7));
|
||||
c1 = _mm_and_si128(_mm_or_si128(ag, rb), mask);
|
||||
|
||||
ag = _mm_and_si128(c2, maskAG);
|
||||
ag = _mm_or_si128(_mm_srli_epi32(ag, 16), _mm_srli_epi32(ag, 6));
|
||||
rb = _mm_and_si128(c2, maskRB);
|
||||
rb = _mm_or_si128(_mm_srli_epi32(rb, 19), _mm_slli_epi32(rb, 7));
|
||||
c2 = _mm_and_si128(_mm_or_si128(ag, rb), mask);
|
||||
|
||||
_mm_store_si128(&dstp[i / 2], _mm_packus_epi32(c1, c2));
|
||||
}
|
||||
// The remainder starts right after those done via SSE.
|
||||
u32 i = sseChunks * 4;
|
||||
#else
|
||||
u32 i = 0;
|
||||
#endif
|
||||
for (; i < numPixels; i++) {
|
||||
dst[i] = BGRA8888toRGBA5551(src[i]);
|
||||
}
|
||||
}
|
||||
|
@ -216,7 +216,3 @@ inline void DeIndexTexture4Optimal(ClutT *dest, const u32 texaddr, int length, C
|
||||
const u8 *indexed = (const u8 *) Memory::GetPointer(texaddr);
|
||||
DeIndexTexture4Optimal(dest, indexed, length, color);
|
||||
}
|
||||
|
||||
void ConvertBGRA8888ToRGBA8888(u32 *dst, const u32 *src, const u32 numPixels);
|
||||
void ConvertRGBA8888ToRGBA5551(u16 *dst, const u32 *src, const u32 numPixels);
|
||||
void ConvertBGRA8888ToRGBA5551(u16 *dst, const u32 *src, const u32 numPixels);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "base/logging.h"
|
||||
|
||||
#include "Common/CPUDetect.h"
|
||||
#include "Common/ColorConv.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/MemMap.h"
|
||||
#include "Core/HDRemaster.h"
|
||||
@ -364,8 +365,7 @@ void VertexDecoder::Step_TcFloatPrescale() const {
|
||||
uv[1] = uvdata[1] * gstate_c.uv.vScale + gstate_c.uv.vOff;
|
||||
}
|
||||
|
||||
void VertexDecoder::Step_Color565() const
|
||||
{
|
||||
void VertexDecoder::Step_Color565() const {
|
||||
u8 *c = decoded_ + decFmt.c0off;
|
||||
u16 cdata = *(u16_le *)(ptr_ + coloff);
|
||||
c[0] = Convert5To8(cdata & 0x1f);
|
||||
@ -375,8 +375,7 @@ void VertexDecoder::Step_Color565() const
|
||||
// Always full alpha.
|
||||
}
|
||||
|
||||
void VertexDecoder::Step_Color5551() const
|
||||
{
|
||||
void VertexDecoder::Step_Color5551() const {
|
||||
u8 *c = decoded_ + decFmt.c0off;
|
||||
u16 cdata = *(u16_le *)(ptr_ + coloff);
|
||||
c[0] = Convert5To8(cdata & 0x1f);
|
||||
@ -386,8 +385,7 @@ void VertexDecoder::Step_Color5551() const
|
||||
gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && c[3] != 0;
|
||||
}
|
||||
|
||||
void VertexDecoder::Step_Color4444() const
|
||||
{
|
||||
void VertexDecoder::Step_Color4444() const {
|
||||
u8 *c = decoded_ + decFmt.c0off;
|
||||
u16 cdata = *(u16_le *)(ptr_ + coloff);
|
||||
for (int j = 0; j < 4; j++)
|
||||
@ -395,8 +393,7 @@ void VertexDecoder::Step_Color4444() const
|
||||
gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && c[3] == 255;
|
||||
}
|
||||
|
||||
void VertexDecoder::Step_Color8888() const
|
||||
{
|
||||
void VertexDecoder::Step_Color8888() const {
|
||||
u8 *c = decoded_ + decFmt.c0off;
|
||||
const u8 *cdata = (const u8*)(ptr_ + coloff);
|
||||
memcpy(c, cdata, sizeof(u8) * 4);
|
||||
|
@ -16,6 +16,8 @@
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include "math/lin/matrix4x4.h"
|
||||
#include "Common/ColorConv.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/Host.h"
|
||||
#include "Core/MemMap.h"
|
||||
#include "Core/Config.h"
|
||||
@ -38,26 +40,6 @@
|
||||
#include <algorithm>
|
||||
|
||||
namespace DX9 {
|
||||
inline u16 RGBA8888toRGB565(u32 px) {
|
||||
return ((px >> 3) & 0x001F) | ((px >> 5) & 0x07E0) | ((px >> 8) & 0xF800);
|
||||
}
|
||||
|
||||
inline u16 RGBA8888toRGBA4444(u32 px) {
|
||||
return ((px >> 4) & 0x000F) | ((px >> 8) & 0x00F0) | ((px >> 12) & 0x0F00) | ((px >> 16) & 0xF000);
|
||||
}
|
||||
|
||||
inline u16 RGBA8888toRGBA5551(u32 px) {
|
||||
return ((px >> 3) & 0x001F) | ((px >> 6) & 0x03E0) | ((px >> 9) & 0x7C00) | ((px >> 16) & 0x8000);
|
||||
}
|
||||
|
||||
inline u16 BGRA8888toRGB565(u32 px) {
|
||||
return ((px >> 19) & 0x001F) | ((px >> 5) & 0x07E0) | ((px << 8) & 0xF800);
|
||||
}
|
||||
|
||||
inline u16 BGRA8888toRGBA4444(u32 px) {
|
||||
return ((px >> 20) & 0x000F) | ((px >> 8) & 0x00F0) | ((px << 4) & 0x0F00) | ((px >> 16) & 0xF000);
|
||||
}
|
||||
|
||||
static void ConvertFromRGBA8888(u8 *dst, u8 *src, u32 dstStride, u32 srcStride, u32 width, u32 height, GEBufferFormat format);
|
||||
|
||||
void CenterRect(float *x, float *y, float *w, float *h,
|
||||
@ -149,24 +131,6 @@ namespace DX9 {
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ARGB8From4444(u16 c, u32 * dst) {
|
||||
*dst = ((c & 0xf) << 4) | (((c >> 4) & 0xf) << 12) | (((c >> 8) & 0xf) << 20) | ((c >> 12) << 28);
|
||||
}
|
||||
static inline void ARGB8From565(u16 c, u32 * dst) {
|
||||
*dst = ((c & 0x001f) << 19) | (((c >> 5) & 0x003f) << 11) | ((((c >> 10) & 0x001f) << 3)) | 0xFF000000;
|
||||
}
|
||||
static inline void ARGB8From5551(u16 c, u32 * dst) {
|
||||
*dst = ((c & 0x001f) << 19) | (((c >> 5) & 0x001f) << 11) | ((((c >> 10) & 0x001f) << 3)) | 0xFF000000;
|
||||
}
|
||||
|
||||
// TODO: Swizzle the texture access instead.
|
||||
static inline u32 RGBA2BGRA(u32 src) {
|
||||
const u32 r = (src & 0x000000FF) << 16;
|
||||
const u32 ga = src & 0xFF00FF00;
|
||||
const u32 b = (src & 0x00FF0000) >> 16;
|
||||
return r | ga | b;
|
||||
}
|
||||
|
||||
void FramebufferManagerDX9::MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) {
|
||||
u8 *convBuf = NULL;
|
||||
D3DLOCKED_RECT rect;
|
||||
@ -207,40 +171,26 @@ namespace DX9 {
|
||||
if (srcPixelFormat != GE_FORMAT_8888 || srcStride != 512) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
switch (srcPixelFormat) {
|
||||
// not tested
|
||||
// not tested
|
||||
case GE_FORMAT_565:
|
||||
{
|
||||
const u16_le *src = (const u16_le *)srcPixels + srcStride * y;
|
||||
u32 *dst = (u32 *)(convBuf + rect.Pitch * y);
|
||||
for (int x = 0; x < width; x++) {
|
||||
u16_le col0 = src[x+0];
|
||||
ARGB8From565(col0, &dst[x + 0]);
|
||||
}
|
||||
ConvertRGB565ToRGBA888F(dst, src, width);
|
||||
}
|
||||
break;
|
||||
// faster
|
||||
case GE_FORMAT_5551:
|
||||
{
|
||||
const u16_le *src = (const u16_le *)srcPixels + srcStride * y;
|
||||
u32 *dst = (u32 *)(convBuf + rect.Pitch * y);
|
||||
for (int x = 0; x < width; x++) {
|
||||
u16_le col0 = src[x+0];
|
||||
ARGB8From5551(col0, &dst[x + 0]);
|
||||
}
|
||||
ConvertRGBA5551ToRGBA8888(dst, src, width);
|
||||
}
|
||||
break;
|
||||
case GE_FORMAT_4444:
|
||||
{
|
||||
const u16_le *src = (const u16_le *)srcPixels + srcStride * y;
|
||||
u8 *dst = (u8 *)(convBuf + rect.Pitch * y);
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
u16_le col = src[x];
|
||||
dst[x * 4 + 0] = (col >> 12) << 4;
|
||||
dst[x * 4 + 1] = ((col >> 8) & 0xf) << 4;
|
||||
dst[x * 4 + 2] = ((col >> 4) & 0xf) << 4;
|
||||
dst[x * 4 + 3] = (col & 0xf) << 4;
|
||||
}
|
||||
u32 *dst = (u32 *)(convBuf + rect.Pitch * y);
|
||||
ConvertRGBA4444ToRGBA8888(dst, src, width);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -248,10 +198,7 @@ namespace DX9 {
|
||||
{
|
||||
const u32_le *src = (const u32_le *)srcPixels + srcStride * y;
|
||||
u32 *dst = (u32 *)(convBuf + rect.Pitch * y);
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
dst[x] = RGBA2BGRA(src[x]);
|
||||
}
|
||||
ConvertBGRA8888ToRGBA8888(dst, src, width);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -260,15 +207,11 @@ namespace DX9 {
|
||||
for (int y = 0; y < height; y++) {
|
||||
const u32_le *src = (const u32_le *)srcPixels + srcStride * y;
|
||||
u32 *dst = (u32 *)(convBuf + rect.Pitch * y);
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
dst[x] = RGBA2BGRA(src[x]);
|
||||
}
|
||||
ConvertBGRA8888ToRGBA8888(dst, src, width);
|
||||
}
|
||||
}
|
||||
|
||||
drawPixelsTex_->UnlockRect(0);
|
||||
// D3DXSaveTextureToFile("game:\\cc.png", D3DXIFF_PNG, drawPixelsTex_, NULL);
|
||||
}
|
||||
|
||||
void FramebufferManagerDX9::DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) {
|
||||
@ -664,7 +607,6 @@ namespace DX9 {
|
||||
}
|
||||
|
||||
void FramebufferManagerDX9::CopyDisplayToOutput() {
|
||||
|
||||
fbo_unbind();
|
||||
dxstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight);
|
||||
currentRenderVfb_ = 0;
|
||||
@ -1035,9 +977,7 @@ namespace DX9 {
|
||||
switch (format) {
|
||||
case GE_FORMAT_565: // BGR 565
|
||||
for (u32 y = 0; y < height; ++y) {
|
||||
for (u32 x = 0; x < width; ++x) {
|
||||
dst16[x] = BGRA8888toRGB565(src32[x]);
|
||||
}
|
||||
ConvertBGRA8888ToRGB565(dst16, src32, width);
|
||||
src32 += srcStride;
|
||||
dst16 += dstStride;
|
||||
}
|
||||
@ -1051,9 +991,7 @@ namespace DX9 {
|
||||
break;
|
||||
case GE_FORMAT_4444: // ABGR 4444
|
||||
for (u32 y = 0; y < height; ++y) {
|
||||
for (u32 x = 0; x < width; ++x) {
|
||||
dst16[x] = BGRA8888toRGBA4444(src32[x]);
|
||||
}
|
||||
ConvertBGRA8888ToRGBA4444(dst16, src32, width);
|
||||
src32 += srcStride;
|
||||
dst16 += dstStride;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "helper/dx_state.h"
|
||||
#include "helper/fbo.h"
|
||||
#include "Common/ColorConv.h"
|
||||
#include "Core/Reporting.h"
|
||||
#include "GPU/Directx9/FramebufferDX9.h"
|
||||
#include "GPU/Directx9/PixelShaderGeneratorDX9.h"
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include "Core/Config.h"
|
||||
#include "Common/Common.h"
|
||||
#include "Common/ColorConv.h"
|
||||
#include "Common/Log.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
#include "Common/CommonFuncs.h"
|
||||
@ -54,48 +55,6 @@
|
||||
/////////////////////////////////////// Helper Functions (mostly math for parallelization)
|
||||
|
||||
namespace {
|
||||
//////////////////////////////////////////////////////////////////// Color space conversion
|
||||
|
||||
// convert 4444 image to 8888, parallelizable
|
||||
void convert4444(u16* data, u32* out, int width, int l, int u) {
|
||||
for(int y = l; y < u; ++y) {
|
||||
for(int x = 0; x < width; ++x) {
|
||||
u32 val = data[y*width + x];
|
||||
u32 r = ((val>> 0) & 0xF) * 17;
|
||||
u32 g = ((val>> 4) & 0xF) * 17;
|
||||
u32 b = ((val>> 8) & 0xF) * 17;
|
||||
u32 a = ((val>>12) & 0xF) * 17;
|
||||
out[y*width + x] = (a << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// convert 565 image to 8888, parallelizable
|
||||
void convert565(u16* data, u32* out, int width, int l, int u) {
|
||||
for(int y = l; y < u; ++y) {
|
||||
for(int x = 0; x < width; ++x) {
|
||||
u32 val = data[y*width + x];
|
||||
u32 r = Convert5To8((val ) & 0x1F);
|
||||
u32 g = Convert6To8((val>> 5) & 0x3F);
|
||||
u32 b = Convert5To8((val>>11) & 0x1F);
|
||||
out[y*width + x] = (0xFF << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// convert 5551 image to 8888, parallelizable
|
||||
void convert5551(u16* data, u32* out, int width, int l, int u) {
|
||||
for(int y = l; y < u; ++y) {
|
||||
for(int x = 0; x < width; ++x) {
|
||||
u32 val = data[y*width + x];
|
||||
u32 r = Convert5To8((val>> 0) & 0x1F);
|
||||
u32 g = Convert5To8((val>> 5) & 0x1F);
|
||||
u32 b = Convert5To8((val>>10) & 0x1F);
|
||||
u32 a = ((val >> 15) & 0x1) * 255;
|
||||
out[y*width + x] = (a << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////// Various image processing
|
||||
|
||||
@ -689,4 +648,4 @@ void TextureScalerDX9::ConvertTo8888(u32 format, u32* source, u32* &dest, int wi
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "Core/System.h"
|
||||
#include "Core/Reporting.h"
|
||||
#include "Core/HLE/sceDisplay.h"
|
||||
#include "Common/ColorConv.h"
|
||||
#include "GPU/ge_constants.h"
|
||||
#include "GPU/GPUState.h"
|
||||
|
||||
@ -96,22 +97,6 @@ static const char color_vs[] =
|
||||
" gl_Position = a_position;\n"
|
||||
"}\n";
|
||||
|
||||
inline u16 RGBA8888toRGB565(u32 px) {
|
||||
return ((px >> 3) & 0x001F) | ((px >> 5) & 0x07E0) | ((px >> 8) & 0xF800);
|
||||
}
|
||||
|
||||
inline u16 RGBA8888toRGBA4444(u32 px) {
|
||||
return ((px >> 4) & 0x000F) | ((px >> 8) & 0x00F0) | ((px >> 12) & 0x0F00) | ((px >> 16) & 0xF000);
|
||||
}
|
||||
|
||||
inline u16 BGRA8888toRGB565(u32 px) {
|
||||
return ((px >> 19) & 0x001F) | ((px >> 5) & 0x07E0) | ((px << 8) & 0xF800);
|
||||
}
|
||||
|
||||
inline u16 BGRA8888toRGBA4444(u32 px) {
|
||||
return ((px >> 20) & 0x000F) | ((px >> 8) & 0x00F0) | ((px << 4) & 0x0F00) | ((px >> 16) & 0xF000);
|
||||
}
|
||||
|
||||
void ConvertFromRGBA8888(u8 *dst, const u8 *src, u32 dstStride, u32 srcStride, u32 width, u32 height, GEBufferFormat format);
|
||||
|
||||
void CenterRect(float *x, float *y, float *w, float *h,
|
||||
@ -421,14 +406,7 @@ void FramebufferManager::MakePixelTexture(const u8 *srcPixels, GEBufferFormat sr
|
||||
{
|
||||
const u16 *src = (const u16 *)srcPixels + srcStride * y;
|
||||
u8 *dst = convBuf_ + 4 * width * y;
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
u16 col = src[x];
|
||||
dst[x * 4] = Convert5To8((col) & 0x1f);
|
||||
dst[x * 4 + 1] = Convert6To8((col >> 5) & 0x3f);
|
||||
dst[x * 4 + 2] = Convert5To8((col >> 11) & 0x1f);
|
||||
dst[x * 4 + 3] = 255;
|
||||
}
|
||||
ConvertRGB565ToRGBA888F((u32 *)dst, src, width);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -436,14 +414,7 @@ void FramebufferManager::MakePixelTexture(const u8 *srcPixels, GEBufferFormat sr
|
||||
{
|
||||
const u16 *src = (const u16 *)srcPixels + srcStride * y;
|
||||
u8 *dst = convBuf_ + 4 * width * y;
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
u16 col = src[x];
|
||||
dst[x * 4] = Convert5To8((col) & 0x1f);
|
||||
dst[x * 4 + 1] = Convert5To8((col >> 5) & 0x1f);
|
||||
dst[x * 4 + 2] = Convert5To8((col >> 10) & 0x1f);
|
||||
dst[x * 4 + 3] = (col >> 15) ? 255 : 0;
|
||||
}
|
||||
ConvertRGBA5551ToRGBA8888((u32 *)dst, src, width);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -451,14 +422,7 @@ void FramebufferManager::MakePixelTexture(const u8 *srcPixels, GEBufferFormat sr
|
||||
{
|
||||
const u16 *src = (const u16 *)srcPixels + srcStride * y;
|
||||
u8 *dst = convBuf_ + 4 * width * y;
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
u16 col = src[x];
|
||||
dst[x * 4] = Convert4To8((col >> 8) & 0xf);
|
||||
dst[x * 4 + 1] = Convert4To8((col >> 4) & 0xf);
|
||||
dst[x * 4 + 2] = Convert4To8(col & 0xf);
|
||||
dst[x * 4 + 3] = Convert4To8(col >> 12);
|
||||
}
|
||||
ConvertRGBA4444ToRGBA8888((u32 *)dst, src, width);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1361,7 +1325,6 @@ void FramebufferManager::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int
|
||||
void ConvertFromRGBA8888(u8 *dst, const u8 *src, u32 dstStride, u32 srcStride, u32 width, u32 height, GEBufferFormat format) {
|
||||
// Must skip stride in the cases below. Some games pack data into the cracks, like MotoGP.
|
||||
const u32 *src32 = (const u32 *)src;
|
||||
|
||||
if (format == GE_FORMAT_8888) {
|
||||
u32 *dst32 = (u32 *)dst;
|
||||
if (src == dst) {
|
||||
@ -1387,17 +1350,13 @@ void ConvertFromRGBA8888(u8 *dst, const u8 *src, u32 dstStride, u32 srcStride, u
|
||||
case GE_FORMAT_565: // BGR 565
|
||||
if (UseBGRA8888()) {
|
||||
for (u32 y = 0; y < height; ++y) {
|
||||
for (u32 x = 0; x < width; ++x) {
|
||||
dst16[x] = BGRA8888toRGB565(src32[x]);
|
||||
}
|
||||
ConvertBGRA8888ToRGB565(dst16, src32, width);
|
||||
src32 += srcStride;
|
||||
dst16 += dstStride;
|
||||
}
|
||||
} else {
|
||||
for (u32 y = 0; y < height; ++y) {
|
||||
for (u32 x = 0; x < width; ++x) {
|
||||
dst16[x] = RGBA8888toRGB565(src32[x]);
|
||||
}
|
||||
ConvertRGBA8888ToRGB565(dst16, src32, width);
|
||||
src32 += srcStride;
|
||||
dst16 += dstStride;
|
||||
}
|
||||
@ -1421,17 +1380,13 @@ void ConvertFromRGBA8888(u8 *dst, const u8 *src, u32 dstStride, u32 srcStride, u
|
||||
case GE_FORMAT_4444: // ABGR 4444
|
||||
if (UseBGRA8888()) {
|
||||
for (u32 y = 0; y < height; ++y) {
|
||||
for (u32 x = 0; x < width; ++x) {
|
||||
dst16[x] = BGRA8888toRGBA4444(src32[x]);
|
||||
}
|
||||
ConvertBGRA8888ToRGBA4444(dst16, src32, width);
|
||||
src32 += srcStride;
|
||||
dst16 += dstStride;
|
||||
}
|
||||
} else {
|
||||
for (u32 y = 0; y < height; ++y) {
|
||||
for (u32 x = 0; x < width; ++x) {
|
||||
dst16[x] = RGBA8888toRGBA4444(src32[x]);
|
||||
}
|
||||
ConvertRGBA8888ToRGBA4444(dst16, src32, width);
|
||||
src32 += srcStride;
|
||||
dst16 += dstStride;
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "gfx_es2/glsl_program.h"
|
||||
#include "gfx_es2/gl_state.h"
|
||||
#include "Common/ColorConv.h"
|
||||
#include "Core/Reporting.h"
|
||||
#include "GPU/GLES/Framebuffer.h"
|
||||
#include "GPU/GLES/ShaderManager.h"
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
#include "Common/ColorConv.h"
|
||||
#include "Core/Host.h"
|
||||
#include "Core/MemMap.h"
|
||||
#include "Core/Reporting.h"
|
||||
@ -2065,47 +2066,36 @@ bool TextureCache::DecodeTexture(u8* output, const GPUgstate &state) {
|
||||
|
||||
switch (dstFmt) {
|
||||
case GL_UNSIGNED_SHORT_4_4_4_4:
|
||||
for (int y = 0; y < h; y++)
|
||||
for (int x = 0; x < bufw; x++) {
|
||||
u32 val = ((u16*)finalBuf)[y*bufw + x];
|
||||
u32 r = ((val>>12) & 0xF) * 17;
|
||||
u32 g = ((val>> 8) & 0xF) * 17;
|
||||
u32 b = ((val>> 4) & 0xF) * 17;
|
||||
u32 a = ((val>> 0) & 0xF) * 17;
|
||||
((u32*)output)[y*w + x] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
for (int y = 0; y < h; y++) {
|
||||
u16 *src = (u16*)finalBuf + y*bufw;
|
||||
u32 *dst = (u32*)output + y*w;
|
||||
ConvertRGBA4444ToRGBA8888(dst, src, bufw);
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_UNSIGNED_SHORT_5_5_5_1:
|
||||
for (int y = 0; y < h; y++)
|
||||
for (int x = 0; x < bufw; x++) {
|
||||
u32 val = ((u16*)finalBuf)[y*bufw + x];
|
||||
u32 r = Convert5To8((val>>11) & 0x1F);
|
||||
u32 g = Convert5To8((val>> 6) & 0x1F);
|
||||
u32 b = Convert5To8((val>> 1) & 0x1F);
|
||||
u32 a = (val & 0x1) * 255;
|
||||
((u32*)output)[y*w + x] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
for (int y = 0; y < h; y++) {
|
||||
u16 *src = (u16*)finalBuf + y*bufw;
|
||||
u32 *dst = (u32*)output + y*w;
|
||||
ConvertRGBA5551ToRGBA8888(dst, src, bufw);
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_UNSIGNED_SHORT_5_6_5:
|
||||
for (int y = 0; y < h; y++)
|
||||
for (int x = 0; x < bufw; x++) {
|
||||
u32 val = ((u16*)finalBuf)[y*bufw + x];
|
||||
u32 a = 0xFF;
|
||||
u32 r = Convert5To8((val>>11) & 0x1F);
|
||||
u32 g = Convert6To8((val>> 5) & 0x3F);
|
||||
u32 b = Convert5To8((val ) & 0x1F);
|
||||
((u32*)output)[y*w + x] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
for (int y = 0; y < h; y++) {
|
||||
u16 *src = (u16*)finalBuf + y*bufw;
|
||||
u32 *dst = (u32*)output + y*w;
|
||||
ConvertRGB565ToRGBA888F(dst, src, bufw);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
for (int y = 0; y < h; y++)
|
||||
for (int y = 0; y < h; y++) {
|
||||
for (int x = 0; x < bufw; x++) {
|
||||
u32 val = ((u32*)finalBuf)[y*bufw + x];
|
||||
((u32*)output)[y*w + x] = ((val & 0xFF000000)) | ((val & 0x00FF0000)>>16) | ((val & 0x0000FF00)) | ((val & 0x000000FF)<<16);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "Core/Config.h"
|
||||
#include "Common/Common.h"
|
||||
#include "Common/ColorConv.h"
|
||||
#include "Common/Log.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
#include "Common/CommonFuncs.h"
|
||||
@ -48,48 +49,6 @@
|
||||
/////////////////////////////////////// Helper Functions (mostly math for parallelization)
|
||||
|
||||
namespace {
|
||||
//////////////////////////////////////////////////////////////////// Color space conversion
|
||||
|
||||
// convert 4444 image to 8888, parallelizable
|
||||
void convert4444(u16* data, u32* out, int width, int l, int u) {
|
||||
for(int y = l; y < u; ++y) {
|
||||
for(int x = 0; x < width; ++x) {
|
||||
u32 val = data[y*width + x];
|
||||
u32 r = ((val>>12) & 0xF) * 17;
|
||||
u32 g = ((val>> 8) & 0xF) * 17;
|
||||
u32 b = ((val>> 4) & 0xF) * 17;
|
||||
u32 a = ((val>> 0) & 0xF) * 17;
|
||||
out[y*width + x] = (a << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// convert 565 image to 8888, parallelizable
|
||||
void convert565(u16* data, u32* out, int width, int l, int u) {
|
||||
for(int y = l; y < u; ++y) {
|
||||
for(int x = 0; x < width; ++x) {
|
||||
u32 val = data[y*width + x];
|
||||
u32 r = Convert5To8((val>>11) & 0x1F);
|
||||
u32 g = Convert6To8((val>> 5) & 0x3F);
|
||||
u32 b = Convert5To8((val ) & 0x1F);
|
||||
out[y*width + x] = (0xFF << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// convert 5551 image to 8888, parallelizable
|
||||
void convert5551(u16* data, u32* out, int width, int l, int u) {
|
||||
for(int y = l; y < u; ++y) {
|
||||
for(int x = 0; x < width; ++x) {
|
||||
u32 val = data[y*width + x];
|
||||
u32 r = Convert5To8((val>>11) & 0x1F);
|
||||
u32 g = Convert5To8((val>> 6) & 0x1F);
|
||||
u32 b = Convert5To8((val>> 1) & 0x1F);
|
||||
u32 a = (val & 0x1) * 255;
|
||||
out[y*width + x] = (a << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////// Various image processing
|
||||
|
||||
|
@ -226,7 +226,6 @@
|
||||
<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" />
|
||||
@ -309,4 +308,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
@ -42,9 +42,6 @@
|
||||
<ClInclude Include="GPUCommon.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Software\Colors.h">
|
||||
<Filter>Software</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Software\Clipper.h">
|
||||
<Filter>Software</Filter>
|
||||
</ClInclude>
|
||||
@ -342,4 +339,4 @@
|
||||
<ItemGroup>
|
||||
<None Include="CMakeLists.txt" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
#include "Common/ColorConv.h"
|
||||
#include "Common/ThreadPools.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/MemMap.h"
|
||||
@ -26,7 +27,6 @@
|
||||
#include "GPU/Common/TextureDecoder.h"
|
||||
#include "GPU/Software/SoftGpu.h"
|
||||
#include "GPU/Software/Rasterizer.h"
|
||||
#include "GPU/Software/Colors.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
|
||||
#include "Common/ColorConv.h"
|
||||
#include "GPU/GPUState.h"
|
||||
#include "GPU/ge_constants.h"
|
||||
#include "GPU/Common/TextureDecoder.h"
|
||||
@ -32,7 +33,6 @@
|
||||
|
||||
#include "GPU/Software/SoftGpu.h"
|
||||
#include "GPU/Software/TransformUnit.h"
|
||||
#include "GPU/Software/Colors.h"
|
||||
#include "GPU/Software/Rasterizer.h"
|
||||
|
||||
static GLuint temp_texture = 0;
|
||||
|
18
Globals.h
18
Globals.h
@ -30,24 +30,6 @@
|
||||
#define IS_LITTLE_ENDIAN (*(const u16 *)"\0\xff" >= 0x100)
|
||||
#define IS_BIG_ENDIAN (*(const u16 *)"\0\xff" < 0x100)
|
||||
|
||||
inline u8 Convert4To8(u8 v)
|
||||
{
|
||||
// Swizzle bits: 00001234 -> 12341234
|
||||
return (v << 4) | (v);
|
||||
}
|
||||
|
||||
inline u8 Convert5To8(u8 v)
|
||||
{
|
||||
// Swizzle bits: 00012345 -> 12345123
|
||||
return (v << 3) | (v >> 2);
|
||||
}
|
||||
|
||||
inline u8 Convert6To8(u8 v)
|
||||
{
|
||||
// Swizzle bits: 00123456 -> 12345612
|
||||
return (v << 2) | (v >> 4);
|
||||
}
|
||||
|
||||
static inline u8 clamp_u8(int i) {
|
||||
#ifdef ARM
|
||||
asm("usat %0, #8, %1" : "=r"(i) : "r"(i));
|
||||
|
@ -129,6 +129,7 @@ EXEC_AND_LIB_FILES := \
|
||||
$(SRC)/ext/udis86/udis86.c \
|
||||
$(SRC)/ext/xbrz/xbrz.cpp \
|
||||
$(SRC)/ext/xxhash.c \
|
||||
$(SRC)/Common/ColorConv.cpp \
|
||||
$(SRC)/Common/Crypto/md5.cpp \
|
||||
$(SRC)/Common/Crypto/sha1.cpp \
|
||||
$(SRC)/Common/Crypto/sha256.cpp \
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "headless/Compare.h"
|
||||
#include "file/file_util.h"
|
||||
#include "Core/Host.h"
|
||||
#include "Common/ColorConv.h"
|
||||
#include "GPU/Common/GPUDebugInterface.h"
|
||||
#include "GPU/Common/TextureDecoder.h"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user