sometimes to advance you have to make a step back.
use plain vertex arrays instead of VBOs to render in Opengl plugin as the nature of the data make VBOs slower. This must bring, depending on the implementation, a good speedup in opengl. in my system now opengl and d3d9 have a difference of 1 to 5 fps depending of the game. some cleanup and a little work pointing to future improvements in the way of rendering. please test and check for any errors. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6139 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
eb40f765c2
commit
9b0357b5e2
|
@ -119,3 +119,119 @@ u32 HashEctor(const u8* ptr, int length)
|
||||||
|
|
||||||
return(crc);
|
return(crc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _M_X64
|
||||||
|
u64 GetHash64(const u8 *src, int len, u32 samples)
|
||||||
|
{
|
||||||
|
const u64 m = 0xc6a4a7935bd1e995;
|
||||||
|
const int r = 47;
|
||||||
|
|
||||||
|
u64 h = len * m;
|
||||||
|
u32 Step = (len/8);
|
||||||
|
const u64 * data = (const u64 *)src;
|
||||||
|
const u64 * end = data + Step;
|
||||||
|
if(samples == 0) samples = Step;
|
||||||
|
Step = Step / samples;
|
||||||
|
if(Step < 1) Step = 1;
|
||||||
|
while(data < end)
|
||||||
|
{
|
||||||
|
u64 k = data[0];
|
||||||
|
data+=Step;
|
||||||
|
k *= m;
|
||||||
|
k ^= k >> r;
|
||||||
|
k *= m;
|
||||||
|
h ^= k;
|
||||||
|
h *= m;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u8 * data2 = (const u8*)end;
|
||||||
|
|
||||||
|
switch(len & 7)
|
||||||
|
{
|
||||||
|
case 7: h ^= u64(data2[6]) << 48;
|
||||||
|
case 6: h ^= u64(data2[5]) << 40;
|
||||||
|
case 5: h ^= u64(data2[4]) << 32;
|
||||||
|
case 4: h ^= u64(data2[3]) << 24;
|
||||||
|
case 3: h ^= u64(data2[2]) << 16;
|
||||||
|
case 2: h ^= u64(data2[1]) << 8;
|
||||||
|
case 1: h ^= u64(data2[0]);
|
||||||
|
h *= m;
|
||||||
|
};
|
||||||
|
|
||||||
|
h ^= h >> r;
|
||||||
|
h *= m;
|
||||||
|
h ^= h >> r;
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
u64 GetHash64(const u8 *src, int len, u32 samples)
|
||||||
|
{
|
||||||
|
const u32 m = 0x5bd1e995;
|
||||||
|
const int r = 24;
|
||||||
|
|
||||||
|
u32 h1 = len;
|
||||||
|
u32 h2 = 0;
|
||||||
|
|
||||||
|
u32 Step = (len / 4);
|
||||||
|
const u32 * data = (const u32 *)src;
|
||||||
|
const u32 * end = data + Step;
|
||||||
|
const u8 * uEnd = (const u8 *)end;
|
||||||
|
if(samples == 0) samples = Step;
|
||||||
|
Step = Step / samples;
|
||||||
|
|
||||||
|
if(Step < 2) Step = 2;
|
||||||
|
|
||||||
|
while(data < end)
|
||||||
|
{
|
||||||
|
u32 k1 = data[0];
|
||||||
|
k1 *= m;
|
||||||
|
k1 ^= k1 >> r;
|
||||||
|
k1 *= m;
|
||||||
|
h1 *= m;
|
||||||
|
h1 ^= k1;
|
||||||
|
|
||||||
|
|
||||||
|
u32 k2 = data[1];
|
||||||
|
k2 *= m;
|
||||||
|
k2 ^= k2 >> r;
|
||||||
|
k2 *= m;
|
||||||
|
h2 *= m;
|
||||||
|
h2 ^= k2;
|
||||||
|
data+=Step;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((len & 7) > 3)
|
||||||
|
{
|
||||||
|
u32 k1 = *(end - 1);
|
||||||
|
k1 *= m;
|
||||||
|
k1 ^= k1 >> r;
|
||||||
|
k1 *= m;
|
||||||
|
h1 *= m;
|
||||||
|
h1 ^= k1;
|
||||||
|
len -= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(len & 3)
|
||||||
|
{
|
||||||
|
case 3: h2 ^= uEnd[2] << 16;
|
||||||
|
case 2: h2 ^= uEnd[1] << 8;
|
||||||
|
case 1: h2 ^= uEnd[0];
|
||||||
|
h2 *= m;
|
||||||
|
};
|
||||||
|
|
||||||
|
h1 ^= h2 >> 18; h1 *= m;
|
||||||
|
h2 ^= h1 >> 22; h2 *= m;
|
||||||
|
h1 ^= h2 >> 17; h1 *= m;
|
||||||
|
h2 ^= h1 >> 19; h2 *= m;
|
||||||
|
|
||||||
|
u64 h = h1;
|
||||||
|
|
||||||
|
h = (h << 32) | h2;
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -24,5 +24,5 @@ u32 HashFletcher(const u8* data_u8, size_t length); // FAST. Length & 1 == 0.
|
||||||
u32 HashAdler32(const u8* data, size_t len); // Fairly accurate, slightly slower
|
u32 HashAdler32(const u8* data, size_t len); // Fairly accurate, slightly slower
|
||||||
u32 HashFNV(const u8* ptr, int length); // Another fast and decent hash
|
u32 HashFNV(const u8* ptr, int length); // Another fast and decent hash
|
||||||
u32 HashEctor(const u8* ptr, int length); // JUNK. DO NOT USE FOR NEW THINGS
|
u32 HashEctor(const u8* ptr, int length); // JUNK. DO NOT USE FOR NEW THINGS
|
||||||
|
u64 GetHash64(const u8 *src, int len, u32 samples);
|
||||||
#endif // _HASH_H_
|
#endif // _HASH_H_
|
||||||
|
|
|
@ -22,7 +22,7 @@ static const char ID[4] = {'D', 'C', 'A', 'C'};
|
||||||
// Update this to the current SVN revision every time you change shader generation code.
|
// Update this to the current SVN revision every time you change shader generation code.
|
||||||
// We don't automatically get this from SVN_REV because that would mean regenerating the
|
// We don't automatically get this from SVN_REV because that would mean regenerating the
|
||||||
// shader cache for every revision, graphics-related or not, which is simply annoying.
|
// shader cache for every revision, graphics-related or not, which is simply annoying.
|
||||||
const int version = 6124;
|
const int version = 6139;
|
||||||
|
|
||||||
LinearDiskCache::LinearDiskCache()
|
LinearDiskCache::LinearDiskCache()
|
||||||
: file_(NULL), num_entries_(0) {
|
: file_(NULL), num_entries_(0) {
|
||||||
|
|
|
@ -22,6 +22,7 @@ namespace VertexManager
|
||||||
{
|
{
|
||||||
|
|
||||||
u8* s_pCurBufferPointer = NULL;
|
u8* s_pCurBufferPointer = NULL;
|
||||||
|
u8* s_pBaseBufferPointer = NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ int GetRemainingVertices(int primitive); // remaining number of vertices that ca
|
||||||
|
|
||||||
// TODO: move, rename.
|
// TODO: move, rename.
|
||||||
extern u8* s_pCurBufferPointer;
|
extern u8* s_pCurBufferPointer;
|
||||||
|
extern u8* s_pBaseBufferPointer;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -233,12 +233,12 @@ static void Decode()
|
||||||
{
|
{
|
||||||
u32 Cmd2 = DataReadU32();
|
u32 Cmd2 = DataReadU32();
|
||||||
int transfer_size = ((Cmd2 >> 16) & 15) + 1;
|
int transfer_size = ((Cmd2 >> 16) & 15) + 1;
|
||||||
u32 address = Cmd2 & 0xFFFF;
|
u32 xf_address = Cmd2 & 0xFFFF;
|
||||||
// TODO - speed this up. pshufb?
|
// TODO - speed this up. pshufb?
|
||||||
u32 data_buffer[16];
|
u32 data_buffer[16];
|
||||||
for (int i = 0; i < transfer_size; i++)
|
for (int i = 0; i < transfer_size; i++)
|
||||||
data_buffer[i] = DataReadU32();
|
data_buffer[i] = DataReadU32();
|
||||||
LoadXFReg(transfer_size, address, data_buffer);
|
LoadXFReg(transfer_size, xf_address, data_buffer);
|
||||||
INCSTAT(stats.thisFrame.numXFLoads);
|
INCSTAT(stats.thisFrame.numXFLoads);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -48,5 +48,5 @@
|
||||||
void OpcodeDecoder_Init();
|
void OpcodeDecoder_Init();
|
||||||
void OpcodeDecoder_Shutdown();
|
void OpcodeDecoder_Shutdown();
|
||||||
void OpcodeDecoder_Run(bool skipped_frame);
|
void OpcodeDecoder_Run(bool skipped_frame);
|
||||||
|
void ExecuteDisplayList(u32 address, u32 size);
|
||||||
#endif // _OPCODE_DECODING_H
|
#endif // _OPCODE_DECODING_H
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
|
|
||||||
#include "CPUDetect.h"
|
#include "CPUDetect.h"
|
||||||
#include "TextureDecoder.h"
|
#include "TextureDecoder.h"
|
||||||
|
|
||||||
#include "OpenCL.h"
|
#include "OpenCL.h"
|
||||||
#if defined(HAVE_OPENCL) && HAVE_OPENCL
|
#if defined(HAVE_OPENCL) && HAVE_OPENCL
|
||||||
#include "OpenCL/OCLTextureDecoder.h"
|
#include "OpenCL/OCLTextureDecoder.h"
|
||||||
|
@ -96,122 +95,6 @@ int TexDecoder_GetTextureSizeInBytes(int width, int height, int format)
|
||||||
return (width * height * TexDecoder_GetTexelSizeInNibbles(format)) / 2;
|
return (width * height * TexDecoder_GetTexelSizeInNibbles(format)) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _M_X64
|
|
||||||
u64 TexDecoder_GetHash64(const u8 *src, int len, u32 samples)
|
|
||||||
{
|
|
||||||
const u64 m = 0xc6a4a7935bd1e995;
|
|
||||||
const int r = 47;
|
|
||||||
|
|
||||||
u64 h = len * m;
|
|
||||||
u32 Step = (len/8);
|
|
||||||
const u64 * data = (const u64 *)src;
|
|
||||||
const u64 * end = data + Step;
|
|
||||||
if(samples == 0) samples = Step;
|
|
||||||
Step = Step / samples;
|
|
||||||
if(Step < 1) Step = 1;
|
|
||||||
while(data < end)
|
|
||||||
{
|
|
||||||
u64 k = data[0];
|
|
||||||
data+=Step;
|
|
||||||
k *= m;
|
|
||||||
k ^= k >> r;
|
|
||||||
k *= m;
|
|
||||||
h ^= k;
|
|
||||||
h *= m;
|
|
||||||
}
|
|
||||||
|
|
||||||
const u8 * data2 = (const u8*)end;
|
|
||||||
|
|
||||||
switch(len & 7)
|
|
||||||
{
|
|
||||||
case 7: h ^= u64(data2[6]) << 48;
|
|
||||||
case 6: h ^= u64(data2[5]) << 40;
|
|
||||||
case 5: h ^= u64(data2[4]) << 32;
|
|
||||||
case 4: h ^= u64(data2[3]) << 24;
|
|
||||||
case 3: h ^= u64(data2[2]) << 16;
|
|
||||||
case 2: h ^= u64(data2[1]) << 8;
|
|
||||||
case 1: h ^= u64(data2[0]);
|
|
||||||
h *= m;
|
|
||||||
};
|
|
||||||
|
|
||||||
h ^= h >> r;
|
|
||||||
h *= m;
|
|
||||||
h ^= h >> r;
|
|
||||||
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
u64 TexDecoder_GetHash64(const u8 *src, int len, u32 samples)
|
|
||||||
{
|
|
||||||
const u32 m = 0x5bd1e995;
|
|
||||||
const int r = 24;
|
|
||||||
|
|
||||||
u32 h1 = len;
|
|
||||||
u32 h2 = 0;
|
|
||||||
|
|
||||||
u32 Step = (len / 4);
|
|
||||||
const u32 * data = (const u32 *)src;
|
|
||||||
const u32 * end = data + Step;
|
|
||||||
const u8 * uEnd = (const u8 *)end;
|
|
||||||
if(samples == 0) samples = Step;
|
|
||||||
Step = Step / samples;
|
|
||||||
|
|
||||||
if(Step < 2) Step = 2;
|
|
||||||
|
|
||||||
while(data < end)
|
|
||||||
{
|
|
||||||
u32 k1 = data[0];
|
|
||||||
k1 *= m;
|
|
||||||
k1 ^= k1 >> r;
|
|
||||||
k1 *= m;
|
|
||||||
h1 *= m;
|
|
||||||
h1 ^= k1;
|
|
||||||
|
|
||||||
|
|
||||||
u32 k2 = data[1];
|
|
||||||
k2 *= m;
|
|
||||||
k2 ^= k2 >> r;
|
|
||||||
k2 *= m;
|
|
||||||
h2 *= m;
|
|
||||||
h2 ^= k2;
|
|
||||||
data+=Step;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((len & 7) > 3)
|
|
||||||
{
|
|
||||||
u32 k1 = *(end - 1);
|
|
||||||
k1 *= m;
|
|
||||||
k1 ^= k1 >> r;
|
|
||||||
k1 *= m;
|
|
||||||
h1 *= m;
|
|
||||||
h1 ^= k1;
|
|
||||||
len -= 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(len & 3)
|
|
||||||
{
|
|
||||||
case 3: h2 ^= uEnd[2] << 16;
|
|
||||||
case 2: h2 ^= uEnd[1] << 8;
|
|
||||||
case 1: h2 ^= uEnd[0];
|
|
||||||
h2 *= m;
|
|
||||||
};
|
|
||||||
|
|
||||||
h1 ^= h2 >> 18; h1 *= m;
|
|
||||||
h2 ^= h1 >> 22; h2 *= m;
|
|
||||||
h1 ^= h2 >> 17; h1 *= m;
|
|
||||||
h2 ^= h1 >> 19; h2 *= m;
|
|
||||||
|
|
||||||
u64 h = h1;
|
|
||||||
|
|
||||||
h = (h << 32) | h2;
|
|
||||||
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int TexDecoder_GetBlockWidthInTexels(u32 format)
|
int TexDecoder_GetBlockWidthInTexels(u32 format)
|
||||||
{
|
{
|
||||||
switch (format)
|
switch (format)
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#ifndef _TEXTUREDECODER_H
|
#ifndef _TEXTUREDECODER_H
|
||||||
#define _TEXTUREDECODER_H
|
#define _TEXTUREDECODER_H
|
||||||
|
#include "hash.h"
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
TMEM_SIZE = 1024*1024,
|
TMEM_SIZE = 1024*1024,
|
||||||
|
@ -86,9 +86,6 @@ enum PC_TexFormat
|
||||||
PC_TexFormat TexDecoder_Decode(u8 *dst, const u8 *src, int width, int height, int texformat, int tlutaddr, int tlutfmt,bool rgbaOnly = false);
|
PC_TexFormat TexDecoder_Decode(u8 *dst, const u8 *src, int width, int height, int texformat, int tlutaddr, int tlutfmt,bool rgbaOnly = false);
|
||||||
PC_TexFormat GetPC_TexFormat(int texformat, int tlutfmt);
|
PC_TexFormat GetPC_TexFormat(int texformat, int tlutfmt);
|
||||||
void TexDecoder_DecodeTexel(u8 *dst, const u8 *src, int s, int t, int imageWidth, int texformat, int tlutaddr, int tlutfmt);
|
void TexDecoder_DecodeTexel(u8 *dst, const u8 *src, int s, int t, int imageWidth, int texformat, int tlutaddr, int tlutfmt);
|
||||||
|
|
||||||
u64 TexDecoder_GetHash64(const u8 *src, int len, u32 samples = 0);
|
|
||||||
|
|
||||||
void TexDecoder_SetTexFmtOverlayOptions(bool enable, bool center);
|
void TexDecoder_SetTexFmtOverlayOptions(bool enable, bool center);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -45,10 +45,6 @@ void GetVertexShaderId(VERTEXSHADERUID *uid, u32 components)
|
||||||
(u32)xfregs.colChans[i].alpha.matsource) << 15;
|
(u32)xfregs.colChans[i].alpha.matsource) << 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fog
|
|
||||||
uid->values[1] |= (((u32)bpmem.fog.c_proj_fsel.fsel & 3) << 30);
|
|
||||||
uid->values[2] |= (((u32)bpmem.fog.c_proj_fsel.fsel >> 2) << 30);
|
|
||||||
|
|
||||||
u32 *pcurvalue = &uid->values[3];
|
u32 *pcurvalue = &uid->values[3];
|
||||||
for (int i = 0; i < xfregs.numTexGens; ++i) {
|
for (int i = 0; i < xfregs.numTexGens; ++i) {
|
||||||
TexMtxInfo tinfo = xfregs.texcoords[i].texmtxinfo;
|
TexMtxInfo tinfo = xfregs.texcoords[i].texmtxinfo;
|
||||||
|
|
|
@ -207,7 +207,7 @@ TextureCache::TCacheEntry* TextureCache::Load(unsigned int stage, u32 address, u
|
||||||
// hires textures and texture dumping not supported, yet
|
// hires textures and texture dumping not supported, yet
|
||||||
if (g_ActiveConfig.bSafeTextureCache/* || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures*/)
|
if (g_ActiveConfig.bSafeTextureCache/* || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures*/)
|
||||||
{
|
{
|
||||||
texHash = TexDecoder_GetHash64(ptr,TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
texHash = GetHash64(ptr,TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||||
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
|
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
|
||||||
{
|
{
|
||||||
// WARNING! texID != address now => may break CopyRenderTargetToTexture (cf. TODO up)
|
// WARNING! texID != address now => may break CopyRenderTargetToTexture (cf. TODO up)
|
||||||
|
@ -217,7 +217,7 @@ TextureCache::TCacheEntry* TextureCache::Load(unsigned int stage, u32 address, u
|
||||||
// each other stored in a single texture, and uses the palette to make different characters
|
// each other stored in a single texture, and uses the palette to make different characters
|
||||||
// visible or invisible. Thus, unless we want to recreate the textures for every drawn character,
|
// visible or invisible. Thus, unless we want to recreate the textures for every drawn character,
|
||||||
// we must make sure that texture with different tluts get different IDs.
|
// we must make sure that texture with different tluts get different IDs.
|
||||||
u64 tlutHash = TexDecoder_GetHash64(&texMem[tlutaddr], TexDecoder_GetPaletteSize(tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
u64 tlutHash = GetHash64(&texMem[tlutaddr], TexDecoder_GetPaletteSize(tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||||
texHash ^= tlutHash;
|
texHash ^= tlutHash;
|
||||||
if (g_ActiveConfig.bSafeTextureCache)
|
if (g_ActiveConfig.bSafeTextureCache)
|
||||||
{
|
{
|
||||||
|
|
|
@ -166,7 +166,7 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
|
||||||
|
|
||||||
if (g_ActiveConfig.bSafeTextureCache || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures)
|
if (g_ActiveConfig.bSafeTextureCache || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures)
|
||||||
{
|
{
|
||||||
texHash = TexDecoder_GetHash64(ptr,TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
texHash = GetHash64(ptr,TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||||
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
|
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
|
||||||
{
|
{
|
||||||
// WARNING! texID != address now => may break CopyRenderTargetToTexture (cf. TODO up)
|
// WARNING! texID != address now => may break CopyRenderTargetToTexture (cf. TODO up)
|
||||||
|
@ -176,7 +176,7 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
|
||||||
// each other stored in a single texture, and uses the palette to make different characters
|
// each other stored in a single texture, and uses the palette to make different characters
|
||||||
// visible or invisible. Thus, unless we want to recreate the textures for every drawn character,
|
// visible or invisible. Thus, unless we want to recreate the textures for every drawn character,
|
||||||
// we must make sure that texture with different tluts get different IDs.
|
// we must make sure that texture with different tluts get different IDs.
|
||||||
u64 tlutHash = TexDecoder_GetHash64(&texMem[tlutaddr], TexDecoder_GetPaletteSize(tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
u64 tlutHash = GetHash64(&texMem[tlutaddr], TexDecoder_GetPaletteSize(tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||||
texHash ^= tlutHash;
|
texHash ^= tlutHash;
|
||||||
if (g_ActiveConfig.bSafeTextureCache)
|
if (g_ActiveConfig.bSafeTextureCache)
|
||||||
{
|
{
|
||||||
|
@ -200,10 +200,10 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
|
||||||
{
|
{
|
||||||
if(!g_ActiveConfig.bCopyEFBToTexture)
|
if(!g_ActiveConfig.bCopyEFBToTexture)
|
||||||
{
|
{
|
||||||
hash_value = TexDecoder_GetHash64(ptr,TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
hash_value = GetHash64(ptr,TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||||
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
|
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
|
||||||
{
|
{
|
||||||
hash_value ^= TexDecoder_GetHash64(&texMem[tlutaddr], TexDecoder_GetPaletteSize(tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
hash_value ^= GetHash64(&texMem[tlutaddr], TexDecoder_GetPaletteSize(tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -450,7 +450,7 @@ u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture,u32 Sou
|
||||||
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight,readStride, true, bScaleByHalf > 0);
|
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight,readStride, true, bScaleByHalf > 0);
|
||||||
TextureCache::MakeRangeDynamic(address,size_in_bytes);
|
TextureCache::MakeRangeDynamic(address,size_in_bytes);
|
||||||
u64 Hashvalue = 0;
|
u64 Hashvalue = 0;
|
||||||
Hashvalue = TexDecoder_GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
Hashvalue = GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||||
return Hashvalue;
|
return Hashvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ struct CachedDisplayList
|
||||||
bool uncachable; // if set, this DL will always be interpreted. This gets set if hash ever changes.
|
bool uncachable; // if set, this DL will always be interpreted. This gets set if hash ever changes.
|
||||||
|
|
||||||
int pass;
|
int pass;
|
||||||
u32 dl_hash;
|
u64 dl_hash;
|
||||||
|
|
||||||
int check;
|
int check;
|
||||||
int next_check;
|
int next_check;
|
||||||
|
@ -128,8 +128,16 @@ bool AnalyzeAndRunDisplayList(u32 address, int size, CachedDisplayList *dl)
|
||||||
int num_index_xf = 0;
|
int num_index_xf = 0;
|
||||||
//int num_draw_call = 0; // unused?
|
//int num_draw_call = 0; // unused?
|
||||||
|
|
||||||
u8 *old_datareader = g_pVideoData;
|
u8* old_pVideoData = g_pVideoData;
|
||||||
g_pVideoData = Memory_GetPtr(address);
|
u8* startAddress = Memory_GetPtr(address);
|
||||||
|
|
||||||
|
// Avoid the crash if Memory_GetPtr failed ..
|
||||||
|
if (startAddress != 0)
|
||||||
|
{
|
||||||
|
g_pVideoData = startAddress;
|
||||||
|
|
||||||
|
// temporarily swap dl and non-dl (small "hack" for the stats)
|
||||||
|
Statistics::SwapDL();
|
||||||
|
|
||||||
u8 *end = g_pVideoData + size;
|
u8 *end = g_pVideoData + size;
|
||||||
while (g_pVideoData < end)
|
while (g_pVideoData < end)
|
||||||
|
@ -143,20 +151,16 @@ bool AnalyzeAndRunDisplayList(u32 address, int size, CachedDisplayList *dl)
|
||||||
|
|
||||||
case GX_LOAD_CP_REG: //0x08
|
case GX_LOAD_CP_REG: //0x08
|
||||||
{
|
{
|
||||||
// Execute
|
|
||||||
u8 sub_cmd = DataReadU8();
|
u8 sub_cmd = DataReadU8();
|
||||||
u32 value = DataReadU32();
|
u32 value = DataReadU32();
|
||||||
LoadCPReg(sub_cmd, value);
|
LoadCPReg(sub_cmd, value);
|
||||||
INCSTAT(stats.thisFrame.numCPLoads);
|
INCSTAT(stats.thisFrame.numCPLoads);
|
||||||
|
|
||||||
// Analyze
|
|
||||||
num_cp_reg++;
|
num_cp_reg++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GX_LOAD_XF_REG:
|
case GX_LOAD_XF_REG:
|
||||||
{
|
{
|
||||||
// Execute
|
|
||||||
u32 Cmd2 = DataReadU32();
|
u32 Cmd2 = DataReadU32();
|
||||||
int transfer_size = ((Cmd2 >> 16) & 15) + 1;
|
int transfer_size = ((Cmd2 >> 16) & 15) + 1;
|
||||||
u32 xf_address = Cmd2 & 0xFFFF;
|
u32 xf_address = Cmd2 & 0xFFFF;
|
||||||
|
@ -166,69 +170,52 @@ bool AnalyzeAndRunDisplayList(u32 address, int size, CachedDisplayList *dl)
|
||||||
data_buffer[i] = DataReadU32();
|
data_buffer[i] = DataReadU32();
|
||||||
LoadXFReg(transfer_size, xf_address, data_buffer);
|
LoadXFReg(transfer_size, xf_address, data_buffer);
|
||||||
INCSTAT(stats.thisFrame.numXFLoads);
|
INCSTAT(stats.thisFrame.numXFLoads);
|
||||||
|
|
||||||
// Analyze
|
|
||||||
num_xf_reg++;
|
num_xf_reg++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GX_LOAD_INDX_A: //used for position matrices
|
case GX_LOAD_INDX_A: //used for position matrices
|
||||||
{
|
{
|
||||||
u32 value = DataReadU32();
|
LoadIndexedXF(DataReadU32(), 0xC);
|
||||||
// Execute
|
|
||||||
LoadIndexedXF(value, 0xC);
|
|
||||||
// Analyze
|
|
||||||
num_index_xf++;
|
num_index_xf++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GX_LOAD_INDX_B: //used for normal matrices
|
case GX_LOAD_INDX_B: //used for normal matrices
|
||||||
{
|
{
|
||||||
u32 value = DataReadU32();
|
LoadIndexedXF(DataReadU32(), 0xD);
|
||||||
// Execute
|
|
||||||
LoadIndexedXF(value, 0xD);
|
|
||||||
// Analyze
|
|
||||||
num_index_xf++;
|
num_index_xf++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GX_LOAD_INDX_C: //used for postmatrices
|
case GX_LOAD_INDX_C: //used for postmatrices
|
||||||
{
|
{
|
||||||
u32 value = DataReadU32();
|
LoadIndexedXF(DataReadU32(), 0xE);
|
||||||
// Execute
|
|
||||||
LoadIndexedXF(value, 0xE);
|
|
||||||
// Analyze
|
|
||||||
num_index_xf++;
|
num_index_xf++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GX_LOAD_INDX_D: //used for lights
|
case GX_LOAD_INDX_D: //used for lights
|
||||||
{
|
{
|
||||||
u32 value = DataReadU32();
|
LoadIndexedXF(DataReadU32(), 0xF);
|
||||||
// Execute
|
|
||||||
LoadIndexedXF(value, 0xF);
|
|
||||||
// Analyze
|
|
||||||
num_index_xf++;
|
num_index_xf++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GX_CMD_CALL_DL:
|
case GX_CMD_CALL_DL:
|
||||||
PanicAlert("Seeing DL call inside DL.");
|
{
|
||||||
|
u32 address = DataReadU32();
|
||||||
|
u32 count = DataReadU32();
|
||||||
|
ExecuteDisplayList(address, count);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
case GX_CMD_UNKNOWN_METRICS: // zelda 4 swords calls it and checks the metrics registers after that
|
||||||
case GX_CMD_UNKNOWN_METRICS:
|
DEBUG_LOG(VIDEO, "GX 0x44: %08x", cmd_byte);
|
||||||
// zelda 4 swords calls it and checks the metrics registers after that
|
|
||||||
break;
|
break;
|
||||||
|
case GX_CMD_INVL_VC: // Invalidate Vertex Cache
|
||||||
case GX_CMD_INVL_VC:// Invalidate (vertex cache?)
|
|
||||||
DEBUG_LOG(VIDEO, "Invalidate (vertex cache?)");
|
DEBUG_LOG(VIDEO, "Invalidate (vertex cache?)");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GX_LOAD_BP_REG: //0x61
|
case GX_LOAD_BP_REG: //0x61
|
||||||
{
|
{
|
||||||
u32 bp_cmd = DataReadU32();
|
u32 bp_cmd = DataReadU32();
|
||||||
// Execute
|
|
||||||
LoadBPReg(bp_cmd);
|
LoadBPReg(bp_cmd);
|
||||||
INCSTAT(stats.thisFrame.numBPLoads);
|
INCSTAT(stats.thisFrame.numBPLoads);
|
||||||
|
|
||||||
// Analyze
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -237,27 +224,29 @@ bool AnalyzeAndRunDisplayList(u32 address, int size, CachedDisplayList *dl)
|
||||||
if (cmd_byte & 0x80)
|
if (cmd_byte & 0x80)
|
||||||
{
|
{
|
||||||
// load vertices (use computed vertex size from FifoCommandRunnable above)
|
// load vertices (use computed vertex size from FifoCommandRunnable above)
|
||||||
|
|
||||||
// Execute
|
|
||||||
u16 numVertices = DataReadU16();
|
u16 numVertices = DataReadU16();
|
||||||
|
|
||||||
VertexLoaderManager::RunVertices(
|
VertexLoaderManager::RunVertices(
|
||||||
cmd_byte & GX_VAT_MASK, // Vertex loader index (0 - 7)
|
cmd_byte & GX_VAT_MASK, // Vertex loader index (0 - 7)
|
||||||
(cmd_byte & GX_PRIMITIVE_MASK) >> GX_PRIMITIVE_SHIFT,
|
(cmd_byte & GX_PRIMITIVE_MASK) >> GX_PRIMITIVE_SHIFT,
|
||||||
numVertices);
|
numVertices);
|
||||||
|
|
||||||
// Analyze
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ERROR_LOG(VIDEO, "DLCache::CompileAndRun: Illegal command %02x", cmd_byte);
|
ERROR_LOG(VIDEO, "OpcodeDecoding::Decode: Illegal command %02x", cmd_byte);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
INCSTAT(stats.numDListsCalled);
|
||||||
|
INCSTAT(stats.thisFrame.numDListsCalled);
|
||||||
|
// un-swap
|
||||||
|
Statistics::SwapDL();
|
||||||
|
}
|
||||||
|
|
||||||
g_pVideoData = old_datareader;
|
// reset to the old pointer
|
||||||
|
g_pVideoData = old_pVideoData;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,10 +260,16 @@ bool AnalyzeAndRunDisplayList(u32 address, int size, CachedDisplayList *dl)
|
||||||
// have the compiled code so we don't have to interpret anymore, we just run it.
|
// have the compiled code so we don't have to interpret anymore, we just run it.
|
||||||
bool CompileAndRunDisplayList(u32 address, int size, CachedDisplayList *dl)
|
bool CompileAndRunDisplayList(u32 address, int size, CachedDisplayList *dl)
|
||||||
{
|
{
|
||||||
VertexManager::Flush();
|
u8* old_pVideoData = g_pVideoData;
|
||||||
|
u8* startAddress = Memory_GetPtr(address);
|
||||||
|
|
||||||
u8 *old_datareader = g_pVideoData;
|
// Avoid the crash if Memory_GetPtr failed ..
|
||||||
g_pVideoData = Memory_GetPtr(address);
|
if (startAddress != 0)
|
||||||
|
{
|
||||||
|
g_pVideoData = startAddress;
|
||||||
|
|
||||||
|
// temporarily swap dl and non-dl (small "hack" for the stats)
|
||||||
|
Statistics::SwapDL();
|
||||||
|
|
||||||
u8 *end = g_pVideoData + size;
|
u8 *end = g_pVideoData + size;
|
||||||
|
|
||||||
|
@ -321,7 +316,7 @@ bool CompileAndRunDisplayList(u32 address, int size, CachedDisplayList *dl)
|
||||||
INCSTAT(stats.thisFrame.numXFLoads);
|
INCSTAT(stats.thisFrame.numXFLoads);
|
||||||
|
|
||||||
// Compile
|
// Compile
|
||||||
emitter.ABI_CallFunctionCCP((void *)&LoadXFReg, transfer_size, address, data_buffer);
|
emitter.ABI_CallFunctionCCP((void *)&LoadXFReg, transfer_size, xf_address, data_buffer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -363,7 +358,12 @@ bool CompileAndRunDisplayList(u32 address, int size, CachedDisplayList *dl)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GX_CMD_CALL_DL:
|
case GX_CMD_CALL_DL:
|
||||||
PanicAlert("Seeing DL call inside DL.");
|
{
|
||||||
|
u32 address = DataReadU32();
|
||||||
|
u32 count = DataReadU32();
|
||||||
|
ExecuteDisplayList(address, count);
|
||||||
|
emitter.ABI_CallFunctionCC((void *)&ExecuteDisplayList, address, count);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GX_CMD_UNKNOWN_METRICS:
|
case GX_CMD_UNKNOWN_METRICS:
|
||||||
|
@ -402,13 +402,13 @@ bool CompileAndRunDisplayList(u32 address, int size, CachedDisplayList *dl)
|
||||||
numVertices);
|
numVertices);
|
||||||
|
|
||||||
// Compile
|
// Compile
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
emitter.MOV(64, R(RAX), Imm64(pre_draw_video_data));
|
emitter.MOV(64, R(RAX), Imm64(pre_draw_video_data));
|
||||||
emitter.MOV(64, M(&g_pVideoData), R(RAX));
|
emitter.MOV(64, M(&g_pVideoData), R(RAX));
|
||||||
#else
|
#else
|
||||||
emitter.MOV(32, R(EAX), Imm32((u32)pre_draw_video_data));
|
emitter.MOV(32, R(EAX), Imm32((u32)pre_draw_video_data));
|
||||||
emitter.MOV(32, M(&g_pVideoData), R(EAX));
|
emitter.MOV(32, M(&g_pVideoData), R(EAX));
|
||||||
#endif
|
#endif
|
||||||
emitter.ABI_CallFunctionCCC(
|
emitter.ABI_CallFunctionCCC(
|
||||||
(void *)&VertexLoaderManager::RunVertices,
|
(void *)&VertexLoaderManager::RunVertices,
|
||||||
cmd_byte & GX_VAT_MASK, // Vertex loader index (0 - 7)
|
cmd_byte & GX_VAT_MASK, // Vertex loader index (0 - 7)
|
||||||
|
@ -423,21 +423,12 @@ bool CompileAndRunDisplayList(u32 address, int size, CachedDisplayList *dl)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emitter.ABI_EmitEpilogue(4);
|
emitter.ABI_EmitEpilogue(4);
|
||||||
|
}
|
||||||
g_pVideoData = old_datareader;
|
g_pVideoData = old_pVideoData;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This one's pretty expensive. We should check if we can get away with only
|
|
||||||
// hashing the entire DL the first 3 frames or something.
|
|
||||||
u32 ComputeDLHash(u32 address, u32 size)
|
|
||||||
{
|
|
||||||
u8 *ptr = Memory_GetPtr(address);
|
|
||||||
return HashFletcher(ptr, size & ~1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
dlcode_cache = (u8 *)AllocateExecutableMemory(DL_CODE_CACHE_SIZE, false); // Don't need low memory.
|
dlcode_cache = (u8 *)AllocateExecutableMemory(DL_CODE_CACHE_SIZE, false); // Don't need low memory.
|
||||||
|
@ -485,8 +476,12 @@ bool HandleDisplayList(u32 address, u32 size)
|
||||||
{
|
{
|
||||||
// Disable display list caching since the benefit isn't much to write home about
|
// Disable display list caching since the benefit isn't much to write home about
|
||||||
// right now...
|
// right now...
|
||||||
|
//Fixed DlistCaching now is fully functional benefits still marginal but when vertex data is stored here the story will be diferent :)
|
||||||
|
//to test remove the next line;
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
if(size == 0) return false;
|
||||||
u64 dl_id = DLCache::CreateMapId(address, size);
|
u64 dl_id = DLCache::CreateMapId(address, size);
|
||||||
DLCache::DLMap::iterator iter = DLCache::dl_map.find(dl_id);
|
DLCache::DLMap::iterator iter = DLCache::dl_map.find(dl_id);
|
||||||
|
|
||||||
|
@ -509,7 +504,7 @@ bool HandleDisplayList(u32 address, u32 size)
|
||||||
break;
|
break;
|
||||||
case DLCache::DLPASS_COMPILE:
|
case DLCache::DLPASS_COMPILE:
|
||||||
// First, check that the hash is the same as the last time.
|
// First, check that the hash is the same as the last time.
|
||||||
if (dl.dl_hash != HashAdler32(Memory_GetPtr(address), size))
|
if (dl.dl_hash != GetHash64(Memory_GetPtr(address), size,0))
|
||||||
{
|
{
|
||||||
// PanicAlert("uncachable %08x", address);
|
// PanicAlert("uncachable %08x", address);
|
||||||
dl.uncachable = true;
|
dl.uncachable = true;
|
||||||
|
@ -524,13 +519,13 @@ bool HandleDisplayList(u32 address, u32 size)
|
||||||
dl.check--;
|
dl.check--;
|
||||||
if (dl.check <= 0)
|
if (dl.check <= 0)
|
||||||
{
|
{
|
||||||
if (dl.dl_hash != HashAdler32(Memory_GetPtr(address), size))
|
if (dl.dl_hash != GetHash64(Memory_GetPtr(address), size,0))
|
||||||
{
|
{
|
||||||
dl.uncachable = true;
|
dl.uncachable = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
dl.check = dl.next_check;
|
dl.check = dl.next_check;
|
||||||
dl.next_check *= 2;
|
//dl.next_check *= 2;
|
||||||
if (dl.next_check > 1024)
|
if (dl.next_check > 1024)
|
||||||
dl.next_check = 1024;
|
dl.next_check = 1024;
|
||||||
}
|
}
|
||||||
|
@ -546,7 +541,7 @@ bool HandleDisplayList(u32 address, u32 size)
|
||||||
DLCache::CachedDisplayList dl;
|
DLCache::CachedDisplayList dl;
|
||||||
|
|
||||||
if (DLCache::AnalyzeAndRunDisplayList(address, size, &dl)) {
|
if (DLCache::AnalyzeAndRunDisplayList(address, size, &dl)) {
|
||||||
dl.dl_hash = HashAdler32(Memory_GetPtr(address), size);
|
dl.dl_hash = GetHash64(Memory_GetPtr(address), size,0);
|
||||||
dl.pass = DLCache::DLPASS_COMPILE;
|
dl.pass = DLCache::DLPASS_COMPILE;
|
||||||
dl.check = 1;
|
dl.check = 1;
|
||||||
dl.next_check = 1;
|
dl.next_check = 1;
|
||||||
|
|
|
@ -29,13 +29,13 @@
|
||||||
#define COMPILED_CODE_SIZE 4096
|
#define COMPILED_CODE_SIZE 4096
|
||||||
|
|
||||||
u32 s_prevcomponents; // previous state set
|
u32 s_prevcomponents; // previous state set
|
||||||
|
/*
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#ifdef _M_IX86
|
#ifdef _M_IX86
|
||||||
#define USE_JIT
|
#define USE_JIT
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
// Note the use of CallCdeclFunction3I etc.
|
// Note the use of CallCdeclFunction3I etc.
|
||||||
// This is a horrible hack that is necessary because in 64-bit mode, Opengl32.dll is based way, way above the 32-bit
|
// This is a horrible hack that is necessary because in 64-bit mode, Opengl32.dll is based way, way above the 32-bit
|
||||||
// address space that is within reach of a CALL, and just doing &fn gives us these high uncallable addresses. So we
|
// address space that is within reach of a CALL, and just doing &fn gives us these high uncallable addresses. So we
|
||||||
|
@ -181,21 +181,21 @@ void GLVertexFormat::SetupVertexPointers() const {
|
||||||
#ifdef USE_JIT
|
#ifdef USE_JIT
|
||||||
((void (*)())(void*)m_compiledCode)();
|
((void (*)())(void*)m_compiledCode)();
|
||||||
#else
|
#else
|
||||||
glVertexPointer(3, GL_FLOAT, vtx_decl.stride, 0);
|
glVertexPointer(3, GL_FLOAT, vtx_decl.stride, VertexManager::s_pBaseBufferPointer);
|
||||||
if (vtx_decl.num_normals >= 1) {
|
if (vtx_decl.num_normals >= 1) {
|
||||||
glNormalPointer(VarToGL(vtx_decl.normal_gl_type), vtx_decl.stride, (void *)vtx_decl.normal_offset[0]);
|
glNormalPointer(VarToGL(vtx_decl.normal_gl_type), vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[0]));
|
||||||
if (vtx_decl.num_normals == 3) {
|
if (vtx_decl.num_normals == 3) {
|
||||||
glVertexAttribPointer(SHADER_NORM1_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (void *)vtx_decl.normal_offset[1]);
|
glVertexAttribPointer(SHADER_NORM1_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[1]));
|
||||||
glVertexAttribPointer(SHADER_NORM2_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (void *)vtx_decl.normal_offset[2]);
|
glVertexAttribPointer(SHADER_NORM2_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[2]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
if (vtx_decl.color_offset[i] != -1) {
|
if (vtx_decl.color_offset[i] != -1) {
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
glColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (void *)vtx_decl.color_offset[i]);
|
glColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.color_offset[i]));
|
||||||
else {
|
else {
|
||||||
glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (void *)vtx_decl.color_offset[i]);
|
glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.color_offset[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,12 +205,12 @@ void GLVertexFormat::SetupVertexPointers() const {
|
||||||
int id = GL_TEXTURE0 + i;
|
int id = GL_TEXTURE0 + i;
|
||||||
glClientActiveTexture(id);
|
glClientActiveTexture(id);
|
||||||
glTexCoordPointer(vtx_decl.texcoord_size[i], VarToGL(vtx_decl.texcoord_gl_type[i]),
|
glTexCoordPointer(vtx_decl.texcoord_size[i], VarToGL(vtx_decl.texcoord_gl_type[i]),
|
||||||
vtx_decl.stride, (void *)vtx_decl.texcoord_offset[i]);
|
vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.texcoord_offset[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vtx_decl.posmtx_offset != -1) {
|
if (vtx_decl.posmtx_offset != -1) {
|
||||||
glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (void *)vtx_decl.posmtx_offset);
|
glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.posmtx_offset));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -381,7 +381,7 @@ u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float
|
||||||
|
|
||||||
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0 && !bFromZBuffer);
|
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0 && !bFromZBuffer);
|
||||||
TextureMngr::MakeRangeDynamic(address,size_in_bytes);
|
TextureMngr::MakeRangeDynamic(address,size_in_bytes);
|
||||||
return TexDecoder_GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
return GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc,
|
void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc,
|
||||||
|
|
|
@ -290,7 +290,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||||
FullFormat = (tex_format | (tlutfmt << 16));
|
FullFormat = (tex_format | (tlutfmt << 16));
|
||||||
if (g_ActiveConfig.bSafeTextureCache || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures)
|
if (g_ActiveConfig.bSafeTextureCache || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures)
|
||||||
{
|
{
|
||||||
texHash = TexDecoder_GetHash64(ptr,TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
texHash = GetHash64(ptr,TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||||
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
|
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
|
||||||
{
|
{
|
||||||
// WARNING! texID != address now => may break CopyRenderTargetToTexture (cf. TODO up)
|
// WARNING! texID != address now => may break CopyRenderTargetToTexture (cf. TODO up)
|
||||||
|
@ -300,7 +300,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||||
// each other stored in a single texture, and uses the palette to make different characters
|
// each other stored in a single texture, and uses the palette to make different characters
|
||||||
// visible or invisible. Thus, unless we want to recreate the textures for every drawn character,
|
// visible or invisible. Thus, unless we want to recreate the textures for every drawn character,
|
||||||
// we must make sure that texture with different tluts get different IDs.
|
// we must make sure that texture with different tluts get different IDs.
|
||||||
u64 tlutHash = TexDecoder_GetHash64(&texMem[tlutaddr], TexDecoder_GetPaletteSize(tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
u64 tlutHash = GetHash64(&texMem[tlutaddr], TexDecoder_GetPaletteSize(tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||||
texHash ^= tlutHash;
|
texHash ^= tlutHash;
|
||||||
if (g_ActiveConfig.bSafeTextureCache)
|
if (g_ActiveConfig.bSafeTextureCache)
|
||||||
{
|
{
|
||||||
|
@ -324,10 +324,10 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||||
{
|
{
|
||||||
if(!g_ActiveConfig.bCopyEFBToTexture)
|
if(!g_ActiveConfig.bCopyEFBToTexture)
|
||||||
{
|
{
|
||||||
hash_value = TexDecoder_GetHash64(ptr,TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
hash_value = GetHash64(ptr,TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||||
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
|
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
|
||||||
{
|
{
|
||||||
hash_value ^= TexDecoder_GetHash64(&texMem[tlutaddr], TexDecoder_GetPaletteSize(tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
hash_value ^= GetHash64(&texMem[tlutaddr], TexDecoder_GetPaletteSize(tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -60,8 +60,8 @@ static GLint max_Index_size = 0;
|
||||||
#define MAXIBUFFERSIZE 0xFFFF
|
#define MAXIBUFFERSIZE 0xFFFF
|
||||||
#define MAXVBOBUFFERCOUNT 0x8
|
#define MAXVBOBUFFERCOUNT 0x8
|
||||||
|
|
||||||
static GLuint s_vboBuffers[MAXVBOBUFFERCOUNT] = {0};
|
//static GLuint s_vboBuffers[MAXVBOBUFFERCOUNT] = {0};
|
||||||
static int s_nCurVBOIndex = 0; // current free buffer
|
//static int s_nCurVBOIndex = 0; // current free buffer
|
||||||
static bool Flushed=false;
|
static bool Flushed=false;
|
||||||
|
|
||||||
|
|
||||||
|
@ -79,8 +79,9 @@ bool Init()
|
||||||
PIBuffer = new u16[max_Index_size];
|
PIBuffer = new u16[max_Index_size];
|
||||||
IndexGenerator::Start(TIBuffer,LIBuffer,PIBuffer);
|
IndexGenerator::Start(TIBuffer,LIBuffer,PIBuffer);
|
||||||
s_pCurBufferPointer = LocalVBuffer;
|
s_pCurBufferPointer = LocalVBuffer;
|
||||||
s_nCurVBOIndex = 0;
|
s_pBaseBufferPointer = LocalVBuffer;
|
||||||
glGenBuffers(ARRAYSIZE(s_vboBuffers), s_vboBuffers);
|
//s_nCurVBOIndex = 0;
|
||||||
|
//glGenBuffers(ARRAYSIZE(s_vboBuffers), s_vboBuffers);
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
g_nativeVertexFmt = NULL;
|
g_nativeVertexFmt = NULL;
|
||||||
Flushed=false;
|
Flushed=false;
|
||||||
|
@ -95,13 +96,13 @@ void Shutdown()
|
||||||
delete [] TIBuffer;
|
delete [] TIBuffer;
|
||||||
delete [] LIBuffer;
|
delete [] LIBuffer;
|
||||||
delete [] PIBuffer;
|
delete [] PIBuffer;
|
||||||
glDeleteBuffers(ARRAYSIZE(s_vboBuffers), s_vboBuffers);
|
//glDeleteBuffers(ARRAYSIZE(s_vboBuffers), s_vboBuffers);
|
||||||
s_nCurVBOIndex = 0;
|
//s_nCurVBOIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResetBuffer()
|
void ResetBuffer()
|
||||||
{
|
{
|
||||||
s_nCurVBOIndex = (s_nCurVBOIndex + 1) % ARRAYSIZE(s_vboBuffers);
|
//s_nCurVBOIndex = (s_nCurVBOIndex + 1) % ARRAYSIZE(s_vboBuffers);
|
||||||
s_pCurBufferPointer = LocalVBuffer;
|
s_pCurBufferPointer = LocalVBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,8 +238,8 @@ void Flush()
|
||||||
|
|
||||||
(void)GL_REPORT_ERROR();
|
(void)GL_REPORT_ERROR();
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, s_vboBuffers[s_nCurVBOIndex]);
|
//glBindBuffer(GL_ARRAY_BUFFER, s_vboBuffers[s_nCurVBOIndex]);
|
||||||
glBufferData(GL_ARRAY_BUFFER, s_pCurBufferPointer - LocalVBuffer, LocalVBuffer, GL_STREAM_DRAW);
|
//glBufferData(GL_ARRAY_BUFFER, s_pCurBufferPointer - LocalVBuffer, LocalVBuffer, GL_STREAM_DRAW);
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
// setup the pointers
|
// setup the pointers
|
||||||
|
@ -339,7 +340,7 @@ void Flush()
|
||||||
if (bpmem.blendmode.blendenable || bpmem.blendmode.subtract)
|
if (bpmem.blendmode.blendenable || bpmem.blendmode.subtract)
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
}
|
}
|
||||||
s_nCurVBOIndex = (s_nCurVBOIndex + 1) % ARRAYSIZE(s_vboBuffers);
|
//s_nCurVBOIndex = (s_nCurVBOIndex + 1) % ARRAYSIZE(s_vboBuffers);
|
||||||
s_pCurBufferPointer = LocalVBuffer;
|
s_pCurBufferPointer = LocalVBuffer;
|
||||||
IndexGenerator::Start(TIBuffer,LIBuffer,PIBuffer);
|
IndexGenerator::Start(TIBuffer,LIBuffer,PIBuffer);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue