Add a NEON version of the tex hash.

Should be used only for NEON devices.  Currently only compiled on Android.
This commit is contained in:
Unknown W. Brackets committed 2013-11-02 02:09:54 -07:00
1 parent 72950d8f93
commit 4d47ccd5df
8 files changed
+155 -33

No files matched your search

+52
View File
@@ -15,10 +15,62 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "Common/CPUDetect.h"
#include "GPU/Common/TextureDecoder.h"
#include "GPU/Common/TextureDecoderNEON.h"
// TODO: Move some common things into here.
#ifdef _M_SSE
#include <xmmintrin.h>
#endif
static u32 QuickTexHashSSE2(const void *checkp, u32 size) {
u32 check = 0;
#ifdef _M_SSE
if (((intptr_t)checkp & 0xf) == 0 && (size & 0x3f) == 0) {
__m128i cursor = _mm_set1_epi32(0);
__m128i cursor2 = _mm_set_epi16(0x0001U, 0x0083U, 0x4309U, 0x4d9bU, 0xb651U, 0x4b73U, 0x9bd9U, 0xc00bU);
__m128i update = _mm_set1_epi16(0x2455U);
const __m128i *p = (const __m128i *)checkp;
for (u32 i = 0; i < size / 16; i += 4) {
__m128i chunk = _mm_mullo_epi16(_mm_load_si128(&p[i]), cursor2);
cursor = _mm_add_epi32(cursor, chunk);
cursor = _mm_xor_si128(cursor, _mm_load_si128(&p[i + 1]));
cursor = _mm_add_epi32(cursor, _mm_load_si128(&p[i + 2]));
chunk = _mm_mullo_epi16(_mm_load_si128(&p[i + 3]), cursor2);
cursor = _mm_xor_si128(cursor, chunk);
cursor2 = _mm_add_epi16(cursor2, update);
}
// Add the four parts into the low i32.
cursor = _mm_add_epi32(cursor, _mm_add_epi32(_mm_srli_si128(cursor, 8), cursor2));
cursor = _mm_add_epi32(cursor, _mm_srli_si128(cursor, 4));
check = _mm_cvtsi128_si32(cursor);
} else {
#else
{
#endif
const u32 *p = (const u32 *)checkp;
for (u32 i = 0; i < size / 8; ++i) {
check += *p++;
check ^= *p++;
}
}
return check;
}
QuickTexHashFunc DoQuickTexHash = &QuickTexHashSSE2;
void SetupQuickTexHash() {
#ifdef ARM
if (cpu_info.bNEON) {
DoQuickTexHash = &QuickTexHashNEON;
}
#endif
}
static inline u32 makecol(int r, int g, int b, int a) {
return (a << 24) | (r << 16) | (g << 8) | b;
}
+4
View File
@@ -22,6 +22,10 @@
#include "GPU/ge_constants.h"
#include "GPU/GPUState.h"
void SetupQuickTexHash();
typedef u32 (*QuickTexHashFunc)(const void *checkp, u32 size);
extern QuickTexHashFunc DoQuickTexHash;
// All these DXT structs are in the reverse order, as compared to PC.
// On PC, alpha comes before color, and interpolants are before the tile data.
+57
View File
@@ -0,0 +1,57 @@
// Copyright (c) 2012- 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 <arm_neon.h>
#include "GPU/Common/TextureDecoder.h"
#ifndef ARM
#error Should not be compiled on non-ARM.
#endif
static const u16 MEMORY_ALIGNED16(QuickTexHashInitial[8]) = {0x0001U, 0x0083U, 0x4309U, 0x4d9bU, 0xb651U, 0x4b73U, 0x9bd9U, 0xc00bU};
u32 QuickTexHashNEON(const void *checkp, u32 size) {
u32 check = 0;
if (((intptr_t)checkp & 0xf) == 0 && (size & 0x3f) == 0) {
uint32x4_t cursor = vdupq_n_u32(0);
uint32x4_t cursor2 = vld1q_u32((const u32 *)QuickTexHashInitial);
uint32x4_t update = vdupq_n_u32(0x24552455U);
const u32 *p = (const u32 *)checkp;
for (u32 i = 0; i < size / 16; i += 4) {
cursor = vmlaq_u32(cursor, vld1q_u32(&p[4 * 0]), cursor2);
cursor = veorq_u32(cursor, vld1q_u32(&p[4 * 1]));
cursor = vaddq_u32(cursor, vld1q_u32(&p[4 * 2]));
cursor = veorq_u32(cursor, vmulq_u32(vld1q_u32(&p[4 * 3]), cursor2));
cursor2 = vaddq_u32(cursor2, update);
p += 4 * 4;
}
cursor = vaddq_u32(cursor, cursor2);
check = vgetq_lane_u32(cursor, 0) + vgetq_lane_u32(cursor, 1) + vgetq_lane_u32(cursor, 2) + vgetq_lane_u32(cursor, 3);
} else {
const u32 *p = (const u32 *)checkp;
for (u32 i = 0; i < size / 8; ++i) {
check += *p++;
check ^= *p++;
}
}
return check;
}
+20
View File
@@ -0,0 +1,20 @@
// Copyright (c) 2012- 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 "GPU/Common/TextureDecoder.h"
u32 QuickTexHashNEON(const void *checkp, u32 size);
+2 -32
View File
@@ -56,6 +56,7 @@ TextureCache::TextureCache() : clearCacheNextFrame_(false), lowMemoryMode_(false
clutBufConverted_ = (u32 *)AllocateAlignedMemory(4096 * sizeof(u32), 16); // 16KB
clutBufRaw_ = (u32 *)AllocateAlignedMemory(4096 * sizeof(u32), 16); // 16KB
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropyLevel);
SetupQuickTexHash();
}
TextureCache::~TextureCache() {
@@ -678,39 +679,8 @@ static inline u32 QuickClutHash(const u8 *clut, u32 bytes) {
static inline u32 QuickTexHash(u32 addr, int bufw, int w, int h, GETextureFormat format) {
const u32 sizeInRAM = (textureBitsPerPixel[format] * bufw * h) / 8;
const u32 *checkp = (const u32 *) Memory::GetPointer(addr);
u32 check = 0;
#ifdef _M_SSE
if (((intptr_t)checkp & 0xf) == 0 && (sizeInRAM & 0x3f) == 0) {
__m128i cursor = _mm_set1_epi32(0);
__m128i cursor2 = _mm_set_epi16(0x0001U, 0x0083U, 0x4309U, 0x4d9bU, 0xb651U, 0x4b73U, 0x9bd9U, 0xc00bU);
__m128i update = _mm_set1_epi16(0x2455U);
const __m128i *p = (const __m128i *)checkp;
for (u32 i = 0; i < sizeInRAM / 16; i += 4) {
__m128i chunk = _mm_mullo_epi16(_mm_load_si128(&p[i]), cursor2);
cursor = _mm_add_epi32(cursor, chunk);
cursor = _mm_xor_si128(cursor, _mm_load_si128(&p[i + 1]));
cursor = _mm_add_epi32(cursor, _mm_load_si128(&p[i + 2]));
chunk = _mm_mullo_epi16(_mm_load_si128(&p[i + 3]), cursor2);
cursor = _mm_xor_si128(cursor, chunk);
cursor2 = _mm_add_epi16(cursor2, update);
}
// Add the four parts into the low i32.
cursor = _mm_add_epi32(cursor, _mm_add_epi32(_mm_srli_si128(cursor, 8), cursor2));
cursor = _mm_add_epi32(cursor, _mm_srli_si128(cursor, 4));
check = _mm_cvtsi128_si32(cursor);
} else {
#else
// TODO: ARM NEON implementation (using CPUDetect to be sure it has NEON.)
{
#endif
for (u32 i = 0; i < sizeInRAM / 8; ++i) {
check += *checkp++;
check ^= *checkp++;
}
}
return check;
return DoQuickTexHash(checkp, sizeInRAM);
}
inline bool TextureCache::TexCacheEntry::Matches(u16 dim2, u8 format2, int maxLevel2) {
+12
View File
@@ -159,6 +159,12 @@
<ClInclude Include="Common\IndexGenerator.h" />
<ClInclude Include="Common\PostShader.h" />
<ClInclude Include="Common\SplineCommon.h" />
<ClInclude Include="Common\TextureDecoderNEON.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="Common\VertexDecoderCommon.h" />
<ClInclude Include="Debugger\Breakpoints.h" />
<ClInclude Include="Debugger\Stepping.h" />
@@ -204,6 +210,12 @@
<ClCompile Include="..\ext\xbrz\xbrz.cpp" />
<ClCompile Include="Common\IndexGenerator.cpp" />
<ClCompile Include="Common\PostShader.cpp" />
<ClCompile Include="Common\TextureDecoderNEON.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="Common\VertexDecoderCommon.cpp" />
<ClCompile Include="Debugger\Breakpoints.cpp" />
<ClCompile Include="Debugger\Stepping.cpp" />
+7 -1
View File
@@ -159,6 +159,9 @@
<ClInclude Include="Common\PostShader.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\TextureDecoderNEON.h">
<Filter>Common</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Math3D.cpp">
@@ -287,8 +290,11 @@
<ClCompile Include="Common\PostShader.cpp">
<Filter>Common</Filter>
</ClCompile>
<ClCompile Include="Common\TextureDecoderNEON.cpp">
<Filter>Common</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="CMakeLists.txt" />
</ItemGroup>
</Project>
</Project>
+1
View File
@@ -147,6 +147,7 @@ EXEC_AND_LIB_FILES := \
$(SRC)/GPU/Common/IndexGenerator.cpp.arm \
$(SRC)/GPU/Common/VertexDecoderCommon.cpp.arm \
$(SRC)/GPU/Common/TextureDecoder.cpp \
$(SRC)/GPU/Common/TextureDecoderNEON.cpp.neon \
$(SRC)/GPU/Common/PostShader.cpp \
$(SRC)/GPU/Debugger/Breakpoints.cpp \
$(SRC)/GPU/Debugger/Stepping.cpp \