From d5733324317df9567f4bce2a0c1d1816326f8c00 Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Wed, 23 Aug 2017 20:04:06 +0100 Subject: [PATCH] More PGRAPH --- src/CxbxKrnl/EmuKrnlHal.cpp | 1 - src/CxbxKrnl/EmuNV2A.cpp | 771 +++++++++++++++++++++++++++++++++++- 2 files changed, 762 insertions(+), 10 deletions(-) diff --git a/src/CxbxKrnl/EmuKrnlHal.cpp b/src/CxbxKrnl/EmuKrnlHal.cpp index 47e42ad3d..1b5306855 100644 --- a/src/CxbxKrnl/EmuKrnlHal.cpp +++ b/src/CxbxKrnl/EmuKrnlHal.cpp @@ -107,7 +107,6 @@ XBSYSAPI EXPORTNUM(38) xboxkrnl::VOID FASTCALL xboxkrnl::HalClearSoftwareInterru ) { LOG_FUNC_ONE_ARG(Request); - LOG_UNIMPLEMENTED(); } diff --git a/src/CxbxKrnl/EmuNV2A.cpp b/src/CxbxKrnl/EmuNV2A.cpp index be5e4c5ef..a5e65a0a7 100644 --- a/src/CxbxKrnl/EmuNV2A.cpp +++ b/src/CxbxKrnl/EmuNV2A.cpp @@ -957,7 +957,6 @@ static void pfifo_run_pusher() { command->nonincreasing = state->method_nonincreasing; command->parameter = word; - printf("Adding Command to Cache\n"); std::lock_guard lk(state->mutex); state->cache.push(command); state->cache_cond.notify_all(); @@ -1190,6 +1189,104 @@ static void load_graphics_object(xbaddr instance_address, GraphicsObject *obj) } } +static GraphicsObject* lookup_graphics_object(xbaddr instance_address) +{ + int i; + for (i = 0; i lk(pgraph.mutex); @@ -1220,9 +1317,672 @@ static void pgraph_method(unsigned int subchannel, unsigned int method, uint32_t } switch (object->graphics_class) { + case NV_CONTEXT_SURFACES_2D: { + switch (method) { + case NV062_SET_CONTEXT_DMA_IMAGE_SOURCE: + context_surfaces_2d->dma_image_source = parameter; + break; + case NV062_SET_CONTEXT_DMA_IMAGE_DESTIN: + context_surfaces_2d->dma_image_dest = parameter; + break; + case NV062_SET_COLOR_FORMAT: + context_surfaces_2d->color_format = parameter; + break; + case NV062_SET_PITCH: + context_surfaces_2d->source_pitch = parameter & 0xFFFF; + context_surfaces_2d->dest_pitch = parameter >> 16; + break; + case NV062_SET_OFFSET_SOURCE: + context_surfaces_2d->source_offset = parameter & 0x07FFFFFF; + break; + case NV062_SET_OFFSET_DESTIN: + context_surfaces_2d->dest_offset = parameter & 0x07FFFFFF; + break; + default: + EmuWarning("EmuNV2A: Unknown NV_CONTEXT_SURFACES_2D Method: 0x%08X\n", method); + } + break; + } + + case NV_IMAGE_BLIT: { + switch (method) { + case NV09F_SET_CONTEXT_SURFACES: + image_blit->context_surfaces = parameter; + break; + case NV09F_SET_OPERATION: + image_blit->operation = parameter; + break; + case NV09F_CONTROL_POINT_IN: + image_blit->in_x = parameter & 0xFFFF; + image_blit->in_y = parameter >> 16; + break; + case NV09F_CONTROL_POINT_OUT: + image_blit->out_x = parameter & 0xFFFF; + image_blit->out_y = parameter >> 16; + break; + case NV09F_SIZE: + image_blit->width = parameter & 0xFFFF; + image_blit->height = parameter >> 16; + + /* I guess this kicks it off? */ + if (image_blit->operation == NV09F_SET_OPERATION_SRCCOPY) { + + printf("NV09F_SET_OPERATION_SRCCOPY"); + + GraphicsObject *context_surfaces_obj = lookup_graphics_object(image_blit->context_surfaces); + assert(context_surfaces_obj); + assert(context_surfaces_obj->graphics_class == NV_CONTEXT_SURFACES_2D); + + ContextSurfaces2DState *context_surfaces = &context_surfaces_obj->data.context_surfaces_2d; + + unsigned int bytes_per_pixel; + switch (context_surfaces->color_format) { + case NV062_SET_COLOR_FORMAT_LE_Y8: + bytes_per_pixel = 1; + break; + case NV062_SET_COLOR_FORMAT_LE_R5G6B5: + bytes_per_pixel = 2; + break; + case NV062_SET_COLOR_FORMAT_LE_A8R8G8B8: + bytes_per_pixel = 4; + break; + default: + printf("Unknown blit surface format: 0x%x\n", context_surfaces->color_format); + assert(false); + break; + } + + xbaddr source_dma_len, dest_dma_len; + uint8_t *source, *dest; + + source = (uint8_t*)nv_dma_map(context_surfaces->dma_image_source, &source_dma_len); + assert(context_surfaces->source_offset < source_dma_len); + source += context_surfaces->source_offset; + + dest = (uint8_t*)nv_dma_map(context_surfaces->dma_image_dest, &dest_dma_len); + assert(context_surfaces->dest_offset < dest_dma_len); + dest += context_surfaces->dest_offset; + + printf(" - 0x%tx -> 0x%tx\n", source - MM_SYSTEM_PHYSICAL_MAP,dest - MM_SYSTEM_PHYSICAL_MAP); + + int y; + for (y = 0; yheight; y++) { + uint8_t *source_row = source + + (image_blit->in_y + y) * context_surfaces->source_pitch + + image_blit->in_x * bytes_per_pixel; + + uint8_t *dest_row = dest + + (image_blit->out_y + y) * context_surfaces->dest_pitch + + image_blit->out_x * bytes_per_pixel; + + memmove(dest_row, source_row, + image_blit->width * bytes_per_pixel); + } + } + else { + assert(false); + } + + break; + default: + EmuWarning("EmuNV2A: Unknown NV_IMAGE_BLIT Method: 0x%08X\n", method); + } + break; + } + + case NV_KELVIN_PRIMITIVE: { + switch (method) { + case NV097_SET_CONTEXT_DMA_NOTIFIES: + kelvin->dma_notifies = parameter; + break; + case NV097_SET_CONTEXT_DMA_A: + pgraph.dma_a = parameter; + break; + case NV097_SET_CONTEXT_DMA_B: + pgraph.dma_b = parameter; + break; + case NV097_SET_CONTEXT_DMA_STATE: + kelvin->dma_state = parameter; + break; + case NV097_SET_CONTEXT_DMA_COLOR: + printf("TODO: pgraph_update_surface\n"); + /* try to get any straggling draws in before the surface's changed :/ */ + //pgraph_update_surface(d, false, true, true); + + pgraph.dma_color = parameter; + break; + case NV097_SET_CONTEXT_DMA_ZETA: + pgraph.dma_zeta = parameter; + break; + case NV097_SET_CONTEXT_DMA_VERTEX_A: + pgraph.dma_vertex_a = parameter; + break; + case NV097_SET_CONTEXT_DMA_VERTEX_B: + pgraph.dma_vertex_b = parameter; + break; + case NV097_SET_CONTEXT_DMA_SEMAPHORE: + kelvin->dma_semaphore = parameter; + break; + case NV097_SET_CONTEXT_DMA_REPORT: + pgraph.dma_report = parameter; + break; + case NV097_SET_SURFACE_CLIP_HORIZONTAL: + printf("TODO: pgraph_update_surface\n"); + //pgraph_update_surface(d, false, true, true); + + pgraph.surface_shape.clip_x = + GET_MASK(parameter, NV097_SET_SURFACE_CLIP_HORIZONTAL_X); + pgraph.surface_shape.clip_width = + GET_MASK(parameter, NV097_SET_SURFACE_CLIP_HORIZONTAL_WIDTH); + break; + case NV097_SET_SURFACE_CLIP_VERTICAL: + printf("TODO: pgraph_update_surface\n"); + //pgraph_update_surface(d, false, true, true); + + pgraph.surface_shape.clip_y = + GET_MASK(parameter, NV097_SET_SURFACE_CLIP_VERTICAL_Y); + pgraph.surface_shape.clip_height = + GET_MASK(parameter, NV097_SET_SURFACE_CLIP_VERTICAL_HEIGHT); + break; + case NV097_SET_SURFACE_FORMAT: + printf("TODO: pgraph_update_surface\n"); + //pgraph_update_surface(d, false, true, true); + + pgraph.surface_shape.color_format = + GET_MASK(parameter, NV097_SET_SURFACE_FORMAT_COLOR); + pgraph.surface_shape.zeta_format = + GET_MASK(parameter, NV097_SET_SURFACE_FORMAT_ZETA); + pgraph.surface_type = + GET_MASK(parameter, NV097_SET_SURFACE_FORMAT_TYPE); + pgraph.surface_shape.anti_aliasing = + GET_MASK(parameter, NV097_SET_SURFACE_FORMAT_ANTI_ALIASING); + pgraph.surface_shape.log_width = + GET_MASK(parameter, NV097_SET_SURFACE_FORMAT_WIDTH); + pgraph.surface_shape.log_height = + GET_MASK(parameter, NV097_SET_SURFACE_FORMAT_HEIGHT); + break; + case NV097_SET_SURFACE_PITCH: + printf("TODO: pgraph_update_surface\n"); + //pgraph_update_surface(d, false, true, true); + + pgraph.surface_color.pitch = + GET_MASK(parameter, NV097_SET_SURFACE_PITCH_COLOR); + pgraph.surface_zeta.pitch = + GET_MASK(parameter, NV097_SET_SURFACE_PITCH_ZETA); + break; + case NV097_SET_SURFACE_COLOR_OFFSET: + printf("TODO: pgraph_update_surface\n"); + //pgraph_update_surface(d, false, true, true); + + pgraph.surface_color.offset = parameter; + break; + case NV097_SET_SURFACE_ZETA_OFFSET: + printf("TODO: pgraph_update_surface\n"); + //pgraph_update_surface(d, false, true, true); + + pgraph.surface_zeta.offset = parameter; + break; + // TODO: Is there a better way to do this? + // MSVC doesn't support GCC's case_range extention + // this prevents use of NV097_SET_COMBINER_ALPHA_ICW ... NV097_SET_COMBINER_ALPHA_ICW + 28 + // Investigated making a macro, but doesn't seem possible to do a variable number of results + case NV097_SET_COMBINER_ALPHA_ICW: case NV097_SET_COMBINER_ALPHA_ICW + 1: case NV097_SET_COMBINER_ALPHA_ICW + 2: + case NV097_SET_COMBINER_ALPHA_ICW + 3: case NV097_SET_COMBINER_ALPHA_ICW + 4: case NV097_SET_COMBINER_ALPHA_ICW + 5: + case NV097_SET_COMBINER_ALPHA_ICW + 6: case NV097_SET_COMBINER_ALPHA_ICW + 7: case NV097_SET_COMBINER_ALPHA_ICW + 8: + case NV097_SET_COMBINER_ALPHA_ICW + 9: case NV097_SET_COMBINER_ALPHA_ICW + 10: case NV097_SET_COMBINER_ALPHA_ICW + 11: + case NV097_SET_COMBINER_ALPHA_ICW + 12: case NV097_SET_COMBINER_ALPHA_ICW + 13: case NV097_SET_COMBINER_ALPHA_ICW + 14: + case NV097_SET_COMBINER_ALPHA_ICW + 15: case NV097_SET_COMBINER_ALPHA_ICW + 16: case NV097_SET_COMBINER_ALPHA_ICW + 17: + case NV097_SET_COMBINER_ALPHA_ICW + 18: case NV097_SET_COMBINER_ALPHA_ICW + 19: case NV097_SET_COMBINER_ALPHA_ICW + 20: + case NV097_SET_COMBINER_ALPHA_ICW + 21: case NV097_SET_COMBINER_ALPHA_ICW + 22: case NV097_SET_COMBINER_ALPHA_ICW + 23: + case NV097_SET_COMBINER_ALPHA_ICW + 24: case NV097_SET_COMBINER_ALPHA_ICW + 25: case NV097_SET_COMBINER_ALPHA_ICW + 26: + case NV097_SET_COMBINER_ALPHA_ICW + 27: case NV097_SET_COMBINER_ALPHA_ICW + 28: + slot = (method - NV097_SET_COMBINER_ALPHA_ICW) / 4; + pgraph.regs[NV_PGRAPH_COMBINEALPHAI0 + slot * 4] = parameter; + break; + case NV097_SET_COMBINER_SPECULAR_FOG_CW0: + pgraph.regs[NV_PGRAPH_COMBINESPECFOG0] = parameter; + break; + case NV097_SET_COMBINER_SPECULAR_FOG_CW1: + pgraph.regs[NV_PGRAPH_COMBINESPECFOG1] = parameter; + break; + CASE_4(NV097_SET_TEXTURE_ADDRESS, 64): + slot = (method - NV097_SET_TEXTURE_ADDRESS) / 64; + pgraph.regs[NV_PGRAPH_TEXADDRESS0 + slot * 4] = parameter; + break; + case NV097_SET_CONTROL0: { + printf("TODO: pgraph_update_surface\n"); + //pgraph_update_surface(d, false, true, true); + + bool stencil_write_enable = + parameter & NV097_SET_CONTROL0_STENCIL_WRITE_ENABLE; + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_0], + NV_PGRAPH_CONTROL_0_STENCIL_WRITE_ENABLE, + stencil_write_enable); + + uint32_t z_format = GET_MASK(parameter, NV097_SET_CONTROL0_Z_FORMAT); + SET_MASK(pgraph.regs[NV_PGRAPH_SETUPRASTER], + NV_PGRAPH_SETUPRASTER_Z_FORMAT, z_format); + + bool z_perspective = + parameter & NV097_SET_CONTROL0_Z_PERSPECTIVE_ENABLE; + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_0], + NV_PGRAPH_CONTROL_0_Z_PERSPECTIVE_ENABLE, + z_perspective); + break; + } + + case NV097_SET_FOG_MODE: { + /* FIXME: There is also NV_PGRAPH_CSV0_D_FOG_MODE */ + unsigned int mode; + switch (parameter) { + case NV097_SET_FOG_MODE_V_LINEAR: + mode = NV_PGRAPH_CONTROL_3_FOG_MODE_LINEAR; break; + case NV097_SET_FOG_MODE_V_EXP: + mode = NV_PGRAPH_CONTROL_3_FOG_MODE_EXP; break; + case NV097_SET_FOG_MODE_V_EXP2: + mode = NV_PGRAPH_CONTROL_3_FOG_MODE_EXP2; break; + case NV097_SET_FOG_MODE_V_EXP_ABS: + mode = NV_PGRAPH_CONTROL_3_FOG_MODE_EXP_ABS; break; + case NV097_SET_FOG_MODE_V_EXP2_ABS: + mode = NV_PGRAPH_CONTROL_3_FOG_MODE_EXP2_ABS; break; + case NV097_SET_FOG_MODE_V_LINEAR_ABS: + mode = NV_PGRAPH_CONTROL_3_FOG_MODE_LINEAR_ABS; break; + default: + assert(false); + break; + } + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_3], NV_PGRAPH_CONTROL_3_FOG_MODE, + mode); + break; + } + case NV097_SET_FOG_GEN_MODE: { + unsigned int mode; + switch (parameter) { + case NV097_SET_FOG_GEN_MODE_V_SPEC_ALPHA: + mode = NV_PGRAPH_CSV0_D_FOGGENMODE_SPEC_ALPHA; break; + case NV097_SET_FOG_GEN_MODE_V_RADIAL: + mode = NV_PGRAPH_CSV0_D_FOGGENMODE_RADIAL; break; + case NV097_SET_FOG_GEN_MODE_V_PLANAR: + mode = NV_PGRAPH_CSV0_D_FOGGENMODE_PLANAR; break; + case NV097_SET_FOG_GEN_MODE_V_ABS_PLANAR: + mode = NV_PGRAPH_CSV0_D_FOGGENMODE_ABS_PLANAR; break; + case NV097_SET_FOG_GEN_MODE_V_FOG_X: + mode = NV_PGRAPH_CSV0_D_FOGGENMODE_FOG_X; break; + default: + assert(false); + break; + } + SET_MASK(pgraph.regs[NV_PGRAPH_CSV0_D], NV_PGRAPH_CSV0_D_FOGGENMODE, mode); + break; + } + case NV097_SET_FOG_ENABLE: + /* + FIXME: There is also: + SET_MASK(pgraph.regs[NV_PGRAPH_CSV0_D], NV_PGRAPH_CSV0_D_FOGENABLE, + parameter); + */ + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_3], NV_PGRAPH_CONTROL_3_FOGENABLE, + parameter); + break; + case NV097_SET_FOG_COLOR: { + /* PGRAPH channels are ARGB, parameter channels are ABGR */ + uint8_t red = GET_MASK(parameter, NV097_SET_FOG_COLOR_RED); + uint8_t green = GET_MASK(parameter, NV097_SET_FOG_COLOR_GREEN); + uint8_t blue = GET_MASK(parameter, NV097_SET_FOG_COLOR_BLUE); + uint8_t alpha = GET_MASK(parameter, NV097_SET_FOG_COLOR_ALPHA); + SET_MASK(pgraph.regs[NV_PGRAPH_FOGCOLOR], NV_PGRAPH_FOGCOLOR_RED, red); + SET_MASK(pgraph.regs[NV_PGRAPH_FOGCOLOR], NV_PGRAPH_FOGCOLOR_GREEN, green); + SET_MASK(pgraph.regs[NV_PGRAPH_FOGCOLOR], NV_PGRAPH_FOGCOLOR_BLUE, blue); + SET_MASK(pgraph.regs[NV_PGRAPH_FOGCOLOR], NV_PGRAPH_FOGCOLOR_ALPHA, alpha); + break; + } + case NV097_SET_ALPHA_TEST_ENABLE: + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_0], + NV_PGRAPH_CONTROL_0_ALPHATESTENABLE, parameter); + break; + case NV097_SET_BLEND_ENABLE: + SET_MASK(pgraph.regs[NV_PGRAPH_BLEND], NV_PGRAPH_BLEND_EN, parameter); + break; + case NV097_SET_CULL_FACE_ENABLE: + SET_MASK(pgraph.regs[NV_PGRAPH_SETUPRASTER], + NV_PGRAPH_SETUPRASTER_CULLENABLE, + parameter); + break; + case NV097_SET_DEPTH_TEST_ENABLE: + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_0], NV_PGRAPH_CONTROL_0_ZENABLE, + parameter); + break; + case NV097_SET_DITHER_ENABLE: + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_0], + NV_PGRAPH_CONTROL_0_DITHERENABLE, parameter); + break; + case NV097_SET_LIGHTING_ENABLE: + SET_MASK(pgraph.regs[NV_PGRAPH_CSV0_C], NV_PGRAPH_CSV0_C_LIGHTING, + parameter); + break; + case NV097_SET_SKIN_MODE: + SET_MASK(pgraph.regs[NV_PGRAPH_CSV0_D], NV_PGRAPH_CSV0_D_SKIN, + parameter); + break; + case NV097_SET_STENCIL_TEST_ENABLE: + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_1], + NV_PGRAPH_CONTROL_1_STENCIL_TEST_ENABLE, parameter); + break; + case NV097_SET_POLY_OFFSET_POINT_ENABLE: + SET_MASK(pgraph.regs[NV_PGRAPH_SETUPRASTER], + NV_PGRAPH_SETUPRASTER_POFFSETPOINTENABLE, parameter); + break; + case NV097_SET_POLY_OFFSET_LINE_ENABLE: + SET_MASK(pgraph.regs[NV_PGRAPH_SETUPRASTER], + NV_PGRAPH_SETUPRASTER_POFFSETLINEENABLE, parameter); + break; + case NV097_SET_POLY_OFFSET_FILL_ENABLE: + SET_MASK(pgraph.regs[NV_PGRAPH_SETUPRASTER], + NV_PGRAPH_SETUPRASTER_POFFSETFILLENABLE, parameter); + break; + case NV097_SET_ALPHA_FUNC: + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_0], + NV_PGRAPH_CONTROL_0_ALPHAFUNC, parameter & 0xF); + break; + case NV097_SET_ALPHA_REF: + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_0], + NV_PGRAPH_CONTROL_0_ALPHAREF, parameter); + break; + case NV097_SET_BLEND_FUNC_SFACTOR: { + unsigned int factor; + switch (parameter) { + case NV097_SET_BLEND_FUNC_SFACTOR_V_ZERO: + factor = NV_PGRAPH_BLEND_SFACTOR_ZERO; break; + case NV097_SET_BLEND_FUNC_SFACTOR_V_ONE: + factor = NV_PGRAPH_BLEND_SFACTOR_ONE; break; + case NV097_SET_BLEND_FUNC_SFACTOR_V_SRC_COLOR: + factor = NV_PGRAPH_BLEND_SFACTOR_SRC_COLOR; break; + case NV097_SET_BLEND_FUNC_SFACTOR_V_ONE_MINUS_SRC_COLOR: + factor = NV_PGRAPH_BLEND_SFACTOR_ONE_MINUS_SRC_COLOR; break; + case NV097_SET_BLEND_FUNC_SFACTOR_V_SRC_ALPHA: + factor = NV_PGRAPH_BLEND_SFACTOR_SRC_ALPHA; break; + case NV097_SET_BLEND_FUNC_SFACTOR_V_ONE_MINUS_SRC_ALPHA: + factor = NV_PGRAPH_BLEND_SFACTOR_ONE_MINUS_SRC_ALPHA; break; + case NV097_SET_BLEND_FUNC_SFACTOR_V_DST_ALPHA: + factor = NV_PGRAPH_BLEND_SFACTOR_DST_ALPHA; break; + case NV097_SET_BLEND_FUNC_SFACTOR_V_ONE_MINUS_DST_ALPHA: + factor = NV_PGRAPH_BLEND_SFACTOR_ONE_MINUS_DST_ALPHA; break; + case NV097_SET_BLEND_FUNC_SFACTOR_V_DST_COLOR: + factor = NV_PGRAPH_BLEND_SFACTOR_DST_COLOR; break; + case NV097_SET_BLEND_FUNC_SFACTOR_V_ONE_MINUS_DST_COLOR: + factor = NV_PGRAPH_BLEND_SFACTOR_ONE_MINUS_DST_COLOR; break; + case NV097_SET_BLEND_FUNC_SFACTOR_V_SRC_ALPHA_SATURATE: + factor = NV_PGRAPH_BLEND_SFACTOR_SRC_ALPHA_SATURATE; break; + case NV097_SET_BLEND_FUNC_SFACTOR_V_CONSTANT_COLOR: + factor = NV_PGRAPH_BLEND_SFACTOR_CONSTANT_COLOR; break; + case NV097_SET_BLEND_FUNC_SFACTOR_V_ONE_MINUS_CONSTANT_COLOR: + factor = NV_PGRAPH_BLEND_SFACTOR_ONE_MINUS_CONSTANT_COLOR; break; + case NV097_SET_BLEND_FUNC_SFACTOR_V_CONSTANT_ALPHA: + factor = NV_PGRAPH_BLEND_SFACTOR_CONSTANT_ALPHA; break; + case NV097_SET_BLEND_FUNC_SFACTOR_V_ONE_MINUS_CONSTANT_ALPHA: + factor = NV_PGRAPH_BLEND_SFACTOR_ONE_MINUS_CONSTANT_ALPHA; break; + default: + fprintf(stderr, "Unknown blend source factor: 0x%x\n", parameter); + assert(false); + break; + } + SET_MASK(pgraph.regs[NV_PGRAPH_BLEND], NV_PGRAPH_BLEND_SFACTOR, factor); + + break; + } + + case NV097_SET_BLEND_FUNC_DFACTOR: { + unsigned int factor; + switch (parameter) { + case NV097_SET_BLEND_FUNC_DFACTOR_V_ZERO: + factor = NV_PGRAPH_BLEND_DFACTOR_ZERO; break; + case NV097_SET_BLEND_FUNC_DFACTOR_V_ONE: + factor = NV_PGRAPH_BLEND_DFACTOR_ONE; break; + case NV097_SET_BLEND_FUNC_DFACTOR_V_SRC_COLOR: + factor = NV_PGRAPH_BLEND_DFACTOR_SRC_COLOR; break; + case NV097_SET_BLEND_FUNC_DFACTOR_V_ONE_MINUS_SRC_COLOR: + factor = NV_PGRAPH_BLEND_DFACTOR_ONE_MINUS_SRC_COLOR; break; + case NV097_SET_BLEND_FUNC_DFACTOR_V_SRC_ALPHA: + factor = NV_PGRAPH_BLEND_DFACTOR_SRC_ALPHA; break; + case NV097_SET_BLEND_FUNC_DFACTOR_V_ONE_MINUS_SRC_ALPHA: + factor = NV_PGRAPH_BLEND_DFACTOR_ONE_MINUS_SRC_ALPHA; break; + case NV097_SET_BLEND_FUNC_DFACTOR_V_DST_ALPHA: + factor = NV_PGRAPH_BLEND_DFACTOR_DST_ALPHA; break; + case NV097_SET_BLEND_FUNC_DFACTOR_V_ONE_MINUS_DST_ALPHA: + factor = NV_PGRAPH_BLEND_DFACTOR_ONE_MINUS_DST_ALPHA; break; + case NV097_SET_BLEND_FUNC_DFACTOR_V_DST_COLOR: + factor = NV_PGRAPH_BLEND_DFACTOR_DST_COLOR; break; + case NV097_SET_BLEND_FUNC_DFACTOR_V_ONE_MINUS_DST_COLOR: + factor = NV_PGRAPH_BLEND_DFACTOR_ONE_MINUS_DST_COLOR; break; + case NV097_SET_BLEND_FUNC_DFACTOR_V_SRC_ALPHA_SATURATE: + factor = NV_PGRAPH_BLEND_DFACTOR_SRC_ALPHA_SATURATE; break; + case NV097_SET_BLEND_FUNC_DFACTOR_V_CONSTANT_COLOR: + factor = NV_PGRAPH_BLEND_DFACTOR_CONSTANT_COLOR; break; + case NV097_SET_BLEND_FUNC_DFACTOR_V_ONE_MINUS_CONSTANT_COLOR: + factor = NV_PGRAPH_BLEND_DFACTOR_ONE_MINUS_CONSTANT_COLOR; break; + case NV097_SET_BLEND_FUNC_DFACTOR_V_CONSTANT_ALPHA: + factor = NV_PGRAPH_BLEND_DFACTOR_CONSTANT_ALPHA; break; + case NV097_SET_BLEND_FUNC_DFACTOR_V_ONE_MINUS_CONSTANT_ALPHA: + factor = NV_PGRAPH_BLEND_DFACTOR_ONE_MINUS_CONSTANT_ALPHA; break; + default: + fprintf(stderr, "Unknown blend destination factor: 0x%x\n", parameter); + assert(false); + break; + } + SET_MASK(pgraph.regs[NV_PGRAPH_BLEND], NV_PGRAPH_BLEND_DFACTOR, factor); + + break; + } + + case NV097_SET_BLEND_COLOR: + pgraph.regs[NV_PGRAPH_BLENDCOLOR] = parameter; + break; + + case NV097_SET_BLEND_EQUATION: { + unsigned int equation; + switch (parameter) { + case NV097_SET_BLEND_EQUATION_V_FUNC_SUBTRACT: + equation = 0; break; + case NV097_SET_BLEND_EQUATION_V_FUNC_REVERSE_SUBTRACT: + equation = 1; break; + case NV097_SET_BLEND_EQUATION_V_FUNC_ADD: + equation = 2; break; + case NV097_SET_BLEND_EQUATION_V_MIN: + equation = 3; break; + case NV097_SET_BLEND_EQUATION_V_MAX: + equation = 4; break; + case NV097_SET_BLEND_EQUATION_V_FUNC_REVERSE_SUBTRACT_SIGNED: + equation = 5; break; + case NV097_SET_BLEND_EQUATION_V_FUNC_ADD_SIGNED: + equation = 6; break; + default: + assert(false); + break; + } + SET_MASK(pgraph.regs[NV_PGRAPH_BLEND], NV_PGRAPH_BLEND_EQN, equation); + + break; + } + + case NV097_SET_DEPTH_FUNC: + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_0], NV_PGRAPH_CONTROL_0_ZFUNC, + parameter & 0xF); + break; + + case NV097_SET_COLOR_MASK: { + pgraph.surface_color.write_enabled_cache |= pgraph_color_write_enabled(); + + bool alpha = parameter & NV097_SET_COLOR_MASK_ALPHA_WRITE_ENABLE; + bool red = parameter & NV097_SET_COLOR_MASK_RED_WRITE_ENABLE; + bool green = parameter & NV097_SET_COLOR_MASK_GREEN_WRITE_ENABLE; + bool blue = parameter & NV097_SET_COLOR_MASK_BLUE_WRITE_ENABLE; + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_0], + NV_PGRAPH_CONTROL_0_ALPHA_WRITE_ENABLE, alpha); + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_0], + NV_PGRAPH_CONTROL_0_RED_WRITE_ENABLE, red); + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_0], + NV_PGRAPH_CONTROL_0_GREEN_WRITE_ENABLE, green); + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_0], + NV_PGRAPH_CONTROL_0_BLUE_WRITE_ENABLE, blue); + break; + } + case NV097_SET_DEPTH_MASK: + pgraph.surface_zeta.write_enabled_cache |= pgraph_zeta_write_enabled(); + + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_0], + NV_PGRAPH_CONTROL_0_ZWRITEENABLE, parameter); + break; + case NV097_SET_STENCIL_MASK: + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_1], + NV_PGRAPH_CONTROL_1_STENCIL_MASK_WRITE, parameter); + break; + case NV097_SET_STENCIL_FUNC: + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_1], + NV_PGRAPH_CONTROL_1_STENCIL_FUNC, parameter & 0xF); + break; + case NV097_SET_STENCIL_FUNC_REF: + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_1], + NV_PGRAPH_CONTROL_1_STENCIL_REF, parameter); + break; + case NV097_SET_STENCIL_FUNC_MASK: + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_1], + NV_PGRAPH_CONTROL_1_STENCIL_MASK_READ, parameter); + break; + case NV097_SET_STENCIL_OP_FAIL: + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_2], + NV_PGRAPH_CONTROL_2_STENCIL_OP_FAIL, + kelvin_map_stencil_op(parameter)); + break; + case NV097_SET_STENCIL_OP_ZFAIL: + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_2], + NV_PGRAPH_CONTROL_2_STENCIL_OP_ZFAIL, + kelvin_map_stencil_op(parameter)); + break; + case NV097_SET_STENCIL_OP_ZPASS: + SET_MASK(pgraph.regs[NV_PGRAPH_CONTROL_2], + NV_PGRAPH_CONTROL_2_STENCIL_OP_ZPASS, + kelvin_map_stencil_op(parameter)); + break; + + case NV097_SET_POLYGON_OFFSET_SCALE_FACTOR: + pgraph.regs[NV_PGRAPH_ZOFFSETFACTOR] = parameter; + break; + case NV097_SET_POLYGON_OFFSET_BIAS: + pgraph.regs[NV_PGRAPH_ZOFFSETBIAS] = parameter; + break; + case NV097_SET_FRONT_POLYGON_MODE: + SET_MASK(pgraph.regs[NV_PGRAPH_SETUPRASTER], + NV_PGRAPH_SETUPRASTER_FRONTFACEMODE, + kelvin_map_polygon_mode(parameter)); + break; + case NV097_SET_BACK_POLYGON_MODE: + SET_MASK(pgraph.regs[NV_PGRAPH_SETUPRASTER], + NV_PGRAPH_SETUPRASTER_BACKFACEMODE, + kelvin_map_polygon_mode(parameter)); + break; + case NV097_SET_CLIP_MIN: + pgraph.regs[NV_PGRAPH_ZCLIPMIN] = parameter; + break; + case NV097_SET_CLIP_MAX: + pgraph.regs[NV_PGRAPH_ZCLIPMAX] = parameter; + break; + case NV097_SET_CULL_FACE: { + unsigned int face; + switch (parameter) { + case NV097_SET_CULL_FACE_V_FRONT: + face = NV_PGRAPH_SETUPRASTER_CULLCTRL_FRONT; break; + case NV097_SET_CULL_FACE_V_BACK: + face = NV_PGRAPH_SETUPRASTER_CULLCTRL_BACK; break; + case NV097_SET_CULL_FACE_V_FRONT_AND_BACK: + face = NV_PGRAPH_SETUPRASTER_CULLCTRL_FRONT_AND_BACK; break; + default: + assert(false); + break; + } + SET_MASK(pgraph.regs[NV_PGRAPH_SETUPRASTER], + NV_PGRAPH_SETUPRASTER_CULLCTRL, + face); + break; + } + case NV097_SET_FRONT_FACE: { + bool ccw; + switch (parameter) { + case NV097_SET_FRONT_FACE_V_CW: + ccw = false; break; + case NV097_SET_FRONT_FACE_V_CCW: + ccw = true; break; + default: + fprintf(stderr, "Unknown front face: 0x%x\n", parameter); + assert(false); + break; + } + SET_MASK(pgraph.regs[NV_PGRAPH_SETUPRASTER], + NV_PGRAPH_SETUPRASTER_FRONTFACE, + ccw ? 1 : 0); + break; + } + case NV097_SET_NORMALIZATION_ENABLE: + SET_MASK(pgraph.regs[NV_PGRAPH_CSV0_C], + NV_PGRAPH_CSV0_C_NORMALIZATION_ENABLE, + parameter); + break; + + case NV097_SET_LIGHT_ENABLE_MASK: + SET_MASK(pgraph.regs[NV_PGRAPH_CSV0_D], + NV_PGRAPH_CSV0_D_LIGHTS, + parameter); + break; + + CASE_4(NV097_SET_TEXGEN_S, 16) : { + slot = (method - NV097_SET_TEXGEN_S) / 16; + unsigned int reg = (slot < 2) ? NV_PGRAPH_CSV1_A + : NV_PGRAPH_CSV1_B; + unsigned int mask = (slot % 2) ? NV_PGRAPH_CSV1_A_T1_S + : NV_PGRAPH_CSV1_A_T0_S; + SET_MASK(pgraph.regs[reg], mask, kelvin_map_texgen(parameter, 0)); + break; + } + CASE_4(NV097_SET_TEXGEN_T, 16) : { + slot = (method - NV097_SET_TEXGEN_T) / 16; + unsigned int reg = (slot < 2) ? NV_PGRAPH_CSV1_A + : NV_PGRAPH_CSV1_B; + unsigned int mask = (slot % 2) ? NV_PGRAPH_CSV1_A_T1_T + : NV_PGRAPH_CSV1_A_T0_T; + SET_MASK(pgraph.regs[reg], mask, kelvin_map_texgen(parameter, 1)); + break; + } + CASE_4(NV097_SET_TEXGEN_R, 16) : { + slot = (method - NV097_SET_TEXGEN_R) / 16; + unsigned int reg = (slot < 2) ? NV_PGRAPH_CSV1_A + : NV_PGRAPH_CSV1_B; + unsigned int mask = (slot % 2) ? NV_PGRAPH_CSV1_A_T1_R + : NV_PGRAPH_CSV1_A_T0_R; + SET_MASK(pgraph.regs[reg], mask, kelvin_map_texgen(parameter, 2)); + break; + } + CASE_4(NV097_SET_TEXGEN_Q, 16) : { + slot = (method - NV097_SET_TEXGEN_Q) / 16; + unsigned int reg = (slot < 2) ? NV_PGRAPH_CSV1_A + : NV_PGRAPH_CSV1_B; + unsigned int mask = (slot % 2) ? NV_PGRAPH_CSV1_A_T1_Q + : NV_PGRAPH_CSV1_A_T0_Q; + SET_MASK(pgraph.regs[reg], mask, kelvin_map_texgen(parameter, 3)); + break; + } + CASE_4(NV097_SET_TEXTURE_MATRIX_ENABLE, 4) : + slot = (method - NV097_SET_TEXTURE_MATRIX_ENABLE) / 4; + pgraph.texture_matrix_enable[slot] = parameter; + break; + + default: + EmuWarning("EmuNV2A: Unknown NV_KELVIN_PRIMITIVE Method: 0x%08X\n", method); + } + break; + } + default: - EmuWarning("EmuNV2A: Unknown Graphics Class/Method 0x%08Xm 0x%08X\n", object->graphics_class, method); + EmuWarning("EmuNV2A: Unknown Graphics Class/Method 0x%08X/0x%08X\n", object->graphics_class, method); break; } } @@ -1237,22 +1997,16 @@ static void* pfifo_puller_thread() std::unique_lock lk(state->mutex); while (state->cache.empty() || !state->pull_enabled) { - printf("Waiting for Cache Lock\n"); state->cache_cond.wait(lk); - printf("Done Waiting for Cache Lock\n"); } // Copy cache to working_cache - printf("Building Working Cache\n"); while (!state->cache.empty()) { - printf("Copying To Working Cache\n"); state->working_cache.push(state->cache.front()); state->cache.pop(); } } - printf("Cache is not empty! \n"); - while (!state->working_cache.empty()) { CacheEntry* command = state->working_cache.front(); state->working_cache.pop(); @@ -1553,7 +2307,6 @@ DEVICE_WRITE32(PFIFO) pfifo.cache1.pull_enabled = true; /* the puller thread should wake up */ - printf("Waking up the Cache lock\n"); pfifo.cache1.cache_cond.notify_all(); } else if (!(value & NV_PFIFO_CACHE1_PULL0_ACCESS) && pfifo.cache1.pull_enabled) {