/* * QEMU Geforce NV2A internal definitions * * Copyright (c) 2012 espes * Copyright (c) 2015 Jannik Vogel * Copyright (c) 2018 Matt Borgerson * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ #ifndef HW_NV2A_INT_H #define HW_NV2A_INT_H #include "qemu/osdep.h" #include "hw/hw.h" // #include "hw/i386/pc.h" // #include "qapi/qmp/qstring.h" // #include "qemu/thread.h" // #include "cpu.h" #include "lru.h" #include "gl/gloffscreen.h" #include "hw/xbox/nv2a/nv2a_debug.h" #include "hw/xbox/nv2a/nv2a_shaders.h" #include "hw/xbox/nv2a/nv2a_debug.h" #include "hw/xbox/nv2a/nv2a_regs.h" #define USE_TEXTURE_CACHE 1 #define GET_MASK(v, mask) (((v) & (mask)) >> ctz32(mask)) #define SET_MASK(v, mask, val) \ ({ \ const unsigned int __val = (val); \ const unsigned int __mask = (mask); \ (v) &= ~(__mask); \ (v) |= ((__val) << ctz32(__mask)) & (__mask); \ }) #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") enum FIFOEngine { ENGINE_SOFTWARE = 0, ENGINE_GRAPHICS = 1, ENGINE_DVD = 2, }; typedef struct DMAObject { unsigned int dma_class; unsigned int dma_target; hwaddr address; hwaddr limit; } DMAObject; typedef struct VertexAttribute { bool dma_select; hwaddr offset; /* inline arrays are packed in order? * Need to pass the offset to converted attributes */ unsigned int inline_array_offset; float inline_value[4]; unsigned int format; unsigned int size; /* size of the data type */ unsigned int count; /* number of components */ uint32_t stride; bool needs_conversion; uint8_t *converted_buffer; unsigned int converted_elements; unsigned int converted_size; unsigned int converted_count; float *inline_buffer; GLint gl_count; GLenum gl_type; GLboolean gl_normalize; GLuint gl_converted_buffer; GLuint gl_inline_buffer; } VertexAttribute; typedef struct Surface { bool draw_dirty; bool buffer_dirty; bool write_enabled_cache; unsigned int pitch; hwaddr offset; } Surface; typedef struct SurfaceShape { unsigned int z_format; unsigned int color_format; unsigned int zeta_format; unsigned int log_width, log_height; unsigned int clip_x, clip_y; unsigned int clip_width, clip_height; unsigned int anti_aliasing; } SurfaceShape; typedef struct TextureShape { bool cubemap; unsigned int dimensionality; unsigned int color_format; unsigned int levels; unsigned int width, height, depth; unsigned int min_mipmap_level, max_mipmap_level; unsigned int pitch; } TextureShape; typedef struct TextureBinding { GLenum gl_target; GLuint gl_texture; unsigned int refcnt; } TextureBinding; typedef struct TextureKey { struct lru_node node; TextureShape state; uint8_t *texture_data; uint8_t *palette_data; TextureBinding *binding; } TextureKey; typedef struct KelvinState { hwaddr object_instance; } KelvinState; typedef struct ContextSurfaces2DState { hwaddr object_instance; hwaddr dma_image_source; hwaddr dma_image_dest; unsigned int color_format; unsigned int source_pitch, dest_pitch; hwaddr source_offset, dest_offset; } ContextSurfaces2DState; typedef struct ImageBlitState { hwaddr object_instance; hwaddr context_surfaces; unsigned int operation; unsigned int in_x, in_y; unsigned int out_x, out_y; unsigned int width, height; } ImageBlitState; typedef struct PGRAPHState { QemuMutex lock; uint32_t pending_interrupts; uint32_t enabled_interrupts; QemuCond interrupt_cond; /* subchannels state we're not sure the location of... */ ContextSurfaces2DState context_surfaces_2d; ImageBlitState image_blit; KelvinState kelvin; QemuCond fifo_access_cond; QemuCond flip_3d; hwaddr dma_color, dma_zeta; Surface surface_color, surface_zeta; unsigned int surface_type; SurfaceShape surface_shape; SurfaceShape last_surface_shape; hwaddr dma_a, dma_b; struct lru texture_cache; struct TextureKey *texture_cache_entries; bool texture_dirty[NV2A_MAX_TEXTURES]; TextureBinding *texture_binding[NV2A_MAX_TEXTURES]; GHashTable *shader_cache; ShaderBinding *shader_binding; 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 */ GloContext *gl_context; GLuint gl_framebuffer; GLuint gl_color_buffer, gl_zeta_buffer; hwaddr dma_state; hwaddr dma_notifies; hwaddr dma_semaphore; hwaddr dma_report; hwaddr report_offset; 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; hwaddr dma_vertex_a, dma_vertex_b; unsigned int primitive_mode; bool enable_vertex_program_write; uint32_t program_data[NV2A_MAX_TRANSFORM_PROGRAM_LENGTH][VSH_TOKEN_SIZE]; uint32_t vsh_constants[NV2A_VERTEXSHADER_CONSTANTS][4]; bool vsh_constants_dirty[NV2A_VERTEXSHADER_CONSTANTS]; /* lighting constant arrays */ uint32_t ltctxa[NV2A_LTCTXA_COUNT][4]; bool ltctxa_dirty[NV2A_LTCTXA_COUNT]; uint32_t ltctxb[NV2A_LTCTXB_COUNT][4]; bool ltctxb_dirty[NV2A_LTCTXB_COUNT]; uint32_t ltc1[NV2A_LTC1_COUNT][4]; bool ltc1_dirty[NV2A_LTC1_COUNT]; // should figure out where these are in lighting context float light_infinite_half_vector[NV2A_MAX_LIGHTS][3]; float light_infinite_direction[NV2A_MAX_LIGHTS][3]; float light_local_position[NV2A_MAX_LIGHTS][3]; float light_local_attenuation[NV2A_MAX_LIGHTS][3]; VertexAttribute vertex_attributes[NV2A_VERTEXSHADER_ATTRIBUTES]; unsigned int inline_array_length; uint32_t inline_array[NV2A_MAX_BATCH_LENGTH]; GLuint gl_inline_array_buffer; unsigned int inline_elements_length; uint32_t inline_elements[NV2A_MAX_BATCH_LENGTH]; unsigned int inline_buffer_length; unsigned int draw_arrays_length; unsigned int draw_arrays_max_count; /* FIXME: Unknown size, possibly endless, 1000 will do for now */ GLint gl_draw_arrays_start[1000]; GLsizei gl_draw_arrays_count[1000]; GLuint gl_element_buffer; GLuint gl_memory_buffer; GLuint gl_vertex_array; uint32_t regs[0x2000]; } PGRAPHState; typedef struct NV2AState { PCIDevice dev; qemu_irq irq; bool exiting; VGACommonState vga; GraphicHwOps hw_ops; QEMUTimer *vblank_timer; MemoryRegion *vram; MemoryRegion vram_pci; uint8_t *vram_ptr; MemoryRegion ramin; uint8_t *ramin_ptr; MemoryRegion mmio; MemoryRegion block_mmio[NV_NUM_BLOCKS]; struct { uint32_t pending_interrupts; uint32_t enabled_interrupts; } pmc; struct { uint32_t pending_interrupts; uint32_t enabled_interrupts; uint32_t regs[0x2000]; QemuMutex lock; QemuThread puller_thread; QemuCond puller_cond; QemuThread pusher_thread; QemuCond pusher_cond; } pfifo; struct { uint32_t regs[0x1000]; } pvideo; struct { uint32_t pending_interrupts; uint32_t enabled_interrupts; uint32_t numerator; uint32_t denominator; uint32_t alarm_time; } ptimer; struct { uint32_t regs[0x1000]; } pfb; struct PGRAPHState pgraph; struct { uint32_t pending_interrupts; uint32_t enabled_interrupts; hwaddr start; } pcrtc; struct { uint32_t core_clock_coeff; uint64_t core_clock_freq; uint32_t memory_clock_coeff; uint32_t video_clock_coeff; uint32_t general_control; uint32_t fp_vdisplay_end; uint32_t fp_vcrtc; uint32_t fp_vsync_end; uint32_t fp_vvalid_end; uint32_t fp_hdisplay_end; uint32_t fp_hcrtc; uint32_t fp_hvalid_end; } pramdac; } NV2AState; typedef struct NV2ABlockInfo { const char *name; hwaddr offset; uint64_t size; MemoryRegionOps ops; } NV2ABlockInfo; static void reg_log_read(int block, hwaddr addr, uint64_t val); static void reg_log_write(int block, hwaddr addr, uint64_t val); #endif