From f169ce4c267ba9311b29d42cafe47d6e05566e14 Mon Sep 17 00:00:00 2001 From: Matt Borgerson Date: Fri, 20 Jul 2018 14:50:25 -0700 Subject: [PATCH] nv2a: Move some defs to nv2a.h and fix minor nits --- hw/xbox/nv2a/nv2a.c | 132 +++++++++++++++---------------------- hw/xbox/nv2a/nv2a.h | 86 ++++++++++++++++-------- hw/xbox/nv2a/nv2a_pgraph.c | 19 ++---- 3 files changed, 119 insertions(+), 118 deletions(-) diff --git a/hw/xbox/nv2a/nv2a.c b/hw/xbox/nv2a/nv2a.c index f9cf0889bf..3aad851910 100644 --- a/hw/xbox/nv2a/nv2a.c +++ b/hw/xbox/nv2a/nv2a.c @@ -20,12 +20,11 @@ */ #include "qemu/osdep.h" +#include "hw/display/vga_regs.h" #include "qapi/error.h" #include "qemu/error-report.h" -#include "qemu/error-report.h" -#include #include "nv2a.h" -#include "hw/display/vga_regs.h" +#include #ifdef __WINNT__ // HACK: mingw-w64 doesn't provide ffs, for now we just shove it here @@ -34,20 +33,18 @@ int ffs(register int valu) { register int bit; - if (valu == 0) + if (valu == 0) { return 0; + } - for (bit = 1; !(valu & 1); bit++) + for (bit = 1; !(valu & 1); bit++) { valu >>= 1; + } return bit; } #endif -DMAObject nv_dma_load(NV2AState *d, hwaddr dma_obj_address); -void *nv_dma_map(NV2AState *d, hwaddr dma_obj_address, hwaddr *len); -void nv2a_init(PCIBus *bus, int devfn, MemoryRegion *ram); - void update_irq(NV2AState *d) { /* PFIFO */ @@ -83,16 +80,16 @@ DMAObject nv_dma_load(NV2AState *d, hwaddr dma_obj_address) { assert(dma_obj_address < memory_region_size(&d->ramin)); - uint32_t *dma_obj = (uint32_t*)(d->ramin_ptr + dma_obj_address); + uint32_t *dma_obj = (uint32_t *)(d->ramin_ptr + dma_obj_address); uint32_t flags = ldl_le_p(dma_obj); uint32_t limit = ldl_le_p(dma_obj + 1); uint32_t frame = ldl_le_p(dma_obj + 2); return (DMAObject){ - .dma_class = GET_MASK(flags, NV_DMA_CLASS), + .dma_class = GET_MASK(flags, NV_DMA_CLASS), .dma_target = GET_MASK(flags, NV_DMA_TARGET), - .address = (frame & NV_DMA_ADDRESS) | GET_MASK(flags, NV_DMA_ADJUST), - .limit = limit, + .address = (frame & NV_DMA_ADDRESS) | GET_MASK(flags, NV_DMA_ADJUST), + .limit = limit, }; } @@ -113,38 +110,11 @@ void *nv_dma_map(NV2AState *d, hwaddr dma_obj_address, hwaddr *len) return d->vram_ptr + dma.address; } -#define DEFINE_PROTO(prefix) \ - uint64_t prefix ## _read(void *opaque, hwaddr addr, unsigned int size); \ - void prefix ## _write(void *opaque, hwaddr addr, uint64_t val, unsigned int size); - -DEFINE_PROTO(pmc) -DEFINE_PROTO(pbus) -DEFINE_PROTO(pfifo) -DEFINE_PROTO(prma) -DEFINE_PROTO(pvideo) -DEFINE_PROTO(ptimer) -DEFINE_PROTO(pcounter) -DEFINE_PROTO(pvpe) -DEFINE_PROTO(ptv) -DEFINE_PROTO(prmfb) -DEFINE_PROTO(prmvio) -DEFINE_PROTO(pfb) -DEFINE_PROTO(pstraps) -DEFINE_PROTO(pgraph) -DEFINE_PROTO(pcrtc) -DEFINE_PROTO(prmcio) -DEFINE_PROTO(pramdac) -DEFINE_PROTO(prmdio) -// DEFINE_PROTO(pramin) -DEFINE_PROTO(user) - -#undef DEFINE_PROTO - #include "nv2a_pbus.c" #include "nv2a_pcrtc.c" #include "nv2a_pfb.c" -#include "nv2a_pgraph.c" #include "nv2a_pfifo.c" +#include "nv2a_pgraph.c" #include "nv2a_pmc.c" #include "nv2a_pramdac.c" #include "nv2a_prmcio.c" @@ -154,42 +124,46 @@ DEFINE_PROTO(user) #include "nv2a_stubs.c" #include "nv2a_user.c" +#define ENTRY(NAME, OFFSET, SIZE, RDFUNC, WRFUNC) \ + [NV_##NAME] = { \ + .name = #NAME, \ + .offset = OFFSET, \ + .size = SIZE, \ + .ops = { .read = RDFUNC, .write = WRFUNC }, \ + } + const struct NV2ABlockInfo blocktable[] = { - -#define ENTRY(NAME, OFFSET, SIZE, RDFUNC, WRFUNC) \ - [ NV_ ## NAME ] = { \ - .name = #NAME, .offset = OFFSET, .size = SIZE, \ - .ops = { .read = RDFUNC, .write = WRFUNC }, \ - }, \ - - ENTRY(PMC, 0x000000, 0x001000, pmc_read, pmc_write) - ENTRY(PBUS, 0x001000, 0x001000, pbus_read, pbus_write) - ENTRY(PFIFO, 0x002000, 0x002000, pfifo_read, pfifo_write) - ENTRY(PRMA, 0x007000, 0x001000, prma_read, prma_write) - ENTRY(PVIDEO, 0x008000, 0x001000, pvideo_read, pvideo_write) - ENTRY(PTIMER, 0x009000, 0x001000, ptimer_read, ptimer_write) - ENTRY(PCOUNTER, 0x00a000, 0x001000, pcounter_read, pcounter_write) - ENTRY(PVPE, 0x00b000, 0x001000, pvpe_read, pvpe_write) - ENTRY(PTV, 0x00d000, 0x001000, ptv_read, ptv_write) - ENTRY(PRMFB, 0x0a0000, 0x020000, prmfb_read, prmfb_write) - ENTRY(PRMVIO, 0x0c0000, 0x001000, prmvio_read, prmvio_write) - ENTRY(PFB, 0x100000, 0x001000, pfb_read, pfb_write) - ENTRY(PSTRAPS, 0x101000, 0x001000, pstraps_read, pstraps_write) - ENTRY(PGRAPH, 0x400000, 0x002000, pgraph_read, pgraph_write) - ENTRY(PCRTC, 0x600000, 0x001000, pcrtc_read, pcrtc_write) - ENTRY(PRMCIO, 0x601000, 0x001000, prmcio_read, prmcio_write) - ENTRY(PRAMDAC, 0x680000, 0x001000, pramdac_read, pramdac_write) - ENTRY(PRMDIO, 0x681000, 0x001000, prmdio_read, prmdio_write) - // ENTRY(PRAMIN, 0x700000, 0x100000, pramin_read, pramin_write) - ENTRY(USER, 0x800000, 0x800000, user_read, user_write) -#undef ENTRY + ENTRY(PMC, 0x000000, 0x001000, pmc_read, pmc_write), + ENTRY(PBUS, 0x001000, 0x001000, pbus_read, pbus_write), + ENTRY(PFIFO, 0x002000, 0x002000, pfifo_read, pfifo_write), + ENTRY(PRMA, 0x007000, 0x001000, prma_read, prma_write), + ENTRY(PVIDEO, 0x008000, 0x001000, pvideo_read, pvideo_write), + ENTRY(PTIMER, 0x009000, 0x001000, ptimer_read, ptimer_write), + ENTRY(PCOUNTER, 0x00a000, 0x001000, pcounter_read, pcounter_write), + ENTRY(PVPE, 0x00b000, 0x001000, pvpe_read, pvpe_write), + ENTRY(PTV, 0x00d000, 0x001000, ptv_read, ptv_write), + ENTRY(PRMFB, 0x0a0000, 0x020000, prmfb_read, prmfb_write), + ENTRY(PRMVIO, 0x0c0000, 0x001000, prmvio_read, prmvio_write), + ENTRY(PFB, 0x100000, 0x001000, pfb_read, pfb_write), + ENTRY(PSTRAPS, 0x101000, 0x001000, pstraps_read, pstraps_write), + ENTRY(PGRAPH, 0x400000, 0x002000, pgraph_read, pgraph_write), + ENTRY(PCRTC, 0x600000, 0x001000, pcrtc_read, pcrtc_write), + ENTRY(PRMCIO, 0x601000, 0x001000, prmcio_read, prmcio_write), + ENTRY(PRAMDAC, 0x680000, 0x001000, pramdac_read, pramdac_write), + ENTRY(PRMDIO, 0x681000, 0x001000, prmdio_read, prmdio_write), + // ENTRY(PRAMIN, 0x700000, 0x100000, pramin_read, pramin_write), + ENTRY(USER, 0x800000, 0x800000, user_read, user_write), }; +#undef ENTRY + const int blocktable_len = ARRAY_SIZE(blocktable); +// FIXME: Add nv2a_reg_names or remove this code // static const char* nv2a_reg_names[] = {}; -void reg_log_read(int block, hwaddr addr, uint64_t val) { +void reg_log_read(int block, hwaddr addr, uint64_t val) +{ if (blocktable[block].name) { // hwaddr naddr = blocktable[block].offset + addr; // if (naddr < ARRAY_SIZE(nv2a_reg_names) && nv2a_reg_names[naddr]) { @@ -197,15 +171,16 @@ void reg_log_read(int block, hwaddr addr, uint64_t val) { // blocktable[block].name, nv2a_reg_names[naddr], val); // } else { NV2A_DPRINTF("%s: read [%" HWADDR_PRIx "] -> 0x%" PRIx64 "\n", - blocktable[block].name, addr, val); + blocktable[block].name, addr, val); // } } else { NV2A_DPRINTF("(%d?): read [%" HWADDR_PRIx "] -> 0x%" PRIx64 "\n", - block, addr, val); + block, addr, val); } } -void reg_log_write(int block, hwaddr addr, uint64_t val) { +void reg_log_write(int block, hwaddr addr, uint64_t val) +{ if (blocktable[block].name) { // hwaddr naddr = blocktable[block].offset + addr; // if (naddr < ARRAY_SIZE(nv2a_reg_names) && nv2a_reg_names[naddr]) { @@ -213,11 +188,11 @@ void reg_log_write(int block, hwaddr addr, uint64_t val) { // blocktable[block].name, nv2a_reg_names[naddr], val); // } else { NV2A_DPRINTF("%s: [%" HWADDR_PRIx "] = 0x%" PRIx64 "\n", - blocktable[block].name, addr, val); + blocktable[block].name, addr, val); // } } else { NV2A_DPRINTF("(%d?): [%" HWADDR_PRIx "] = 0x%" PRIx64 "\n", - block, addr, val); + block, addr, val); } } @@ -346,8 +321,8 @@ static void nv2a_get_offsets(VGACommonState *s, *pstart_addr = start_addr; line_compare = s->cr[VGA_CRTC_LINE_COMPARE] | - ((s->cr[VGA_CRTC_OVERFLOW] & 0x10) << 4) | - ((s->cr[VGA_CRTC_MAX_SCAN] & 0x40) << 3); + ((s->cr[VGA_CRTC_OVERFLOW] & 0x10) << 4) | + ((s->cr[VGA_CRTC_MAX_SCAN] & 0x40) << 3); *pline_compare = line_compare; } @@ -395,7 +370,6 @@ static void nv2a_init_memory(NV2AState *d, MemoryRegion *ram) d->vga.vram_ptr = memory_region_get_ram_ptr(&d->vga.vram); vga_dirty_log_start(&d->vga); - pgraph_init(d); /* fire up puller */ @@ -460,7 +434,7 @@ static void nv2a_realize(PCIDevice *dev, Error **errp) QSIMPLEQ_INIT(&d->pfifo.cache1.retired_entries); /* Pre-allocate memory for CacheEntry objects */ - for (i=0; i < 100000; i++) { + for (i = 0; i < 100000; i++) { CacheEntry *command = g_malloc0(sizeof(CacheEntry)); assert(command != NULL); QSIMPLEQ_INSERT_TAIL(&d->pfifo.cache1.available_entries, diff --git a/hw/xbox/nv2a/nv2a.h b/hw/xbox/nv2a/nv2a.h index c2c51beec0..998c2029cf 100644 --- a/hw/xbox/nv2a/nv2a.h +++ b/hw/xbox/nv2a/nv2a.h @@ -23,44 +23,41 @@ #define HW_NV2A_H #include "hw/hw.h" -#include "hw/i386/pc.h" -#include "ui/console.h" -#include "hw/pci/pci.h" -#include "ui/console.h" #include "hw/display/vga.h" #include "hw/display/vga_int.h" -#include "qemu/thread.h" +#include "hw/i386/pc.h" +#include "hw/pci/pci.h" #include "qapi/qmp/qstring.h" +#include "qemu/thread.h" #include "cpu.h" #include "g-lru-cache.h" -#include "swizzle.h" -#include "nv2a_shaders.h" #include "nv2a_debug.h" #include "nv2a_int.h" - +#include "nv2a_shaders.h" +#include "swizzle.h" #include "gl/gloffscreen.h" #define USE_TEXTURE_CACHE -#define GET_MASK(v, mask) (((v) & (mask)) >> (ffs(mask)-1)) +#define GET_MASK(v, mask) (((v) & (mask)) >> (ffs(mask) - 1)) -#define SET_MASK(v, mask, val) ({ \ - const unsigned int __val = (val); \ - const unsigned int __mask = (mask); \ - (v) &= ~(__mask); \ - (v) |= ((__val) << (ffs(__mask)-1)) & (__mask); \ +#define SET_MASK(v, mask, val) \ + ({ \ + const unsigned int __val = (val); \ + const unsigned int __mask = (mask); \ + (v) &= ~(__mask); \ + (v) |= ((__val) << (ffs(__mask) - 1)) & (__mask); \ }) -#define CASE_4(v, step) \ - case (v): \ - case (v)+(step): \ - case (v)+(step)*2: \ - case (v)+(step)*3 +#define CASE_4(v, step) \ + case (v): \ + case ((v) + (step)): \ + case ((v) + (step) * 2): \ + case ((v) + (step) * 3) -#define NV2A_DEVICE(obj) \ - OBJECT_CHECK(NV2AState, (obj), "nv2a") +#define NV2A_DEVICE(obj) OBJECT_CHECK(NV2AState, (obj), "nv2a") void reg_log_read(int block, hwaddr addr, uint64_t val); void reg_log_write(int block, hwaddr addr, uint64_t val); @@ -147,8 +144,8 @@ typedef struct TextureShape { typedef struct TextureKey { TextureShape state; uint64_t data_hash; - uint8_t* texture_data; - uint8_t* palette_data; + uint8_t *texture_data; + uint8_t *palette_data; } TextureKey; typedef struct TextureBinding { @@ -248,7 +245,7 @@ typedef struct PGRAPHState { bool texture_matrix_enable[NV2A_MAX_TEXTURES]; /* FIXME: Move to NV_PGRAPH_BUMPMAT... */ - float bump_env_matrix[NV2A_MAX_TEXTURES-1][4]; /* 3 allowed stages with 2x2 matrix each */ + float bump_env_matrix[NV2A_MAX_TEXTURES - 1][4]; /* 3 allowed stages with 2x2 matrix each */ GloContext *gl_context; GLuint gl_framebuffer; @@ -260,7 +257,7 @@ typedef struct PGRAPHState { bool zpass_pixel_count_enable; unsigned int zpass_pixel_count_result; unsigned int gl_zpass_pixel_count_query_count; - GLuint* gl_zpass_pixel_count_queries; + GLuint *gl_zpass_pixel_count_queries; hwaddr dma_vertex_a, dma_vertex_b; @@ -311,7 +308,6 @@ typedef struct PGRAPHState { uint32_t regs[0x2000]; } PGRAPHState; - typedef struct CacheEntry { QSIMPLEQ_ENTRY(CacheEntry) entry; unsigned int method : 14; @@ -431,7 +427,7 @@ typedef struct NV2AState { } NV2AState; typedef struct NV2ABlockInfo { - const char* name; + const char *name; hwaddr offset; uint64_t size; MemoryRegionOps ops; @@ -440,9 +436,45 @@ typedef struct NV2ABlockInfo { extern const struct NV2ABlockInfo blocktable[]; extern const int blocktable_len; +DMAObject nv_dma_load(NV2AState *d, hwaddr dma_obj_address); +void *nv_dma_map(NV2AState *d, hwaddr dma_obj_address, hwaddr *len); +void nv2a_init(PCIBus *bus, int devfn, MemoryRegion *ram); void pgraph_init(NV2AState *d); void *pfifo_puller_thread(void *opaque); void pgraph_destroy(PGRAPHState *pg); void update_irq(NV2AState *d); +void pgraph_context_switch(NV2AState *d, unsigned int channel_id); +void pgraph_wait_fifo_access(NV2AState *d); +void pgraph_method(NV2AState *d, + unsigned int subchannel, + unsigned int method, + uint32_t parameter); + +#define DEFINE_PROTO(n) \ + uint64_t n##_read(void *opaque, hwaddr addr, unsigned int size); \ + void n##_write(void *opaque, hwaddr addr, uint64_t val, unsigned int size); + +DEFINE_PROTO(pmc) +DEFINE_PROTO(pbus) +DEFINE_PROTO(pfifo) +DEFINE_PROTO(prma) +DEFINE_PROTO(pvideo) +DEFINE_PROTO(ptimer) +DEFINE_PROTO(pcounter) +DEFINE_PROTO(pvpe) +DEFINE_PROTO(ptv) +DEFINE_PROTO(prmfb) +DEFINE_PROTO(prmvio) +DEFINE_PROTO(pfb) +DEFINE_PROTO(pstraps) +DEFINE_PROTO(pgraph) +DEFINE_PROTO(pcrtc) +DEFINE_PROTO(prmcio) +DEFINE_PROTO(pramdac) +DEFINE_PROTO(prmdio) +// DEFINE_PROTO(pramin) +DEFINE_PROTO(user) + +#undef DEFINE_PROTO #endif diff --git a/hw/xbox/nv2a/nv2a_pgraph.c b/hw/xbox/nv2a/nv2a_pgraph.c index 7e5398866b..c3c20889b6 100644 --- a/hw/xbox/nv2a/nv2a_pgraph.c +++ b/hw/xbox/nv2a/nv2a_pgraph.c @@ -261,12 +261,7 @@ static const SurfaceColorFormatInfo kelvin_surface_color_format_map[] = { {4, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV}, }; -uint64_t pgraph_read(void *opaque, hwaddr addr, unsigned int size); -void pgraph_write(void *opaque, hwaddr addr, uint64_t val, unsigned int size); - -static void pgraph_context_switch(NV2AState *d, unsigned int channel_id); static void pgraph_set_context_user(NV2AState *d, uint32_t val); -static void pgraph_wait_fifo_access(NV2AState *d); static void pgraph_method_log(unsigned int subchannel, unsigned int graphics_class, unsigned int method, uint32_t parameter); static void pgraph_allocate_inline_buffer_vertices(PGRAPHState *pg, unsigned int attr); static void pgraph_finish_inline_buffer_vertex(PGRAPHState *pg); @@ -440,10 +435,10 @@ void pgraph_write(void *opaque, hwaddr addr, uint64_t val, unsigned int size) qemu_mutex_unlock(&d->pgraph.lock); } -static void pgraph_method(NV2AState *d, - unsigned int subchannel, - unsigned int method, - uint32_t parameter) +void pgraph_method(NV2AState *d, + unsigned int subchannel, + unsigned int method, + uint32_t parameter) { int i; GraphicsSubchannel *subchannel_data; @@ -2311,7 +2306,7 @@ static void pgraph_method(NV2AState *d, if (parameter & NV097_CLEAR_SURFACE_STENCIL) { gl_mask |= GL_STENCIL_BUFFER_BIT; glStencilMask(0xff); - glClearStencil(gl_clear_stencil); + glClearStencil(gl_clear_stencil); } } if (write_color) { @@ -2516,7 +2511,7 @@ static void pgraph_method(NV2AState *d, } -static void pgraph_context_switch(NV2AState *d, unsigned int channel_id) +void pgraph_context_switch(NV2AState *d, unsigned int channel_id) { bool valid; valid = d->pgraph.channel_valid && d->pgraph.channel_id == channel_id; @@ -2540,7 +2535,7 @@ static void pgraph_context_switch(NV2AState *d, unsigned int channel_id) } } -static void pgraph_wait_fifo_access(NV2AState *d) { +void pgraph_wait_fifo_access(NV2AState *d) { while (!d->pgraph.fifo_access) { qemu_cond_wait(&d->pgraph.fifo_access_cond, &d->pgraph.lock); }