naomi2: Fix T&L matrix. vmem elan ram support.

Fix T&L matrix (wild riders)
Open GL support for normal/light matrix
handle elan RAM in vmem
This commit is contained in:
Flyinghead 2022-01-28 21:24:30 +01:00
parent 010d257b69
commit de1322b928
19 changed files with 252 additions and 143 deletions

View File

@ -1,6 +1,7 @@
#include "_vmem.h"
#include "hw/aica/aica_if.h"
#include "hw/pvr/pvr_mem.h"
#include "hw/pvr/elan.h"
#include "hw/sh4/dyna/blockmanager.h"
#include "hw/sh4/sh4_mem.h"
#include "oslib/oslib.h"
@ -24,6 +25,11 @@ static _vmem_WriteMem32FP* _vmem_WF32[HANDLER_COUNT];
//upper 8b of the address
static void* _vmem_MemInfo_ptr[0x100];
#define MAP_RAM_START_OFFSET 0
#define MAP_VRAM_START_OFFSET (MAP_RAM_START_OFFSET+RAM_SIZE)
#define MAP_ARAM_START_OFFSET (MAP_VRAM_START_OFFSET+VRAM_SIZE)
#define MAP_ERAM_START_OFFSET (MAP_ARAM_START_OFFSET+ARAM_SIZE)
void* _vmem_read_const(u32 addr,bool& ismem,u32 sz)
{
u32 page=addr>>24;
@ -417,7 +423,8 @@ static void _vmem_set_p0_mappings()
{0x05000000, 0x06000000, 0, 0, false}, // 32 bit path (unused)
{0x06000000, 0x07000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror
{0x07000000, 0x08000000, 0, 0, false}, // 32 bit path (unused) mirror
{0x08000000, 0x0C000000, 0, 0, false}, // Area 2
{0x08000000, 0x0A000000, 0, 0, false}, // Area 2
{0x0A000000, 0x0C000000, MAP_ERAM_START_OFFSET, elan::ELAN_RAM_SIZE, true}, // Area 2 (Elan RAM)
{0x0C000000, 0x10000000, MAP_RAM_START_OFFSET, RAM_SIZE, true}, // Area 3 (main RAM + 3 mirrors)
{0x10000000, 0x80000000, 0, 0, false}, // Area 4-7 (unused)
};
@ -434,7 +441,7 @@ bool _vmem_reserve()
// Use vmem only if settings mandate so, and if we have proper exception handlers.
#if !defined(TARGET_NO_EXCEPTIONS)
if (!settings.dynarec.disable_nvmem)
vmemstatus = vmem_platform_init((void**)&virt_ram_base, (void**)&p_sh4rcb);
vmemstatus = vmem_platform_init((void**)&virt_ram_base, (void**)&p_sh4rcb, RAM_SIZE_MAX + VRAM_SIZE_MAX + ARAM_SIZE_MAX + elan::ELAN_RAM_SIZE);
#endif
return true;
}
@ -451,6 +458,8 @@ static void _vmem_term_mappings()
vram.data = nullptr;
free_pages(aica_ram.data);
aica_ram.data = nullptr;
free_pages(elan::RAM);
elan::RAM = nullptr;
}
}
@ -478,6 +487,8 @@ void _vmem_init_mappings()
aica_ram.size = ARAM_SIZE;
aica_ram.data = (u8*)malloc_pages(ARAM_SIZE);
elan::RAM = (u8*)malloc_pages(elan::ELAN_RAM_SIZE);
}
else {
NOTICE_LOG(VMEM, "Info: nvmem is enabled, with addr space of size %s", vmemstatus == MemType4GB ? "4GB" : "512MB");
@ -493,7 +504,8 @@ void _vmem_init_mappings()
{0x05000000, 0x06000000, 0, 0, false}, // 32 bit path (unused)
{0x06000000, 0x07000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror
{0x07000000, 0x08000000, 0, 0, false}, // 32 bit path (unused) mirror
{0x08000000, 0x0C000000, 0, 0, false}, // Area 2
{0x08000000, 0x0A000000, 0, 0, false}, // Area 2
{0x0A000000, 0x0C000000, MAP_ERAM_START_OFFSET, elan::ELAN_RAM_SIZE, true}, // Area 2 (Elan RAM)
{0x0C000000, 0x10000000, MAP_RAM_START_OFFSET, RAM_SIZE, true}, // Area 3 (main RAM + 3 mirrors)
{0x10000000, 0x20000000, 0, 0, false}, // Area 4-7 (unused)
// This is outside of the 512MB addr space. We map 8MB in all cases to help some games read past the end of aica ram
@ -505,6 +517,7 @@ void _vmem_init_mappings()
aica_ram.data = &virt_ram_base[0x20000000]; // Points to the writable AICA addrspace
vram.data = &virt_ram_base[0x04000000]; // Points to first vram mirror (writable and lockable)
mem_b.data = &virt_ram_base[0x0C000000]; // Main memory, first mirror
elan::RAM = &virt_ram_base[0x0A000000];
}
else
{
@ -520,7 +533,8 @@ void _vmem_init_mappings()
{0x85000000, 0x86000000, 0, 0, false}, // 32 bit path (unused)
{0x86000000, 0x87000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror
{0x87000000, 0x88000000, 0, 0, false}, // 32 bit path (unused) mirror
{0x88000000, 0x8C000000, 0, 0, false}, // Area 2
{0x88000000, 0x8A000000, 0, 0, false}, // Area 2
{0x8A000000, 0x8C000000, MAP_ERAM_START_OFFSET, elan::ELAN_RAM_SIZE, true}, // Area 2 (Elan RAM)
{0x8C000000, 0x90000000, MAP_RAM_START_OFFSET, RAM_SIZE, true}, // Area 3 (main RAM + 3 mirrors)
{0x90000000, 0xA0000000, 0, 0, false}, // Area 4-7 (unused)
// P2
@ -533,7 +547,8 @@ void _vmem_init_mappings()
{0xA5000000, 0xA6000000, 0, 0, false}, // 32 bit path (unused)
{0xA6000000, 0xA7000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror
{0xA7000000, 0xA8000000, 0, 0, false}, // 32 bit path (unused) mirror
{0xA8000000, 0xAC000000, 0, 0, false}, // Area 2
{0xA8000000, 0xAA000000, 0, 0, false}, // Area 2
{0xAA000000, 0xAC000000, MAP_ERAM_START_OFFSET, elan::ELAN_RAM_SIZE, true}, // Area 2 (Elan RAM)
{0xAC000000, 0xB0000000, MAP_RAM_START_OFFSET, RAM_SIZE, true}, // Area 3 (main RAM + 3 mirrors)
{0xB0000000, 0xC0000000, 0, 0, false}, // Area 4-7 (unused)
// P3
@ -546,7 +561,8 @@ void _vmem_init_mappings()
{0xC5000000, 0xC6000000, 0, 0, false}, // 32 bit path (unused)
{0xC6000000, 0xC7000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror
{0xC7000000, 0xC8000000, 0, 0, false}, // 32 bit path (unused) mirror
{0xC8000000, 0xCC000000, 0, 0, false}, // Area 2
{0xC8000000, 0xCA000000, 0, 0, false}, // Area 2
{0xCA000000, 0xCC000000, MAP_ERAM_START_OFFSET, elan::ELAN_RAM_SIZE, true}, // Area 2 (Elan RAM)
{0xCC000000, 0xD0000000, MAP_RAM_START_OFFSET, RAM_SIZE, true}, // Area 3 (main RAM + 3 mirrors)
{0xD0000000, 0x100000000L, 0, 0, false}, // Area 4-7 (unused)
};
@ -556,6 +572,7 @@ void _vmem_init_mappings()
aica_ram.data = &virt_ram_base[0x80800000]; // Points to the first AICA addrspace in P1
vram.data = &virt_ram_base[0x84000000]; // Points to first vram mirror (writable and lockable) in P1
mem_b.data = &virt_ram_base[0x8C000000]; // Main memory, first mirror in P1
elan::RAM = &virt_ram_base[0x8A000000];
vmem_4gb_space = true;
}

View File

@ -15,7 +15,7 @@ struct vmem_mapping {
// Platform specific vmemory API
// To initialize (maybe) the vmem subsystem
VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr);
VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr, size_t ramSize);
// To reset the on-demand allocated pages.
void vmem_platform_reset_mem(void *ptr, unsigned size_bytes);
// To handle a fault&allocate an ondemand page.
@ -109,10 +109,6 @@ static inline bool _nvmem_4gb_space() {
}
void _vmem_bm_reset();
#define MAP_RAM_START_OFFSET 0
#define MAP_VRAM_START_OFFSET (MAP_RAM_START_OFFSET+RAM_SIZE)
#define MAP_ARAM_START_OFFSET (MAP_VRAM_START_OFFSET+VRAM_SIZE)
void _vmem_protect_vram(u32 addr, u32 size);
void _vmem_unprotect_vram(u32 addr, u32 size);
u32 _vmem_get_vram_offset(void *addr);

View File

@ -24,6 +24,7 @@ namespace memwatch
VramWatcher vramWatcher;
RamWatcher ramWatcher;
AicaRamWatcher aramWatcher;
ElanRamWatcher elanWatcher;
void AicaRamWatcher::protectMem(u32 addr, u32 size)
{
@ -107,5 +108,63 @@ u32 AicaRamWatcher::getMemOffset(void *p)
return addr;
}
void ElanRamWatcher::protectMem(u32 addr, u32 size)
{
using namespace elan;
size = std::min(ELAN_RAM_SIZE - addr, size) & ~PAGE_MASK;
if (_nvmem_enabled())
{
mem_region_lock(virt_ram_base + 0x0a000000 + addr, size); // P0
if (_nvmem_4gb_space())
{
mem_region_lock(virt_ram_base + 0x8a000000 + addr, size); // P1
mem_region_lock(virt_ram_base + 0xaa000000 + addr, size); // P2
}
} else {
mem_region_lock(RAM + addr, size);
}
}
void ElanRamWatcher::unprotectMem(u32 addr, u32 size)
{
using namespace elan;
size = std::min(ELAN_RAM_SIZE - addr, size) & ~PAGE_MASK;
if (_nvmem_enabled())
{
mem_region_unlock(virt_ram_base + 0x0a000000 + addr, size); // P0
if (_nvmem_4gb_space())
{
mem_region_unlock(virt_ram_base + 0x8a000000 + addr, size); // P1
mem_region_unlock(virt_ram_base + 0xaa000000 + addr, size); // P2
}
} else {
mem_region_unlock(RAM + addr, size);
}
}
u32 ElanRamWatcher::getMemOffset(void *p)
{
using namespace elan;
u32 addr;
if (_nvmem_enabled())
{
if ((u8 *)p < virt_ram_base || (u8 *)p >= virt_ram_base + 0x100000000L)
return -1;
addr = (u32)((u8 *)p - virt_ram_base);
u32 area = (addr >> 29) & 7;
if (area != 0 && area != 4 && area != 5) // P0, P1 or P2 only
return -1;
addr &= 0x1fffffff;
if (addr < 0x0a000000 || addr >= 0x0a000000 + ELAN_RAM_SIZE)
return -1;
addr &= ~(ELAN_RAM_SIZE - 1);
} else {
if ((u8 *)p < RAM || (u8 *)p >= &RAM[ELAN_RAM_SIZE])
return -1;
addr = (u32)((u8 *)p - RAM);
}
return addr;
}
}

View File

@ -22,6 +22,7 @@
#include "hw/sh4/dyna/blockmanager.h"
#include "hw/sh4/sh4_mem.h"
#include "hw/pvr/pvr_mem.h"
#include "hw/pvr/elan.h"
#include "rend/TexCache.h"
#include <array>
#include <unordered_map>
@ -148,9 +149,26 @@ public:
}
};
class ElanRamWatcher : public Watcher<ElanRamWatcher>
{
friend class Watcher<ElanRamWatcher>;
protected:
void protectMem(u32 addr, u32 size);
void unprotectMem(u32 addr, u32 size);
u32 getMemOffset(void *p);
public:
void *getMemPage(u32 addr)
{
return &elan::RAM[addr];
}
};
extern VramWatcher vramWatcher;
extern RamWatcher ramWatcher;
extern AicaRamWatcher aramWatcher;
extern ElanRamWatcher elanWatcher;
inline static bool writeAccess(void *p)
{
@ -166,6 +184,8 @@ inline static bool writeAccess(void *p)
VramLockedWrite((u8 *)p);
return true;
}
if (settings.platform.isNaomi2() && elanWatcher.hit(p))
return true;
return aramWatcher.hit(p);
}
@ -176,6 +196,7 @@ inline static void protect()
vramWatcher.protect();
ramWatcher.protect();
aramWatcher.protect();
elanWatcher.protect();
}
inline static void reset()
@ -183,6 +204,7 @@ inline static void reset()
vramWatcher.reset();
ramWatcher.reset();
aramWatcher.reset();
elanWatcher.reset();
}
}

