Rebase and cleanup, removed irrelevant code, lv2 lle gcm for now

This commit is contained in:
Jake 2017-06-19 01:08:07 -05:00
parent 2e47c42367
commit 036aadc66b
13 changed files with 334 additions and 48 deletions

View file

@ -880,7 +880,7 @@ s32 _spurs::stop_event_helper(ppu_thread& ppu, vm::ptr<CellSpurs> spurs)
return CELL_SPURS_CORE_ERROR_STAT;
}
if (sys_event_port_send(ppu, spurs->eventPort, 0, 1, 0) != CELL_OK)
if (sys_event_port_send(spurs->eventPort, 0, 1, 0) != CELL_OK)
{
return CELL_SPURS_CORE_ERROR_STAT;
}
@ -2794,7 +2794,7 @@ s32 cellSpursEventFlagSet(ppu_thread& ppu, vm::ptr<CellSpursEventFlag> eventFlag
// Signal the PPU thread to be woken up
eventFlag->pendingRecvTaskEvents[ppuWaitSlot] = ppuEvents;
CHECK_SUCCESS(sys_event_port_send(ppu, eventFlag->eventPortId, 0, 0, 0));
CHECK_SUCCESS(sys_event_port_send(eventFlag->eventPortId, 0, 0, 0));
}
if (pendingRecv)

View file

@ -24,7 +24,7 @@ static const std::unordered_map<std::string, int> s_prx_ignore
{ "/dev_flash/sys/external/libaudio.sprx", 0 },
{ "/dev_flash/sys/external/libbeisobmf.sprx", 0 },
{ "/dev_flash/sys/external/libcamera.sprx", 0 },
{ "/dev_flash/sys/external/libgcm_sys.sprx", 0 },
//{ "/dev_flash/sys/external/libgcm_sys.sprx", 0 },
{ "/dev_flash/sys/external/libgem.sprx", 0 },
{ "/dev_flash/sys/external/libio.sprx", 0 },
{ "/dev_flash/sys/external/libmedi.sprx", 0 },

View file

