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
 * Copyright 2010 Christoph Bumiller
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * copy of this software and associated documentation files (the "Software"),
6
 * to deal in the Software without restriction, including without limitation
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
 * and/or sell copies of the Software, and to permit persons to whom the
9
 * Software is furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice shall be included in
12
 * all copies or substantial portions of the Software.
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20
 * OTHER DEALINGS IN THE SOFTWARE.
21
 */
22
 
23
#include "util/u_format.h"
24
#include "util/u_format_s3tc.h"
25
#include "pipe/p_screen.h"
26
 
27
#include "nv50_context.h"
28
#include "nv50_screen.h"
29
 
30
#include "nouveau/nv_object.xml.h"
31
#include 
32
 
33
#ifndef NOUVEAU_GETPARAM_GRAPH_UNITS
34
# define NOUVEAU_GETPARAM_GRAPH_UNITS 13
35
#endif
36
 
37
/* affected by LOCAL_WARPS_LOG_ALLOC / LOCAL_WARPS_NO_CLAMP */
38
#define LOCAL_WARPS_ALLOC 32
39
/* affected by STACK_WARPS_LOG_ALLOC / STACK_WARPS_NO_CLAMP */
40
#define STACK_WARPS_ALLOC 32
41
 
42
#define THREADS_IN_WARP 32
43
 
44
#define ONE_TEMP_SIZE (4/*vector*/ * sizeof(float))
45
 
46
static boolean
47
nv50_screen_is_format_supported(struct pipe_screen *pscreen,
48
                                enum pipe_format format,
49
                                enum pipe_texture_target target,
50
                                unsigned sample_count,
51
                                unsigned bindings)
52
{
53
   if (sample_count > 8)
54
      return FALSE;
55
   if (!(0x117 & (1 << sample_count))) /* 0, 1, 2, 4 or 8 */
56
      return FALSE;
57
   if (sample_count == 8 && util_format_get_blocksizebits(format) >= 128)
58
      return FALSE;
59
 
60
   if (!util_format_is_supported(format, bindings))
61
      return FALSE;
62
 
63
   switch (format) {
64
   case PIPE_FORMAT_Z16_UNORM:
65
      if (nv50_screen(pscreen)->tesla->oclass < NVA0_3D_CLASS)
66
         return FALSE;
67
      break;
68
   default:
69
      break;
70
   }
71
 
72
   /* transfers & shared are always supported */
73
   bindings &= ~(PIPE_BIND_TRANSFER_READ |
74
                 PIPE_BIND_TRANSFER_WRITE |
75
                 PIPE_BIND_SHARED);
76
 
77
   return (nv50_format_table[format].usage & bindings) == bindings;
78
}
79
 