View File

@ -71,8 +71,7 @@ static _vmem_handler elanRegHandler;
static _vmem_handler elanCmdHandler;
static _vmem_handler elanRamHandler;
static u8 *elanRAM;
constexpr u32 ELAN_RAM_SIZE = 32 * 1024 * 1024;
u8 *RAM;
static u32 reg10;
static u32 reg74;
@ -244,7 +243,7 @@ T DYNACALL read_elancmd(u32 addr)
static GMP *curGmp;
static glm::mat4x4 curMatrix;
static float *taMVMatrix;
static glm::mat4x4 lightMatrix;
static float *taNormalMatrix;
static glm::mat4 projectionMatrix;
static float *taProjMatrix;
static LightModel *curLightModel;
@ -295,35 +294,41 @@ struct State
if (instance == Null)
{
taMVMatrix = nullptr;
taNormalMatrix = nullptr;
envMapUOffset = 0.f;
envMapVOffset = 0.f;
return;
}
InstanceMatrix *mat = (InstanceMatrix *)&elanRAM[instance];
DEBUG_LOG(PVR, "Matrix %f %f %f %f\n %f %f %f %f\n %f %f %f %f\nLight: %f %f %f\n %f %f %f",
-mat->tm00, -mat->tm01, -mat->tm02, -mat->mat03,
mat->tm10, mat->tm11, mat->tm12, mat->mat13,
mat->tm20, mat->tm21, mat->tm22, -mat->mat23,
mat->lm00, mat->lm01, mat->lm02,
mat->lm10, mat->lm11, mat->lm12);
InstanceMatrix *mat = (InstanceMatrix *)&RAM[instance];
DEBUG_LOG(PVR, "Matrix %f %f %f %f\n %f %f %f %f\n %f %f %f %f\nLight: %f %f %f\n %f %f %f\n %f %f %f",
-mat->tm00, -mat->tm10, -mat->tm20, -mat->tm30,
mat->tm01, mat->tm11, mat->tm21, mat->tm31,
-mat->tm02, -mat->tm12, -mat->tm22, -mat->tm32,
mat->lm00, mat->lm10, mat->lm20,
mat->lm01, mat->lm11, mat->lm21,
mat->lm02, mat->lm12, mat->lm22);
curMatrix = glm::mat4x4{
-mat->tm00, mat->tm10, mat->tm20, 0,
-mat->tm01, mat->tm11, mat->tm21, 0,
-mat->tm02, mat->tm12, mat->tm22, 0,
-mat->mat03, mat->mat13, -mat->mat23, 1
-mat->tm00, mat->tm01, -mat->tm02, 0.f,
-mat->tm10, mat->tm11, -mat->tm12, 0.f,
-mat->tm20, mat->tm21, -mat->tm22, 0.f,
-mat->tm30, mat->tm31, -mat->tm32, 1.f
};
lightMatrix = glm::mat4x4{
-mat->lm00, mat->lm10, mat->tm20, 0,
-mat->lm01, mat->lm11, mat->tm21, 0,
-mat->lm02, mat->lm12, mat->tm22, 0,
-mat->mat03, mat->mat13, -mat->mat23, 1
glm::mat4x4 normalMatrix = glm::mat4x4{
mat->lm00, mat->lm01, mat->lm02, 0.f,
mat->lm10, mat->lm11, mat->lm12, 0.f,
mat->lm20, mat->lm21, mat->lm22, 0.f,
-mat->tm30, mat->tm31, -mat->tm32, 1.f
};
nearPlane = mat->_near;
farPlane = mat->_far;
envMapUOffset = mat->envMapU;
envMapVOffset = mat->envMapV;
taMVMatrix = ta_add_matrix(glm::value_ptr(curMatrix));
if (normalMatrix != curMatrix)
taNormalMatrix = ta_add_matrix(glm::value_ptr(normalMatrix));
else
taNormalMatrix = taMVMatrix;
}
void setProjectionMatrix(void *p)
@ -339,9 +344,12 @@ struct State
taProjMatrix = nullptr;
return;
}
ProjMatrix *pm = (ProjMatrix *)&elanRAM[projMatrix];
ProjMatrix *pm = (ProjMatrix *)&RAM[projMatrix];
DEBUG_LOG(PVR, "Proj matrix x: %f %f y: %f %f near %f far %f", pm->fx, pm->tx, pm->fy, pm->ty, nearPlane, farPlane);
// fx = -m00 * w/2
// tx = -m20 * w/2 + left + w/2
// fy = -m11 * h/2
// ty = -m21 * h/2 + top + h/2
projectionMatrix = glm::mat4(
-pm->fx, 0, 0, 0,
0, pm->fy, 0, 0,
@ -362,7 +370,7 @@ struct State
curGmp = nullptr;
else
{
curGmp = (GMP *)&elanRAM[gmp];
curGmp = (GMP *)&RAM[gmp];
DEBUG_LOG(PVR, "GMP paramSelect %x clip %d", curGmp->paramSelect.full, curGmp->pcw.userClip);
}
}
@ -380,7 +388,7 @@ struct State
curLightModel = nullptr;
else
{
curLightModel = (LightModel *)&elanRAM[lightModel];
curLightModel = (LightModel *)&RAM[lightModel];
DEBUG_LOG(PVR, "Light model mask: diffuse %04x specular %04x, ambient base %08x offset %08x", curLightModel->diffuseMask0, curLightModel->specularMask0,
curLightModel->ambientBase0, curLightModel->ambientOffset0);
}
@ -400,7 +408,7 @@ struct State
elan::curLights[lightId] = nullptr;
return;
}
PointLight *plight = (PointLight *)&elanRAM[lights[lightId]];
PointLight *plight = (PointLight *)&RAM[lights[lightId]];
if (plight->pcw.parallelLight)
{
ParallelLight *light = (ParallelLight *)plight;
@ -447,10 +455,10 @@ struct State
static u32 elanRamAddress(void *p)
{
if ((u8 *)p < elanRAM || (u8 *)p >= elanRAM + ELAN_RAM_SIZE)
if ((u8 *)p < RAM || (u8 *)p >= RAM + ELAN_RAM_SIZE)
return Null;
else
return (u32)((u8 *)p - elanRAM);
return (u32)((u8 *)p - RAM);
}
void serialize(Serializer& ser)
@ -537,21 +545,21 @@ static u32 packColor(const glm::vec4& color)
}
template<typename T>
glm::vec4 getNormal(const T& vtx)
glm::vec3 getNormal(const T& vtx)
{
return glm::vec4((int8_t)vtx.header.nx / 127.f, (int8_t)vtx.header.ny / 127.f, (int8_t)vtx.header.nz / 127.f, 0);
return { (int8_t)vtx.header.nx / 127.f, (int8_t)vtx.header.ny / 127.f, (int8_t)vtx.header.nz / 127.f };
}
template<>
glm::vec4 getNormal(const N2_VERTEX_VNU& vtx)
glm::vec3 getNormal(const N2_VERTEX_VNU& vtx)
{
return glm::vec4(vtx.normal.nx, vtx.normal.ny, vtx.normal.nz, 0);
return { vtx.normal.nx, vtx.normal.ny, vtx.normal.nz };
}
template<typename T>
void setNormal(Vertex& vd, const T& vs)
{
glm::vec4 normal = getNormal(vs);
glm::vec3 normal = getNormal(vs);
vd.nx = normal.x;
vd.ny = normal.y;
vd.nz = normal.z;
@ -734,20 +742,10 @@ static void boundingBox(const T* vertices, u32 count, glm::vec3& min, glm::vec3&
glm::vec3 extentY = curMatrix * glm::vec4(0, extents.y, 0, 0);
glm::vec3 extentZ = curMatrix * glm::vec4(0, 0, extents.z, 0);
// new AA extents
const float newX = std::abs(glm::dot(glm::vec3{ 1.f, 0.f, 0.f }, extentX)) +
std::abs(glm::dot(glm::vec3{ 1.f, 0.f, 0.f }, extentY)) +
std::abs(glm::dot(glm::vec3{ 1.f, 0.f, 0.f }, extentZ));
glm::vec3 newExtent = glm::abs(extentX) + glm::abs(extentY) + glm::abs(extentZ);
const float newY = std::abs(glm::dot(glm::vec3{ 0.f, 1.f, 0.f }, extentX)) +
std::abs(glm::dot(glm::vec3{ 0.f, 1.f, 0.f }, extentY)) +
std::abs(glm::dot(glm::vec3{ 0.f, 1.f, 0.f }, extentZ));
const float newZ = std::abs(glm::dot(glm::vec3{ 0.f, 0.f, 1.f }, extentX)) +
std::abs(glm::dot(glm::vec3{ 0.f, 0.f, 1.f }, extentY)) +
std::abs(glm::dot(glm::vec3{ 0.f, 0.f, 1.f }, extentZ));
min = glm::vec3(center) - glm::vec3(newX, newY, newZ);
max = glm::vec3(center) + glm::vec3(newX, newY, newZ);
min = glm::vec3(center) - newExtent;
max = glm::vec3(center) + newExtent;
}
template <typename T>
@ -763,7 +761,14 @@ static bool isInFrustum(const T* vertices, u32 count)
glm::vec4 pmax = projectionMatrix * glm::vec4(max, 1);
if (std::isnan(pmin.x) || std::isnan(pmin.y) || std::isnan(pmax.x) || std::isnan(pmax.y))
return false;
// TODO ...
// // Check the farthest side
// float w = std::max(pmin.w, pmax.w);
// glm::vec2 smin = glm::min(glm::vec2(pmin) / w, glm::vec2(pmax) / w);
// glm::vec2 smax = glm::max(glm::vec2(pmin) / w, glm::vec2(pmax) / w);
//
// if (smax.x <= -214 || smin.x >= 854 // FIXME viewport dimensions
// || smax.y < 0 || smin.y >= 480)
// return false;
return true;
}
@ -926,7 +931,7 @@ static void sendLights()
light.routing = plight->routing;
light.dmode = plight->dmode;
light.smode = N2_LMETHOD_SINGLE_SIDED;
memcpy(light.direction, glm::value_ptr(glm::normalize(glm::vec4(-(int8_t)plight->dirX, -(int8_t)plight->dirY, -(int8_t)plight->dirZ, 0))),
memcpy(light.direction, glm::value_ptr(glm::normalize(glm::vec4(-(int8_t)plight->dirX, (int8_t)plight->dirY, -(int8_t)plight->dirZ, 0))),
sizeof(light.direction));
}
else
@ -956,6 +961,7 @@ static void setStateParams(PolyParam& pp)
sendLights();
pp.tileclip = state.tileclip;
pp.mvMatrix = taMVMatrix;
pp.normalMatrix = taNormalMatrix;
pp.projMatrix = taProjMatrix;
pp.lightModel = taLightModel;
pp.envMapping = false;
@ -1183,9 +1189,9 @@ static void executeCommand(u8 *data, int size)
{
verify(size >= 0);
verify(size < (int)ELAN_RAM_SIZE);
// if (0x2b00 == (u32)(data - elanRAM))
// if (0x2b00 == (u32)(data - RAM))
// for (int i = 0; i < size; i += 4)
// DEBUG_LOG(PVR, "Elan Parse %08x: %08x", (u32)(&data[i] - elanRAM), *(u32 *)&data[i]);
// DEBUG_LOG(PVR, "Elan Parse %08x: %08x", (u32)(&data[i] - RAM), *(u32 *)&data[i]);
while (size >= 32)
{
@ -1235,7 +1241,7 @@ static void executeCommand(u8 *data, int size)
//{
// WARN_LOG(PVR, "Other instance %08x %08x", instance->id1, instance->id2);
// for (int i = 0; i < 32; i += 4)
// INFO_LOG(PVR, " %08x: %08x", (u32)(&data[i] - elanRAM), *(u32 *)&data[i]);
// INFO_LOG(PVR, " %08x: %08x", (u32)(&data[i] - RAM), *(u32 *)&data[i]);
//}
size -= sizeof(LightModel);
}
@ -1247,7 +1253,7 @@ static void executeCommand(u8 *data, int size)
cullingReversed = (model->id1 & 0x08000000) == 0;
state.setClipMode(model->pcw);
DEBUG_LOG(PVR, "Model offset %x size %x clip %d", model->offset, model->size, model->pcw.userClip);
executeCommand(&elanRAM[model->offset & 0x1ffffff8], model->size);
executeCommand(&RAM[model->offset & 0x1ffffff8], model->size);
cullingReversed = false;
size -= sizeof(Model);
}
@ -1296,7 +1302,7 @@ static void executeCommand(u8 *data, int size)
{
Link *link = (Link *)data;
DEBUG_LOG(PVR, "Link to %x (%x)", link->offset & 0x1ffffff8, link->size);
executeCommand(&elanRAM[link->offset & 0x1ffffff8], link->size);
executeCommand(&RAM[link->offset & 0x1ffffff8], link->size);
size -= sizeof(Link);
}
break;
@ -1363,7 +1369,7 @@ static void executeCommand(u8 *data, int size)
if (pcw != 0)
INFO_LOG(PVR, "Unhandled command %x", pcw);
for (int i = 0; i < 32; i += 4)
DEBUG_LOG(PVR, " %08x: %08x", (u32)(&data[i] - elanRAM), *(u32 *)&data[i]);
DEBUG_LOG(PVR, " %08x: %08x", (u32)(&data[i] - RAM), *(u32 *)&data[i]);
size -= 32;
}
}
@ -1391,33 +1397,30 @@ void DYNACALL write_elancmd(u32 addr, T data)
template<typename T>
T DYNACALL read_elanram(u32 addr)
{
return *(T *)&elanRAM[addr & (ELAN_RAM_SIZE - 1)];
return *(T *)&RAM[addr & (ELAN_RAM_SIZE - 1)];
}
template<typename T>
void DYNACALL write_elanram(u32 addr, T data)
{
*(T *)&elanRAM[addr & (ELAN_RAM_SIZE - 1)] = data;
*(T *)&RAM[addr & (ELAN_RAM_SIZE - 1)] = data;
}
void init()
{
elanRAM = (u8 *)allocAligned(PAGE_SIZE, ELAN_RAM_SIZE);
}
void reset(bool hard)
{
if (hard)
{
memset(elanRAM, 0, ELAN_RAM_SIZE);
memset(RAM, 0, ELAN_RAM_SIZE);
state.reset();
}
}
void term()
{
freeAligned(elanRAM);
elanRAM = nullptr;
}
void vmem_init()
@ -1432,7 +1435,7 @@ void vmem_map(u32 base)
_vmem_map_handler(elanRegHandler, base | 8, base | 8);
_vmem_map_handler(elanCmdHandler, base | 9, base | 9);
_vmem_map_handler(elanRamHandler, base | 0xA, base | 0xB);
_vmem_map_block(elanRAM, base | 0xA, base | 0xB, ELAN_RAM_SIZE - 1);
_vmem_map_block(RAM, base | 0xA, base | 0xB, ELAN_RAM_SIZE - 1);
}
void serialize(Serializer& ser)
@ -1443,7 +1446,7 @@ void serialize(Serializer& ser)
ser << reg74;
ser << elanCmd;
if (!ser.rollback())
ser.serialize(elanRAM, ELAN_RAM_SIZE);
ser.serialize(RAM, ELAN_RAM_SIZE);
state.serialize(ser);
}
@ -1455,7 +1458,7 @@ void deserialize(Deserializer& deser)
deser >> reg74;
deser >> elanCmd;
if (!deser.rollback())
deser.deserialize(elanRAM, ELAN_RAM_SIZE);
deser.deserialize(RAM, ELAN_RAM_SIZE);
state.deserialize(deser);
}