@ -1,14 +1,75 @@
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/Cell/PPUModule.h"
#include "Emu/RSX/GSRender.h"
#include "Emu/IdManager.h"
#include "Emu/Cell/ErrorCodes.h"
#include "sys_rsx.h"
#include "sys_event.h"
namespace vm { using namespace ps3; }
logs::channel sys_rsx("sys_rsx");
struct RsxDriverInfo {
be_t<u32> version_driver;
be_t<u32> version_gpu;
be_t<u32> memory_size;
be_t<u32> hardware_channel;
be_t<u32> nvcore_frequency;
be_t<u32> memory_frequency;
u8 unk[0x10A8];
struct Head {
be_t<u32> flip;
be_t<u32> unk[4];
be_t<f32> unk1;
be_t<u32> unk2[5];
be_t<u32> unk3;
be_t<u32> unk4[4];
} head[8];
be_t<u32> handlers;
be_t<u32> unk1;
be_t<u32> unk2;
be_t<u32> unk3;
be_t<u32> handler_queue;
};
struct RsxDmaControl {
u8 resv[0x40];
be_t<u32> put;
be_t<u32> get;
be_t<u32> ref;
be_t<u32> unk[2];
be_t<u32> unk1;
};
struct RsxSemaphore {
be_t<u64> val;
be_t<u64> pad;
be_t<u64> timestamp;
};
struct RsxNotify {
be_t<u64> timestamp;
be_t<u64> zero;
};
struct RsxReport {
be_t<u64> timestamp;
be_t<u32> val;
be_t<u32> pad;
};
struct RsxReports {
RsxSemaphore semaphore[0x100];
RsxNotify notify[64];
RsxReport report[2048];
};
be_t<u32> g_rsx_event_port;
u32 g_driverInfo;
s32 sys_rsx_device_open()
{
sys_rsx.todo("sys_rsx_device_open()");
@ -37,6 +98,9 @@ s32 sys_rsx_memory_allocate(vm::ptr<u32> mem_handle, vm::ptr<u64> mem_addr, u32
{
sys_rsx.todo("sys_rsx_memory_allocate(mem_handle=*0x%x, mem_addr=*0x%x, size=0x%x, flags=0x%llx, a5=0x%llx, a6=0x%llx, a7=0x%llx)", mem_handle, mem_addr, size, flags, a5, a6, a7);
*mem_handle = 1;
*mem_addr = vm::falloc(0xC0000000, size, vm::video);
return CELL_OK;
}
@ -60,10 +124,62 @@ s32 sys_rsx_memory_free(u32 mem_handle)
* @param mem_ctx (IN): mem_ctx given by sys_rsx_memory_allocate
* @param system_mode (IN):
*/
s32 sys_rsx_context_allocate(vm::ptr<u32> context_id, vm::ptr<u32> lpar_dma_control, vm::ptr<u32> lpar_driver_info, vm::ptr<u32> lpar_reports, u64 mem_ctx, u64 system_mode)
s32 sys_rsx_context_allocate(vm::ptr<u32> context_id, vm::ptr<u64> lpar_dma_control, vm::ptr<u64> lpar_driver_info, vm::ptr<u64> lpar_reports, u64 mem_ctx, u64 system_mode)
{
sys_rsx.todo("sys_rsx_context_allocate(context_id=*0x%x, lpar_dma_control=*0x%x, lpar_driver_info=*0x%x, lpar_reports=*0x%x, mem_ctx=0x%llx, system_mode=0x%llx)",
context_id, lpar_dma_control, lpar_driver_info, lpar_reports, mem_ctx, system_mode);
sys_rsx.todo("sys_rsx_context_allocate(context_id=*0x%x, lpar_dma_control=*0x%x, lpar_driver_info=*0x%x, lpar_reports=*0x%x, mem_ctx=0x%llx, system_mode=0x%llx)",
context_id, lpar_dma_control, lpar_driver_info, lpar_reports, mem_ctx, system_mode);
vm::falloc(0x40000000, 0x10000000, vm::rsx_context);
*context_id = 0x55555555;
*lpar_dma_control = 0x40100000;
*lpar_driver_info = 0x40200000;
*lpar_reports = 0x40300000;
auto &driverInfo = vm::_ref<RsxDriverInfo>(*lpar_driver_info);
driverInfo.version_driver = 0x211;
driverInfo.version_gpu = 0x5c;
driverInfo.memory_size = 0xFE00000;
driverInfo.nvcore_frequency = 500000000;
driverInfo.memory_frequency = 650000000;
g_driverInfo = *lpar_driver_info;
auto &dmaControl = vm::_ref<RsxDmaControl>(*lpar_dma_control);
dmaControl.get = 0;
dmaControl.put = 0;
if (false/*system_mode == CELL_GCM_SYSTEM_MODE_IOMAP_512MB*/)
RSXIOMem.SetRange(0, 0x20000000 /*512MB*/);
else
RSXIOMem.SetRange(0, 0x10000000 /*256MB*/);
sys_event_queue_attribute_t attr;
attr.protocol = SYS_SYNC_PRIORITY;
attr.type = SYS_PPU_QUEUE;
auto queueId = vm::make_var<u32>(0);
sys_event_queue_create(queueId, vm::make_var(attr), 0, 0x20);
driverInfo.handler_queue = queueId->value();
sys_event_port_create(queueId, SYS_EVENT_PORT_LOCAL, 0);
sys_event_port_connect_local(queueId->value(), driverInfo.handler_queue);
g_rsx_event_port = queueId->value();
const auto render = fxm::get<GSRender>();
render->ctrl = vm::_ptr<CellGcmControl>(*lpar_dma_control);
//render->intr_thread = idm::make_ptr<ppu_thread>("_gcm_intr_thread", 1, 0x4000);
//render->intr_thread->run();
//render->ctxt_addr = 0;
render->gcm_buffers.set(vm::alloc(sizeof(CellGcmDisplayInfo) * 8, vm::main));
render->zculls_addr = vm::alloc(sizeof(CellGcmZcullInfo) * 8, vm::main);
render->tiles_addr = vm::alloc(sizeof(CellGcmTileInfo) * 15, vm::main);
render->gcm_buffers_count = 7;
render->gcm_current_buffer = 0;
render->main_mem_addr = 0;
render->label_addr = *lpar_reports;
render->init(0x30100000, 0x200000, *lpar_dma_control, 0xC0000000);
return CELL_OK;
}
@ -90,8 +206,10 @@ s32 sys_rsx_context_free(u32 context_id)
s32 sys_rsx_context_iomap(u32 context_id, u32 io, u32 ea, u32 size, u64 flags)
{
sys_rsx.todo("sys_rsx_context_iomap(context_id=0x%x, io=0x%x, ea=0x%x, size=0x%x, flags=0x%llx)", context_id, io, ea, size, flags);
return CELL_OK;
if (RSXIOMem.Map(ea, size, io))
return CELL_OK;
LOG_ERROR(RSX, "rsx_iomap failed");
return CELL_EINVAL;
}
/*
@ -101,11 +219,13 @@ s32 sys_rsx_context_iomap(u32 context_id, u32 io, u32 ea, u32 size, u64 flags)
* @param io_addr (IN): IO address. E.g. 0x00600000 (Start page 6)
* @param size (IN): Size to unmap in byte. E.g. 0x00200000
*/
s32 sys_rsx_context_iounmap(u32 context_id, u32 a2, u32 io_addr, u32 size)
s32 sys_rsx_context_iounmap(u32 context_id, u32 io_addr, u32 a3, u32 size)
{
sys_rsx.todo("sys_rsx_context_iounmap(context_id=0x%x, a2=0x%x, io_addr=0x%x, size=0x%x)", context_id, a2, io_addr, size);
return CELL_OK;
sys_rsx.todo("sys_rsx_context_iounmap(context_id=0x%x, io_addr=0x%x, a3=0x%x, size=0x%x)", context_id, io_addr, a3, size);
if (RSXIOMem.UnmapAddress(io_addr, size))
return CELL_OK;
LOG_ERROR(RSX, "rsx_iounmap failed");
return CELL_EINVAL;
}
/*
@ -120,33 +240,64 @@ s32 sys_rsx_context_iounmap(u32 context_id, u32 a2, u32 io_addr, u32 size)
s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u64 a5, u64 a6)
{
sys_rsx.todo("sys_rsx_context_attribute(context_id=0x%x, package_id=0x%x, a3=0x%llx, a4=0x%llx, a5=0x%llx, a6=0x%llx)", context_id, package_id, a3, a4, a5, a6);
const auto render = fxm::get<GSRender>();
auto &driverInfo = vm::_ref<RsxDriverInfo>(g_driverInfo);
switch(package_id)
{
case 0x001: // FIFO
render->ctrl->get = a3;
render->ctrl->put = a4;
break;
case 0x100: // Display mode set
break;
case 0x101: // Display sync
case 0x101: // Display sync
break;
case 0x102: // Display flip
driverInfo.head[a3].flip |= 0x80000000;
if (a3 == 0)
sys_event_port_send(g_rsx_event_port, 0, (1 << 3), 0);
if (a3 == 1)
sys_event_port_send(g_rsx_event_port, 0, (1 << 4), 0);
break;
case 0x103: // ?
case 0x103: // Display Queue
driverInfo.head[a3].flip |= 0x40000000 | (1 << a4);
if (a3 == 0)
sys_event_port_send(g_rsx_event_port, 0, (1 << 5), 0);
if (a3 == 1)
sys_event_port_send(g_rsx_event_port, 0, (1 << 6), 0);
break;
case 0x104: // Display buffer
break;
{
u8 id = a3 & 0xFF;
u32 width = (a4 >> 32) & 0xFFFFFFFF;
u32 height = a4 & 0xFFFFFFFF;
u32 pitch = (a5 >> 32) & 0xFFFFFFFF;
u32 offset = a5 & 0xFFFFFFFF;
if (id > 7)
return -17;
render->gcm_buffers[id].width = width;
render->gcm_buffers[id].height = height;
render->gcm_buffers[id].pitch = pitch;
render->gcm_buffers[id].offset = offset;
}
break;
case 0x106: // ? (Used by cellGcmInitPerfMon)
break;
case 0x10a: // ?
if (a3 > 7)
return -17;
driverInfo.head[a3].flip &= a4;
driverInfo.head[a3].flip |= a5;
break;
case 0x10D: // ?
break;
case 0x300: // Tiles
break;
@ -162,6 +313,9 @@ s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u6
case 0x602: // Framebuffer blit sync
break;
case 0x603: // Framebuffer close
break;
default:
return CELL_EINVAL;
}
@ -175,19 +329,19 @@ s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u6
* @param a2 (OUT): Unused?
* @param dev_id (IN): An immediate value and always 8. (cellGcmInitPerfMon uses 11, 10, 9, 7, 12 successively).
*/
s32 sys_rsx_device_map(vm::ptr<u32> addr, vm::ptr<u32> a2, u32 dev_id)
s32 sys_rsx_device_map(vm::ptr<u64> addr, vm::ptr<u64> a2, u32 dev_id)
{
sys_rsx.todo("sys_rsx_device_map(addr=*0x%x, a2=*0x%x, dev_id=0x%x)", addr, a2, dev_id);
if (dev_id > 15) {
// TODO: Throw RSX error
return CELL_EINVAL;
if (dev_id != 8) {
// TODO: lv1 related
fmt::throw_exception("sys_rsx_device_map: Invalid dev_id %d", dev_id);
}
if (dev_id == 0 || dev_id > 8) {
// TODO: lv1 related so we may ignore it.
// if (something) { return CELL_EPERM; }
}
// a2 seems to not be referenced in cellGcmSys
*a2 = 0;
*addr = 0x40000000;
return CELL_OK;
}

View file

@ -5,11 +5,11 @@ s32 sys_rsx_device_open();
s32 sys_rsx_device_close();
s32 sys_rsx_memory_allocate(vm::ps3::ptr<u32> mem_handle, vm::ps3::ptr<u64> mem_addr, u32 size, u64 flags, u64 a5, u64 a6, u64 a7);
s32 sys_rsx_memory_free(u32 mem_handle);
s32 sys_rsx_context_allocate(vm::ps3::ptr<u32> context_id, vm::ps3::ptr<u32> lpar_dma_control, vm::ps3::ptr<u32> lpar_driver_info, vm::ps3::ptr<u32> lpar_reports, u64 mem_ctx, u64 system_mode);
s32 sys_rsx_context_allocate(vm::ps3::ptr<u32> context_id, vm::ps3::ptr<u64> lpar_dma_control, vm::ps3::ptr<u64> lpar_driver_info, vm::ps3::ptr<u64> lpar_reports, u64 mem_ctx, u64 system_mode);
s32 sys_rsx_context_free(u32 context_id);
s32 sys_rsx_context_iomap(u32 context_id, u32 io, u32 ea, u32 size, u64 flags);
s32 sys_rsx_context_iounmap(u32 context_id, u32 a2, u32 io_addr, u32 size);
s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u64 a5, u64 a6);
s32 sys_rsx_device_map(vm::ps3::ptr<u32> addr, vm::ps3::ptr<u32> a2, u32 dev_id);
s32 sys_rsx_device_map(vm::ps3::ptr<u64> addr, vm::ps3::ptr<u64> a2, u32 dev_id);
s32 sys_rsx_device_unmap(u32 dev_id);
s32 sys_rsx_attribute(u32 a1, u32 a2, u32 a3, u32 a4, u32 a5);

View file

@ -55,13 +55,13 @@ bool VirtualMemoryBlock::Map(u32 realaddr, u32 size, u32 addr)
return false;
}
for (u32 i = 0; i<m_mapped_memory.size(); ++i)
/*for (u32 i = 0; i<m_mapped_memory.size(); ++i)
{
if (addr >= m_mapped_memory[i].addr && addr + size - 1 <= m_mapped_memory[i].addr + m_mapped_memory[i].size - 1)
{
return false;
}
}
}*/
m_mapped_memory.emplace_back(addr, realaddr, size);
return true;

View file

@ -781,6 +781,7 @@ namespace vm
{
std::make_shared<block_t>(0x00010000, 0x1FFF0000), // main
std::make_shared<block_t>(0x20000000, 0x10000000), // user
std::make_shared<block_t>(0x40000000, 0x30000000), // rsx contexts
std::make_shared<block_t>(0xC0000000, 0x10000000), // video
std::make_shared<block_t>(0xD0000000, 0x10000000), // stack
std::make_shared<block_t>(0xE0000000, 0x20000000), // SPU reserved

View file

@ -16,6 +16,7 @@ namespace vm
{
main,
user_space,
rsx_context,
video,
stack,

View file

@ -7,11 +7,21 @@
struct CellGcmControl
{
atomic_be_t<u32> put;
atomic_be_t<u32> get;
atomic_be_t<u32> ref;
u8 resv[0x40];
atomic_be_t<u32> put;
atomic_be_t<u32> get;
atomic_be_t<u32> ref;
be_t<u32> unk[2];
be_t<u32> unk1;
};
/*struct CellGcmControl
{
atomic_be_t<u32> put;
atomic_be_t<u32> get;
atomic_be_t<u32> ref;
};*/
struct CellGcmConfig
{
be_t<u32> localAddress;

View file

@ -57,8 +57,9 @@ namespace rsx
//}
}
case CELL_GCM_CONTEXT_DMA_TO_MEMORY_GET_REPORT:
return 0x100000 + offset; // TODO: Properly implement
case CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_LOCAL:
return 0x40300000 + offset;
//return 0x100000 + offset; // TODO: Properly implement
case CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_MAIN:
return 0x800 + offset; // TODO: Properly implement
@ -71,13 +72,16 @@ namespace rsx
case CELL_GCM_CONTEXT_DMA_SEMAPHORE_RW:
case CELL_GCM_CONTEXT_DMA_SEMAPHORE_R:
return 0x100 + offset; // TODO: Properly implement
return 0x40100000 + offset;
//return 0x100 + offset; // TODO: Properly implement
case CELL_GCM_CONTEXT_DMA_DEVICE_RW:
fmt::throw_exception("Unimplemented CELL_GCM_CONTEXT_DMA_DEVICE_RW (offset=0x%x, location=0x%x)" HERE, offset, location);
return 0x40000000 + offset;
//fmt::throw_exception("Unimplemented CELL_GCM_CONTEXT_DMA_DEVICE_RW (offset=0x%x, location=0x%x)" HERE, offset, location);
case CELL_GCM_CONTEXT_DMA_DEVICE_R:
fmt::throw_exception("Unimplemented CELL_GCM_CONTEXT_DMA_DEVICE_R (offset=0x%x, location=0x%x)" HERE, offset, location);
return 0x40000000 + offset;
//fmt::throw_exception("Unimplemented CELL_GCM_CONTEXT_DMA_DEVICE_R (offset=0x%x, location=0x%x)" HERE, offset, location);
default:
fmt::throw_exception("Invalid location (offset=0x%x, location=0x%x)" HERE, offset, location);
@ -500,7 +504,7 @@ namespace rsx
u32 reg = ((cmd & RSX_METHOD_NON_INCREMENT_CMD_MASK) == RSX_METHOD_NON_INCREMENT_CMD) ? first_cmd : first_cmd + i;
u32 value = args[i];
//LOG_NOTICE(RSX, "%s(0x%x) = 0x%x", get_method_name(reg).c_str(), reg, value);
//LOG_WARNING(RSX, "%s(0x%x) = 0x%x", get_method_name(reg).c_str(), reg, value);
method_registers.decode(reg, value);

View file

@ -142,6 +142,8 @@ namespace rsx
u32 gcm_current_buffer;
u32 ctxt_addr;
u32 label_addr;
u32 nv406e_semaphore_addr;
u32 nv4097_semaphore_index;
u32 local_mem_addr, main_mem_addr;
bool strict_ordering[0x1000];

View file

@ -968,7 +968,7 @@ rsx::blit_engine::context_dma rsx::blit_engine::to_context_dma(u32 in)
{
switch (in)
{
case CELL_GCM_CONTEXT_DMA_TO_MEMORY_GET_REPORT: return rsx::blit_engine::context_dma::to_memory_get_report;
case CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_LOCAL: return rsx::blit_engine::context_dma::to_memory_get_report;
case CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_MAIN: return rsx::blit_engine::context_dma::report_location_main;
case CELL_GCM_CONTEXT_DMA_MEMORY_HOST_BUFFER: return rsx::blit_engine::context_dma::memory_host_buffer;
}

View file

@ -704,7 +704,7 @@ enum
{
CELL_GCM_CONTEXT_DMA_MEMORY_FRAME_BUFFER = 0xFEED0000, // Local memory
CELL_GCM_CONTEXT_DMA_MEMORY_HOST_BUFFER = 0xFEED0001, // Main memory
CELL_GCM_CONTEXT_DMA_TO_MEMORY_GET_REPORT = 0x66626660,
CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_LOCAL = 0x66626660,
CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_MAIN = 0xBAD68000,
CELL_GCM_CONTEXT_DMA_NOTIFY_MAIN_0 = 0x6660420F,

View file

@ -6,12 +6,15 @@
#include "rsx_utils.h"
#include "rsx_decode.h"
#include "Emu/Cell/PPUCallback.h"
#include "Emu/Cell/lv2/sys_rsx.h"
#include <sstream>
#include <cereal/archives/binary.hpp>
#include <thread>
#include <Windows.h>
template <>
void fmt_class_string<frame_limit_type>::format(std::string& out, u64 arg)
{
@ -58,11 +61,20 @@ namespace rsx
rsx->ctrl->ref.exchange(arg);
}
void set_context_dma_semaphore(thread* rsx, u32 _reg, u32 arg)
{
LOG_ERROR(RSX, "dmaSemaphore: 0x%x", arg);
rsx->nv406e_semaphore_addr = arg;
}
void semaphore_acquire(thread* rsx, u32 _reg, u32 arg)
{
//TODO: dma
while (vm::ps3::read32(rsx->label_addr + method_registers.semaphore_offset_406e()) != arg)
//while (vm::ps3::read32(rsx->label_addr + method_registers.semaphore_offset_406e()) != arg)
const u32 addr = get_address(method_registers.semaphore_offset_406e(), rsx->nv406e_semaphore_addr);
while (vm::ps3::read32(addr) != arg)
{
break;
if (Emu.IsStopped())
break;
@ -73,10 +85,51 @@ namespace rsx
void semaphore_release(thread* rsx, u32 _reg, u32 arg)
{
//TODO: dma
vm::ps3::write32(rsx->label_addr + method_registers.semaphore_offset_406e(), arg);
//vm::ps3::write32(rsx->label_addr + method_registers.semaphore_offset_406e(), arg);
const u32 addr = get_address(method_registers.semaphore_offset_406e(), rsx->nv406e_semaphore_addr);
vm::ps3::write32(addr, arg);
}
}
struct RsxSemaphore {
be_t<u32> val;
be_t<u32> pad;
be_t<u64> timestamp;
};
struct RsxNotify {
be_t<u64> timestamp;
be_t<u64> zero;
};
struct RsxReport {
be_t<u64> timestamp;
be_t<u32> val;
be_t<u32> pad;
};
struct RsxReports {
RsxSemaphore semaphore[0x100];
RsxNotify notify[64];
RsxReport report[2048];
};
u64 ptimer_gettime() {
static struct PerformanceFreqHolder {
u64 value;
PerformanceFreqHolder() {
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
value = freq.QuadPart;
}
} freq;
LARGE_INTEGER cycle;
QueryPerformanceCounter(&cycle);
const u64 sec = cycle.QuadPart / freq.value;
return sec * 1000000000 + (cycle.QuadPart % freq.value) * 1000000000 / freq.value;
}
namespace nv4097
{
void clear(thread* rsx, u32 _reg, u32 arg)
@ -93,6 +146,11 @@ namespace rsx
}
}
/*void set_context_dma_semaphore(thread* rsx, u32 _reg, u32 arg)
{
rsx->nv4097_semaphore_index = arg >> 4;
}*/
void texture_read_semaphore_release(thread* rsx, u32 _reg, u32 arg)
{
if (!rsx->do_method(NV4097_TEXTURE_READ_SEMAPHORE_RELEASE, arg))
@ -101,7 +159,15 @@ namespace rsx
}
//TODO: dma
vm::ps3::write32(rsx->label_addr + method_registers.semaphore_offset_4097(), arg);
//vm::ps3::write32(rsx->label_addr + method_registers.semaphore_offset_4097(), arg);
//const u32 addr = get_address(method_registers.semaphore_offset_4097(), rsx->nv4097_semaphore_index);
//vm::ps3::write32(addr, arg);
const u32 index = method_registers.semaphore_offset_4097() >> 4;
LOG_ERROR(RSX, "readrelease: 0x%x, 0x%x, addr:0x%x", arg, index, rsx->label_addr);
auto& sema = vm::ps3::_ref<RsxReports>(rsx->label_addr);
sema.semaphore[index].val = arg;
sema.semaphore[index].pad = 0;
sema.semaphore[index].timestamp = ptimer_gettime();
}
void back_end_write_semaphore_release(thread* rsx, u32 _reg, u32 arg)
@ -112,8 +178,18 @@ namespace rsx
}
//TODO: dma
vm::ps3::write32(rsx->label_addr + method_registers.semaphore_offset_4097(),
(arg & 0xff00ff00) | ((arg & 0xff) << 16) | ((arg >> 16) & 0xff));
//vm::ps3::write32(rsx->label_addr + method_registers.semaphore_offset_4097(),
// (arg & 0xff00ff00) | ((arg & 0xff) << 16) | ((arg >> 16) & 0xff));
//const u32 addr = get_address(method_registers.semaphore_offset_4097(), rsx->nv4097_semaphore_addr);
//vm::ps3::write32(addr, (arg & 0xff00ff00) | ((arg & 0xff) << 16) | ((arg >> 16) & 0xff));
const u32 index = method_registers.semaphore_offset_4097() >> 4;
u32 val = (arg & 0xff00ff00) | ((arg & 0xff) << 16) | ((arg >> 16) & 0xff);
LOG_ERROR(RSX, "wriuterelease: 0x%x, 0x%x, addr:0x%x", val, index, rsx->label_addr);
auto& sema = vm::ps3::_ref<RsxReports>(rsx->label_addr);
sema.semaphore[index].val = val;
sema.semaphore[index].pad = 0;
sema.semaphore[index].timestamp = ptimer_gettime();
}
template<u32 id, u32 index, int count, typename type>
@ -472,6 +548,7 @@ namespace rsx
if (in_origin != blit_engine::transfer_origin::corner)
{
LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown origin (%d)", (u8)in_origin);
return;
}
if (operation != rsx::blit_engine::transfer_operation::srccopy)
@ -900,6 +977,28 @@ namespace rsx
}
}
namespace gcm
{
template<u32 index>
struct driver_flip
{
static void impl(thread* rsx, u32 _reg, u32 arg)
{
sys_rsx_context_attribute(0x55555555, 0x102, index, arg, 0, 0);
}
};
template<u32 index>
struct queue_flip
{
static void impl(thread* rsx, u32 _reg, u32 arg)
{
flip_command(rsx, _reg, arg);
sys_rsx_context_attribute(0x55555555, 0x103, index, arg, 0, 0);
}
};
}
void rsx_state::reset()
{
//setup method registers
@ -971,7 +1070,7 @@ namespace rsx
registers[NV4097_SET_SURFACE_FORMAT] = (8 << 0) | (2 << 5) | (0 << 12) | (1 << 16) | (1 << 24);
// rsx dma initial values
registers[NV4097_SET_CONTEXT_DMA_REPORT] = CELL_GCM_CONTEXT_DMA_TO_MEMORY_GET_REPORT;
registers[NV4097_SET_CONTEXT_DMA_REPORT] = CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_LOCAL;
registers[NV406E_SET_CONTEXT_DMA_SEMAPHORE] = CELL_GCM_CONTEXT_DMA_SEMAPHORE_RW;
registers[NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN] = CELL_GCM_CONTEXT_DMA_MEMORY_FRAME_BUFFER;
registers[NV309E_SET_CONTEXT_DMA_IMAGE] = CELL_GCM_CONTEXT_DMA_MEMORY_FRAME_BUFFER;
@ -1081,10 +1180,17 @@ namespace rsx
methods[NV4097_SET_SURFACE_COLOR_BOFFSET] = nullptr;
methods[NV4097_SET_SURFACE_PITCH_B] = nullptr;
methods[NV4097_SET_SURFACE_COLOR_TARGET] = nullptr;
methods[0x224 >> 2] = nullptr;
methods[0x228 >> 2] = nullptr;
methods[0x230 >> 2] = nullptr;
methods[NV4097_SET_SURFACE_PITCH_Z] = nullptr;
methods[NV4097_INVALIDATE_ZCULL] = nullptr;
methods[NV4097_SET_CYLINDRICAL_WRAP] = nullptr;
methods[NV4097_SET_CYLINDRICAL_WRAP1] = nullptr;
methods[0x240 >> 2] = nullptr;
methods[0x244 >> 2] = nullptr;
methods[0x248 >> 2] = nullptr;
methods[0x24C >> 2] = nullptr;
methods[NV4097_SET_SURFACE_PITCH_C] = nullptr;
methods[NV4097_SET_SURFACE_PITCH_D] = nullptr;
methods[NV4097_SET_SURFACE_COLOR_COFFSET] = nullptr;
@ -1153,6 +1259,7 @@ namespace rsx
methods[NV4097_SET_FOG_MODE] = nullptr;
methods[NV4097_SET_FOG_PARAMS] = nullptr;
methods[NV4097_SET_FOG_PARAMS + 1] = nullptr;
methods[0x8d8 >> 2] = nullptr;
methods[NV4097_SET_SHADER_PROGRAM] = nullptr;
methods[NV4097_SET_VERTEX_TEXTURE_OFFSET] = nullptr;
methods[NV4097_SET_VERTEX_TEXTURE_FORMAT] = nullptr;
@ -1362,6 +1469,8 @@ namespace rsx
bind_array<GCM_FLIP_HEAD, 1, 2, nullptr>();
bind_array<GCM_DRIVER_QUEUE, 1, 8, nullptr>();
bind_array<(0x400 >> 2), 1, 0x10, nullptr>();
bind_array<(0x440 >> 2), 1, 0x20, nullptr>();
bind_array<NV4097_SET_ANISO_SPREAD, 1, 16, nullptr>();
bind_array<NV4097_SET_VERTEX_TEXTURE_OFFSET, 1, 8 * 4, nullptr>();
bind_array<NV4097_SET_VERTEX_DATA_SCALED4S_M, 1, 32, nullptr>();
@ -1384,6 +1493,7 @@ namespace rsx
// NV406E
bind<NV406E_SET_REFERENCE, nv406e::set_reference>();
bind<NV406E_SET_CONTEXT_DMA_SEMAPHORE, nv406e::set_context_dma_semaphore>();
bind<NV406E_SEMAPHORE_ACQUIRE, nv406e::semaphore_acquire>();
bind<NV406E_SEMAPHORE_RELEASE, nv406e::semaphore_release>();
@ -1398,6 +1508,7 @@ namespace rsx
*/
// NV4097
//bind<NV4097_SET_CONTEXT_DMA_SEMAPHORE, nv4097::set_context_dma_semaphore>();
bind<NV4097_TEXTURE_READ_SEMAPHORE_RELEASE, nv4097::texture_read_semaphore_release>();
bind<NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE, nv4097::back_end_write_semaphore_release>();
bind<NV4097_SET_BEGIN_END, nv4097::set_begin_end>();
@ -1459,6 +1570,9 @@ namespace rsx
bind<GCM_FLIP_COMMAND, flip_command>();
bind_array<GCM_SET_USER_COMMAND, 1, 2, user_command>();
bind_range<GCM_FLIP_HEAD, 1, 2, gcm::driver_flip>();
bind_range<GCM_DRIVER_QUEUE, 1, 8, gcm::queue_flip>();
return true;
}();
}