nv50_screen.c revision 1b749dc34f8d83cf3dfa863279b1fe2b356d34b2
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 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 * 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 32#ifndef NOUVEAU_GETPARAM_GRAPH_UNITS 33# define NOUVEAU_GETPARAM_GRAPH_UNITS 13 34#endif 35 36static boolean 37nv50_screen_is_format_supported(struct pipe_screen *pscreen, 38 enum pipe_format format, 39 enum pipe_texture_target target, 40 unsigned sample_count, 41 unsigned bindings) 42{ 43 if (!(0x117 & (1 << sample_count))) /* 0, 1, 2, 4 or 8 */ 44 return FALSE; 45 if (sample_count == 8 && util_format_get_blocksizebits(format) >= 128) 46 return FALSE; 47 48 if (!util_format_is_supported(format, bindings)) 49 return FALSE; 50 51 switch (format) { 52 case PIPE_FORMAT_Z16_UNORM: 53 if (nv50_screen(pscreen)->tesla->oclass < NVA0_3D_CLASS) 54 return FALSE; 55 break; 56 case PIPE_FORMAT_R8G8B8A8_UNORM: 57 case PIPE_FORMAT_R8G8B8X8_UNORM: 58 /* HACK: GL requires equal formats for MS resolve and window is BGRA */ 59 if (bindings & PIPE_BIND_RENDER_TARGET) 60 return FALSE; 61 default: 62 break; 63 } 64 65 /* transfers & shared are always supported */ 66 bindings &= ~(PIPE_BIND_TRANSFER_READ | 67 PIPE_BIND_TRANSFER_WRITE | 68 PIPE_BIND_SHARED); 69 70 return (nv50_format_table[format].usage & bindings) == bindings; 71} 72 73static int 74nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) 75{ 76 switch (param) { 77 case PIPE_CAP_MAX_COMBINED_SAMPLERS: 78 return 64; 79 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: 80 return 14; 81 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 82 return 12; 83 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 84 return 14; 85 case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: /* shader support missing */ 86 return 0; 87 case PIPE_CAP_MIN_TEXEL_OFFSET: 88 return -8; 89 case PIPE_CAP_MAX_TEXEL_OFFSET: 90 return 7; 91 case PIPE_CAP_TEXTURE_MIRROR_CLAMP: 92 case PIPE_CAP_TEXTURE_SWIZZLE: 93 case PIPE_CAP_TEXTURE_SHADOW_MAP: 94 case PIPE_CAP_NPOT_TEXTURES: 95 case PIPE_CAP_ANISOTROPIC_FILTER: 96 case PIPE_CAP_SCALED_RESOLVE: 97 return 1; 98 case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: 99 case PIPE_CAP_SEAMLESS_CUBE_MAP: 100 return nv50_screen(pscreen)->tesla->oclass >= NVA0_3D_CLASS; 101 case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: 102 return 0; 103 case PIPE_CAP_TWO_SIDED_STENCIL: 104 case PIPE_CAP_DEPTH_CLIP_DISABLE: 105 case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: 106 case PIPE_CAP_POINT_SPRITE: 107 return 1; 108 case PIPE_CAP_SM3: 109 return 1; 110 case PIPE_CAP_GLSL_FEATURE_LEVEL: 111 return 130; 112 case PIPE_CAP_MAX_RENDER_TARGETS: 113 return 8; 114 case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: 115 return 1; 116 case PIPE_CAP_FRAGMENT_COLOR_CLAMPED: 117 case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: 118 case PIPE_CAP_VERTEX_COLOR_CLAMPED: 119 return 1; 120 case PIPE_CAP_TIMER_QUERY: 121 case PIPE_CAP_OCCLUSION_QUERY: 122 return 1; 123 case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: 124 return 0; 125 case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: 126 return 128; 127 case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: 128 return 32; 129 case PIPE_CAP_BLEND_EQUATION_SEPARATE: 130 case PIPE_CAP_INDEP_BLEND_ENABLE: 131 return 1; 132 case PIPE_CAP_INDEP_BLEND_FUNC: 133 return nv50_screen(pscreen)->tesla->oclass >= NVA3_3D_CLASS; 134 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 135 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 136 return 1; 137 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: 138 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: 139 return 0; 140 case PIPE_CAP_SHADER_STENCIL_EXPORT: 141 return 0; 142 case PIPE_CAP_PRIMITIVE_RESTART: 143 case PIPE_CAP_TGSI_INSTANCEID: 144 case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: 145 case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: 146 case PIPE_CAP_CONDITIONAL_RENDER: 147 case PIPE_CAP_TEXTURE_BARRIER: 148 case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: 149 return 1; 150 case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS: 151 case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS: 152 return 0; /* state trackers will know better */ 153 case PIPE_CAP_USER_VERTEX_BUFFERS: 154 case PIPE_CAP_USER_INDEX_BUFFERS: 155 case PIPE_CAP_USER_CONSTANT_BUFFERS: 156 return 1; 157 case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: 158 return 256; 159 case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: 160 case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: 161 case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: 162 return 0; 163 default: 164 NOUVEAU_ERR("unknown PIPE_CAP %d\n", param); 165 return 0; 166 } 167} 168 169static int 170nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, 171 enum pipe_shader_cap param) 172{ 173 switch (shader) { 174 case PIPE_SHADER_VERTEX: 175 case PIPE_SHADER_GEOMETRY: 176 case PIPE_SHADER_FRAGMENT: 177 break; 178 default: 179 return 0; 180 } 181 182 switch (param) { 183 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 184 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 185 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 186 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 187 return 16384; 188 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 189 return 4; 190 case PIPE_SHADER_CAP_MAX_INPUTS: 191 if (shader == PIPE_SHADER_VERTEX) 192 return 32; 193 return 0x300 / 16; 194 case PIPE_SHADER_CAP_MAX_CONSTS: 195 return 65536 / 16; 196 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 197 return 14; 198 case PIPE_SHADER_CAP_MAX_ADDRS: 199 return 1; 200 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 201 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 202 return shader != PIPE_SHADER_FRAGMENT; 203 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 204 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 205 return 1; 206 case PIPE_SHADER_CAP_MAX_PREDS: 207 return 0; 208 case PIPE_SHADER_CAP_MAX_TEMPS: 209 return NV50_CAP_MAX_PROGRAM_TEMPS; 210 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: 211 return 1; 212 case PIPE_SHADER_CAP_SUBROUTINES: 213 return 0; /* please inline, or provide function declarations */ 214 case PIPE_SHADER_CAP_INTEGERS: 215 return 1; 216 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 217 return 32; 218 default: 219 NOUVEAU_ERR("unknown PIPE_SHADER_CAP %d\n", param); 220 return 0; 221 } 222} 223 224static float 225nv50_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param) 226{ 227 switch (param) { 228 case PIPE_CAPF_MAX_LINE_WIDTH: 229 case PIPE_CAPF_MAX_LINE_WIDTH_AA: 230 return 10.0f; 231 case PIPE_CAPF_MAX_POINT_WIDTH: 232 case PIPE_CAPF_MAX_POINT_WIDTH_AA: 233 return 64.0f; 234 case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: 235 return 16.0f; 236 case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: 237 return 4.0f; 238 default: 239 NOUVEAU_ERR("unknown PIPE_CAP %d\n", param); 240 return 0.0f; 241 } 242} 243 244static void 245nv50_screen_destroy(struct pipe_screen *pscreen) 246{ 247 struct nv50_screen *screen = nv50_screen(pscreen); 248 249 if (screen->base.fence.current) { 250 nouveau_fence_wait(screen->base.fence.current); 251 nouveau_fence_ref (NULL, &screen->base.fence.current); 252 } 253 if (screen->base.pushbuf) 254 screen->base.pushbuf->user_priv = NULL; 255 256 if (screen->blitctx) 257 FREE(screen->blitctx); 258 259 nouveau_bo_ref(NULL, &screen->code); 260 nouveau_bo_ref(NULL, &screen->tls_bo); 261 nouveau_bo_ref(NULL, &screen->stack_bo); 262 nouveau_bo_ref(NULL, &screen->txc); 263 nouveau_bo_ref(NULL, &screen->uniforms); 264 nouveau_bo_ref(NULL, &screen->fence.bo); 265 266 nouveau_heap_destroy(&screen->vp_code_heap); 267 nouveau_heap_destroy(&screen->gp_code_heap); 268 nouveau_heap_destroy(&screen->fp_code_heap); 269 270 if (screen->tic.entries) 271 FREE(screen->tic.entries); 272 273 nouveau_object_del(&screen->tesla); 274 nouveau_object_del(&screen->eng2d); 275 nouveau_object_del(&screen->m2mf); 276 nouveau_object_del(&screen->sync); 277 278 nouveau_screen_fini(&screen->base); 279 280 FREE(screen); 281} 282 283static void 284nv50_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence) 285{ 286 struct nv50_screen *screen = nv50_screen(pscreen); 287 struct nouveau_pushbuf *push = screen->base.pushbuf; 288 289 /* we need to do it after possible flush in MARK_RING */ 290 *sequence = ++screen->base.fence.sequence; 291 292 PUSH_DATA (push, NV50_FIFO_PKHDR(NV50_3D(QUERY_ADDRESS_HIGH), 4)); 293 PUSH_DATAh(push, screen->fence.bo->offset); 294 PUSH_DATA (push, screen->fence.bo->offset); 295 PUSH_DATA (push, *sequence); 296 PUSH_DATA (push, NV50_3D_QUERY_GET_MODE_WRITE_UNK0 | 297 NV50_3D_QUERY_GET_UNK4 | 298 NV50_3D_QUERY_GET_UNIT_CROP | 299 NV50_3D_QUERY_GET_TYPE_QUERY | 300 NV50_3D_QUERY_GET_QUERY_SELECT_ZERO | 301 NV50_3D_QUERY_GET_SHORT); 302} 303 304static u32 305nv50_screen_fence_update(struct pipe_screen *pscreen) 306{ 307 return nv50_screen(pscreen)->fence.map[0]; 308} 309 310static int 311nv50_screen_init_hwctx(struct nv50_screen *screen, unsigned tls_space) 312{ 313 struct nouveau_pushbuf *push = screen->base.pushbuf; 314 struct nv04_fifo *fifo; 315 unsigned i; 316 317 fifo = (struct nv04_fifo *)screen->base.channel->data; 318 319 BEGIN_NV04(push, SUBC_M2MF(NV01_SUBCHAN_OBJECT), 1); 320 PUSH_DATA (push, screen->m2mf->handle); 321 BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_DMA_NOTIFY), 3); 322 PUSH_DATA (push, screen->sync->handle); 323 PUSH_DATA (push, fifo->vram); 324 PUSH_DATA (push, fifo->vram); 325 326 BEGIN_NV04(push, SUBC_2D(NV01_SUBCHAN_OBJECT), 1); 327 PUSH_DATA (push, screen->eng2d->handle); 328 BEGIN_NV04(push, NV50_2D(DMA_NOTIFY), 4); 329 PUSH_DATA (push, screen->sync->handle); 330 PUSH_DATA (push, fifo->vram); 331 PUSH_DATA (push, fifo->vram); 332 PUSH_DATA (push, fifo->vram); 333 BEGIN_NV04(push, NV50_2D(OPERATION), 1); 334 PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY); 335 BEGIN_NV04(push, NV50_2D(CLIP_ENABLE), 1); 336 PUSH_DATA (push, 0); 337 BEGIN_NV04(push, NV50_2D(COLOR_KEY_ENABLE), 1); 338 PUSH_DATA (push, 0); 339 BEGIN_NV04(push, SUBC_2D(0x0888), 1); 340 PUSH_DATA (push, 1); 341 342 BEGIN_NV04(push, SUBC_3D(NV01_SUBCHAN_OBJECT), 1); 343 PUSH_DATA (push, screen->tesla->handle); 344 345 BEGIN_NV04(push, NV50_3D(COND_MODE), 1); 346 PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS); 347 348 BEGIN_NV04(push, NV50_3D(DMA_NOTIFY), 1); 349 PUSH_DATA (push, screen->sync->handle); 350 BEGIN_NV04(push, NV50_3D(DMA_ZETA), 11); 351 for (i = 0; i < 11; ++i) 352 PUSH_DATA(push, fifo->vram); 353 BEGIN_NV04(push, NV50_3D(DMA_COLOR(0)), NV50_3D_DMA_COLOR__LEN); 354 for (i = 0; i < NV50_3D_DMA_COLOR__LEN; ++i) 355 PUSH_DATA(push, fifo->vram); 356 357 BEGIN_NV04(push, NV50_3D(REG_MODE), 1); 358 PUSH_DATA (push, NV50_3D_REG_MODE_STRIPED); 359 BEGIN_NV04(push, NV50_3D(UNK1400_LANES), 1); 360 PUSH_DATA (push, 0xf); 361 362 if (debug_get_bool_option("NOUVEAU_SHADER_WATCHDOG", TRUE)) { 363 BEGIN_NV04(push, NV50_3D(WATCHDOG_TIMER), 1); 364 PUSH_DATA (push, 0x18); 365 } 366 367 BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1); 368 PUSH_DATA (push, 1); 369 370 BEGIN_NV04(push, NV50_3D(CSAA_ENABLE), 1); 371 PUSH_DATA (push, 0); 372 BEGIN_NV04(push, NV50_3D(MULTISAMPLE_ENABLE), 1); 373 PUSH_DATA (push, 0); 374 BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1); 375 PUSH_DATA (push, NV50_3D_MULTISAMPLE_MODE_MS1); 376 BEGIN_NV04(push, NV50_3D(MULTISAMPLE_CTRL), 1); 377 PUSH_DATA (push, 0); 378 BEGIN_NV04(push, NV50_3D(LINE_LAST_PIXEL), 1); 379 PUSH_DATA (push, 0); 380 BEGIN_NV04(push, NV50_3D(BLEND_SEPARATE_ALPHA), 1); 381 PUSH_DATA (push, 1); 382 383 if (screen->tesla->oclass >= NVA0_3D_CLASS) { 384 BEGIN_NV04(push, SUBC_3D(NVA0_3D_TEX_MISC), 1); 385 PUSH_DATA (push, NVA0_3D_TEX_MISC_SEAMLESS_CUBE_MAP); 386 } 387 388 BEGIN_NV04(push, NV50_3D(SCREEN_Y_CONTROL), 1); 389 PUSH_DATA (push, 0); 390 BEGIN_NV04(push, NV50_3D(WINDOW_OFFSET_X), 2); 391 PUSH_DATA (push, 0); 392 PUSH_DATA (push, 0); 393 BEGIN_NV04(push, NV50_3D(ZCULL_REGION), 1); 394 PUSH_DATA (push, 0x3f); 395 396 BEGIN_NV04(push, NV50_3D(VP_ADDRESS_HIGH), 2); 397 PUSH_DATAh(push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2)); 398 PUSH_DATA (push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2)); 399 400 BEGIN_NV04(push, NV50_3D(FP_ADDRESS_HIGH), 2); 401 PUSH_DATAh(push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2)); 402 PUSH_DATA (push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2)); 403 404 BEGIN_NV04(push, NV50_3D(GP_ADDRESS_HIGH), 2); 405 PUSH_DATAh(push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2)); 406 PUSH_DATA (push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2)); 407 408 BEGIN_NV04(push, NV50_3D(LOCAL_ADDRESS_HIGH), 3); 409 PUSH_DATAh(push, screen->tls_bo->offset); 410 PUSH_DATA (push, screen->tls_bo->offset); 411 PUSH_DATA (push, util_logbase2(tls_space / 8)); 412 413 BEGIN_NV04(push, NV50_3D(STACK_ADDRESS_HIGH), 3); 414 PUSH_DATAh(push, screen->stack_bo->offset); 415 PUSH_DATA (push, screen->stack_bo->offset); 416 PUSH_DATA (push, 4); 417 418 BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); 419 PUSH_DATAh(push, screen->uniforms->offset + (0 << 16)); 420 PUSH_DATA (push, screen->uniforms->offset + (0 << 16)); 421 PUSH_DATA (push, (NV50_CB_PVP << 16) | 0x0000); 422 423 BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); 424 PUSH_DATAh(push, screen->uniforms->offset + (1 << 16)); 425 PUSH_DATA (push, screen->uniforms->offset + (1 << 16)); 426 PUSH_DATA (push, (NV50_CB_PGP << 16) | 0x0000); 427 428 BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); 429 PUSH_DATAh(push, screen->uniforms->offset + (2 << 16)); 430 PUSH_DATA (push, screen->uniforms->offset + (2 << 16)); 431 PUSH_DATA (push, (NV50_CB_PFP << 16) | 0x0000); 432 433 BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); 434 PUSH_DATAh(push, screen->uniforms->offset + (3 << 16)); 435 PUSH_DATA (push, screen->uniforms->offset + (3 << 16)); 436 PUSH_DATA (push, (NV50_CB_AUX << 16) | 0x0200); 437 438 BEGIN_NI04(push, NV50_3D(SET_PROGRAM_CB), 6); 439 PUSH_DATA (push, (NV50_CB_PVP << 12) | 0x001); 440 PUSH_DATA (push, (NV50_CB_PGP << 12) | 0x021); 441 PUSH_DATA (push, (NV50_CB_PFP << 12) | 0x031); 442 PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf01); 443 PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf21); 444 PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf31); 445 446 /* max TIC (bits 4:8) & TSC bindings, per program type */ 447 for (i = 0; i < 3; ++i) { 448 BEGIN_NV04(push, NV50_3D(TEX_LIMITS(i)), 1); 449 PUSH_DATA (push, 0x54); 450 } 451 452 BEGIN_NV04(push, NV50_3D(TIC_ADDRESS_HIGH), 3); 453 PUSH_DATAh(push, screen->txc->offset); 454 PUSH_DATA (push, screen->txc->offset); 455 PUSH_DATA (push, NV50_TIC_MAX_ENTRIES - 1); 456 457 BEGIN_NV04(push, NV50_3D(TSC_ADDRESS_HIGH), 3); 458 PUSH_DATAh(push, screen->txc->offset + 65536); 459 PUSH_DATA (push, screen->txc->offset + 65536); 460 PUSH_DATA (push, NV50_TSC_MAX_ENTRIES - 1); 461 462 BEGIN_NV04(push, NV50_3D(LINKED_TSC), 1); 463 PUSH_DATA (push, 0); 464 465 BEGIN_NV04(push, NV50_3D(CLIP_RECTS_EN), 1); 466 PUSH_DATA (push, 0); 467 BEGIN_NV04(push, NV50_3D(CLIP_RECTS_MODE), 1); 468 PUSH_DATA (push, NV50_3D_CLIP_RECTS_MODE_INSIDE_ANY); 469 BEGIN_NV04(push, NV50_3D(CLIP_RECT_HORIZ(0)), 8 * 2); 470 for (i = 0; i < 8 * 2; ++i) 471 PUSH_DATA(push, 0); 472 BEGIN_NV04(push, NV50_3D(CLIPID_ENABLE), 1); 473 PUSH_DATA (push, 0); 474 475 BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1); 476 PUSH_DATA (push, 1); 477 BEGIN_NV04(push, NV50_3D(DEPTH_RANGE_NEAR(0)), 2); 478 PUSH_DATAf(push, 0.0f); 479 PUSH_DATAf(push, 1.0f); 480 481 BEGIN_NV04(push, NV50_3D(VIEW_VOLUME_CLIP_CTRL), 1); 482#ifdef NV50_SCISSORS_CLIPPING 483 PUSH_DATA (push, 0x0000); 484#else 485 PUSH_DATA (push, 0x1080); 486#endif 487 488 BEGIN_NV04(push, NV50_3D(CLEAR_FLAGS), 1); 489 PUSH_DATA (push, NV50_3D_CLEAR_FLAGS_CLEAR_RECT_VIEWPORT); 490 491 /* We use scissors instead of exact view volume clipping, 492 * so they're always enabled. 493 */ 494 BEGIN_NV04(push, NV50_3D(SCISSOR_ENABLE(0)), 3); 495 PUSH_DATA (push, 1); 496 PUSH_DATA (push, 8192 << 16); 497 PUSH_DATA (push, 8192 << 16); 498 499 BEGIN_NV04(push, NV50_3D(RASTERIZE_ENABLE), 1); 500 PUSH_DATA (push, 1); 501 BEGIN_NV04(push, NV50_3D(POINT_RASTER_RULES), 1); 502 PUSH_DATA (push, NV50_3D_POINT_RASTER_RULES_OGL); 503 BEGIN_NV04(push, NV50_3D(FRAG_COLOR_CLAMP_EN), 1); 504 PUSH_DATA (push, 0x11111111); 505 BEGIN_NV04(push, NV50_3D(EDGEFLAG), 1); 506 PUSH_DATA (push, 1); 507 508 PUSH_KICK (push); 509 510 return 0; 511} 512 513#define FAIL_SCREEN_INIT(str, err) \ 514 do { \ 515 NOUVEAU_ERR(str, err); \ 516 nv50_screen_destroy(pscreen); \ 517 return NULL; \ 518 } while(0) 519 520struct pipe_screen * 521nv50_screen_create(struct nouveau_device *dev) 522{ 523 struct nv50_screen *screen; 524 struct pipe_screen *pscreen; 525 struct nouveau_object *chan; 526 uint64_t value; 527 uint32_t tesla_class; 528 unsigned stack_size, max_warps, tls_space; 529 int ret; 530 531 screen = CALLOC_STRUCT(nv50_screen); 532 if (!screen) 533 return NULL; 534 pscreen = &screen->base.base; 535 536 screen->base.sysmem_bindings = PIPE_BIND_CONSTANT_BUFFER; 537 538 ret = nouveau_screen_init(&screen->base, dev); 539 if (ret) 540 FAIL_SCREEN_INIT("nouveau_screen_init failed: %d\n", ret); 541 542 screen->base.pushbuf->user_priv = screen; 543 screen->base.pushbuf->rsvd_kick = 5; 544 545 chan = screen->base.channel; 546 547 pscreen->destroy = nv50_screen_destroy; 548 pscreen->context_create = nv50_create; 549 pscreen->is_format_supported = nv50_screen_is_format_supported; 550 pscreen->get_param = nv50_screen_get_param; 551 pscreen->get_shader_param = nv50_screen_get_shader_param; 552 pscreen->get_paramf = nv50_screen_get_paramf; 553 554 nv50_screen_init_resource_functions(pscreen); 555 556 nouveau_screen_init_vdec(&screen->base); 557 558 ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, 559 NULL, &screen->fence.bo); 560 if (ret) 561 goto fail; 562 nouveau_bo_map(screen->fence.bo, 0, NULL); 563 screen->fence.map = screen->fence.bo->map; 564 screen->base.fence.emit = nv50_screen_fence_emit; 565 screen->base.fence.update = nv50_screen_fence_update; 566 567 ret = nouveau_object_new(chan, 0xbeef0301, NOUVEAU_NOTIFIER_CLASS, 568 &(struct nv04_notify){ .length = 32 }, 569 sizeof(struct nv04_notify), &screen->sync); 570 if (ret) 571 FAIL_SCREEN_INIT("Error allocating notifier: %d\n", ret); 572 573 574 ret = nouveau_object_new(chan, 0xbeef5039, NV50_M2MF_CLASS, 575 NULL, 0, &screen->m2mf); 576 if (ret) 577 FAIL_SCREEN_INIT("Error allocating PGRAPH context for M2MF: %d\n", ret); 578 579 580 ret = nouveau_object_new(chan, 0xbeef502d, NV50_2D_CLASS, 581 NULL, 0, &screen->eng2d); 582 if (ret) 583 FAIL_SCREEN_INIT("Error allocating PGRAPH context for 2D: %d\n", ret); 584 585 switch (dev->chipset & 0xf0) { 586 case 0x50: 587 tesla_class = NV50_3D_CLASS; 588 break; 589 case 0x80: 590 case 0x90: 591 tesla_class = NV84_3D_CLASS; 592 break; 593 case 0xa0: 594 switch (dev->chipset) { 595 case 0xa0: 596 case 0xaa: 597 case 0xac: 598 tesla_class = NVA0_3D_CLASS; 599 break; 600 case 0xaf: 601 tesla_class = NVAF_3D_CLASS; 602 break; 603 default: 604 tesla_class = NVA3_3D_CLASS; 605 break; 606 } 607 break; 608 default: 609 FAIL_SCREEN_INIT("Not a known NV50 chipset: NV%02x\n", dev->chipset); 610 break; 611 } 612 screen->base.class_3d = tesla_class; 613 614 ret = nouveau_object_new(chan, 0xbeef5097, tesla_class, 615 NULL, 0, &screen->tesla); 616 if (ret) 617 FAIL_SCREEN_INIT("Error allocating PGRAPH context for 3D: %d\n", ret); 618 619 620 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 621 3 << NV50_CODE_BO_SIZE_LOG2, NULL, &screen->code); 622 if (ret) 623 goto fail; 624 625 nouveau_heap_init(&screen->vp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2); 626 nouveau_heap_init(&screen->gp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2); 627 nouveau_heap_init(&screen->fp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2); 628 629 nouveau_getparam(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value); 630 631 max_warps = util_bitcount(value & 0xffff); 632 max_warps *= util_bitcount((value >> 24) & 0xf) * 32; 633 634 stack_size = max_warps * 64 * 8; 635 636 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, stack_size, NULL, 637 &screen->stack_bo); 638 if (ret) 639 FAIL_SCREEN_INIT("Failed to allocate stack bo: %d\n", ret); 640 641 tls_space = NV50_CAP_MAX_PROGRAM_TEMPS * 16; 642 643 screen->tls_size = tls_space * max_warps * 32; 644 645 if (nouveau_mesa_debug) 646 debug_printf("max_warps = %i, tls_size = %"PRIu64" KiB\n", 647 max_warps, screen->tls_size >> 10); 648 649 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, screen->tls_size, NULL, 650 &screen->tls_bo); 651 if (ret) 652 FAIL_SCREEN_INIT("Failed to allocate stack bo: %d\n", ret); 653 654 655 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 4 << 16, NULL, 656 &screen->uniforms); 657 if (ret) 658 goto fail; 659 660 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 3 << 16, NULL, 661 &screen->txc); 662 if (ret) 663 FAIL_SCREEN_INIT("Could not allocate TIC/TSC bo: %d\n", ret); 664 665 screen->tic.entries = CALLOC(4096, sizeof(void *)); 666 screen->tsc.entries = screen->tic.entries + 2048; 667 668 669 if (!nv50_blitctx_create(screen)) 670 goto fail; 671 672 if (nv50_screen_init_hwctx(screen, tls_space)) 673 goto fail; 674 675 nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE); 676 677 return pscreen; 678 679fail: 680 nv50_screen_destroy(pscreen); 681 return NULL; 682} 683 684int 685nv50_screen_tic_alloc(struct nv50_screen *screen, void *entry) 686{ 687 int i = screen->tic.next; 688 689 while (screen->tic.lock[i / 32] & (1 << (i % 32))) 690 i = (i + 1) & (NV50_TIC_MAX_ENTRIES - 1); 691 692 screen->tic.next = (i + 1) & (NV50_TIC_MAX_ENTRIES - 1); 693 694 if (screen->tic.entries[i]) 695 nv50_tic_entry(screen->tic.entries[i])->id = -1; 696 697 screen->tic.entries[i] = entry; 698 return i; 699} 700 701int 702nv50_screen_tsc_alloc(struct nv50_screen *screen, void *entry) 703{ 704 int i = screen->tsc.next; 705 706 while (screen->tsc.lock[i / 32] & (1 << (i % 32))) 707 i = (i + 1) & (NV50_TSC_MAX_ENTRIES - 1); 708 709 screen->tsc.next = (i + 1) & (NV50_TSC_MAX_ENTRIES - 1); 710 711 if (screen->tsc.entries[i]) 712 nv50_tsc_entry(screen->tsc.entries[i])->id = -1; 713 714 screen->tsc.entries[i] = entry; 715 return i; 716} 717