View File

@ -31,4 +31,6 @@ void vmem_map(u32 base);
void serialize(Serializer& ser);
void deserialize(Deserializer& deser);
extern u8 *RAM;
constexpr u32 ELAN_RAM_SIZE = 32 * 1024 * 1024;
}

View File

@ -96,33 +96,33 @@ struct InstanceMatrix : public ElanBase
u32 _res1; // 08000200
float envMapU; // env map U offset
float lm00;
float lm01;
float lm02;
float lm10;
float lm20;
float lm01;
float lm11;
float lm21;
float lm02;
float lm12;
float tm20;
float tm21;
float tm22;
float lm22;
float envMapV; // env map V offset
float _res2[4];
u32 _res3; // 08000100
float _near;
float tm00;
float tm10;
float mfr2;
float tm01;
float tm11;
float mfr6;
float tm02;
float tm10;
float tm11;
float tm12;
float mfr10;
float mat03;
float mat13;
float mat23;
float tm20;
float tm21;
float tm22;
float tm30;
float tm31;
float tm32;
float _far;
float mproj6;
float mproj6; // 1 / near
bool isInstanceMatrix() const {
return id1 == 0xf && id2 == 0x7f;

View File

@ -50,6 +50,7 @@ struct PolyParam
BaseTextureCacheData *texture1;
float *mvMatrix;
float *normalMatrix;
float *projMatrix;
float glossCoef0;
float glossCoef1;
@ -187,7 +188,6 @@ struct rend_context
List<N2Matrix> matrices;
List<N2LightModel> lightModels;
bool init = false;
void Clear()
{
@ -270,9 +270,8 @@ struct TA_context
rend.modtrig.Init(16384, &rend.Overrun, "modtrig");
rend.render_passes.Init(sizeof(RenderPass) * 10, &rend.Overrun, "render_passes"); // 10 render passes
rend.matrices.Init(1000, &rend.Overrun, "matrices");
rend.matrices.Init(2000, &rend.Overrun, "matrices");
rend.lightModels.Init(100, &rend.Overrun, "lightModels");
rend.init = true;
Reset();
}

View File

@ -2077,7 +2077,6 @@ static bool ClearZBeforePass(int pass_number)
void rend_context::newRenderPass()
{
verify(init);
if (global_param_op.used() > 0
|| global_param_tr.used() > 0
|| global_param_pt.used() > 0)

View File

@ -123,7 +123,7 @@ static mem_handle_t allocate_shared_filemem(unsigned size)
// In negative offsets of the pointer (up to FPCB size, usually 65/129MB) the context and jump table
// can be found. If the platform init returns error, the user is responsible for initializing the
// memory using a fallback (that is, regular mallocs and falling back to slow memory JIT).
VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr)
VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr, size_t ramSize)
{
return MemTypeError;
#if 0

View File

@ -159,9 +159,9 @@ static size_t reserved_size;
// In negative offsets of the pointer (up to FPCB size, usually 65/129MB) the context and jump table
// can be found. If the platform init returns error, the user is responsible for initializing the
// memory using a fallback (that is, regular mallocs and falling back to slow memory JIT).
VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr) {
VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr, size_t ramSize) {
// Firt let's try to allocate the shm-backed memory
vmem_fd = allocate_shared_filemem(RAM_SIZE_MAX + VRAM_SIZE_MAX + ARAM_SIZE_MAX);
vmem_fd = allocate_shared_filemem(ramSize);
if (vmem_fd < 0)
return MemTypeError;

View File

@ -125,10 +125,12 @@ struct MemPages
ram = memwatch::ramWatcher.getPages();
vram = memwatch::vramWatcher.getPages();
aram = memwatch::aramWatcher.getPages();
elanram = memwatch::elanWatcher.getPages();
}
memwatch::PageMap ram;
memwatch::PageMap vram;
memwatch::PageMap aram;
memwatch::PageMap elanram;
};
static std::unordered_map<int, MemPages> deltaStates;
static int lastSavedFrame = -1;
@ -276,12 +278,6 @@ static bool load_game_state(unsigned char *buffer, int len)
Deserializer deser(buffer, len, true);
int frame;
deser >> frame;
dc_deserialize(deser);
if (deser.size() != (u32)len)
{
ERROR_LOG(NETWORK, "load_game_state len %d used %d", len, (int)deser.size());
die("fatal");
}
for (int f = lastSavedFrame - 1; f >= frame; f--)
{
const MemPages& pages = deltaStates[f];
@ -291,8 +287,16 @@ static bool load_game_state(unsigned char *buffer, int len)
memcpy(memwatch::vramWatcher.getMemPage(pair.first), &pair.second[0], PAGE_SIZE);
for (const auto& pair : pages.aram)
memcpy(memwatch::aramWatcher.getMemPage(pair.first), &pair.second[0], PAGE_SIZE);
DEBUG_LOG(NETWORK, "Restored frame %d pages: %d ram, %d vram, %d aica ram", f, (u32)pages.ram.size(),
(u32)pages.vram.size(), (u32)pages.aram.size());
for (const auto& pair : pages.elanram)
memcpy(memwatch::elanWatcher.getMemPage(pair.first), &pair.second[0], PAGE_SIZE);
DEBUG_LOG(NETWORK, "Restored frame %d pages: %d ram, %d vram, %d eram, %d aica ram", f, (u32)pages.ram.size(),
(u32)pages.vram.size(), (u32)pages.elanram.size(), (u32)pages.aram.size());
}
dc_deserialize(deser);
if (deser.size() != (u32)len)
{
ERROR_LOG(NETWORK, "load_game_state len %d used %d", len, (int)deser.size());
die("fatal");
}
rend_allow_rollback(); // ggpo might load another state right after this one
memwatch::reset();
@ -374,8 +378,8 @@ static bool save_game_state(unsigned char **buffer, int *len, int *checksum, int
#endif
// Save the delta to frame-1
deltaStates[frame - 1].load();
DEBUG_LOG(NETWORK, "Saved frame %d pages: %d ram, %d vram, %d aica ram", frame - 1, (u32)deltaStates[frame - 1].ram.size(),
(u32)deltaStates[frame - 1].vram.size(), (u32)deltaStates[frame - 1].aram.size());
DEBUG_LOG(NETWORK, "Saved frame %d pages: %d ram, %d vram, %d eram, %d aica ram", frame - 1, (u32)deltaStates[frame - 1].ram.size(),
(u32)deltaStates[frame - 1].vram.size(), (u32)deltaStates[frame - 1].elanram.size(), (u32)deltaStates[frame - 1].aram.size());
}
memwatch::protect();