80
static int
81
nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
82
{
83
   const uint16_t class_3d = nouveau_screen(pscreen)->class_3d;
84
 
85
   switch (param) {
86
   case PIPE_CAP_MAX_COMBINED_SAMPLERS:
87
      return 64;
88
   case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
89
      return 14;
90
   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
91
      return 12;
92
   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
93
      return 14;
94
   case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
95
      return 512;
96
   case PIPE_CAP_MIN_TEXEL_OFFSET:
97
      return -8;
98
   case PIPE_CAP_MAX_TEXEL_OFFSET:
99
      return 7;
100
   case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
101
   case PIPE_CAP_TEXTURE_SWIZZLE:
102
   case PIPE_CAP_TEXTURE_SHADOW_MAP:
103
   case PIPE_CAP_NPOT_TEXTURES:
104
   case PIPE_CAP_ANISOTROPIC_FILTER:
105
   case PIPE_CAP_SCALED_RESOLVE:
106
   case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
107
      return 1;
108
   case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
109
      return 65536;
110
   case PIPE_CAP_SEAMLESS_CUBE_MAP:
111
      return nv50_screen(pscreen)->tesla->oclass >= NVA0_3D_CLASS;
112
   case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
113
      return 0;
114
   case PIPE_CAP_CUBE_MAP_ARRAY:
115
      return 0;
116
      /*
117
      return nv50_screen(pscreen)->tesla->oclass >= NVA3_3D_CLASS;
118
      */
119
   case PIPE_CAP_TWO_SIDED_STENCIL:
120
   case PIPE_CAP_DEPTH_CLIP_DISABLE:
121
   case PIPE_CAP_POINT_SPRITE:
122
      return 1;
123
   case PIPE_CAP_SM3:
124
      return 1;
125
   case PIPE_CAP_GLSL_FEATURE_LEVEL:
126
      return 140;
127
   case PIPE_CAP_MAX_RENDER_TARGETS:
128
      return 8;
129
   case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
130
      return 1;
131
   case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
132
   case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
133
   case PIPE_CAP_VERTEX_COLOR_CLAMPED:
134
      return 1;
135
   case PIPE_CAP_QUERY_TIMESTAMP:
136
   case PIPE_CAP_QUERY_TIME_ELAPSED:
137
   case PIPE_CAP_OCCLUSION_QUERY:
138
      return 1;
139
   case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
140
      return 4;
141
   case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
142
   case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
143
      return 64;
144
   case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
145
      return (class_3d >= NVA0_3D_CLASS) ? 1 : 0;
146
   case PIPE_CAP_BLEND_EQUATION_SEPARATE:
147
   case PIPE_CAP_INDEP_BLEND_ENABLE:
148
      return 1;
149
   case PIPE_CAP_INDEP_BLEND_FUNC:
150
      return nv50_screen(pscreen)->tesla->oclass >= NVA3_3D_CLASS;
151
   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
152
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
153
      return 1;
154
   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
155
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
156
      return 0;
157
   case PIPE_CAP_SHADER_STENCIL_EXPORT:
158
      return 0;
159
   case PIPE_CAP_PRIMITIVE_RESTART:
160
   case PIPE_CAP_TGSI_INSTANCEID:
161
   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
162
   case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
163
   case PIPE_CAP_CONDITIONAL_RENDER:
164
   case PIPE_CAP_TEXTURE_BARRIER:
165
   case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
166
   case PIPE_CAP_START_INSTANCE:
167
      return 1;
168
   case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
169
      return 0; /* state trackers will know better */
170
   case PIPE_CAP_USER_CONSTANT_BUFFERS:
171
   case PIPE_CAP_USER_INDEX_BUFFERS:
172
   case PIPE_CAP_USER_VERTEX_BUFFERS:
173
      return 1;
174
   case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
175
      return 256;
176
   case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
177
      return 1; /* 256 for binding as RT, but that's not possible in GL */
178
   case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
179
      return NOUVEAU_MIN_BUFFER_MAP_ALIGN;
180
   case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
181
   case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
182
   case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
183
   case PIPE_CAP_TGSI_TEXCOORD:
184
   case PIPE_CAP_TEXTURE_MULTISAMPLE:
185
      return 0;
186
   case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
187
      return 1;
188
   case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
189
      return 0;
190
   case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
191
      return PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50;
192
   case PIPE_CAP_ENDIANNESS:
193
      return PIPE_ENDIAN_LITTLE;
194
   default:
195
      NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
196
      return 0;
197
   }
198
}
199
 
200
static int
201
nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
202
                             enum pipe_shader_cap param)
203
{
204
   switch (shader) {
205
   case PIPE_SHADER_VERTEX:
206
   case PIPE_SHADER_GEOMETRY:
207
   case PIPE_SHADER_FRAGMENT:
208
      break;
209
   default:
210
      return 0;
211
   }
212
 
213
   switch (param) {
214
   case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
215
   case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
216
   case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
217
   case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
218
      return 16384;
219
   case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
220
      return 4;
221
   case PIPE_SHADER_CAP_MAX_INPUTS:
222
      if (shader == PIPE_SHADER_VERTEX)
223
         return 32;
4401 Serge 224
      return 15;
4358 Serge 225
   case PIPE_SHADER_CAP_MAX_CONSTS:
226
      return 65536 / 16;
227
   case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
228
      return NV50_MAX_PIPE_CONSTBUFS;
229
   case PIPE_SHADER_CAP_MAX_ADDRS:
230
      return 1;
231
   case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
232
   case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
233
      return shader != PIPE_SHADER_FRAGMENT;
234
   case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
235
   case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
236
      return 1;
237
   case PIPE_SHADER_CAP_MAX_PREDS:
238
      return 0;
239
   case PIPE_SHADER_CAP_MAX_TEMPS:
240
      return nv50_screen(pscreen)->max_tls_space / ONE_TEMP_SIZE;
241
   case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
242
      return 1;
243
   case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
244
      return 0;
245
   case PIPE_SHADER_CAP_SUBROUTINES:
246
      return 0; /* please inline, or provide function declarations */
247
   case PIPE_SHADER_CAP_INTEGERS:
248
      return 1;
249
   case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
250
      return 32;
251
   default:
252
      NOUVEAU_ERR("unknown PIPE_SHADER_CAP %d\n", param);
253
      return 0;
254
   }
255
}
256
 
257
static float
258
nv50_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
259
{
260
   switch (param) {
261
   case PIPE_CAPF_MAX_LINE_WIDTH:
262
   case PIPE_CAPF_MAX_LINE_WIDTH_AA:
263
      return 10.0f;
264
   case PIPE_CAPF_MAX_POINT_WIDTH:
265
   case PIPE_CAPF_MAX_POINT_WIDTH_AA:
266
      return 64.0f;
267
   case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
268
      return 16.0f;
269
   case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
270
      return 4.0f;
271
   default:
272
      NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
273
      return 0.0f;
274
   }
275
}
276
 
277
static void
278
nv50_screen_destroy(struct pipe_screen *pscreen)
279
{
280
   struct nv50_screen *screen = nv50_screen(pscreen);
281
 
282
   if (screen->base.fence.current) {
283
      nouveau_fence_wait(screen->base.fence.current);
284
      nouveau_fence_ref (NULL, &screen->base.fence.current);
285
   }
286
   if (screen->base.pushbuf)
287
      screen->base.pushbuf->user_priv = NULL;
288
 
289
   if (screen->blitter)
290
      nv50_blitter_destroy(screen);
291
 
292
   nouveau_bo_ref(NULL, &screen->code);
293
   nouveau_bo_ref(NULL, &screen->tls_bo);
294
   nouveau_bo_ref(NULL, &screen->stack_bo);
295
   nouveau_bo_ref(NULL, &screen->txc);
296
   nouveau_bo_ref(NULL, &screen->uniforms);
297
   nouveau_bo_ref(NULL, &screen->fence.bo);
298
 
299
   nouveau_heap_destroy(&screen->vp_code_heap);
300
   nouveau_heap_destroy(&screen->gp_code_heap);
301
   nouveau_heap_destroy(&screen->fp_code_heap);
302
 
303
   FREE(screen->tic.entries);
304
 
305
   nouveau_object_del(&screen->tesla);
306
   nouveau_object_del(&screen->eng2d);
307
   nouveau_object_del(&screen->m2mf);
308
   nouveau_object_del(&screen->sync);
309
 
310
   nouveau_screen_fini(&screen->base);
311
 
312
   FREE(screen);
313
}
314
 
315
static void
316
nv50_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence)
317
{
318
   struct nv50_screen *screen = nv50_screen(pscreen);
319
   struct nouveau_pushbuf *push = screen->base.pushbuf;
320
 
321
   /* we need to do it after possible flush in MARK_RING */
322
   *sequence = ++screen->base.fence.sequence;
323
 
324
   PUSH_DATA (push, NV50_FIFO_PKHDR(NV50_3D(QUERY_ADDRESS_HIGH), 4));
325
   PUSH_DATAh(push, screen->fence.bo->offset);
326
   PUSH_DATA (push, screen->fence.bo->offset);
327
   PUSH_DATA (push, *sequence);
328
   PUSH_DATA (push, NV50_3D_QUERY_GET_MODE_WRITE_UNK0 |
329
                    NV50_3D_QUERY_GET_UNK4 |
330
                    NV50_3D_QUERY_GET_UNIT_CROP |
331
                    NV50_3D_QUERY_GET_TYPE_QUERY |
332
                    NV50_3D_QUERY_GET_QUERY_SELECT_ZERO |
333
                    NV50_3D_QUERY_GET_SHORT);
334
}
335
 
336
static u32
337
nv50_screen_fence_update(struct pipe_screen *pscreen)
338
{
339
   return nv50_screen(pscreen)->fence.map[0];
340
}
341
 
342
static void
343
nv50_screen_init_hwctx(struct nv50_screen *screen)
344
{
345
   struct nouveau_pushbuf *push = screen->base.pushbuf;
346
   struct nv04_fifo *fifo;
347
   unsigned i;
348
 
349
   fifo = (struct nv04_fifo *)screen->base.channel->data;
350
 
351
   BEGIN_NV04(push, SUBC_M2MF(NV01_SUBCHAN_OBJECT), 1);
352
   PUSH_DATA (push, screen->m2mf->handle);
353
   BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_DMA_NOTIFY), 3);
354
   PUSH_DATA (push, screen->sync->handle);
355
   PUSH_DATA (push, fifo->vram);
356
   PUSH_DATA (push, fifo->vram);
357
 
358
   BEGIN_NV04(push, SUBC_2D(NV01_SUBCHAN_OBJECT), 1);
359
   PUSH_DATA (push, screen->eng2d->handle);
360
   BEGIN_NV04(push, NV50_2D(DMA_NOTIFY), 4);
361
   PUSH_DATA (push, screen->sync->handle);
362
   PUSH_DATA (push, fifo->vram);
363
   PUSH_DATA (push, fifo->vram);
364
   PUSH_DATA (push, fifo->vram);
365
   BEGIN_NV04(push, NV50_2D(OPERATION), 1);
366
   PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY);
367
   BEGIN_NV04(push, NV50_2D(CLIP_ENABLE), 1);
368
   PUSH_DATA (push, 0);
369
   BEGIN_NV04(push, NV50_2D(COLOR_KEY_ENABLE), 1);
370
   PUSH_DATA (push, 0);
371
   BEGIN_NV04(push, SUBC_2D(0x0888), 1);
372
   PUSH_DATA (push, 1);
373
 
374
   BEGIN_NV04(push, SUBC_3D(NV01_SUBCHAN_OBJECT), 1);
375
   PUSH_DATA (push, screen->tesla->handle);
376
 
377
   BEGIN_NV04(push, NV50_3D(COND_MODE), 1);
378
   PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS);
379
 
380
   BEGIN_NV04(push, NV50_3D(DMA_NOTIFY), 1);
381
   PUSH_DATA (push, screen->sync->handle);
382
   BEGIN_NV04(push, NV50_3D(DMA_ZETA), 11);
383
   for (i = 0; i < 11; ++i)
384
      PUSH_DATA(push, fifo->vram);
385
   BEGIN_NV04(push, NV50_3D(DMA_COLOR(0)), NV50_3D_DMA_COLOR__LEN);
386
   for (i = 0; i < NV50_3D_DMA_COLOR__LEN; ++i)
387
      PUSH_DATA(push, fifo->vram);
388
 
389
   BEGIN_NV04(push, NV50_3D(REG_MODE), 1);
390
   PUSH_DATA (push, NV50_3D_REG_MODE_STRIPED);
391
   BEGIN_NV04(push, NV50_3D(UNK1400_LANES), 1);
392
   PUSH_DATA (push, 0xf);
393
 
394
   if (debug_get_bool_option("NOUVEAU_SHADER_WATCHDOG", TRUE)) {
395
      BEGIN_NV04(push, NV50_3D(WATCHDOG_TIMER), 1);
396
      PUSH_DATA (push, 0x18);
397
   }
398
 
399
   BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1);
400
   PUSH_DATA (push, 1);
401
 
402
   BEGIN_NV04(push, NV50_3D(CSAA_ENABLE), 1);
403
   PUSH_DATA (push, 0);
404
   BEGIN_NV04(push, NV50_3D(MULTISAMPLE_ENABLE), 1);
405
   PUSH_DATA (push, 0);
406
   BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1);
407
   PUSH_DATA (push, NV50_3D_MULTISAMPLE_MODE_MS1);
408
   BEGIN_NV04(push, NV50_3D(MULTISAMPLE_CTRL), 1);
409
   PUSH_DATA (push, 0);
410
   BEGIN_NV04(push, NV50_3D(LINE_LAST_PIXEL), 1);
411
   PUSH_DATA (push, 0);
412
   BEGIN_NV04(push, NV50_3D(BLEND_SEPARATE_ALPHA), 1);
413
   PUSH_DATA (push, 1);
414
 
415
   if (screen->tesla->oclass >= NVA0_3D_CLASS) {
416
      BEGIN_NV04(push, SUBC_3D(NVA0_3D_TEX_MISC), 1);
417
      PUSH_DATA (push, NVA0_3D_TEX_MISC_SEAMLESS_CUBE_MAP);
418
   }
419
 
420
   BEGIN_NV04(push, NV50_3D(SCREEN_Y_CONTROL), 1);
421
   PUSH_DATA (push, 0);
422
   BEGIN_NV04(push, NV50_3D(WINDOW_OFFSET_X), 2);
423
   PUSH_DATA (push, 0);
424
   PUSH_DATA (push, 0);
425
   BEGIN_NV04(push, NV50_3D(ZCULL_REGION), 1);
426
   PUSH_DATA (push, 0x3f);
427
 
428
   BEGIN_NV04(push, NV50_3D(VP_ADDRESS_HIGH), 2);
429
   PUSH_DATAh(push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2));
430
   PUSH_DATA (push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2));
431
 
432
   BEGIN_NV04(push, NV50_3D(FP_ADDRESS_HIGH), 2);
433
   PUSH_DATAh(push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2));
434
   PUSH_DATA (push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2));
435
 
436
   BEGIN_NV04(push, NV50_3D(GP_ADDRESS_HIGH), 2);
437
   PUSH_DATAh(push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2));
438
   PUSH_DATA (push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2));
439
 
440
   BEGIN_NV04(push, NV50_3D(LOCAL_ADDRESS_HIGH), 3);
441
   PUSH_DATAh(push, screen->tls_bo->offset);
442
   PUSH_DATA (push, screen->tls_bo->offset);
443
   PUSH_DATA (push, util_logbase2(screen->cur_tls_space / 8));
444
 
445
   BEGIN_NV04(push, NV50_3D(STACK_ADDRESS_HIGH), 3);
446
   PUSH_DATAh(push, screen->stack_bo->offset);
447
   PUSH_DATA (push, screen->stack_bo->offset);
448
   PUSH_DATA (push, 4);
449
 
450
   BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
451
   PUSH_DATAh(push, screen->uniforms->offset + (0 << 16));
452
   PUSH_DATA (push, screen->uniforms->offset + (0 << 16));
453
   PUSH_DATA (push, (NV50_CB_PVP << 16) | 0x0000);
454
 
455
   BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
456
   PUSH_DATAh(push, screen->uniforms->offset + (1 << 16));
457
   PUSH_DATA (push, screen->uniforms->offset + (1 << 16));
458
   PUSH_DATA (push, (NV50_CB_PGP << 16) | 0x0000);
459
 
460
   BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
461
   PUSH_DATAh(push, screen->uniforms->offset + (2 << 16));
462
   PUSH_DATA (push, screen->uniforms->offset + (2 << 16));
463
   PUSH_DATA (push, (NV50_CB_PFP << 16) | 0x0000);
464
 
465
   BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
466
   PUSH_DATAh(push, screen->uniforms->offset + (3 << 16));
467
   PUSH_DATA (push, screen->uniforms->offset + (3 << 16));
468
   PUSH_DATA (push, (NV50_CB_AUX << 16) | 0x0200);
469
 
470
   BEGIN_NI04(push, NV50_3D(SET_PROGRAM_CB), 3);
471
   PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf01);
472
   PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf21);
473
   PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf31);
474
 
475
   /* return { 0.0, 0.0, 0.0, 0.0 } on out-of-bounds vtxbuf access */
476
   BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
477
   PUSH_DATA (push, ((1 << 9) << 6) | NV50_CB_AUX);
478
   BEGIN_NI04(push, NV50_3D(CB_DATA(0)), 4);
479
   PUSH_DATAf(push, 0.0f);
480
   PUSH_DATAf(push, 0.0f);
481
   PUSH_DATAf(push, 0.0f);
482
   PUSH_DATAf(push, 0.0f);
483
   BEGIN_NV04(push, NV50_3D(VERTEX_RUNOUT_ADDRESS_HIGH), 2);
484
   PUSH_DATAh(push, screen->uniforms->offset + (3 << 16) + (1 << 9));
485
   PUSH_DATA (push, screen->uniforms->offset + (3 << 16) + (1 << 9));
486
 
487
   /* max TIC (bits 4:8) & TSC bindings, per program type */
488
   for (i = 0; i < 3; ++i) {
489
      BEGIN_NV04(push, NV50_3D(TEX_LIMITS(i)), 1);
490
      PUSH_DATA (push, 0x54);
491
   }
492
 
493
   BEGIN_NV04(push, NV50_3D(TIC_ADDRESS_HIGH), 3);
494
   PUSH_DATAh(push, screen->txc->offset);
495
   PUSH_DATA (push, screen->txc->offset);
496
   PUSH_DATA (push, NV50_TIC_MAX_ENTRIES - 1);
497
 
498
   BEGIN_NV04(push, NV50_3D(TSC_ADDRESS_HIGH), 3);
499
   PUSH_DATAh(push, screen->txc->offset + 65536);
500
   PUSH_DATA (push, screen->txc->offset + 65536);
501
   PUSH_DATA (push, NV50_TSC_MAX_ENTRIES - 1);
502
 
503
   BEGIN_NV04(push, NV50_3D(LINKED_TSC), 1);
504
   PUSH_DATA (push, 0);
505
 
506
   BEGIN_NV04(push, NV50_3D(CLIP_RECTS_EN), 1);
507
   PUSH_DATA (push, 0);
508
   BEGIN_NV04(push, NV50_3D(CLIP_RECTS_MODE), 1);
509
   PUSH_DATA (push, NV50_3D_CLIP_RECTS_MODE_INSIDE_ANY);
510
   BEGIN_NV04(push, NV50_3D(CLIP_RECT_HORIZ(0)), 8 * 2);
511
   for (i = 0; i < 8 * 2; ++i)
512
      PUSH_DATA(push, 0);
513
   BEGIN_NV04(push, NV50_3D(CLIPID_ENABLE), 1);
514
   PUSH_DATA (push, 0);
515
 
516
   BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1);
517
   PUSH_DATA (push, 1);
518
   BEGIN_NV04(push, NV50_3D(DEPTH_RANGE_NEAR(0)), 2);
519
   PUSH_DATAf(push, 0.0f);
520
   PUSH_DATAf(push, 1.0f);
521
 
522
   BEGIN_NV04(push, NV50_3D(VIEW_VOLUME_CLIP_CTRL), 1);
523
#ifdef NV50_SCISSORS_CLIPPING
524
   PUSH_DATA (push, 0x0000);
525
#else
526
   PUSH_DATA (push, 0x1080);
527
#endif
528
 
529
   BEGIN_NV04(push, NV50_3D(CLEAR_FLAGS), 1);
530
   PUSH_DATA (push, NV50_3D_CLEAR_FLAGS_CLEAR_RECT_VIEWPORT);
531
 
532
   /* We use scissors instead of exact view volume clipping,
533
    * so they're always enabled.
534
    */
535
   BEGIN_NV04(push, NV50_3D(SCISSOR_ENABLE(0)), 3);
536
   PUSH_DATA (push, 1);
537
   PUSH_DATA (push, 8192 << 16);
538
   PUSH_DATA (push, 8192 << 16);
539
 
540
   BEGIN_NV04(push, NV50_3D(RASTERIZE_ENABLE), 1);
541
   PUSH_DATA (push, 1);
542
   BEGIN_NV04(push, NV50_3D(POINT_RASTER_RULES), 1);
543
   PUSH_DATA (push, NV50_3D_POINT_RASTER_RULES_OGL);
544
   BEGIN_NV04(push, NV50_3D(FRAG_COLOR_CLAMP_EN), 1);
545
   PUSH_DATA (push, 0x11111111);
546
   BEGIN_NV04(push, NV50_3D(EDGEFLAG), 1);
547
   PUSH_DATA (push, 1);
548
 
549
   PUSH_KICK (push);
550
}
551
 
552
static int nv50_tls_alloc(struct nv50_screen *screen, unsigned tls_space,
553
      uint64_t *tls_size)
554
{
555
   struct nouveau_device *dev = screen->base.device;
556
   int ret;
557
 
558
   screen->cur_tls_space = util_next_power_of_two(tls_space / ONE_TEMP_SIZE) *
559
         ONE_TEMP_SIZE;
560
   if (nouveau_mesa_debug)
561
      debug_printf("allocating space for %u temps\n",
562
            util_next_power_of_two(tls_space / ONE_TEMP_SIZE));
563
   *tls_size = screen->cur_tls_space * util_next_power_of_two(screen->TPs) *
564
         screen->MPsInTP * LOCAL_WARPS_ALLOC * THREADS_IN_WARP;
565
 
566
   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16,
567
                        *tls_size, NULL, &screen->tls_bo);
568
   if (ret) {
569
      NOUVEAU_ERR("Failed to allocate local bo: %d\n", ret);
570
      return ret;
571
   }
572
 
573
   return 0;
574
}
575
 
576
int nv50_tls_realloc(struct nv50_screen *screen, unsigned tls_space)
577
{
578
   struct nouveau_pushbuf *push = screen->base.pushbuf;
579
   int ret;
580
   uint64_t tls_size;
581
 
582
   if (tls_space < screen->cur_tls_space)
583
      return 0;
584
   if (tls_space > screen->max_tls_space) {
585
      /* fixable by limiting number of warps (LOCAL_WARPS_LOG_ALLOC /
586
       * LOCAL_WARPS_NO_CLAMP) */
587
      NOUVEAU_ERR("Unsupported number of temporaries (%u > %u). Fixable if someone cares.\n",
588
            (unsigned)(tls_space / ONE_TEMP_SIZE),
589
            (unsigned)(screen->max_tls_space / ONE_TEMP_SIZE));
590
      return -ENOMEM;
591
   }
592
 
593
   nouveau_bo_ref(NULL, &screen->tls_bo);
594
   ret = nv50_tls_alloc(screen, tls_space, &tls_size);
595
   if (ret)
596
      return ret;
597
 
598
   BEGIN_NV04(push, NV50_3D(LOCAL_ADDRESS_HIGH), 3);
599
   PUSH_DATAh(push, screen->tls_bo->offset);
600
   PUSH_DATA (push, screen->tls_bo->offset);
601
   PUSH_DATA (push, util_logbase2(screen->cur_tls_space / 8));
602
 
603
   return 1;
604
}
605
 
606
struct pipe_screen *
607
nv50_screen_create(struct nouveau_device *dev)
608
{
609
   struct nv50_screen *screen;
610
   struct pipe_screen *pscreen;
611
   struct nouveau_object *chan;
612
   uint64_t value;
613
   uint32_t tesla_class;
614
   unsigned stack_size;
615
   int ret;
616
 
617
   screen = CALLOC_STRUCT(nv50_screen);
618
   if (!screen)
619
      return NULL;
620
   pscreen = &screen->base.base;
621
 
622
   ret = nouveau_screen_init(&screen->base, dev);
623
   if (ret) {
624
      NOUVEAU_ERR("nouveau_screen_init failed: %d\n", ret);
625
      goto fail;
626
   }
627
 
628
   /* TODO: Prevent FIFO prefetch before transfer of index buffers and
629
    *  admit them to VRAM.
630
    */
631
   screen->base.vidmem_bindings |= PIPE_BIND_CONSTANT_BUFFER |
632
      PIPE_BIND_VERTEX_BUFFER;
633
   screen->base.sysmem_bindings |=
634
      PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER;
635
 
636
   screen->base.pushbuf->user_priv = screen;
637
   screen->base.pushbuf->rsvd_kick = 5;
638
 
639
   chan = screen->base.channel;
640
 
641
   pscreen->destroy = nv50_screen_destroy;
642
   pscreen->context_create = nv50_create;
643
   pscreen->is_format_supported = nv50_screen_is_format_supported;
644
   pscreen->get_param = nv50_screen_get_param;
645
   pscreen->get_shader_param = nv50_screen_get_shader_param;
646
   pscreen->get_paramf = nv50_screen_get_paramf;
647
 
648
   nv50_screen_init_resource_functions(pscreen);
649
 
650
   if (screen->base.device->chipset < 0x84) {
651
      /* PMPEG */
652
      nouveau_screen_init_vdec(&screen->base);
653
   } else if (screen->base.device->chipset < 0x98 ||
654
              screen->base.device->chipset == 0xa0) {
655
      /* VP2 */
656
      screen->base.base.get_video_param = nv84_screen_get_video_param;
657
      screen->base.base.is_video_format_supported = nv84_screen_video_supported;
658
   } else {
659
      /* Unsupported, but need to init pointers. */
660
      nouveau_screen_init_vdec(&screen->base);
661
   }
662
 
663
   ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096,
664
                        NULL, &screen->fence.bo);
665
   if (ret) {
666
      NOUVEAU_ERR("Failed to allocate fence bo: %d\n", ret);
667
      goto fail;
668
   }
669
 
670
   nouveau_bo_map(screen->fence.bo, 0, NULL);
671
   screen->fence.map = screen->fence.bo->map;
672
   screen->base.fence.emit = nv50_screen_fence_emit;
673
   screen->base.fence.update = nv50_screen_fence_update;
674
 
675
   ret = nouveau_object_new(chan, 0xbeef0301, NOUVEAU_NOTIFIER_CLASS,
676
                            &(struct nv04_notify){ .length = 32 },
677
                            sizeof(struct nv04_notify), &screen->sync);
678
   if (ret) {
679
      NOUVEAU_ERR("Failed to allocate notifier: %d\n", ret);
680
      goto fail;
681
   }
682
 
683
   ret = nouveau_object_new(chan, 0xbeef5039, NV50_M2MF_CLASS,
684
                            NULL, 0, &screen->m2mf);
685
   if (ret) {
686
      NOUVEAU_ERR("Failed to allocate PGRAPH context for M2MF: %d\n", ret);
687
      goto fail;
688
   }
689
 
690
   ret = nouveau_object_new(chan, 0xbeef502d, NV50_2D_CLASS,
691
                            NULL, 0, &screen->eng2d);
692
   if (ret) {
693
      NOUVEAU_ERR("Failed to allocate PGRAPH context for 2D: %d\n", ret);
694
      goto fail;
695
   }
696
 
697
   switch (dev->chipset & 0xf0) {
698
   case 0x50:
699
      tesla_class = NV50_3D_CLASS;
700
      break;
701
   case 0x80:
702
   case 0x90:
703
      tesla_class = NV84_3D_CLASS;
704
      break;
705
   case 0xa0:
706
      switch (dev->chipset) {
707
      case 0xa0:
708
      case 0xaa:
709
      case 0xac:
710
         tesla_class = NVA0_3D_CLASS;
711
         break;
712
      case 0xaf:
713
         tesla_class = NVAF_3D_CLASS;
714
         break;
715
      default:
716
         tesla_class = NVA3_3D_CLASS;
717
         break;
718
      }
719
      break;
720
   default:
721
      NOUVEAU_ERR("Not a known NV50 chipset: NV%02x\n", dev->chipset);
722
      goto fail;
723
   }
724
   screen->base.class_3d = tesla_class;
725
 
726
   ret = nouveau_object_new(chan, 0xbeef5097, tesla_class,
727
                            NULL, 0, &screen->tesla);
