1 #include "util/u_format.h"
3 #include "nv40_context.h"
5 #define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,sx,sy,sz,sw) \
9 NV40TCL_TEX_FORMAT_FORMAT_##tf, \
10 (NV34TCL_TX_SWIZZLE_S0_X_##ts0x | NV34TCL_TX_SWIZZLE_S0_Y_##ts0y | \
11 NV34TCL_TX_SWIZZLE_S0_Z_##ts0z | NV34TCL_TX_SWIZZLE_S0_W_##ts0w | \
12 NV34TCL_TX_SWIZZLE_S1_X_##ts1x | NV34TCL_TX_SWIZZLE_S1_Y_##ts1y | \
13 NV34TCL_TX_SWIZZLE_S1_Z_##ts1z | NV34TCL_TX_SWIZZLE_S1_W_##ts1w), \
14 ((NV34TCL_TX_FILTER_SIGNED_RED*sx) | (NV34TCL_TX_FILTER_SIGNED_GREEN*sy) | \
15 (NV34TCL_TX_FILTER_SIGNED_BLUE*sz) | (NV34TCL_TX_FILTER_SIGNED_ALPHA*sw)) \
18 struct nv40_texture_format
{
26 static struct nv40_texture_format
27 nv40_texture_formats
[] = {
28 _(B8G8R8X8_UNORM
, A8R8G8B8
, S1
, S1
, S1
, ONE
, X
, Y
, Z
, W
, 0, 0, 0, 0),
29 _(B8G8R8A8_UNORM
, A8R8G8B8
, S1
, S1
, S1
, S1
, X
, Y
, Z
, W
, 0, 0, 0, 0),
30 _(B5G5R5A1_UNORM
, A1R5G5B5
, S1
, S1
, S1
, S1
, X
, Y
, Z
, W
, 0, 0, 0, 0),
31 _(B4G4R4A4_UNORM
, A4R4G4B4
, S1
, S1
, S1
, S1
, X
, Y
, Z
, W
, 0, 0, 0, 0),
32 _(B5G6R5_UNORM
, R5G6B5
, S1
, S1
, S1
, ONE
, X
, Y
, Z
, W
, 0, 0, 0, 0),
33 _(L8_UNORM
, L8
, S1
, S1
, S1
, ONE
, X
, X
, X
, X
, 0, 0, 0, 0),
34 _(A8_UNORM
, L8
, ZERO
, ZERO
, ZERO
, S1
, X
, X
, X
, X
, 0, 0, 0, 0),
35 _(R16_SNORM
, A16
, ZERO
, ZERO
, S1
, ONE
, X
, X
, X
, Y
, 1, 1, 1, 1),
36 _(I8_UNORM
, L8
, S1
, S1
, S1
, S1
, X
, X
, X
, X
, 0, 0, 0, 0),
37 _(L8A8_UNORM
, A8L8
, S1
, S1
, S1
, S1
, X
, X
, X
, Y
, 0, 0, 0, 0),
38 _(Z16_UNORM
, Z16
, S1
, S1
, S1
, ONE
, X
, X
, X
, X
, 0, 0, 0, 0),
39 _(S8Z24_UNORM
, Z24
, S1
, S1
, S1
, ONE
, X
, X
, X
, X
, 0, 0, 0, 0),
40 _(DXT1_RGB
, DXT1
, S1
, S1
, S1
, ONE
, X
, Y
, Z
, W
, 0, 0, 0, 0),
41 _(DXT1_RGBA
, DXT1
, S1
, S1
, S1
, S1
, X
, Y
, Z
, W
, 0, 0, 0, 0),
42 _(DXT3_RGBA
, DXT3
, S1
, S1
, S1
, S1
, X
, Y
, Z
, W
, 0, 0, 0, 0),
43 _(DXT5_RGBA
, DXT5
, S1
, S1
, S1
, S1
, X
, Y
, Z
, W
, 0, 0, 0, 0),
47 static struct nv40_texture_format
*
48 nv40_fragtex_format(uint pipe_format
)
50 struct nv40_texture_format
*tf
= nv40_texture_formats
;
53 if (tf
->pipe
== pipe_format
)
58 NOUVEAU_ERR("unknown texture format %s\n", util_format_name(pipe_format
));
63 static struct nouveau_stateobj
*
64 nv40_fragtex_build(struct nv40_context
*nv40
, int unit
)
66 struct nv40_sampler_state
*ps
= nv40
->tex_sampler
[unit
];
67 struct nv40_miptree
*nv40mt
= nv40
->tex_miptree
[unit
];
68 struct nouveau_bo
*bo
= nouveau_bo(nv40mt
->buffer
);
69 struct pipe_texture
*pt
= &nv40mt
->base
;
70 struct nv40_texture_format
*tf
;
71 struct nouveau_stateobj
*so
;
72 uint32_t txf
, txs
, txp
;
73 unsigned tex_flags
= NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_RD
;
75 tf
= nv40_fragtex_format(pt
->format
);
80 txf
|= tf
->format
| 0x8000;
81 txf
|= ((pt
->last_level
+ 1) << NV40TCL_TEX_FORMAT_MIPMAP_COUNT_SHIFT
);
84 txf
|= NV34TCL_TX_FORMAT_NO_BORDER
;
87 case PIPE_TEXTURE_CUBE
:
88 txf
|= NV34TCL_TX_FORMAT_CUBIC
;
91 txf
|= NV34TCL_TX_FORMAT_DIMS_2D
;
94 txf
|= NV34TCL_TX_FORMAT_DIMS_3D
;
97 txf
|= NV34TCL_TX_FORMAT_DIMS_1D
;
100 NOUVEAU_ERR("Unknown target %d\n", pt
->target
);
104 if (!(pt
->tex_usage
& NOUVEAU_TEXTURE_USAGE_LINEAR
)) {
107 txp
= nv40mt
->level
[0].pitch
;
108 txf
|= NV40TCL_TEX_FORMAT_LINEAR
;
113 so
= so_new(2, 9, 2);
114 so_method(so
, nv40
->screen
->eng3d
, NV34TCL_TX_OFFSET(unit
), 8);
115 so_reloc (so
, bo
, 0, tex_flags
| NOUVEAU_BO_LOW
, 0, 0);
116 so_reloc (so
, bo
, txf
, tex_flags
| NOUVEAU_BO_OR
,
117 NV34TCL_TX_FORMAT_DMA0
, NV34TCL_TX_FORMAT_DMA1
);
118 so_data (so
, ps
->wrap
);
119 so_data (so
, NV40TCL_TEX_ENABLE_ENABLE
| ps
->en
);
121 so_data (so
, ps
->filt
| tf
->sign
| 0x2000 /*voodoo*/);
122 so_data (so
, (pt
->width0
<< NV34TCL_TX_NPOT_SIZE_W_SHIFT
) |
124 so_data (so
, ps
->bcol
);
125 so_method(so
, nv40
->screen
->eng3d
, NV40TCL_TEX_SIZE1(unit
), 1);
126 so_data (so
, (pt
->depth0
<< NV40TCL_TEX_SIZE1_DEPTH_SHIFT
) | txp
);
132 nv40_fragtex_validate(struct nv40_context
*nv40
)
134 struct nv40_fragment_program
*fp
= nv40
->fragprog
;
135 struct nv40_state
*state
= &nv40
->state
;
136 struct nouveau_stateobj
*so
;
137 unsigned samplers
, unit
;
139 samplers
= state
->fp_samplers
& ~fp
->samplers
;
141 unit
= ffs(samplers
) - 1;
142 samplers
&= ~(1 << unit
);
144 so
= so_new(1, 1, 0);
145 so_method(so
, nv40
->screen
->eng3d
, NV34TCL_TX_ENABLE(unit
), 1);
147 so_ref(so
, &nv40
->state
.hw
[NV40_STATE_FRAGTEX0
+ unit
]);
148 state
->dirty
|= (1ULL << (NV40_STATE_FRAGTEX0
+ unit
));
151 samplers
= nv40
->dirty_samplers
& fp
->samplers
;
153 unit
= ffs(samplers
) - 1;
154 samplers
&= ~(1 << unit
);
156 so
= nv40_fragtex_build(nv40
, unit
);
157 so_ref(so
, &nv40
->state
.hw
[NV40_STATE_FRAGTEX0
+ unit
]);
159 state
->dirty
|= (1ULL << (NV40_STATE_FRAGTEX0
+ unit
));
162 nv40
->state
.fp_samplers
= fp
->samplers
;
166 struct nv40_state_entry nv40_state_fragtex
= {
167 .validate
= nv40_fragtex_validate
,
169 .pipe
= NV40_NEW_SAMPLER
| NV40_NEW_FRAGPROG
,