Subversion Repositories Kolibri OS

Rev

Rev 4358 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
 
2
#include "os/os_time.h"
3
4
 
5
nv50_validate_fb(struct nv50_context *nv50)
6
{
7
   struct nouveau_pushbuf *push = nv50->base.pushbuf;
8
   struct pipe_framebuffer_state *fb = &nv50->framebuffer;
9
   unsigned i;
10
   unsigned ms_mode = NV50_3D_MULTISAMPLE_MODE_MS1;
11
   uint32_t array_size = 0xffff, array_mode = 0;
12
13
 
14
15
 
16
   PUSH_DATA (push, (076543210 << 4) | fb->nr_cbufs);
17
   BEGIN_NV04(push, NV50_3D(SCREEN_SCISSOR_HORIZ), 2);
18
   PUSH_DATA (push, fb->width << 16);
19
   PUSH_DATA (push, fb->height << 16);
20
21
 
22
      struct nv50_miptree *mt = nv50_miptree(fb->cbufs[i]->texture);
23
      struct nv50_surface *sf = nv50_surface(fb->cbufs[i]);
24
      struct nouveau_bo *bo = mt->base.bo;
25
26
 
27
      if (mt->layout_3d)
28
         array_mode = NV50_3D_RT_ARRAY_MODE_MODE_3D; /* 1 << 16 */
29
30
 
31
      assert(mt->layout_3d || !array_mode || array_size == 1);
32
33
 
34
      PUSH_DATAh(push, bo->offset + sf->offset);
35
      PUSH_DATA (push, bo->offset + sf->offset);
36
      PUSH_DATA (push, nv50_format_table[sf->base.format].rt);
37
      if (likely(nouveau_bo_memtype(bo))) {
38
         PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
39
         PUSH_DATA (push, mt->layer_stride >> 2);
40
         BEGIN_NV04(push, NV50_3D(RT_HORIZ(i)), 2);
41
         PUSH_DATA (push, sf->width);
42
         PUSH_DATA (push, sf->height);
43
         BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
44
         PUSH_DATA (push, array_mode | array_size);
45
      } else {
46
         PUSH_DATA (push, 0);
47
         PUSH_DATA (push, 0);
48
         BEGIN_NV04(push, NV50_3D(RT_HORIZ(i)), 2);
49
         PUSH_DATA (push, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch);
50
         PUSH_DATA (push, sf->height);
51
         BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
52
         PUSH_DATA (push, 0);
53
54
 
55
         assert(!mt->ms_mode);
56
      }
57
58
 
59
60
 
61
         nv50->state.rt_serialize = TRUE;
62
      mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
63
      mt->base.status &= ~NOUVEAU_BUFFER_STATUS_GPU_READING;
4401 Serge 64
4358 Serge 65
 
66
      BCTX_REFN(nv50->bufctx_3d, FB, &mt->base, WR);
67
   }
68
69
 
70
      struct nv50_miptree *mt = nv50_miptree(fb->zsbuf->texture);
71
      struct nv50_surface *sf = nv50_surface(fb->zsbuf);
72
      struct nouveau_bo *bo = mt->base.bo;
73
      int unk = mt->base.base.target == PIPE_TEXTURE_3D || sf->depth == 1;
74
75
 
76
      PUSH_DATAh(push, bo->offset + sf->offset);
77
      PUSH_DATA (push, bo->offset + sf->offset);
78
      PUSH_DATA (push, nv50_format_table[fb->zsbuf->format].rt);
79
      PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
80
      PUSH_DATA (push, mt->layer_stride >> 2);
81
      BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
82
      PUSH_DATA (push, 1);
83
      BEGIN_NV04(push, NV50_3D(ZETA_HORIZ), 3);
84
      PUSH_DATA (push, sf->width);
85
      PUSH_DATA (push, sf->height);
86
      PUSH_DATA (push, (unk << 16) | sf->depth);
87
88
 
89
90
 
91
         nv50->state.rt_serialize = TRUE;
92
      mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
93
      mt->base.status &= ~NOUVEAU_BUFFER_STATUS_GPU_READING;
4401 Serge 94
4358 Serge 95
 
96
   } else {
97
      BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
98
      PUSH_DATA (push, 0);
99
   }
100
101
 
102
   PUSH_DATA (push, ms_mode);
103
104
 
105
   PUSH_DATA (push, fb->width << 16);
106
   PUSH_DATA (push, fb->height << 16);
107
}
108
109
 
110
nv50_validate_blend_colour(struct nv50_context *nv50)
111
{
112
   struct nouveau_pushbuf *push = nv50->base.pushbuf;
113
114
 
115
   PUSH_DATAf(push, nv50->blend_colour.color[0]);
116
   PUSH_DATAf(push, nv50->blend_colour.color[1]);
117
   PUSH_DATAf(push, nv50->blend_colour.color[2]);
118
   PUSH_DATAf(push, nv50->blend_colour.color[3]);
119
}
120
121
 
122
nv50_validate_stencil_ref(struct nv50_context *nv50)
123
{
124
   struct nouveau_pushbuf *push = nv50->base.pushbuf;
125
126
 
127
   PUSH_DATA (push, nv50->stencil_ref.ref_value[0]);
128
   BEGIN_NV04(push, NV50_3D(STENCIL_BACK_FUNC_REF), 1);
129
   PUSH_DATA (push, nv50->stencil_ref.ref_value[1]);
130
}
131
132
 
133
nv50_validate_stipple(struct nv50_context *nv50)
134
{
135
   struct nouveau_pushbuf *push = nv50->base.pushbuf;
136
   unsigned i;
137
138
 
139
   for (i = 0; i < 32; ++i)
140
      PUSH_DATA(push, util_bswap32(nv50->stipple.stipple[i]));
141
}
142
143
 
144
nv50_validate_scissor(struct nv50_context *nv50)
145
{
146
   struct nouveau_pushbuf *push = nv50->base.pushbuf;
147
   struct pipe_scissor_state *s = &nv50->scissor;
148
#ifdef NV50_SCISSORS_CLIPPING
149
   struct pipe_viewport_state *vp = &nv50->viewport;
150
   int minx, maxx, miny, maxy;
151
152
 
153
         (NV50_NEW_SCISSOR | NV50_NEW_VIEWPORT | NV50_NEW_FRAMEBUFFER)) &&
154
       nv50->state.scissor == nv50->rast->pipe.scissor)
155
      return;
156
   nv50->state.scissor = nv50->rast->pipe.scissor;
157
158
 
159
      minx = s->minx;
160
      maxx = s->maxx;
161
      miny = s->miny;
162
      maxy = s->maxy;
163
   } else {
164
      minx = 0;
165
      maxx = nv50->framebuffer.width;
166
      miny = 0;
167
      maxy = nv50->framebuffer.height;
168
   }
169
170
 
171
   maxx = MIN2(maxx, (int)(vp->translate[0] + fabsf(vp->scale[0])));
172
   miny = MAX2(miny, (int)(vp->translate[1] - fabsf(vp->scale[1])));
173
   maxy = MIN2(maxy, (int)(vp->translate[1] + fabsf(vp->scale[1])));
174
175
 
176
   PUSH_DATA (push, (maxx << 16) | minx);
177
   PUSH_DATA (push, (maxy << 16) | miny);
178
#else
179
   BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2);
180
   PUSH_DATA (push, (s->maxx << 16) | s->minx);
181
   PUSH_DATA (push, (s->maxy << 16) | s->miny);
182
#endif
183
}
184
185
 
186
nv50_validate_viewport(struct nv50_context *nv50)
187
{
188
   struct nouveau_pushbuf *push = nv50->base.pushbuf;
189
   float zmin, zmax;
190
191
 
192
   PUSH_DATAf(push, nv50->viewport.translate[0]);
193
   PUSH_DATAf(push, nv50->viewport.translate[1]);
194
   PUSH_DATAf(push, nv50->viewport.translate[2]);
195
   BEGIN_NV04(push, NV50_3D(VIEWPORT_SCALE_X(0)), 3);
196
   PUSH_DATAf(push, nv50->viewport.scale[0]);
197
   PUSH_DATAf(push, nv50->viewport.scale[1]);
198
   PUSH_DATAf(push, nv50->viewport.scale[2]);
199
200
 
201
   zmax = nv50->viewport.translate[2] + fabsf(nv50->viewport.scale[2]);
202
203
 
204
   BEGIN_NV04(push, NV50_3D(DEPTH_RANGE_NEAR(0)), 2);
205
   PUSH_DATAf(push, zmin);
206
   PUSH_DATAf(push, zmax);
207
#endif
208
}
209
210
 
211
nv50_check_program_ucps(struct nv50_context *nv50,
212
                        struct nv50_program *vp, uint8_t mask)
213
{
214
   const unsigned n = util_logbase2(mask) + 1;
215
216
 
217
      return;
218
   nv50_program_destroy(nv50, vp);
219
220
 
221
   if (likely(vp == nv50->vertprog)) {
222
      nv50->dirty |= NV50_NEW_VERTPROG;
223
      nv50_vertprog_validate(nv50);
224
   } else {
225
      nv50->dirty |= NV50_NEW_GMTYPROG;
226
      nv50_gmtyprog_validate(nv50);
227
   }
228
   nv50_fp_linkage_validate(nv50);
229
}
230
231
 
232
nv50_validate_clip(struct nv50_context *nv50)
233
{
234
   struct nouveau_pushbuf *push = nv50->base.pushbuf;
235
   struct nv50_program *vp;
236
   uint8_t clip_enable;
237
238
 
239
      BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
240
      PUSH_DATA (push, (0 << 8) | NV50_CB_AUX);
241
      BEGIN_NI04(push, NV50_3D(CB_DATA(0)), PIPE_MAX_CLIP_PLANES * 4);
242
      PUSH_DATAp(push, &nv50->clip.ucp[0][0], PIPE_MAX_CLIP_PLANES * 4);
243
   }
244
245
 
246
   if (likely(!vp))
247
      vp = nv50->vertprog;
248
249
 
250
251
 
252
   PUSH_DATA (push, clip_enable);
253
254
 
255
      nv50_check_program_ucps(nv50, vp, clip_enable);
256
}
257
258
 
259
nv50_validate_blend(struct nv50_context *nv50)
260
{
261
   struct nouveau_pushbuf *push = nv50->base.pushbuf;
262
263
 
264
   PUSH_DATAp(push, nv50->blend->state, nv50->blend->size);
265
}
266
267
 
268
nv50_validate_zsa(struct nv50_context *nv50)
269
{
270
   struct nouveau_pushbuf *push = nv50->base.pushbuf;
271
272
 
273
   PUSH_DATAp(push, nv50->zsa->state, nv50->zsa->size);
274
}
275
276
 
277
nv50_validate_rasterizer(struct nv50_context *nv50)
278
{
279
   struct nouveau_pushbuf *push = nv50->base.pushbuf;
280
281
 
282
   PUSH_DATAp(push, nv50->rast->state, nv50->rast->size);
283
}
284
285
 
286
nv50_validate_sample_mask(struct nv50_context *nv50)
287
{
288
   struct nouveau_pushbuf *push = nv50->base.pushbuf;
289
290
 
291
   {
292
      nv50->sample_mask & 0xffff,
293
      nv50->sample_mask & 0xffff,
294
      nv50->sample_mask & 0xffff,
295
      nv50->sample_mask & 0xffff
296
   };
297
298
 
299
   PUSH_DATA (push, mask[0]);
300
   PUSH_DATA (push, mask[1]);
301
   PUSH_DATA (push, mask[2]);
302
   PUSH_DATA (push, mask[3]);
303
}
304
305
 
306
nv50_switch_pipe_context(struct nv50_context *ctx_to)
307
{
308
   struct nv50_context *ctx_from = ctx_to->screen->cur_ctx;
309
310
 
311
      ctx_to->state = ctx_from->state;
312
313
 
314
315
 
316
      ctx_to->dirty &= ~(NV50_NEW_VERTEX | NV50_NEW_ARRAYS);
317
318
 
319
      ctx_to->dirty &= ~NV50_NEW_VERTPROG;
320
   if (!ctx_to->fragprog)
321
      ctx_to->dirty &= ~NV50_NEW_FRAGPROG;
322
323
 
324
      ctx_to->dirty &= ~NV50_NEW_BLEND;
325
   if (!ctx_to->rast)
326
#ifdef NV50_SCISSORS_CLIPPING
327
      ctx_to->dirty &= ~(NV50_NEW_RASTERIZER | NV50_NEW_SCISSOR);
328
#else
329
      ctx_to->dirty &= ~NV50_NEW_RASTERIZER;
330
#endif
331
   if (!ctx_to->zsa)
332
      ctx_to->dirty &= ~NV50_NEW_ZSA;
333
334
 
335
}
336
337
 
