mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-24 03:50:32 +01:00
nvfx: support nv30 simulation on nv40
This commit is contained in:
parent
d8bba2ef69
commit
357a7e90df
7 changed files with 50 additions and 32 deletions
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
0
src/gallium/drivers/nvfx/nvfx_surface.h
Normal file
0
src/gallium/drivers/nvfx/nvfx_surface.h
Normal 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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue