nv50_state_validate.c revision 714cb4a86c1f503334b37ca6c24272fa1bdf7899
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 struct nouveau_grobj *tesla = nv50->screen->tesla; 161 struct nouveau_stateobj *so; 162 unsigned i; 163 164 if (nv50->dirty & NV50_NEW_FRAMEBUFFER) 165 nv50_state_validate_fb(nv50); 166 167 if (nv50->dirty & NV50_NEW_BLEND) 168 so_ref(nv50->blend->so, &nv50->state.blend); 169 170 if (nv50->dirty & NV50_NEW_ZSA) 171 so_ref(nv50->zsa->so, &nv50->state.zsa); 172 173 if (nv50->dirty & (NV50_NEW_VERTPROG | NV50_NEW_VERTPROG_CB)) 174 nv50_vertprog_validate(nv50); 175 176 if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_FRAGPROG_CB)) 177 nv50_fragprog_validate(nv50); 178 179 if (nv50->dirty & NV50_NEW_RASTERIZER) 180 so_ref(nv50->rasterizer->so, &nv50->state.rast); 181 182 if (nv50->dirty & NV50_NEW_BLEND_COLOUR) { 183 so = so_new(5, 0); 184 so_method(so, tesla, NV50TCL_BLEND_COLOR(0), 4); 185 so_data (so, fui(nv50->blend_colour.color[0])); 186 so_data (so, fui(nv50->blend_colour.color[1])); 187 so_data (so, fui(nv50->blend_colour.color[2])); 188 so_data (so, fui(nv50->blend_colour.color[3])); 189 so_ref(so, &nv50->state.blend_colour); 190 } 191 192 if (nv50->dirty & NV50_NEW_STIPPLE) { 193 so = so_new(33, 0); 194 so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_PATTERN(0), 32); 195 for (i = 0; i < 32; i++) 196 so_data(so, nv50->stipple.stipple[i]); 197 so_ref(so, &nv50->state.stipple); 198 } 199 200 if (nv50->dirty & (NV50_NEW_SCISSOR | NV50_NEW_RASTERIZER)) { 201 struct pipe_rasterizer_state *rast = &nv50->rasterizer->pipe; 202 struct pipe_scissor_state *s = &nv50->scissor; 203 204 if (nv50->state.scissor && 205 (rast->scissor == 0 && nv50->state.scissor_enabled == 0)) 206 goto scissor_uptodate; 207 nv50->state.scissor_enabled = rast->scissor; 208 209 so = so_new(3, 0); 210 so_method(so, tesla, 0xff4, 2); //NV50TCL_SCISSOR_HORIZ, 2); 211 if (nv50->state.scissor_enabled) { 212 so_data(so, ((s->maxx - s->minx) << 16) | s->minx); 213 so_data(so, ((s->maxy - s->miny) << 16) | s->miny); 214 } else { 215 so_data(so, (8192 << 16)); 216 so_data(so, (8192 << 16)); 217 } 218 so_ref(so, &nv50->state.scissor); 219 nv50->state.dirty |= NV50_NEW_SCISSOR; 220 } 221scissor_uptodate: 222 223 if (nv50->dirty & NV50_NEW_VIEWPORT) { 224 so = so_new(8, 0); 225 so_method(so, tesla, NV50TCL_VIEWPORT_UNK0(0), 3); 226 so_data (so, fui(nv50->viewport.translate[0])); 227 so_data (so, fui(nv50->viewport.translate[1])); 228 so_data (so, fui(nv50->viewport.translate[2])); 229 so_method(so, tesla, NV50TCL_VIEWPORT_UNK1(0), 3); 230 so_data (so, fui(nv50->viewport.scale[0])); 231 so_data (so, fui(-nv50->viewport.scale[1])); 232 so_data (so, fui(nv50->viewport.scale[2])); 233 so_ref(so, &nv50->state.viewport); 234 } 235 236 if (nv50->dirty & NV50_NEW_SAMPLER) { 237 int i; 238 239 so = so_new(nv50->sampler_nr * 8 + 3, 0); 240 so_method(so, tesla, 0x0f00, 1); 241 so_data (so, NV50_CB_TSC); 242 so_method(so, tesla, 0x40000f04, nv50->sampler_nr * 8); 243 for (i = 0; i < nv50->sampler_nr; i++) 244 so_datap (so, nv50->sampler[i], 8); 245 so_ref(so, &nv50->state.tsc_upload); 246 } 247 248 if (nv50->dirty & NV50_NEW_TEXTURE) { 249 int i; 250 251 so = so_new(nv50->miptree_nr * 8 + 3, nv50->miptree_nr * 2); 252 so_method(so, tesla, 0x0f00, 1); 253 so_data (so, NV50_CB_TIC); 254 so_method(so, tesla, 0x40000f04, nv50->miptree_nr * 8); 255 for (i = 0; i < nv50->miptree_nr; i++) { 256 struct nv50_miptree *mt = nv50->miptree[i]; 257 258 so_data (so, 0x2a712488); 259 so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | 260 NOUVEAU_BO_LOW, 0, 0); 261 so_data (so, 0xd0c05000); 262 so_data (so, 0x00300000); 263 so_data (so, mt->base.width[0]); 264 so_data (so, (mt->base.depth[0] << 16) | 265 mt->base.height[0]); 266 so_data (so, 0x03000000); 267 so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | 268 NOUVEAU_BO_HIGH, 0, 0); 269 } 270 271 so_ref(so, &nv50->state.tic_upload); 272 } 273 274 if (nv50->dirty & NV50_NEW_ARRAYS) 275 nv50_vbo_validate(nv50); 276 277 nv50->state.dirty |= nv50->dirty; 278 nv50->dirty = 0; 279 nv50_state_emit(nv50); 280 281 return TRUE; 282} 283 284