338
    void (*func)(struct nv50_context *);
339
    uint32_t states;
340
} validate_list[] = {
341
    { nv50_validate_fb,            NV50_NEW_FRAMEBUFFER },
342
    { nv50_validate_blend,         NV50_NEW_BLEND },
343
    { nv50_validate_zsa,           NV50_NEW_ZSA },
344
    { nv50_validate_sample_mask,   NV50_NEW_SAMPLE_MASK },
345
    { nv50_validate_rasterizer,    NV50_NEW_RASTERIZER },
346
    { nv50_validate_blend_colour,  NV50_NEW_BLEND_COLOUR },
347
    { nv50_validate_stencil_ref,   NV50_NEW_STENCIL_REF },
348
    { nv50_validate_stipple,       NV50_NEW_STIPPLE },
349
#ifdef NV50_SCISSORS_CLIPPING
350
    { nv50_validate_scissor,       NV50_NEW_SCISSOR | NV50_NEW_VIEWPORT |
351
                                   NV50_NEW_RASTERIZER |
352
                                   NV50_NEW_FRAMEBUFFER },
353
#else
354
    { nv50_validate_scissor,       NV50_NEW_SCISSOR },
355
#endif
356
    { nv50_validate_viewport,      NV50_NEW_VIEWPORT },
357
    { nv50_vertprog_validate,      NV50_NEW_VERTPROG },
358
    { nv50_gmtyprog_validate,      NV50_NEW_GMTYPROG },
359
    { nv50_fragprog_validate,      NV50_NEW_FRAGPROG },
360
    { nv50_fp_linkage_validate,    NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG |
361
                                   NV50_NEW_GMTYPROG | NV50_NEW_RASTERIZER },
362
    { nv50_gp_linkage_validate,    NV50_NEW_GMTYPROG | NV50_NEW_VERTPROG },
363
    { nv50_validate_derived_rs,    NV50_NEW_FRAGPROG | NV50_NEW_RASTERIZER |
364
                                   NV50_NEW_VERTPROG | NV50_NEW_GMTYPROG },
365
    { nv50_validate_clip,          NV50_NEW_CLIP | NV50_NEW_RASTERIZER |
366
                                   NV50_NEW_VERTPROG | NV50_NEW_GMTYPROG },
367
    { nv50_constbufs_validate,     NV50_NEW_CONSTBUF },
368
    { nv50_validate_textures,      NV50_NEW_TEXTURES },
369
    { nv50_validate_samplers,      NV50_NEW_SAMPLERS },
370
    { nv50_stream_output_validate, NV50_NEW_STRMOUT |
371
                                   NV50_NEW_VERTPROG | NV50_NEW_GMTYPROG },
372
    { nv50_vertex_arrays_validate, NV50_NEW_VERTEX | NV50_NEW_ARRAYS }
373
};
374
#define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0]))
375
376
 
377
nv50_state_validate(struct nv50_context *nv50, uint32_t mask, unsigned words)
378
{
379
   uint32_t state_mask;
380
   int ret;
381
   unsigned i;
382
383
 
384
      nv50_switch_pipe_context(nv50);
385
386
 
387
388
 
389
      for (i = 0; i < validate_list_len; ++i) {
390
         struct state_validate *validate = &validate_list[i];
391
392
 
393
            validate->func(nv50);
394
      }
395
      nv50->dirty &= ~state_mask;
396
397
 
398
         nv50->state.rt_serialize = FALSE;
399
         BEGIN_NV04(nv50->base.pushbuf, SUBC_3D(NV50_GRAPH_SERIALIZE), 1);
400
         PUSH_DATA (nv50->base.pushbuf, 0);
401
      }
402
403
 
404
   }
405
   nouveau_pushbuf_bufctx(nv50->base.pushbuf, nv50->bufctx_3d);
406
   ret = nouveau_pushbuf_validate(nv50->base.pushbuf);
407
408
 
409
      nv50->state.flushed = FALSE;
410
      nv50_bufctx_fence(nv50->bufctx_3d, TRUE);
411
   }
412
   return !ret;
413
}
414