More NV2A porting from XQEMU

Current Status:
Official XDK titles deadlock while calling BlockOnTime.
NXDK titles are generating render commands and appear to be working, although we do not actually implement pgraph yet, so we get a blank screen.
This commit is contained in:
Luke Usher 2017-08-14 20:45:53 +01:00 committed by PatrickvL
parent abdaf89602
commit c9cc6eced0
2 changed files with 62 additions and 27 deletions

View File

@ -339,7 +339,7 @@ typedef struct ChannelControl {
struct { struct {
uint32_t pending_interrupts; uint32_t pending_interrupts;
uint32_t enabled_interrupts; uint32_t enabled_interrupts;
uint32_t regs[NV_PMC_SIZE / sizeof(uint32_t)]; // TODO : union uint32_t regs[NV_PMC_SIZE]; // TODO : union
} pmc; } pmc;
struct { struct {
@ -347,11 +347,11 @@ struct {
uint32_t enabled_interrupts; uint32_t enabled_interrupts;
std::thread puller_thread; std::thread puller_thread;
Cache1State cache1; Cache1State cache1;
uint32_t regs[NV_PFIFO_SIZE / sizeof(uint32_t)]; // TODO : union uint32_t regs[NV_PFIFO_SIZE]; // TODO : union
} pfifo; } pfifo;
struct { struct {
uint32_t regs[NV_PVIDEO_SIZE / sizeof(uint32_t)]; // TODO : union uint32_t regs[NV_PVIDEO_SIZE]; // TODO : union
} pvideo; } pvideo;
@ -361,18 +361,18 @@ struct {
uint32_t numerator; uint32_t numerator;
uint32_t denominator; uint32_t denominator;
uint32_t alarm_time; uint32_t alarm_time;
uint32_t regs[NV_PTIMER_SIZE / sizeof(uint32_t)]; // TODO : union uint32_t regs[NV_PTIMER_SIZE]; // TODO : union
} ptimer; } ptimer;
struct { struct {
uint32_t regs[NV_PFB_SIZE / sizeof(uint32_t)]; // TODO : union uint32_t regs[NV_PFB_SIZE]; // TODO : union
} pfb; } pfb;
struct { struct {
uint32_t pending_interrupts; uint32_t pending_interrupts;
uint32_t enabled_interrupts; uint32_t enabled_interrupts;
uint32_t start; uint32_t start;
uint32_t regs[NV_PCRTC_SIZE / sizeof(uint32_t)]; // TODO : union uint32_t regs[NV_PCRTC_SIZE]; // TODO : union
} pcrtc; } pcrtc;
struct { struct {
@ -380,11 +380,11 @@ struct {
uint64_t core_clock_freq; uint64_t core_clock_freq;
uint32_t memory_clock_coeff; uint32_t memory_clock_coeff;
uint32_t video_clock_coeff; uint32_t video_clock_coeff;
uint32_t regs[NV_PRAMDAC_SIZE / sizeof(uint32_t)]; // TODO : union uint32_t regs[NV_PRAMDAC_SIZE]; // TODO : union
} pramdac; } pramdac;
struct { struct {
uint32_t regs[NV_PRAMIN_SIZE / sizeof(uint32_t)]; // TODO : union uint32_t regs[NV_PRAMIN_SIZE]; // TODO : union
} pramin; } pramin;
struct { struct {
@ -494,7 +494,7 @@ struct {
GLuint gl_memory_buffer; GLuint gl_memory_buffer;
GLuint gl_vertex_array; GLuint gl_vertex_array;
uint32_t regs[NV_PGRAPH_SIZE / sizeof(uint32_t)]; // TODO : union uint32_t regs[NV_PGRAPH_SIZE]; // TODO : union
} pgraph; } pgraph;
static void update_irq() static void update_irq()
@ -846,11 +846,11 @@ DEBUG_START(USER)
#define DEBUG_READ32(DEV) DbgPrintf("EmuX86 Read32 NV2A " #DEV "(0x%08X) = 0x%08X [Handled, %s]\n", addr, result, DebugNV_##DEV##(addr)) #define DEBUG_READ32(DEV) DbgPrintf("EmuX86 Read32 NV2A " #DEV "(0x%08X) = 0x%08X [Handle%s]\n", addr, result, DebugNV_##DEV##(addr))
#define DEBUG_READ32_UNHANDLED(DEV) { DbgPrintf("EmuX86 Read32 NV2A " #DEV "(0x%08X) = 0x%08X [Unhandled, %s]\n", addr, result, DebugNV_##DEV##(addr)); return result; } #define DEBUG_READ32_UNHANDLED(DEV) { DbgPrintf("EmuX86 Read32 NV2A " #DEV "(0x%08X) = 0x%08X [Unhandle%s]\n", addr, result, DebugNV_##DEV##(addr)); return result; }
#define DEBUG_WRITE32(DEV) DbgPrintf("EmuX86 Write32 NV2A " #DEV "(0x%08X, 0x%08X) [Handled, %s]\n", addr, value, DebugNV_##DEV##(addr)) #define DEBUG_WRITE32(DEV) DbgPrintf("EmuX86 Write32 NV2A " #DEV "(0x%08X, 0x%08X) [Handle%s]\n", addr, value, DebugNV_##DEV##(addr))
#define DEBUG_WRITE32_UNHANDLED(DEV) { DbgPrintf("EmuX86 Write32 NV2A " #DEV "(0x%08X, 0x%08X) [Unhandled, %s]\n", addr, value, DebugNV_##DEV##(addr)); return; } #define DEBUG_WRITE32_UNHANDLED(DEV) { DbgPrintf("EmuX86 Write32 NV2A " #DEV "(0x%08X, 0x%08X) [Unhandle%s]\n", addr, value, DebugNV_##DEV##(addr)); return; }
#define DEVICE_READ32(DEV) uint32_t EmuNV2A_##DEV##_Read32(xbaddr addr) #define DEVICE_READ32(DEV) uint32_t EmuNV2A_##DEV##_Read32(xbaddr addr)
#define DEVICE_READ32_SWITCH() uint32_t result = 0; switch (addr) #define DEVICE_READ32_SWITCH() uint32_t result = 0; switch (addr)
@ -863,9 +863,7 @@ DEBUG_START(USER)
static inline uint32_t ldl_le_p(const void *p) static inline uint32_t ldl_le_p(const void *p)
{ {
uint32_t val; return *(uint32_t*)p;
memcpy(&val, p, 4);
return val;
} }
static DMAObject nv_dma_load(xbaddr dma_obj_address) static DMAObject nv_dma_load(xbaddr dma_obj_address)
@ -1128,7 +1126,7 @@ static void pgraph_wait_fifo_access() {
} }
} }
static void pgraph_method_log(unsigned int subchannel, unsigned int graphics_class,unsigned int method, uint32_t parameter) { static void pgraph_method_log(unsigned int subchannel, unsigned int graphics_class, unsigned int method, uint32_t parameter) {
static unsigned int last = 0; static unsigned int last = 0;
static unsigned int count = 0; static unsigned int count = 0;
@ -1168,7 +1166,31 @@ static void pgraph_method_log(unsigned int subchannel, unsigned int graphics_cla
last = method; last = method;
} }
static void pgraph_method(unsigned int subchannel, unsigned int method, uint32_t parameter) static void load_graphics_object(xbaddr instance_address, GraphicsObject *obj)
{
uint8_t *obj_ptr;
uint32_t switch1, switch2, switch3;
assert(instance_address < NV_PRAMIN_SIZE);
obj_ptr = (uint8_t*)(NV2A_ADDR + NV_PRAMIN_ADDR + instance_address);
switch1 = ldl_le_p((uint32_t*)obj_ptr);
switch2 = ldl_le_p((uint32_t*)(obj_ptr + 4));
switch3 = ldl_le_p((uint32_t*)(obj_ptr + 8));
obj->graphics_class = switch1 & NV_PGRAPH_CTX_SWITCH1_GRCLASS;
/* init graphics object */
switch (obj->graphics_class) {
case NV_KELVIN_PRIMITIVE:
// kelvin->vertex_attributes[NV2A_VERTEX_ATTR_DIFFUSE].inline_value = 0xFFFFFFF;
break;
default:
break;
}
}
static void pgraph_method(unsigned int subchannel, unsigned int method, uint32_t parameter)
{ {
std::lock_guard<std::mutex> lk(pgraph.mutex); std::lock_guard<std::mutex> lk(pgraph.mutex);
@ -1182,12 +1204,27 @@ static void pgraph_method(unsigned int subchannel, unsigned int method, uint32_t
subchannel_data = &pgraph.subchannel_data[subchannel]; subchannel_data = &pgraph.subchannel_data[subchannel];
object = &subchannel_data->object; object = &subchannel_data->object;
ContextSurfaces2DState *context_surfaces_2d = &object->data.context_surfaces_2d; ContextSurfaces2DState *context_surfaces_2d = &object->data.context_surfaces_2d;
ImageBlitState *image_blit = &object->data.image_blit; ImageBlitState *image_blit = &object->data.image_blit;
KelvinState *kelvin = &object->data.kelvin; KelvinState *kelvin = &object->data.kelvin;
printf("PGRAPH METHOD!\n");
pgraph_method_log(subchannel, object->graphics_class, method, parameter); pgraph_method_log(subchannel, object->graphics_class, method, parameter);
if (method == NV_SET_OBJECT) {
subchannel_data->object_instance = parameter;
//qemu_mutex_lock_iothread();
load_graphics_object(parameter, object);
//qemu_mutex_unlock_iothread();
return;
}
switch (object->graphics_class) {
default:
EmuWarning("EmuNV2A: Unknown Graphics Class/Method 0x%08Xm 0x%08X\n", object->graphics_class, method);
break;
}
} }
static void* pfifo_puller_thread() static void* pfifo_puller_thread()
@ -1669,14 +1706,11 @@ DEVICE_READ32(PTIMER)
case NV_PTIMER_INTR_EN_0: case NV_PTIMER_INTR_EN_0:
result = ptimer.enabled_interrupts; result = ptimer.enabled_interrupts;
break; break;
case NV_PTIMER_DENOMINATOR:
result = ptimer.denominator;
break;
case NV_PTIMER_NUMERATOR: case NV_PTIMER_NUMERATOR:
result = ptimer.numerator; result = ptimer.numerator;
break; break;
case NV_PTIMER_ALARM_0: case NV_PTIMER_DENOMINATOR:
result = ptimer.alarm_time; result = ptimer.denominator;
break; break;
case NV_PTIMER_TIME_0: case NV_PTIMER_TIME_0:
result = (ptimer_get_clock() & 0x7ffffff) << 5; result = (ptimer_get_clock() & 0x7ffffff) << 5;
@ -2083,7 +2117,7 @@ DEVICE_READ32(PRAMDAC)
break; break;
default: default:
DEVICE_READ32_REG(pramdac); // Was : DEBUG_READ32_UNHANDLED(PRAMDAC); //DEVICE_READ32_REG(pramdac); // Was : DEBUG_READ32_UNHANDLED(PRAMDAC);
break; break;
} }
@ -2119,7 +2153,7 @@ DEVICE_WRITE32(PRAMDAC)
break; break;
default: default:
DEVICE_WRITE32_REG(pramdac); // Was : DEBUG_WRITE32_UNHANDLED(PRAMDAC); //DEVICE_WRITE32_REG(pramdac); // Was : DEBUG_WRITE32_UNHANDLED(PRAMDAC);
break; break;
} }

View File

@ -704,6 +704,7 @@
# define NV062_SET_CONTEXT_DMA_IMAGE_DESTIN 0x00000188 # define NV062_SET_CONTEXT_DMA_IMAGE_DESTIN 0x00000188
# define NV062_SET_COLOR_FORMAT 0x00000300 # define NV062_SET_COLOR_FORMAT 0x00000300
# define NV062_SET_COLOR_FORMAT_LE_Y8 0x01 # define NV062_SET_COLOR_FORMAT_LE_Y8 0x01
# define NV062_SET_COLOR_FORMAT_LE_R5G6B5 0x04
# define NV062_SET_COLOR_FORMAT_LE_A8R8G8B8 0x0A # define NV062_SET_COLOR_FORMAT_LE_A8R8G8B8 0x0A
# define NV062_SET_PITCH 0x00000304 # define NV062_SET_PITCH 0x00000304
# define NV062_SET_OFFSET_SOURCE 0x00000308 # define NV062_SET_OFFSET_SOURCE 0x00000308