View File

@ -43,10 +43,11 @@ struct gl4PipelineShader
GLint fog_control;
GLint trilinear_alpha;
GLint fog_clamp_min, fog_clamp_max;
GLint normal_matrix;
GLint ndcMat;
GLint palette_index;
// Naomi2
GLint mvMat;
GLint normalMat;
GLint projMat;
GLint glossCoef0;
GLint lightCount;
@ -73,6 +74,7 @@ struct gl4PipelineShader
GLint attnAngleB;
} lights[elan::MAX_LIGHTS];
float *lastMvMat;
float *lastNormalMat;
float *lastProjMat;
N2LightModel *lastLightModel;
@ -100,14 +102,14 @@ struct gl4_ctx
{
GLuint program;
GLuint normal_matrix;
GLuint ndcMat;
} modvol_shader;
struct
{
GLuint program;
GLuint normal_matrix;
GLuint ndcMat;
GLint mvMat;
GLint projMat;
} n2ModVolShader;
@ -173,7 +175,7 @@ extern struct gl4ShaderUniforms_t
TCW tcw1;
float fog_clamp_min[4];
float fog_clamp_max[4];
glm::mat4 normal_mat;
glm::mat4 ndcMat;
struct {
bool enabled;
int x;
@ -234,8 +236,8 @@ extern struct gl4ShaderUniforms_t
if (s->fog_clamp_max != -1)
glUniform4fv(s->fog_clamp_max, 1, fog_clamp_max);
if (s->normal_matrix != -1)
glUniformMatrix4fv(s->normal_matrix, 1, GL_FALSE, &normal_mat[0][0]);
if (s->ndcMat != -1)
glUniformMatrix4fv(s->ndcMat, 1, GL_FALSE, &ndcMat[0][0]);
if (s->palette_index != -1)
glUniform1i(s->palette_index, palette_index);

View File

@ -59,7 +59,7 @@ static const char* VertexShaderSource = R"(
#endif
// Uniforms
uniform mat4 normal_matrix;
uniform mat4 ndcMat;
// Input
in vec4 in_pos;
@ -80,7 +80,7 @@ noperspective out vec2 vtx_uv1;
void main()
{
vec4 vpos = normal_matrix * in_pos;
vec4 vpos = ndcMat * in_pos;
vtx_base = in_base;
vtx_offs = in_offs;
vtx_uv = vec3(in_uv * vpos.z, vpos.z);
@ -528,7 +528,7 @@ bool gl4CompilePipelineShader(gl4PipelineShader* s, const char *fragment_source
s->fog_clamp_min = -1;
s->fog_clamp_max = -1;
}
s->normal_matrix = glGetUniformLocation(s->program, "normal_matrix");
s->ndcMat = glGetUniformLocation(s->program, "ndcMat");
// Shadow stencil for OP/PT rendering pass
gu = glGetUniformLocation(s->program, "shadow_stencil");
@ -591,13 +591,13 @@ static void create_modvol_shader()
.addSource(ModifierVolumeShader);
gl4.modvol_shader.program = gl_CompileAndLink(vertexShader.generate().c_str(), fragmentShader.generate().c_str());
gl4.modvol_shader.normal_matrix = glGetUniformLocation(gl4.modvol_shader.program, "normal_matrix");
gl4.modvol_shader.ndcMat = glGetUniformLocation(gl4.modvol_shader.program, "ndcMat");
N2Vertex4Source n2VertexShader(false, true);
N2Geometry4Shader geometryShader(false, true);
gl4.n2ModVolShader.program = gl_CompileAndLink(n2VertexShader.generate().c_str(), fragmentShader.generate().c_str(),
geometryShader.generate().c_str());
gl4.n2ModVolShader.normal_matrix = glGetUniformLocation(gl4.n2ModVolShader.program, "normal_matrix");
gl4.n2ModVolShader.ndcMat = glGetUniformLocation(gl4.n2ModVolShader.program, "ndcMat");
gl4.n2ModVolShader.mvMat = glGetUniformLocation(gl4.n2ModVolShader.program, "mvMat");
gl4.n2ModVolShader.projMat = glGetUniformLocation(gl4.n2ModVolShader.program, "projMat");
}
@ -715,7 +715,7 @@ static bool RenderFrame(int width, int height)
const bool is_rtt = pvrrc.isRTT;
TransformMatrix<COORD_OPENGL> matrices(pvrrc, width, height);
gl4ShaderUniforms.normal_mat = matrices.GetNormalMatrix();
gl4ShaderUniforms.ndcMat = matrices.GetNormalMatrix();
const glm::mat4& scissor_mat = matrices.GetScissorMatrix();
ViewportMatrix = matrices.GetViewportMatrix();
@ -761,10 +761,10 @@ static bool RenderFrame(int width, int height)
if (config::Fog)
{
glcache.UseProgram(gl4.modvol_shader.program);
glUniformMatrix4fv(gl4.modvol_shader.normal_matrix, 1, GL_FALSE, &gl4ShaderUniforms.normal_mat[0][0]);
glUniformMatrix4fv(gl4.modvol_shader.ndcMat, 1, GL_FALSE, &gl4ShaderUniforms.ndcMat[0][0]);
glcache.UseProgram(gl4.n2ModVolShader.program);
glUniformMatrix4fv(gl4.n2ModVolShader.normal_matrix, 1, GL_FALSE, &gl4ShaderUniforms.normal_mat[0][0]);
glUniformMatrix4fv(gl4.n2ModVolShader.ndcMat, 1, GL_FALSE, &gl4ShaderUniforms.ndcMat[0][0]);
}
for (auto& it : gl4.shaders)
resetN2UniformCache(&it.second);

View File

@ -93,7 +93,7 @@ const char* GouraudSource = R"(
static const char* VertexShaderSource = R"(
/* Vertex constants*/
uniform highp vec4 depth_scale;
uniform highp mat4 normal_matrix;
uniform highp mat4 ndcMat;
uniform highp float sp_FOG_DENSITY;
/* Vertex input */
@ -108,7 +108,7 @@ NOPERSPECTIVE out highp vec3 vtx_uv;
void main()
{
highp vec4 vpos = normal_matrix * in_pos;
highp vec4 vpos = ndcMat * in_pos;
vtx_base = in_base;
vtx_offs = in_offs;
#if TARGET_GL == GLES2
@ -787,7 +787,7 @@ bool CompilePipelineShader(PipelineShader* s)
s->fog_clamp_min = -1;
s->fog_clamp_max = -1;
}
s->normal_matrix = glGetUniformLocation(s->program, "normal_matrix");
s->ndcMat = glGetUniformLocation(s->program, "ndcMat");
if (s->naomi2)
initN2Uniforms(s);
@ -892,14 +892,14 @@ static void create_modvol_shader()
.addSource(ModifierVolumeShader);
gl.modvol_shader.program = gl_CompileAndLink(vertexShader.generate().c_str(), fragmentShader.generate().c_str());
gl.modvol_shader.normal_matrix = glGetUniformLocation(gl.modvol_shader.program, "normal_matrix");
gl.modvol_shader.ndcMat = glGetUniformLocation(gl.modvol_shader.program, "ndcMat");
gl.modvol_shader.sp_ShaderColor = glGetUniformLocation(gl.modvol_shader.program, "sp_ShaderColor");
gl.modvol_shader.depth_scale = glGetUniformLocation(gl.modvol_shader.program, "depth_scale");
N2VertexSource n2vertexShader(false, true);
N2GeometryShader geometryShader(false, true);
gl.n2ModVolShader.program = gl_CompileAndLink(n2vertexShader.generate().c_str(), fragmentShader.generate().c_str(), geometryShader.generate().c_str());
gl.n2ModVolShader.normal_matrix = glGetUniformLocation(gl.n2ModVolShader.program, "normal_matrix");
gl.n2ModVolShader.ndcMat = glGetUniformLocation(gl.n2ModVolShader.program, "ndcMat");
gl.n2ModVolShader.sp_ShaderColor = glGetUniformLocation(gl.n2ModVolShader.program, "sp_ShaderColor");
gl.n2ModVolShader.depth_scale = glGetUniformLocation(gl.n2ModVolShader.program, "depth_scale");
gl.n2ModVolShader.mvMat = glGetUniformLocation(gl.n2ModVolShader.program, "mvMat");
@ -1208,7 +1208,7 @@ bool RenderFrame(int width, int height)
vtx_max_fZ *= 1.001f;
TransformMatrix<COORD_OPENGL> matrices(pvrrc, width, height);
ShaderUniforms.normal_mat = matrices.GetNormalMatrix();
ShaderUniforms.ndcMat = matrices.GetNormalMatrix();
const glm::mat4& scissor_mat = matrices.GetScissorMatrix();
ViewportMatrix = matrices.GetViewportMatrix();
@ -1235,13 +1235,13 @@ bool RenderFrame(int width, int height)
glcache.UseProgram(gl.modvol_shader.program);
if (gl.modvol_shader.depth_scale != -1)
glUniform4fv(gl.modvol_shader.depth_scale, 1, ShaderUniforms.depth_coefs);
glUniformMatrix4fv(gl.modvol_shader.normal_matrix, 1, GL_FALSE, &ShaderUniforms.normal_mat[0][0]);
glUniformMatrix4fv(gl.modvol_shader.ndcMat, 1, GL_FALSE, &ShaderUniforms.ndcMat[0][0]);
glUniform1f(gl.modvol_shader.sp_ShaderColor, 1 - FPU_SHAD_SCALE.scale_factor / 256.f);
glcache.UseProgram(gl.n2ModVolShader.program);
if (gl.n2ModVolShader.depth_scale != -1)
glUniform4fv(gl.n2ModVolShader.depth_scale, 1, ShaderUniforms.depth_coefs);
glUniformMatrix4fv(gl.n2ModVolShader.normal_matrix, 1, GL_FALSE, &ShaderUniforms.normal_mat[0][0]);
glUniformMatrix4fv(gl.n2ModVolShader.ndcMat, 1, GL_FALSE, &ShaderUniforms.ndcMat[0][0]);
glUniform1f(gl.n2ModVolShader.sp_ShaderColor, 1 - FPU_SHAD_SCALE.scale_factor / 256.f);
ShaderUniforms.PT_ALPHA=(PT_ALPHA_REF&0xFF)/255.0f;

View File

@ -50,10 +50,11 @@ struct PipelineShader
GLint sp_FOG_DENSITY;
GLint trilinear_alpha;
GLint fog_clamp_min, fog_clamp_max;
GLint normal_matrix;
GLint ndcMat;
GLint palette_index;
// Naomi2
GLint mvMat;
GLint normalMat;
GLint projMat;
GLint glossCoef0;
GLint lightCount;
@ -80,6 +81,7 @@ struct PipelineShader
GLint attnAngleB;
} lights[elan::MAX_LIGHTS];
float *lastMvMat;
float *lastNormalMat;
float *lastProjMat;
N2LightModel *lastLightModel;
@ -109,7 +111,7 @@ struct gl_ctx
GLint depth_scale;
GLint sp_ShaderColor;
GLint normal_matrix;
GLint ndcMat;
} modvol_shader;
struct
@ -118,7 +120,7 @@ struct gl_ctx
GLint depth_scale;
GLint sp_ShaderColor;
GLint normal_matrix;
GLint ndcMat;
GLint mvMat;
GLint projMat;
@ -202,7 +204,7 @@ void GetFramebufferScaling(float& scale_x, float& scale_y, float& scissoring_sca
void GetFramebufferSize(float& dc_width, float& dc_height);
void SetupMatrices(float dc_width, float dc_height,
float scale_x, float scale_y, float scissoring_scale_x, float scissoring_scale_y,
float &ds2s_offs_x, glm::mat4& normal_mat, glm::mat4& scissor_mat);
float &ds2s_offs_x, glm::mat4& ndcMat, glm::mat4& scissor_mat);
void SetCull(u32 CullMode);
s32 SetTileClip(u32 val, GLint uniform);
@ -237,7 +239,7 @@ extern struct ShaderUniforms_t
float trilinear_alpha;
float fog_clamp_min[4];
float fog_clamp_max[4];
glm::mat4 normal_mat;
glm::mat4 ndcMat;
struct {
bool enabled;
int x;
@ -269,8 +271,8 @@ extern struct ShaderUniforms_t
if (s->fog_clamp_max != -1)
glUniform4fv(s->fog_clamp_max, 1, fog_clamp_max);
if (s->normal_matrix != -1)
glUniformMatrix4fv(s->normal_matrix, 1, GL_FALSE, &normal_mat[0][0]);
if (s->ndcMat != -1)
glUniformMatrix4fv(s->ndcMat, 1, GL_FALSE, &ndcMat[0][0]);
if (s->palette_index != -1)
glUniform1i(s->palette_index, palette_index);

View File

@ -19,11 +19,9 @@
#include "naomi2.h"
const char* N2VertexShader = R"(
uniform vec4 depth_scale;
uniform mat4 normal_matrix;
uniform float sp_FOG_DENSITY;
uniform mat4 mvMat;
uniform mat4 normalMat;
uniform mat4 projMat;
uniform int envMapping;
uniform int bumpMapping;
@ -50,7 +48,7 @@ INTERPOLATION out vec4 vs_offs1;
noperspective out vec2 vs_uv1;
#endif
#endif
out float gl_ClipDistance[6];
out float gl_ClipDistance[2];
void main()
{
@ -66,7 +64,7 @@ void main()
if (bumpMapping == 1)
computeBumpMap(vs_offs, vs_offs1, normalize(in_normal));
#endif
vec4 vnorm = normalize(mvMat * vec4(in_normal, 0.0));
vec4 vnorm = normalize(normalMat * vec4(in_normal, 0.0));
if (bumpMapping == 0)
computeColors(vs_base, vs_offs, vpos.xyz, vnorm.xyz);
vs_uv.xy = in_uv;
@ -298,7 +296,7 @@ const char *GeometryClippingShader = R"(
layout (triangles) in;
layout (triangle_strip, max_vertices = 12) out;
uniform mat4 normal_matrix;
uniform mat4 ndcMat;
#if GEOM_ONLY == 0
INTERPOLATION in highp vec4 vs_base[3];
@ -421,7 +419,7 @@ int clip3(in vec3 dist, inout Vertex v0, inout Vertex v1, inout Vertex v2, out V
void wDivide(inout Vertex v)
{
v.pos = vec4(v.pos.xy / v.pos.w, 1.0 / v.pos.w, 1.0);
v.pos = normal_matrix * v.pos;
v.pos = ndcMat * v.pos;
#if GEOM_ONLY == 1
v.uv = vec3(0.0, 0.0, v.pos.z);
#else

View File

@ -48,6 +48,7 @@ template<typename ShaderType>
void initN2Uniforms(ShaderType *shader)
{
shader->mvMat = glGetUniformLocation(shader->program, "mvMat");
shader->normalMat = glGetUniformLocation(shader->program, "normalMat");
shader->projMat = glGetUniformLocation(shader->program, "projMat");
shader->glossCoef0 = glGetUniformLocation(shader->program, "glossCoef0");
shader->envMapping = glGetUniformLocation(shader->program, "envMapping");
@ -99,12 +100,17 @@ void setN2Uniforms(const PolyParam *pp, ShaderType *shader)
if (pp->mvMatrix != shader->lastMvMat)
{
shader->lastMvMat = pp->mvMatrix;
glUniformMatrix4fv(shader->mvMat, 1, GL_FALSE, &pp->mvMatrix[0]);
glUniformMatrix4fv(shader->mvMat, 1, GL_FALSE, pp->mvMatrix);
}
if (pp->normalMatrix != shader->lastNormalMat)
{
shader->lastNormalMat = pp->normalMatrix;
glUniformMatrix4fv(shader->normalMat, 1, GL_FALSE, pp->normalMatrix);
}
if (pp->projMatrix != shader->lastProjMat)
{
shader->lastProjMat = pp->projMatrix;
glUniformMatrix4fv(shader->projMat, 1, GL_FALSE, &pp->projMatrix[0]);
glUniformMatrix4fv(shader->projMat, 1, GL_FALSE, pp->projMatrix);
}
glUniform1f(shader->glossCoef0, pp->glossCoef0);

View File

@ -49,7 +49,7 @@ static std::vector<void *> mapped_regions;
// Please read the POSIX implementation for more information. On Windows this is
// rather straightforward.
VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr)
VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr, size_t ramSize)
{
#ifdef TARGET_UWP
return MemTypeError;
@ -58,7 +58,7 @@ VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr)
mapped_regions.reserve(32);
// First let's try to allocate the in-memory file
mem_handle = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, RAM_SIZE_MAX + VRAM_SIZE_MAX + ARAM_SIZE_MAX, 0);
mem_handle = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, ramSize, 0);
// Now allocate the actual address space (it will be 64KB aligned on windows).
unsigned memsize = 512*1024*1024 + sizeof(Sh4RCB) + ARAM_SIZE_MAX;