DRI2: report swap events correctly in direct rendered case
[mesa.git] / src / gallium / drivers / nv30 / nv30_fragtex.c
1 #include "util/u_format.h"
2
3 #include "nv30_context.h"
4 #include "nouveau/nouveau_util.h"
5
6 #define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w) \
7 { \
8 TRUE, \
9 PIPE_FORMAT_##m, \
10 NV34TCL_TX_FORMAT_FORMAT_##tf, \
11 (NV34TCL_TX_SWIZZLE_S0_X_##ts0x | NV34TCL_TX_SWIZZLE_S0_Y_##ts0y | \
12 NV34TCL_TX_SWIZZLE_S0_Z_##ts0z | NV34TCL_TX_SWIZZLE_S0_W_##ts0w | \
13 NV34TCL_TX_SWIZZLE_S1_X_##ts1x | NV34TCL_TX_SWIZZLE_S1_Y_##ts1y | \
14 NV34TCL_TX_SWIZZLE_S1_Z_##ts1z | NV34TCL_TX_SWIZZLE_S1_W_##ts1w) \
15 }
16
17 struct nv30_texture_format {
18 boolean defined;
19 uint pipe;
20 int format;
21 int swizzle;
22 };
23
24 static struct nv30_texture_format
25 nv30_texture_formats[] = {
26 _(B8G8R8X8_UNORM, A8R8G8B8, S1, S1, S1, ONE, X, Y, Z, W),
27 _(B8G8R8A8_UNORM, A8R8G8B8, S1, S1, S1, S1, X, Y, Z, W),
28 _(B5G5R5A1_UNORM, A1R5G5B5, S1, S1, S1, S1, X, Y, Z, W),
29 _(B4G4R4A4_UNORM, A4R4G4B4, S1, S1, S1, S1, X, Y, Z, W),
30 _(B5G6R5_UNORM , R5G6B5 , S1, S1, S1, ONE, X, Y, Z, W),
31 _(L8_UNORM , L8 , S1, S1, S1, ONE, X, X, X, X),
32 _(A8_UNORM , L8 , ZERO, ZERO, ZERO, S1, X, X, X, X),
33 _(I8_UNORM , L8 , S1, S1, S1, S1, X, X, X, X),
34 _(L8A8_UNORM , A8L8 , S1, S1, S1, S1, X, X, X, Y),
35 _(Z16_UNORM , R5G6B5 , S1, S1, S1, ONE, X, X, X, X),
36 _(S8Z24_UNORM , A8R8G8B8, S1, S1, S1, ONE, X, X, X, X),
37 _(DXT1_RGB , DXT1 , S1, S1, S1, ONE, X, Y, Z, W),
38 _(DXT1_RGBA , DXT1 , S1, S1, S1, S1, X, Y, Z, W),
39 _(DXT3_RGBA , DXT3 , S1, S1, S1, S1, X, Y, Z, W),
40 _(DXT5_RGBA , DXT5 , S1, S1, S1, S1, X, Y, Z, W),
41 {},
42 };
43
44 static struct nv30_texture_format *
45 nv30_fragtex_format(uint pipe_format)
46 {
47 struct nv30_texture_format *tf = nv30_texture_formats;
48
49 while (tf->defined) {
50 if (tf->pipe == pipe_format)
51 return tf;
52 tf++;
53 }
54
55 NOUVEAU_ERR("unknown texture format %s\n", util_format_name(pipe_format));
56 return NULL;
57 }
58
59
60 static struct nouveau_stateobj *
61 nv30_fragtex_build(struct nv30_context *nv30, int unit)
62 {
63 struct nv30_sampler_state *ps = nv30->tex_sampler[unit];
64 struct nv30_miptree *nv30mt = nv30->tex_miptree[unit];
65 struct pipe_texture *pt = &nv30mt->base;
66 struct nouveau_bo *bo = nouveau_bo(nv30mt->buffer);
67 struct nv30_texture_format *tf;
68 struct nouveau_stateobj *so;
69 uint32_t txf, txs;
70 unsigned tex_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
71
72 tf = nv30_fragtex_format(pt->format);
73 if (!tf)
74 return NULL;
75
76 txf = tf->format;
77 txf |= ((pt->last_level>0) ? NV34TCL_TX_FORMAT_MIPMAP : 0);
78 txf |= log2i(pt->width0) << NV34TCL_TX_FORMAT_BASE_SIZE_U_SHIFT;
79 txf |= log2i(pt->height0) << NV34TCL_TX_FORMAT_BASE_SIZE_V_SHIFT;
80 txf |= log2i(pt->depth0) << NV34TCL_TX_FORMAT_BASE_SIZE_W_SHIFT;
81 txf |= NV34TCL_TX_FORMAT_NO_BORDER | 0x10000;
82
83 switch (pt->target) {
84 case PIPE_TEXTURE_CUBE:
85 txf |= NV34TCL_TX_FORMAT_CUBIC;
86 /* fall-through */
87 case PIPE_TEXTURE_2D:
88 txf |= NV34TCL_TX_FORMAT_DIMS_2D;
89 break;
90 case PIPE_TEXTURE_3D:
91 txf |= NV34TCL_TX_FORMAT_DIMS_3D;
92 break;
93 case PIPE_TEXTURE_1D:
94 txf |= NV34TCL_TX_FORMAT_DIMS_1D;
95 break;
96 default:
97 NOUVEAU_ERR("Unknown target %d\n", pt->target);
98 return NULL;
99 }
100
101 txs = tf->swizzle;
102
103 so = so_new(1, 8, 2);
104 so_method(so, nv30->screen->rankine, NV34TCL_TX_OFFSET(unit), 8);
105 so_reloc (so, bo, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0);
106 so_reloc (so, bo, txf, tex_flags | NOUVEAU_BO_OR,
107 NV34TCL_TX_FORMAT_DMA0, NV34TCL_TX_FORMAT_DMA1);
108 so_data (so, ps->wrap);
109 so_data (so, NV34TCL_TX_ENABLE_ENABLE | ps->en);
110 so_data (so, txs);
111 so_data (so, ps->filt | 0x2000 /*voodoo*/);
112 so_data (so, (pt->width0 << NV34TCL_TX_NPOT_SIZE_W_SHIFT) |
113 pt->height0);
114 so_data (so, ps->bcol);
115
116 return so;
117 }
118
119 static boolean
120 nv30_fragtex_validate(struct nv30_context *nv30)
121 {
122 struct nv30_fragment_program *fp = nv30->fragprog;
123 struct nv30_state *state = &nv30->state;
124 struct nouveau_stateobj *so;
125 unsigned samplers, unit;
126
127 samplers = state->fp_samplers & ~fp->samplers;
128 while (samplers) {
129 unit = ffs(samplers) - 1;
130 samplers &= ~(1 << unit);
131
132 so = so_new(1, 1, 0);
133 so_method(so, nv30->screen->rankine, NV34TCL_TX_ENABLE(unit), 1);
134 so_data (so, 0);
135 so_ref(so, &nv30->state.hw[NV30_STATE_FRAGTEX0 + unit]);
136 so_ref(NULL, &so);
137 state->dirty |= (1ULL << (NV30_STATE_FRAGTEX0 + unit));
138 }
139
140 samplers = nv30->dirty_samplers & fp->samplers;
141 while (samplers) {
142 unit = ffs(samplers) - 1;
143 samplers &= ~(1 << unit);
144
145 so = nv30_fragtex_build(nv30, unit);
146 so_ref(so, &nv30->state.hw[NV30_STATE_FRAGTEX0 + unit]);
147 so_ref(NULL, &so);
148 state->dirty |= (1ULL << (NV30_STATE_FRAGTEX0 + unit));
149 }
150
151 nv30->state.fp_samplers = fp->samplers;
152 return FALSE;
153 }
154
155 struct nv30_state_entry nv30_state_fragtex = {
156 .validate = nv30_fragtex_validate,
157 .dirty = {
158 .pipe = NV30_NEW_SAMPLER | NV30_NEW_FRAGPROG,
159 .hw = 0
160 }
161 };