nvfx: support nv30 simulation on nv40
authorLuca Barbieri <luca@luca-barbieri.com>
Sun, 5 Sep 2010 20:00:26 +0000 (22:00 +0200)
committerLuca Barbieri <luca@luca-barbieri.com>
Sun, 5 Sep 2010 21:41:33 +0000 (23:41 +0200)
src/gallium/drivers/nvfx/nvfx_context.c
src/gallium/drivers/nvfx/nvfx_context.h
src/gallium/drivers/nvfx/nvfx_fragprog.c
src/gallium/drivers/nvfx/nvfx_screen.c
src/gallium/drivers/nvfx/nvfx_screen.h
src/gallium/drivers/nvfx/nvfx_surface.h [new file with mode: 0644]
src/gallium/drivers/nvfx/nvfx_vertprog.c

index 9baf78b02a10b5ea6760a2ec598fbc4099b55232..62d623b9ffe36acf750e73c39cf5d489cc26ac22 100644 (file)
@@ -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.
         */
index 48a9cd2b7c61b6c835339b423e9d76206ca0fd96..6ef2a6945d7a612a64b81fb36e796712efd53e24 100644 (file)
@@ -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;
index 44c7968d88e4babd2661361426e572b5409d135c..fc9d5b96cef0a54051b2c716e4ba907bfc77b892 100644 (file)
@@ -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<src>:
                // IF (NE.xxxx) ELSE <else> END <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;
index b72e6aa1a85f78d603f4a9e52c9cd2bd0c569a47..0290370d9896dd82ffb627a7993622439a186209 100644 (file)
@@ -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;
        }
index 566fcb12085713c5d0fb9206ec2ccfbd6672fea5..b1f07187c78c4e28e4547e212eadd14da75ae8e0 100644 (file)
@@ -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 (file)
index 0000000..e69de29
index 570bb452b5ef0d01b4e2e66318f86a8ebefd4936..6e5b6c093630b3caa560a6ee68f5dd3140b9b6f2 100644 (file)
@@ -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);