728
   if (ret) {
729
      NOUVEAU_ERR("Failed to allocate PGRAPH context for 3D: %d\n", ret);
730
      goto fail;
731
   }
732
 
733
   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16,
734
                        3 << NV50_CODE_BO_SIZE_LOG2, NULL, &screen->code);
735
   if (ret) {
736
      NOUVEAU_ERR("Failed to allocate code bo: %d\n", ret);
737
      goto fail;
738
   }
739
 
740
   nouveau_heap_init(&screen->vp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
741
   nouveau_heap_init(&screen->gp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
742
   nouveau_heap_init(&screen->fp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
743
 
744
   nouveau_getparam(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value);
745
 
746
   screen->TPs = util_bitcount(value & 0xffff);
747
   screen->MPsInTP = util_bitcount((value >> 24) & 0xf);
748
 
749
   stack_size = util_next_power_of_two(screen->TPs) * screen->MPsInTP *
750
         STACK_WARPS_ALLOC * 64 * 8;
751
 
752
   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, stack_size, NULL,
753
                        &screen->stack_bo);
754
   if (ret) {
755
      NOUVEAU_ERR("Failed to allocate stack bo: %d\n", ret);
756
      goto fail;
757
   }
758
 
759
   uint64_t size_of_one_temp = util_next_power_of_two(screen->TPs) *
760
         screen->MPsInTP * LOCAL_WARPS_ALLOC *  THREADS_IN_WARP *
761
         ONE_TEMP_SIZE;
762
   screen->max_tls_space = dev->vram_size / size_of_one_temp * ONE_TEMP_SIZE;
763
   screen->max_tls_space /= 2; /* half of vram */
764
 
765
   /* hw can address max 64 KiB */
766
   screen->max_tls_space = MIN2(screen->max_tls_space, 64 << 10);
767
 
768
   uint64_t tls_size;
769
   unsigned tls_space = 4/*temps*/ * ONE_TEMP_SIZE;
770
   ret = nv50_tls_alloc(screen, tls_space, &tls_size);
771
   if (ret)
772
      goto fail;
773
 
774
   if (nouveau_mesa_debug)
775
      debug_printf("TPs = %u, MPsInTP = %u, VRAM = %"PRIu64" MiB, tls_size = %"PRIu64" KiB\n",
776
            screen->TPs, screen->MPsInTP, dev->vram_size >> 20, tls_size >> 10);
777
 
778
   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 4 << 16, NULL,
779
                        &screen->uniforms);
780
   if (ret) {
781
      NOUVEAU_ERR("Failed to allocate uniforms bo: %d\n", ret);
782
      goto fail;
783
   }
784
 
785
   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 3 << 16, NULL,
786
                        &screen->txc);
787
   if (ret) {
788
      NOUVEAU_ERR("Failed to allocate TIC/TSC bo: %d\n", ret);
789
      goto fail;
790
   }
791
 
792
   screen->tic.entries = CALLOC(4096, sizeof(void *));
793
   screen->tsc.entries = screen->tic.entries + 2048;
794
 
795
   if (!nv50_blitter_create(screen))
796
      goto fail;
797
 
798
   nv50_screen_init_hwctx(screen);
799
 
800
   nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE);
801
 
802
   return pscreen;
803
 
804
fail:
805
   nv50_screen_destroy(pscreen);
806
   return NULL;
807
}
808
 
809
int
810
nv50_screen_tic_alloc(struct nv50_screen *screen, void *entry)
811
{
812
   int i = screen->tic.next;
813
 
814
   while (screen->tic.lock[i / 32] & (1 << (i % 32)))
815
      i = (i + 1) & (NV50_TIC_MAX_ENTRIES - 1);
816
 
817
   screen->tic.next = (i + 1) & (NV50_TIC_MAX_ENTRIES - 1);
818
 
819
   if (screen->tic.entries[i])
820
      nv50_tic_entry(screen->tic.entries[i])->id = -1;
821
 
822
   screen->tic.entries[i] = entry;
823
   return i;
824
}
825
 
826
int
827
nv50_screen_tsc_alloc(struct nv50_screen *screen, void *entry)
828
{
829
   int i = screen->tsc.next;
830
 
831
   while (screen->tsc.lock[i / 32] & (1 << (i % 32)))
832
      i = (i + 1) & (NV50_TSC_MAX_ENTRIES - 1);
833
 
834
   screen->tsc.next = (i + 1) & (NV50_TSC_MAX_ENTRIES - 1);
835
 
836
   if (screen->tsc.entries[i])
837
      nv50_tsc_entry(screen->tsc.entries[i])->id = -1;
838
 
839
   screen->tsc.entries[i] = entry;
840
   return i;
841
}