From 357a7e90dfab9ea0ea32936fd4a5f973a5caadc8 Mon Sep 17 00:00:00 2001 From: Luca Barbieri Date: Sun, 5 Sep 2010 22:00:26 +0200 Subject: [PATCH] nvfx: support nv30 simulation on nv40 --- src/gallium/drivers/nvfx/nvfx_context.c | 1 + src/gallium/drivers/nvfx/nvfx_context.h | 1 + src/gallium/drivers/nvfx/nvfx_fragprog.c | 20 +++++----- src/gallium/drivers/nvfx/nvfx_screen.c | 49 +++++++++++++++--------- src/gallium/drivers/nvfx/nvfx_screen.h | 3 ++ src/gallium/drivers/nvfx/nvfx_surface.h | 0 src/gallium/drivers/nvfx/nvfx_vertprog.c | 8 ++-- 7 files changed, 50 insertions(+), 32 deletions(-) create mode 100644 src/gallium/drivers/nvfx/nvfx_surface.h diff --git a/src/gallium/drivers/nvfx/nvfx_context.c b/src/gallium/drivers/nvfx/nvfx_context.c index 9baf78b02a1..62d623b9ffe 100644 --- a/src/gallium/drivers/nvfx/nvfx_context.c +++ b/src/gallium/drivers/nvfx/nvfx_context.c @@ -77,6 +77,7 @@ nvfx_create(struct pipe_screen *pscreen, void *priv) nvfx->pipe.flush = nvfx_flush; nvfx->is_nv4x = screen->is_nv4x; + nvfx->use_nv4x = screen->use_nv4x; /* TODO: it seems that nv30 might have fixed function clipping usable with vertex programs * However, my code for that doesn't work, so use vp clipping for all cards, which works. */ diff --git a/src/gallium/drivers/nvfx/nvfx_context.h b/src/gallium/drivers/nvfx/nvfx_context.h index 48a9cd2b7c6..6ef2a6945d7 100644 --- a/src/gallium/drivers/nvfx/nvfx_context.h +++ b/src/gallium/drivers/nvfx/nvfx_context.h @@ -141,6 +141,7 @@ struct nvfx_context { struct nvfx_screen *screen; unsigned is_nv4x; /* either 0 or ~0 */ + unsigned use_nv4x; /* either 0 or ~0 */ boolean use_vp_clipping; struct draw_context *draw; diff --git a/src/gallium/drivers/nvfx/nvfx_fragprog.c b/src/gallium/drivers/nvfx/nvfx_fragprog.c index 44c7968d88e..fc9d5b96cef 100644 --- a/src/gallium/drivers/nvfx/nvfx_fragprog.c +++ b/src/gallium/drivers/nvfx/nvfx_fragprog.c @@ -828,7 +828,7 @@ nvfx_fragprog_parse_instruction(struct nvfx_context* nvfx, struct nvfx_fpc *fpc, case TGSI_OPCODE_IF: // MOVRC0 R31 (TR0.xyzw), R: // IF (NE.xxxx) ELSE END - if(!nvfx->is_nv4x) + if(!nvfx->use_nv4x) goto nv3x_cflow; nv40_fp_if(fpc, src[0]); break; @@ -836,7 +836,7 @@ nvfx_fragprog_parse_instruction(struct nvfx_context* nvfx, struct nvfx_fpc *fpc, case TGSI_OPCODE_ELSE: { uint32_t *hw; - if(!nvfx->is_nv4x) + if(!nvfx->use_nv4x) goto nv3x_cflow; assert(util_dynarray_contains(&fpc->if_stack, unsigned)); hw = &fpc->fp->insn[util_dynarray_top(&fpc->if_stack, unsigned)]; @@ -847,7 +847,7 @@ nvfx_fragprog_parse_instruction(struct nvfx_context* nvfx, struct nvfx_fpc *fpc, case TGSI_OPCODE_ENDIF: { uint32_t *hw; - if(!nvfx->is_nv4x) + if(!nvfx->use_nv4x) goto nv3x_cflow; assert(util_dynarray_contains(&fpc->if_stack, unsigned)); hw = &fpc->fp->insn[util_dynarray_pop(&fpc->if_stack, unsigned)]; @@ -870,19 +870,19 @@ nvfx_fragprog_parse_instruction(struct nvfx_context* nvfx, struct nvfx_fpc *fpc, break; case TGSI_OPCODE_CAL: - if(!nvfx->is_nv4x) + if(!nvfx->use_nv4x) goto nv3x_cflow; nv40_fp_cal(fpc, finst->Label.Label); break; case TGSI_OPCODE_RET: - if(!nvfx->is_nv4x) + if(!nvfx->use_nv4x) goto nv3x_cflow; nv40_fp_ret(fpc); break; case TGSI_OPCODE_BGNLOOP: - if(!nvfx->is_nv4x) + if(!nvfx->use_nv4x) goto nv3x_cflow; /* TODO: we should support using two nested REPs to allow a > 255 iteration count */ nv40_fp_rep(fpc, 255, finst->Label.Label); @@ -892,7 +892,7 @@ nvfx_fragprog_parse_instruction(struct nvfx_context* nvfx, struct nvfx_fpc *fpc, break; case TGSI_OPCODE_BRK: - if(!nvfx->is_nv4x) + if(!nvfx->use_nv4x) goto nv3x_cflow; nv40_fp_brk(fpc); break; @@ -947,7 +947,7 @@ nvfx_fragprog_parse_decl_output(struct nvfx_context* nvfx, struct nvfx_fpc *fpc, case 2: hw = 3; break; case 3: hw = 4; break; } - if(hw > ((nvfx->is_nv4x) ? 4 : 2)) { + if(hw > ((nvfx->use_nv4x) ? 4 : 2)) { NOUVEAU_ERR("bad rcol index\n"); return FALSE; } @@ -968,7 +968,7 @@ nvfx_fragprog_prepare(struct nvfx_context* nvfx, struct nvfx_fpc *fpc) struct tgsi_parse_context p; int high_temp = -1, i; struct util_semantic_set set; - unsigned num_texcoords = nvfx->is_nv4x ? 10 : 8; + unsigned num_texcoords = nvfx->use_nv4x ? 10 : 8; fpc->fp->num_slots = util_semantic_set_from_program_file(&set, fpc->pfp->pipe.tokens, TGSI_FILE_INPUT); if(fpc->fp->num_slots > num_texcoords) @@ -1062,7 +1062,7 @@ nvfx_fragprog_translate(struct nvfx_context *nvfx, if (!fpc) goto out_err; - fpc->max_temps = nvfx->is_nv4x ? 48 : 32; + fpc->max_temps = nvfx->use_nv4x ? 48 : 32; fpc->pfp = pfp; fpc->fp = fp; fpc->num_regs = 2; diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c index b72e6aa1a85..0290370d989 100644 --- a/src/gallium/drivers/nvfx/nvfx_screen.c +++ b/src/gallium/drivers/nvfx/nvfx_screen.c @@ -27,7 +27,7 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: return 16; case PIPE_CAP_NPOT_TEXTURES: - return !!screen->is_nv4x; + return screen->advertise_npot; case PIPE_CAP_TWO_SIDED_STENCIL: return 1; case PIPE_CAP_GLSL: @@ -37,7 +37,7 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_POINT_SPRITE: return 1; case PIPE_CAP_MAX_RENDER_TARGETS: - return screen->is_nv4x ? 4 : 2; + return screen->use_nv4x ? 4 : 2; case PIPE_CAP_OCCLUSION_QUERY: return 1; case PIPE_CAP_TIMER_QUERY: @@ -53,7 +53,7 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: return 13; case PIPE_CAP_TEXTURE_MIRROR_CLAMP: - return !!screen->is_nv4x; + return !!screen->use_nv4x; case PIPE_CAP_TEXTURE_MIRROR_REPEAT: return 1; case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: @@ -61,7 +61,7 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TGSI_CONT_SUPPORTED: return 0; case PIPE_CAP_BLEND_EQUATION_SEPARATE: - return !!screen->is_nv4x; + return screen->advertise_blend_equation_separate; case PIPE_CAP_MAX_COMBINED_SAMPLERS: return 16; case PIPE_CAP_INDEP_BLEND_ENABLE: @@ -85,35 +85,35 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH: /* FIXME: is it the dynamic (nv30:0/nv40:24) or the static value (nv30:0/nv40:4) ? */ - return screen->is_nv4x ? 4 : 0; + return screen->use_nv4x ? 4 : 0; case PIPE_CAP_MAX_FS_INPUTS: - return screen->is_nv4x ? 12 : 10; + return screen->use_nv4x ? 12 : 10; case PIPE_CAP_MAX_FS_CONSTS: - return screen->is_nv4x ? 224 : 32; + return screen->use_nv4x ? 224 : 32; case PIPE_CAP_MAX_FS_TEMPS: return 32; case PIPE_CAP_MAX_FS_ADDRS: - return screen->is_nv4x ? 1 : 0; + return screen->use_nv4x ? 1 : 0; case PIPE_CAP_MAX_FS_PREDS: return 0; /* we could expose these, but nothing uses them */ case PIPE_CAP_MAX_VS_INSTRUCTIONS: case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS: - return screen->is_nv4x ? 512 : 256; + return screen->use_nv4x ? 512 : 256; case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS: case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS: - return screen->is_nv4x ? 512 : 0; + return screen->use_nv4x ? 512 : 0; case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH: /* FIXME: is it the dynamic (nv30:24/nv40:24) or the static value (nv30:1/nv40:4) ? */ - return screen->is_nv4x ? 4 : 1; + return screen->use_nv4x ? 4 : 1; case PIPE_CAP_MAX_VS_INPUTS: return 16; case PIPE_CAP_MAX_VS_CONSTS: /* - 6 is for clip planes; Gallium should be fixed to put * them in the vertex shader itself, so we don't need to reserve these */ - return (screen->is_nv4x ? 468 : 256) - 6; + return (screen->use_nv4x ? 468 : 256) - 6; case PIPE_CAP_MAX_VS_TEMPS: - return screen->is_nv4x ? 32 : 13; + return screen->use_nv4x ? 32 : 13; case PIPE_CAP_MAX_VS_ADDRS: return 2; case PIPE_CAP_MAX_VS_PREDS: @@ -141,7 +141,7 @@ nvfx_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_MAX_POINT_WIDTH_AA: return 64.0; case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: - return screen->is_nv4x ? 16.0 : 8.0; + return screen->use_nv4x ? 16.0 : 8.0; case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: return 15.0; default: @@ -200,7 +200,7 @@ nvfx_screen_is_format_supported(struct pipe_screen *pscreen, return FALSE; if(format == PIPE_FORMAT_R32G32B32A32_FLOAT && !screen->advertise_fp32) return FALSE; - if(screen->is_nv4x) + if(screen->use_nv4x) { if(tf->fmt[4] < 0) return FALSE; @@ -432,6 +432,19 @@ nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) return NULL; } + screen->advertise_npot = !!screen->is_nv4x; + screen->advertise_blend_equation_separate = !!screen->is_nv4x; + screen->use_nv4x = screen->is_nv4x; + + if(screen->is_nv4x) { + if(debug_get_bool_option("NVFX_SIMULATE_NV30", FALSE)) + screen->use_nv4x = 0; + if(!debug_get_bool_option("NVFX_NPOT", TRUE)) + screen->advertise_npot = 0; + if(!debug_get_bool_option("NVFX_BLEND_EQ_SEP", TRUE)) + screen->advertise_blend_equation_separate = 0; + } + screen->force_swtnl = debug_get_bool_option("NVFX_SWTNL", FALSE); screen->trace_draw = debug_get_bool_option("NVFX_TRACE_DRAW", FALSE); @@ -443,7 +456,7 @@ nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) * it should, due to several restrictions. * The only exception is fp16 on nv40. */ - screen->advertise_fp16 = debug_get_bool_option("NVFX_FP16", !!screen->is_nv4x); + screen->advertise_fp16 = debug_get_bool_option("NVFX_FP16", !!screen->use_nv4x); screen->advertise_fp32 = debug_get_bool_option("NVFX_FP32", 0); screen->vertex_buffer_reloc_flags = nvfx_screen_get_vertex_buffer_flags(screen); @@ -498,8 +511,8 @@ nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) LIST_INITHEAD(&screen->query_list); /* Vtxprog resources */ - if (nouveau_resource_init(&screen->vp_exec_heap, 0, screen->is_nv4x ? 512 : 256) || - nouveau_resource_init(&screen->vp_data_heap, 0, screen->is_nv4x ? 468 : 256)) { + if (nouveau_resource_init(&screen->vp_exec_heap, 0, screen->use_nv4x ? 512 : 256) || + nouveau_resource_init(&screen->vp_data_heap, 0, screen->use_nv4x ? 468 : 256)) { nvfx_screen_destroy(pscreen); return NULL; } diff --git a/src/gallium/drivers/nvfx/nvfx_screen.h b/src/gallium/drivers/nvfx/nvfx_screen.h index 566fcb12085..b1f07187c78 100644 --- a/src/gallium/drivers/nvfx/nvfx_screen.h +++ b/src/gallium/drivers/nvfx/nvfx_screen.h @@ -15,12 +15,15 @@ struct nvfx_screen { struct nvfx_context *cur_ctx; unsigned is_nv4x; /* either 0 or ~0 */ + unsigned use_nv4x; /* either 0 or ~0 */ boolean force_swtnl; boolean trace_draw; unsigned vertex_buffer_reloc_flags; unsigned index_buffer_reloc_flags; unsigned advertise_fp16; unsigned advertise_fp32; + unsigned advertise_npot; + unsigned advertise_blend_equation_separate; /* HW graphics objects */ struct nouveau_grobj *eng3d; diff --git a/src/gallium/drivers/nvfx/nvfx_surface.h b/src/gallium/drivers/nvfx/nvfx_surface.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/gallium/drivers/nvfx/nvfx_vertprog.c b/src/gallium/drivers/nvfx/nvfx_vertprog.c index 570bb452b5e..6e5b6c09363 100644 --- a/src/gallium/drivers/nvfx/nvfx_vertprog.c +++ b/src/gallium/drivers/nvfx/nvfx_vertprog.c @@ -297,8 +297,8 @@ nvfx_vp_emit(struct nvfx_vpc *vpc, struct nvfx_insn insn) if(insn.sat) { - assert(nvfx->is_nv4x); - if(nvfx->is_nv4x) + assert(nvfx->use_nv4x); + if(nvfx->use_nv4x) hw[0] |= NV40_VP_INST_SATURATE; } @@ -519,7 +519,7 @@ nvfx_vertprog_parse_instruction(struct nvfx_context* nvfx, struct nvfx_vpc *vpc, if(finst->Instruction.Saturate == TGSI_SAT_ZERO_ONE) { assert(finst->Instruction.Opcode != TGSI_OPCODE_ARL); - if(nvfx->is_nv4x) + if(nvfx->use_nv4x) sat = TRUE; else if(dst.type != NVFXSR_TEMP) dst = temp(vpc); @@ -757,7 +757,7 @@ nvfx_vertprog_parse_instruction(struct nvfx_context* nvfx, struct nvfx_vpc *vpc, return FALSE; } - if(finst->Instruction.Saturate == TGSI_SAT_ZERO_ONE && !nvfx->is_nv4x) + if(finst->Instruction.Saturate == TGSI_SAT_ZERO_ONE && !nvfx->use_nv4x) { if(!vpc->r_0_1.type) vpc->r_0_1 = constant(vpc, -1, 0, 1, 0, 0); -- 2.30.2