nv50_state_validate.c revision 47771bcd2fb5bcfecfa076c19360436351c21c95
1#include "nv50_context.h" 2#include "nouveau/nouveau_stateobj.h" 3 4static void 5nv50_state_validate_fb(struct nv50_context *nv50) 6{ 7 struct nouveau_grobj *tesla = nv50->screen->tesla; 8 struct nouveau_stateobj *so = so_new(128, 18); 9 struct pipe_framebuffer_state *fb = &nv50->framebuffer; 10 unsigned i, w, h, gw = 0; 11 12 for (i = 0; i < fb->num_cbufs; i++) { 13 if (!gw) { 14 w = fb->cbufs[i]->width; 15 h = fb->cbufs[i]->height; 16 gw = 1; 17 } else { 18 assert(w == fb->cbufs[i]->width); 19 assert(h == fb->cbufs[i]->height); 20 } 21 22 so_method(so, tesla, NV50TCL_RT_HORIZ(i), 2); 23 so_data (so, fb->cbufs[i]->width); 24 so_data (so, fb->cbufs[i]->height); 25 26 so_method(so, tesla, NV50TCL_RT_ADDRESS_HIGH(i), 5); 27 so_reloc (so, fb->cbufs[i]->buffer, fb->cbufs[i]->offset, 28 NOUVEAU_BO_VRAM | NOUVEAU_BO_HIGH, 0, 0); 29 so_reloc (so, fb->cbufs[i]->buffer, fb->cbufs[i]->offset, 30 NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW, 0, 0); 31 switch (fb->cbufs[i]->format) { 32 case PIPE_FORMAT_A8R8G8B8_UNORM: 33 so_data(so, 0xcf); 34 break; 35 case PIPE_FORMAT_R5G6B5_UNORM: 36 so_data(so, 0xe8); 37 break; 38 default: 39 { 40 char fmt[128]; 41 pf_sprint_name(fmt, fb->cbufs[i]->format); 42 NOUVEAU_ERR("AIIII unknown format %s\n", fmt); 43 } 44 so_data(so, 0xe6); 45 break; 46 } 47 so_data(so, 0x00000040); 48 so_data(so, 0x00000000); 49 50 so_method(so, tesla, 0x1224, 1); 51 so_data (so, 1); 52 } 53 54 if (fb->zsbuf) { 55 if (!gw) { 56 w = fb->zsbuf->width; 57 h = fb->zsbuf->height; 58 gw = 1; 59 } else { 60 assert(w == fb->zsbuf->width); 61 assert(h == fb->zsbuf->height); 62 } 63 64 so_method(so, tesla, NV50TCL_ZETA_ADDRESS_HIGH, 5); 65 so_reloc (so, fb->zsbuf->buffer, fb->zsbuf->offset, 66 NOUVEAU_BO_VRAM | NOUVEAU_BO_HIGH, 0, 0); 67 so_reloc (so, fb->zsbuf->buffer, fb->zsbuf->offset, 68 NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW, 0, 0); 69 switch (fb->zsbuf->format) { 70 case PIPE_FORMAT_Z24S8_UNORM: 71 so_data(so, 0x16); 72 break; 73 case PIPE_FORMAT_Z16_UNORM: 74 so_data(so, 0x15); 75 break; 76 default: 77 { 78 char fmt[128]; 79 pf_sprint_name(fmt, fb->zsbuf->format); 80 NOUVEAU_ERR("AIIII unknown format %s\n", fmt); 81 } 82 so_data(so, 0x16); 83 break; 84 } 85 so_data(so, 0x00000040); 86 so_data(so, 0x00000000); 87 88 so_method(so, tesla, 0x1538, 1); 89 so_data (so, 1); 90 so_method(so, tesla, 0x1228, 3); 91 so_data (so, fb->zsbuf->width); 92 so_data (so, fb->zsbuf->height); 93 so_data (so, 0x00010001); 94 } 95 96 so_method(so, tesla, NV50TCL_VIEWPORT_HORIZ, 2); 97 so_data (so, w << 16); 98 so_data (so, h << 16); 99 so_method(so, tesla, 0xff4, 2); 100 so_data (so, w << 16); 101 so_data (so, h << 16); 102 so_method(so, tesla, 0xdf8, 2); 103 so_data (so, 0); 104 so_data (so, h); 105 106 so_ref(so, &nv50->state.fb); 107} 108 109static void 110nv50_state_emit(struct nv50_context *nv50) 111{ 112 struct nv50_screen *screen = nv50->screen; 113 struct nouveau_winsys *nvws = screen->nvws; 114 115 if (nv50->pctx_id != screen->cur_pctx) { 116 nv50->state.dirty |= 0xffffffff; 117 screen->cur_pctx = nv50->pctx_id; 118 } 119 120 if (nv50->state.dirty & NV50_NEW_FRAMEBUFFER) 121 so_emit(nvws, nv50->state.fb); 122 if (nv50->state.dirty & NV50_NEW_BLEND) 123 so_emit(nvws, nv50->state.blend); 124 if (nv50->state.dirty & NV50_NEW_ZSA) 125 so_emit(nvws, nv50->state.zsa); 126 if (nv50->state.dirty & NV50_NEW_VERTPROG) 127 so_emit(nvws, nv50->state.vertprog); 128 if (nv50->state.dirty & NV50_NEW_FRAGPROG) 129 so_emit(nvws, nv50->state.fragprog); 130 if (nv50->state.dirty & NV50_NEW_RASTERIZER) 131 so_emit(nvws, nv50->state.rast); 132 if (nv50->state.dirty & NV50_NEW_BLEND_COLOUR) 133 so_emit(nvws, nv50->state.blend_colour); 134 if (nv50->state.dirty & NV50_NEW_STIPPLE) 135 so_emit(nvws, nv50->state.stipple); 136 if (nv50->state.dirty & NV50_NEW_SCISSOR) 137 so_emit(nvws, nv50->state.scissor); 138 if (nv50->state.dirty & NV50_NEW_VIEWPORT) 139 so_emit(nvws, nv50->state.viewport); 140 if (nv50->state.dirty & NV50_NEW_SAMPLER) 141 so_emit(nvws, nv50->state.tsc_upload); 142 if (nv50->state.dirty & NV50_NEW_TEXTURE) 143 so_emit(nvws, nv50->state.tic_upload); 144 if (nv50->state.dirty & NV50_NEW_ARRAYS) { 145 so_emit(nvws, nv50->state.vtxfmt); 146 so_emit(nvws, nv50->state.vtxbuf); 147 } 148 nv50->state.dirty = 0; 149 150 so_emit_reloc_markers(nvws, nv50->state.fb); 151 so_emit_reloc_markers(nvws, nv50->state.vertprog); 152 so_emit_reloc_markers(nvws, nv50->state.fragprog); 153 so_emit_reloc_markers(nvws, nv50->state.vtxbuf); 154 so_emit_reloc_markers(nvws, nv50->screen->static_init); 155} 156 157boolean 158nv50_state_validate(struct nv50_context *nv50) 159{ 160 const struct pipe_framebuffer_state *fb = &nv50->framebuffer; 161 struct nouveau_grobj *tesla = nv50->screen->tesla; 162 struct nouveau_stateobj *so; 163 unsigned i; 164 165 for (i = 0; i < fb->num_cbufs; i++) 166 fb->cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED; 167 168 if (fb->zsbuf) 169 fb->zsbuf->status = PIPE_SURFACE_STATUS_DEFINED; 170 171 if (nv50->dirty & NV50_NEW_FRAMEBUFFER) 172 nv50_state_validate_fb(nv50); 173 174 if (nv50->dirty & NV50_NEW_BLEND) 175 so_ref(nv50->blend->so, &nv50->state.blend); 176 177 if (nv50->dirty & NV50_NEW_ZSA) 178 so_ref(nv50->zsa->so, &nv50->state.zsa); 179 180 if (nv50->dirty & (NV50_NEW_VERTPROG | NV50_NEW_VERTPROG_CB)) 181 nv50_vertprog_validate(nv50); 182 183 if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_FRAGPROG_CB)) 184 nv50_fragprog_validate(nv50); 185 186 if (nv50->dirty & NV50_NEW_RASTERIZER) 187 so_ref(nv50->rasterizer->so, &nv50->state.rast); 188 189 if (nv50->dirty & NV50_NEW_BLEND_COLOUR) { 190 so = so_new(5, 0); 191 so_method(so, tesla, NV50TCL_BLEND_COLOR(0), 4); 192 so_data (so, fui(nv50->blend_colour.color[0])); 193 so_data (so, fui(nv50->blend_colour.color[1])); 194 so_data (so, fui(nv50->blend_colour.color[2])); 195 so_data (so, fui(nv50->blend_colour.color[3])); 196 so_ref(so, &nv50->state.blend_colour); 197 } 198 199 if (nv50->dirty & NV50_NEW_STIPPLE) { 200 so = so_new(33, 0); 201 so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_PATTERN(0), 32); 202 for (i = 0; i < 32; i++) 203 so_data(so, nv50->stipple.stipple[i]); 204 so_ref(so, &nv50->state.stipple); 205 } 206 207 if (nv50->dirty & (NV50_NEW_SCISSOR | NV50_NEW_RASTERIZER)) { 208 struct pipe_rasterizer_state *rast = &nv50->rasterizer->pipe; 209 struct pipe_scissor_state *s = &nv50->scissor; 210 211 if (nv50->state.scissor && 212 (rast->scissor == 0 && nv50->state.scissor_enabled == 0)) 213 goto scissor_uptodate; 214 nv50->state.scissor_enabled = rast->scissor; 215 216 so = so_new(3, 0); 217 so_method(so, tesla, 0xff4, 2); //NV50TCL_SCISSOR_HORIZ, 2); 218 if (nv50->state.scissor_enabled) { 219 so_data(so, ((s->maxx - s->minx) << 16) | s->minx); 220 so_data(so, ((s->maxy - s->miny) << 16) | s->miny); 221 } else { 222 so_data(so, (8192 << 16)); 223 so_data(so, (8192 << 16)); 224 } 225 so_ref(so, &nv50->state.scissor); 226 nv50->state.dirty |= NV50_NEW_SCISSOR; 227 } 228scissor_uptodate: 229 230 if (nv50->dirty & NV50_NEW_VIEWPORT) { 231 so = so_new(8, 0); 232 so_method(so, tesla, NV50TCL_VIEWPORT_UNK0(0), 3); 233 so_data (so, fui(nv50->viewport.translate[0])); 234 so_data (so, fui(nv50->viewport.translate[1])); 235 so_data (so, fui(nv50->viewport.translate[2])); 236 so_method(so, tesla, NV50TCL_VIEWPORT_UNK1(0), 3); 237 so_data (so, fui(nv50->viewport.scale[0])); 238 so_data (so, fui(-nv50->viewport.scale[1])); 239 so_data (so, fui(nv50->viewport.scale[2])); 240 so_ref(so, &nv50->state.viewport); 241 } 242 243 if (nv50->dirty & NV50_NEW_SAMPLER) { 244 int i; 245 246 so = so_new(nv50->sampler_nr * 8 + 3, 0); 247 so_method(so, tesla, 0x0f00, 1); 248 so_data (so, NV50_CB_TSC); 249 so_method(so, tesla, 0x40000f04, nv50->sampler_nr * 8); 250 for (i = 0; i < nv50->sampler_nr; i++) 251 so_datap (so, nv50->sampler[i], 8); 252 so_ref(so, &nv50->state.tsc_upload); 253 } 254 255 if (nv50->dirty & NV50_NEW_TEXTURE) { 256 int i; 257 258 so = so_new(nv50->miptree_nr * 8 + 3, nv50->miptree_nr * 2); 259 so_method(so, tesla, 0x0f00, 1); 260 so_data (so, NV50_CB_TIC); 261 so_method(so, tesla, 0x40000f04, nv50->miptree_nr * 8); 262 for (i = 0; i < nv50->miptree_nr; i++) { 263 struct nv50_miptree *mt = nv50->miptree[i]; 264 265 so_data (so, 0x2a712488); 266 so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | 267 NOUVEAU_BO_LOW, 0, 0); 268 so_data (so, 0xd0c05000); 269 so_data (so, 0x00300000); 270 so_data (so, mt->base.width[0]); 271 so_data (so, (mt->base.depth[0] << 16) | 272 mt->base.height[0]); 273 so_data (so, 0x03000000); 274 so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | 275 NOUVEAU_BO_HIGH, 0, 0); 276 } 277 278 so_ref(so, &nv50->state.tic_upload); 279 } 280 281 if (nv50->dirty & NV50_NEW_ARRAYS) 282 nv50_vbo_validate(nv50); 283 284 nv50->state.dirty |= nv50->dirty; 285 nv50->dirty = 0; 286 nv50_state_emit(nv50); 287 288 return TRUE; 289} 290 291