mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 14:19:46 -06:00
Merge pull request #2480 from phire/GamesDoWeirdShit
Fix invalid pointer errors in Burnout 2.
This commit is contained in:
@ -23,11 +23,13 @@ void SWLoadCPReg(u32 sub_cmd, u32 value)
|
|||||||
case 0x50:
|
case 0x50:
|
||||||
g_main_cp_state.vtx_desc.Hex &= ~0x1FFFF; // keep the Upper bits
|
g_main_cp_state.vtx_desc.Hex &= ~0x1FFFF; // keep the Upper bits
|
||||||
g_main_cp_state.vtx_desc.Hex |= value;
|
g_main_cp_state.vtx_desc.Hex |= value;
|
||||||
|
g_main_cp_state.bases_dirty = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x60:
|
case 0x60:
|
||||||
g_main_cp_state.vtx_desc.Hex &= 0x1FFFF; // keep the lower 17Bits
|
g_main_cp_state.vtx_desc.Hex &= 0x1FFFF; // keep the lower 17Bits
|
||||||
g_main_cp_state.vtx_desc.Hex |= (u64)value << 17;
|
g_main_cp_state.vtx_desc.Hex |= (u64)value << 17;
|
||||||
|
g_main_cp_state.bases_dirty = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x70:
|
case 0x70:
|
||||||
@ -48,7 +50,7 @@ void SWLoadCPReg(u32 sub_cmd, u32 value)
|
|||||||
// Pointers to vertex arrays in GC RAM
|
// Pointers to vertex arrays in GC RAM
|
||||||
case 0xA0:
|
case 0xA0:
|
||||||
g_main_cp_state.array_bases[sub_cmd & 0xF] = value;
|
g_main_cp_state.array_bases[sub_cmd & 0xF] = value;
|
||||||
cached_arraybases[sub_cmd & 0xF] = Memory::GetPointer(value);
|
g_main_cp_state.bases_dirty = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xB0:
|
case 0xB0:
|
||||||
|
@ -16,8 +16,10 @@
|
|||||||
#include "VideoBackends/Software/XFMemLoader.h"
|
#include "VideoBackends/Software/XFMemLoader.h"
|
||||||
|
|
||||||
#include "VideoCommon/VertexLoaderBase.h"
|
#include "VideoCommon/VertexLoaderBase.h"
|
||||||
|
#include "VideoCommon/VertexLoaderManager.h"
|
||||||
#include "VideoCommon/VertexLoaderUtils.h"
|
#include "VideoCommon/VertexLoaderUtils.h"
|
||||||
|
|
||||||
|
|
||||||
SWVertexLoader::SWVertexLoader() :
|
SWVertexLoader::SWVertexLoader() :
|
||||||
m_VertexSize(0)
|
m_VertexSize(0)
|
||||||
{
|
{
|
||||||
@ -176,6 +178,8 @@ void SWVertexLoader::LoadVertex()
|
|||||||
// reserve memory for the destination of the vertex loader
|
// reserve memory for the destination of the vertex loader
|
||||||
m_LoadedVertices.resize(vdec.stride + 4);
|
m_LoadedVertices.resize(vdec.stride + 4);
|
||||||
|
|
||||||
|
VertexLoaderManager::UpdateVertexArrayPointers();
|
||||||
|
|
||||||
// convert the vertex from the gc format to the videocommon (hardware optimized) format
|
// convert the vertex from the gc format to the videocommon (hardware optimized) format
|
||||||
u8* old = g_video_buffer_read_ptr;
|
u8* old = g_video_buffer_read_ptr;
|
||||||
int converted_vertices = m_CurrentLoader->RunVertices(
|
int converted_vertices = m_CurrentLoader->RunVertices(
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
#include "VideoCommon/CPMemory.h"
|
#include "VideoCommon/CPMemory.h"
|
||||||
|
|
||||||
// CP state
|
// CP state
|
||||||
u8 *cached_arraybases[16];
|
|
||||||
|
|
||||||
CPState g_main_cp_state;
|
CPState g_main_cp_state;
|
||||||
CPState g_preprocess_cp_state;
|
CPState g_preprocess_cp_state;
|
||||||
|
|
||||||
@ -24,7 +22,10 @@ void DoCPState(PointerWrap& p)
|
|||||||
p.DoArray(g_main_cp_state.vtx_attr, 8);
|
p.DoArray(g_main_cp_state.vtx_attr, 8);
|
||||||
p.DoMarker("CP Memory");
|
p.DoMarker("CP Memory");
|
||||||
if (p.mode == PointerWrap::MODE_READ)
|
if (p.mode == PointerWrap::MODE_READ)
|
||||||
|
{
|
||||||
CopyPreprocessCPStateFromMain();
|
CopyPreprocessCPStateFromMain();
|
||||||
|
g_main_cp_state.bases_dirty = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CopyPreprocessCPStateFromMain()
|
void CopyPreprocessCPStateFromMain()
|
||||||
|
@ -88,6 +88,12 @@ union TVtxDesc
|
|||||||
{
|
{
|
||||||
u32 Hex0, Hex1;
|
u32 Hex0, Hex1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Easily index into the Position..Tex7Coord fields.
|
||||||
|
u32 GetVertexArrayStatus(int idx)
|
||||||
|
{
|
||||||
|
return (Hex >> (9 + idx * 2)) & 0x3;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
union UVAT_group0
|
union UVAT_group0
|
||||||
@ -249,6 +255,7 @@ struct CPState final
|
|||||||
|
|
||||||
// Attributes that actually belong to VertexLoaderManager:
|
// Attributes that actually belong to VertexLoaderManager:
|
||||||
BitSet32 attr_dirty;
|
BitSet32 attr_dirty;
|
||||||
|
bool bases_dirty;
|
||||||
VertexLoaderBase* vertex_loaders[8];
|
VertexLoaderBase* vertex_loaders[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -261,7 +268,6 @@ extern void CopyPreprocessCPStateFromMain();
|
|||||||
extern CPState g_main_cp_state;
|
extern CPState g_main_cp_state;
|
||||||
extern CPState g_preprocess_cp_state;
|
extern CPState g_preprocess_cp_state;
|
||||||
|
|
||||||
extern u8 *cached_arraybases[16];
|
|
||||||
|
|
||||||
// Might move this into its own file later.
|
// Might move this into its own file later.
|
||||||
void LoadCPReg(u32 SubCmd, u32 Value, bool is_preprocess = false);
|
void LoadCPReg(u32 SubCmd, u32 Value, bool is_preprocess = false);
|
||||||
|
@ -212,7 +212,6 @@ void VideoBackendHardware::DoState(PointerWrap& p)
|
|||||||
if (p.GetMode() == PointerWrap::MODE_READ)
|
if (p.GetMode() == PointerWrap::MODE_READ)
|
||||||
{
|
{
|
||||||
m_invalid = true;
|
m_invalid = true;
|
||||||
RecomputeCachedArraybases();
|
|
||||||
|
|
||||||
// Clear all caches that touch RAM
|
// Clear all caches that touch RAM
|
||||||
// (? these don't appear to touch any emulation state that gets saved. moved to on load only.)
|
// (? these don't appear to touch any emulation state that gets saved. moved to on load only.)
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "VideoCommon/VertexLoaderARM64.h"
|
#include "VideoCommon/VertexLoaderARM64.h"
|
||||||
|
#include "VideoCommon/VertexLoaderManager.h"
|
||||||
|
|
||||||
using namespace Arm64Gen;
|
using namespace Arm64Gen;
|
||||||
|
|
||||||
@ -331,7 +332,7 @@ void VertexLoaderARM64::GenerateVertexLoader()
|
|||||||
MOV(saved_count, count_reg);
|
MOV(saved_count, count_reg);
|
||||||
|
|
||||||
MOVI2R(stride_reg, (u64)&g_main_cp_state.array_strides);
|
MOVI2R(stride_reg, (u64)&g_main_cp_state.array_strides);
|
||||||
MOVI2R(arraybase_reg, (u64)&cached_arraybases);
|
MOVI2R(arraybase_reg, (u64)&VertexLoaderManager::cached_arraybases);
|
||||||
MOVI2R(scale_reg, (u64)&scale_factors);
|
MOVI2R(scale_reg, (u64)&scale_factors);
|
||||||
|
|
||||||
const u8* loop_start = GetCodePtr();
|
const u8* loop_start = GetCodePtr();
|
||||||
|
@ -35,6 +35,8 @@ static std::mutex s_vertex_loader_map_lock;
|
|||||||
static VertexLoaderMap s_vertex_loader_map;
|
static VertexLoaderMap s_vertex_loader_map;
|
||||||
// TODO - change into array of pointers. Keep a map of all seen so far.
|
// TODO - change into array of pointers. Keep a map of all seen so far.
|
||||||
|
|
||||||
|
u8 *cached_arraybases[12];
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
MarkAllDirty();
|
MarkAllDirty();
|
||||||
@ -42,7 +44,6 @@ void Init()
|
|||||||
map_entry = nullptr;
|
map_entry = nullptr;
|
||||||
for (auto& map_entry : g_preprocess_cp_state.vertex_loaders)
|
for (auto& map_entry : g_preprocess_cp_state.vertex_loaders)
|
||||||
map_entry = nullptr;
|
map_entry = nullptr;
|
||||||
RecomputeCachedArraybases();
|
|
||||||
SETSTAT(stats.numVertexLoaders, 0);
|
SETSTAT(stats.numVertexLoaders, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,6 +54,27 @@ void Shutdown()
|
|||||||
s_native_vertex_map.clear();
|
s_native_vertex_map.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateVertexArrayPointers()
|
||||||
|
{
|
||||||
|
// Anything to update?
|
||||||
|
if (!g_main_cp_state.bases_dirty)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Some games such as Burnout 2 can put invalid addresses into
|
||||||
|
// the array base registers. (see issue 8591)
|
||||||
|
// But the vertex arrays with invalid addresses aren't actually enabled.
|
||||||
|
// Note: Only array bases 0 through 11 are used by the Vertex loaders.
|
||||||
|
// 12 through 15 are used for loading data into xfmem.
|
||||||
|
for (int i = 0; i < 12; i++)
|
||||||
|
{
|
||||||
|
// Only update the array base if the vertex description states we are going to use it.
|
||||||
|
if (g_main_cp_state.vtx_desc.GetVertexArrayStatus(i) >= 0x2)
|
||||||
|
cached_arraybases[i] = Memory::GetPointer(g_main_cp_state.array_bases[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_main_cp_state.bases_dirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
struct entry
|
struct entry
|
||||||
@ -136,6 +158,11 @@ static VertexLoaderBase* RefreshLoader(int vtx_attr_group, bool preprocess = fal
|
|||||||
} else {
|
} else {
|
||||||
loader = state->vertex_loaders[vtx_attr_group];
|
loader = state->vertex_loaders[vtx_attr_group];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lookup pointers for any vertex arrays.
|
||||||
|
if (!preprocess)
|
||||||
|
UpdateVertexArrayPointers();
|
||||||
|
|
||||||
return loader;
|
return loader;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,12 +230,14 @@ void LoadCPReg(u32 sub_cmd, u32 value, bool is_preprocess)
|
|||||||
state->vtx_desc.Hex &= ~0x1FFFF; // keep the Upper bits
|
state->vtx_desc.Hex &= ~0x1FFFF; // keep the Upper bits
|
||||||
state->vtx_desc.Hex |= value;
|
state->vtx_desc.Hex |= value;
|
||||||
state->attr_dirty = BitSet32::AllTrue(8);
|
state->attr_dirty = BitSet32::AllTrue(8);
|
||||||
|
state->bases_dirty = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x60:
|
case 0x60:
|
||||||
state->vtx_desc.Hex &= 0x1FFFF; // keep the lower 17Bits
|
state->vtx_desc.Hex &= 0x1FFFF; // keep the lower 17Bits
|
||||||
state->vtx_desc.Hex |= (u64)value << 17;
|
state->vtx_desc.Hex |= (u64)value << 17;
|
||||||
state->attr_dirty = BitSet32::AllTrue(8);
|
state->attr_dirty = BitSet32::AllTrue(8);
|
||||||
|
state->bases_dirty = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x70:
|
case 0x70:
|
||||||
@ -232,8 +261,7 @@ void LoadCPReg(u32 sub_cmd, u32 value, bool is_preprocess)
|
|||||||
// Pointers to vertex arrays in GC RAM
|
// Pointers to vertex arrays in GC RAM
|
||||||
case 0xA0:
|
case 0xA0:
|
||||||
state->array_bases[sub_cmd & 0xF] = value;
|
state->array_bases[sub_cmd & 0xF] = value;
|
||||||
if (update_global_state)
|
state->bases_dirty = true;
|
||||||
cached_arraybases[sub_cmd & 0xF] = Memory::GetPointer(value);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xB0:
|
case 0xB0:
|
||||||
@ -262,11 +290,3 @@ void FillCPMemoryArray(u32 *memory)
|
|||||||
memory[0xB0 + i] = g_main_cp_state.array_strides[i];
|
memory[0xB0 + i] = g_main_cp_state.array_strides[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecomputeCachedArraybases()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
cached_arraybases[i] = Memory::GetPointer(g_main_cp_state.array_bases[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -24,6 +24,9 @@ namespace VertexLoaderManager
|
|||||||
void AppendListToString(std::string *dest);
|
void AppendListToString(std::string *dest);
|
||||||
|
|
||||||
NativeVertexFormat* GetCurrentVertexFormat();
|
NativeVertexFormat* GetCurrentVertexFormat();
|
||||||
|
|
||||||
|
// Resolved pointers to array bases. Used by vertex loaders.
|
||||||
|
extern u8 *cached_arraybases[12];
|
||||||
|
void UpdateVertexArrayPointers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecomputeCachedArraybases();
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "Common/Intrinsics.h"
|
#include "Common/Intrinsics.h"
|
||||||
#include "Common/JitRegister.h"
|
#include "Common/JitRegister.h"
|
||||||
#include "Common/x64ABI.h"
|
#include "Common/x64ABI.h"
|
||||||
|
#include "VideoCommon/VertexLoaderManager.h"
|
||||||
#include "VideoCommon/VertexLoaderX64.h"
|
#include "VideoCommon/VertexLoaderX64.h"
|
||||||
|
|
||||||
using namespace Gen;
|
using namespace Gen;
|
||||||
@ -58,7 +59,7 @@ OpArg VertexLoaderX64::GetVertexAddr(int array, u64 attribute)
|
|||||||
}
|
}
|
||||||
// TODO: Move cached_arraybases into CPState and use MDisp() relative to a constant register loaded with &g_main_cp_state.
|
// TODO: Move cached_arraybases into CPState and use MDisp() relative to a constant register loaded with &g_main_cp_state.
|
||||||
IMUL(32, scratch1, M(&g_main_cp_state.array_strides[array]));
|
IMUL(32, scratch1, M(&g_main_cp_state.array_strides[array]));
|
||||||
MOV(64, R(scratch2), M(&cached_arraybases[array]));
|
MOV(64, R(scratch2), M(&VertexLoaderManager::cached_arraybases[array]));
|
||||||
return MRegSum(scratch1, scratch2);
|
return MRegSum(scratch1, scratch2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "VideoCommon/VertexLoader.h"
|
#include "VideoCommon/VertexLoader.h"
|
||||||
#include "VideoCommon/VertexLoader_Color.h"
|
#include "VideoCommon/VertexLoader_Color.h"
|
||||||
|
#include "VideoCommon/VertexLoaderManager.h"
|
||||||
#include "VideoCommon/VertexManagerBase.h"
|
#include "VideoCommon/VertexManagerBase.h"
|
||||||
#include "VideoCommon/VideoCommon.h"
|
#include "VideoCommon/VideoCommon.h"
|
||||||
|
|
||||||
@ -100,7 +101,7 @@ template <typename I>
|
|||||||
void Color_ReadIndex_16b_565(VertexLoader* loader)
|
void Color_ReadIndex_16b_565(VertexLoader* loader)
|
||||||
{
|
{
|
||||||
auto const Index = DataRead<I>();
|
auto const Index = DataRead<I>();
|
||||||
u16 val = Common::swap16(*(const u16 *)(cached_arraybases[ARRAY_COLOR + loader->m_colIndex] + (Index * g_main_cp_state.array_strides[ARRAY_COLOR + loader->m_colIndex])));
|
u16 val = Common::swap16(*(const u16 *)(VertexLoaderManager::cached_arraybases[ARRAY_COLOR + loader->m_colIndex] + (Index * g_main_cp_state.array_strides[ARRAY_COLOR + loader->m_colIndex])));
|
||||||
_SetCol565(loader, val);
|
_SetCol565(loader, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +109,7 @@ template <typename I>
|
|||||||
void Color_ReadIndex_24b_888(VertexLoader* loader)
|
void Color_ReadIndex_24b_888(VertexLoader* loader)
|
||||||
{
|
{
|
||||||
auto const Index = DataRead<I>();
|
auto const Index = DataRead<I>();
|
||||||
const u8 *iAddress = cached_arraybases[ARRAY_COLOR + loader->m_colIndex] + (Index * g_main_cp_state.array_strides[ARRAY_COLOR + loader->m_colIndex]);
|
const u8 *iAddress = VertexLoaderManager::cached_arraybases[ARRAY_COLOR + loader->m_colIndex] + (Index * g_main_cp_state.array_strides[ARRAY_COLOR + loader->m_colIndex]);
|
||||||
_SetCol(loader, _Read24(iAddress));
|
_SetCol(loader, _Read24(iAddress));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +117,7 @@ template <typename I>
|
|||||||
void Color_ReadIndex_32b_888x(VertexLoader* loader)
|
void Color_ReadIndex_32b_888x(VertexLoader* loader)
|
||||||
{
|
{
|
||||||
auto const Index = DataRead<I>();
|
auto const Index = DataRead<I>();
|
||||||
const u8 *iAddress = cached_arraybases[ARRAY_COLOR + loader->m_colIndex] + (Index * g_main_cp_state.array_strides[ARRAY_COLOR + loader->m_colIndex]);
|
const u8 *iAddress = VertexLoaderManager::cached_arraybases[ARRAY_COLOR + loader->m_colIndex] + (Index * g_main_cp_state.array_strides[ARRAY_COLOR + loader->m_colIndex]);
|
||||||
_SetCol(loader, _Read24(iAddress));
|
_SetCol(loader, _Read24(iAddress));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +125,7 @@ template <typename I>
|
|||||||
void Color_ReadIndex_16b_4444(VertexLoader* loader)
|
void Color_ReadIndex_16b_4444(VertexLoader* loader)
|
||||||
{
|
{
|
||||||
auto const Index = DataRead<I>();
|
auto const Index = DataRead<I>();
|
||||||
u16 val = *(const u16 *)(cached_arraybases[ARRAY_COLOR + loader->m_colIndex] + (Index * g_main_cp_state.array_strides[ARRAY_COLOR + loader->m_colIndex]));
|
u16 val = *(const u16 *)(VertexLoaderManager::cached_arraybases[ARRAY_COLOR + loader->m_colIndex] + (Index * g_main_cp_state.array_strides[ARRAY_COLOR + loader->m_colIndex]));
|
||||||
_SetCol4444(loader, val);
|
_SetCol4444(loader, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +133,7 @@ template <typename I>
|
|||||||
void Color_ReadIndex_24b_6666(VertexLoader* loader)
|
void Color_ReadIndex_24b_6666(VertexLoader* loader)
|
||||||
{
|
{
|
||||||
auto const Index = DataRead<I>();
|
auto const Index = DataRead<I>();
|
||||||
const u8* pData = cached_arraybases[ARRAY_COLOR + loader->m_colIndex] + (Index * g_main_cp_state.array_strides[ARRAY_COLOR + loader->m_colIndex]) - 1;
|
const u8* pData = VertexLoaderManager::cached_arraybases[ARRAY_COLOR + loader->m_colIndex] + (Index * g_main_cp_state.array_strides[ARRAY_COLOR + loader->m_colIndex]) - 1;
|
||||||
u32 val = Common::swap32(pData);
|
u32 val = Common::swap32(pData);
|
||||||
_SetCol6666(loader, val);
|
_SetCol6666(loader, val);
|
||||||
}
|
}
|
||||||
@ -141,7 +142,7 @@ template <typename I>
|
|||||||
void Color_ReadIndex_32b_8888(VertexLoader* loader)
|
void Color_ReadIndex_32b_8888(VertexLoader* loader)
|
||||||
{
|
{
|
||||||
auto const Index = DataRead<I>();
|
auto const Index = DataRead<I>();
|
||||||
const u8 *iAddress = cached_arraybases[ARRAY_COLOR + loader->m_colIndex] + (Index * g_main_cp_state.array_strides[ARRAY_COLOR + loader->m_colIndex]);
|
const u8 *iAddress = VertexLoaderManager::cached_arraybases[ARRAY_COLOR + loader->m_colIndex] + (Index * g_main_cp_state.array_strides[ARRAY_COLOR + loader->m_colIndex]);
|
||||||
_SetCol(loader, _Read32(iAddress));
|
_SetCol(loader, _Read32(iAddress));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "VideoCommon/VertexLoader.h"
|
#include "VideoCommon/VertexLoader.h"
|
||||||
#include "VideoCommon/VertexLoader_Normal.h"
|
#include "VideoCommon/VertexLoader_Normal.h"
|
||||||
|
#include "VideoCommon/VertexLoaderManager.h"
|
||||||
#include "VideoCommon/VertexManagerBase.h"
|
#include "VideoCommon/VertexManagerBase.h"
|
||||||
#include "VideoCommon/VideoCommon.h"
|
#include "VideoCommon/VideoCommon.h"
|
||||||
|
|
||||||
@ -71,7 +72,7 @@ __forceinline void Normal_Index_Offset()
|
|||||||
static_assert(std::is_unsigned<I>::value, "Only unsigned I is sane!");
|
static_assert(std::is_unsigned<I>::value, "Only unsigned I is sane!");
|
||||||
|
|
||||||
auto const index = DataRead<I>();
|
auto const index = DataRead<I>();
|
||||||
auto const data = reinterpret_cast<const T*>(cached_arraybases[ARRAY_NORMAL]
|
auto const data = reinterpret_cast<const T*>(VertexLoaderManager::cached_arraybases[ARRAY_NORMAL]
|
||||||
+ (index * g_main_cp_state.array_strides[ARRAY_NORMAL]) + sizeof(T) * 3 * Offset);
|
+ (index * g_main_cp_state.array_strides[ARRAY_NORMAL]) + sizeof(T) * 3 * Offset);
|
||||||
ReadIndirect<T, N * 3>(data);
|
ReadIndirect<T, N * 3>(data);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "VideoCommon/VertexLoader.h"
|
#include "VideoCommon/VertexLoader.h"
|
||||||
#include "VideoCommon/VertexLoader_Position.h"
|
#include "VideoCommon/VertexLoader_Position.h"
|
||||||
|
#include "VideoCommon/VertexLoaderManager.h"
|
||||||
#include "VideoCommon/VertexManagerBase.h"
|
#include "VideoCommon/VertexManagerBase.h"
|
||||||
#include "VideoCommon/VideoCommon.h"
|
#include "VideoCommon/VideoCommon.h"
|
||||||
|
|
||||||
@ -46,7 +47,7 @@ void LOADERDECL Pos_ReadIndex(VertexLoader* loader)
|
|||||||
|
|
||||||
auto const index = DataRead<I>();
|
auto const index = DataRead<I>();
|
||||||
loader->m_vertexSkip = index == std::numeric_limits<I>::max();
|
loader->m_vertexSkip = index == std::numeric_limits<I>::max();
|
||||||
auto const data = reinterpret_cast<const T*>(cached_arraybases[ARRAY_POSITION] + (index * g_main_cp_state.array_strides[ARRAY_POSITION]));
|
auto const data = reinterpret_cast<const T*>(VertexLoaderManager::cached_arraybases[ARRAY_POSITION] + (index * g_main_cp_state.array_strides[ARRAY_POSITION]));
|
||||||
auto const scale = loader->m_posScale;
|
auto const scale = loader->m_posScale;
|
||||||
DataReader dst(g_vertex_manager_write_ptr, nullptr);
|
DataReader dst(g_vertex_manager_write_ptr, nullptr);
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "VideoCommon/VertexLoader.h"
|
#include "VideoCommon/VertexLoader.h"
|
||||||
#include "VideoCommon/VertexLoader_TextCoord.h"
|
#include "VideoCommon/VertexLoader_TextCoord.h"
|
||||||
|
#include "VideoCommon/VertexLoaderManager.h"
|
||||||
#include "VideoCommon/VertexManagerBase.h"
|
#include "VideoCommon/VertexManagerBase.h"
|
||||||
#include "VideoCommon/VideoCommon.h"
|
#include "VideoCommon/VideoCommon.h"
|
||||||
|
|
||||||
@ -67,7 +68,7 @@ void LOADERDECL TexCoord_ReadIndex(VertexLoader* loader)
|
|||||||
static_assert(std::is_unsigned<I>::value, "Only unsigned I is sane!");
|
static_assert(std::is_unsigned<I>::value, "Only unsigned I is sane!");
|
||||||
|
|
||||||
auto const index = DataRead<I>();
|
auto const index = DataRead<I>();
|
||||||
auto const data = reinterpret_cast<const T*>(cached_arraybases[ARRAY_TEXCOORD0 + loader->m_tcIndex]
|
auto const data = reinterpret_cast<const T*>(VertexLoaderManager::cached_arraybases[ARRAY_TEXCOORD0 + loader->m_tcIndex]
|
||||||
+ (index * g_main_cp_state.array_strides[ARRAY_TEXCOORD0 + loader->m_tcIndex]));
|
+ (index * g_main_cp_state.array_strides[ARRAY_TEXCOORD0 + loader->m_tcIndex]));
|
||||||
auto const scale = loader->m_tcScale[loader->m_tcIndex];
|
auto const scale = loader->m_tcScale[loader->m_tcIndex];
|
||||||
DataReader dst(g_vertex_manager_write_ptr, nullptr);
|
DataReader dst(g_vertex_manager_write_ptr, nullptr);
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "VideoCommon/DataReader.h"
|
#include "VideoCommon/DataReader.h"
|
||||||
#include "VideoCommon/OpcodeDecoding.h"
|
#include "VideoCommon/OpcodeDecoding.h"
|
||||||
#include "VideoCommon/VertexLoaderBase.h"
|
#include "VideoCommon/VertexLoaderBase.h"
|
||||||
|
#include "VideoCommon/VertexLoaderManager.h"
|
||||||
|
|
||||||
TEST(VertexLoaderUID, UniqueEnough)
|
TEST(VertexLoaderUID, UniqueEnough)
|
||||||
{
|
{
|
||||||
@ -151,7 +152,7 @@ TEST_P(VertexLoaderParamTest, PositionAll)
|
|||||||
Input<u8>(i);
|
Input<u8>(i);
|
||||||
else
|
else
|
||||||
Input<u16>(i);
|
Input<u16>(i);
|
||||||
cached_arraybases[ARRAY_POSITION] = m_src.GetPointer();
|
VertexLoaderManager::cached_arraybases[ARRAY_POSITION] = m_src.GetPointer();
|
||||||
g_main_cp_state.array_strides[ARRAY_POSITION] = elements * elem_size;
|
g_main_cp_state.array_strides[ARRAY_POSITION] = elements * elem_size;
|
||||||
}
|
}
|
||||||
CreateAndCheckSizes(input_size, elements * sizeof(float));
|
CreateAndCheckSizes(input_size, elements * sizeof(float));
|
||||||
@ -192,7 +193,7 @@ TEST_F(VertexLoaderTest, PositionIndex16FloatXY)
|
|||||||
m_vtx_attr.g0.PosFormat = FORMAT_FLOAT;
|
m_vtx_attr.g0.PosFormat = FORMAT_FLOAT;
|
||||||
CreateAndCheckSizes(sizeof(u16), 2 * sizeof(float));
|
CreateAndCheckSizes(sizeof(u16), 2 * sizeof(float));
|
||||||
Input<u16>(1); Input<u16>(0);
|
Input<u16>(1); Input<u16>(0);
|
||||||
cached_arraybases[ARRAY_POSITION] = m_src.GetPointer();
|
VertexLoaderManager::cached_arraybases[ARRAY_POSITION] = m_src.GetPointer();
|
||||||
g_main_cp_state.array_strides[ARRAY_POSITION] = sizeof(float); // ;)
|
g_main_cp_state.array_strides[ARRAY_POSITION] = sizeof(float); // ;)
|
||||||
Input(1.f); Input(2.f); Input(3.f);
|
Input(1.f); Input(2.f); Input(3.f);
|
||||||
RunVertices(2);
|
RunVertices(2);
|
||||||
@ -297,9 +298,9 @@ TEST_F(VertexLoaderTest, LargeFloatVertexSpeed)
|
|||||||
|
|
||||||
CreateAndCheckSizes(33, 156);
|
CreateAndCheckSizes(33, 156);
|
||||||
|
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 12; i++)
|
||||||
{
|
{
|
||||||
cached_arraybases[i] = m_src.GetPointer();
|
VertexLoaderManager::cached_arraybases[i] = m_src.GetPointer();
|
||||||
g_main_cp_state.array_strides[i] = 129;
|
g_main_cp_state.array_strides[i] = 129;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user