r600_pipe.c revision b97e41c7b18c363a303693fb841fe606b1106fe6
1/* 2 * Copyright 2010 Jerome Glisse <glisse@freedesktop.org> 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 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. 22 */ 23#include <stdio.h> 24#include <errno.h> 25#include <pipe/p_defines.h> 26#include <pipe/p_state.h> 27#include <pipe/p_context.h> 28#include <tgsi/tgsi_scan.h> 29#include <tgsi/tgsi_parse.h> 30#include <tgsi/tgsi_util.h> 31#include <util/u_blitter.h> 32#include <util/u_double_list.h> 33#include <util/u_format_s3tc.h> 34#include <util/u_transfer.h> 35#include <util/u_surface.h> 36#include <util/u_pack_color.h> 37#include <util/u_memory.h> 38#include <util/u_inlines.h> 39#include "util/u_upload_mgr.h" 40#include <pipebuffer/pb_buffer.h> 41#include "r600.h" 42#include "r600d.h" 43#include "r600_resource.h" 44#include "r600_shader.h" 45#include "r600_pipe.h" 46#include "r600_state_inlines.h" 47#include "r600_video_context.h" 48 49/* 50 * pipe_context 51 */ 52static void r600_flush(struct pipe_context *ctx, unsigned flags, 53 struct pipe_fence_handle **fence) 54{ 55 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 56#if 0 57 static int dc = 0; 58 char dname[256]; 59#endif 60 61 if (!rctx->ctx.pm4_cdwords) 62 return; 63 64#if 0 65 sprintf(dname, "gallium-%08d.bof", dc); 66 if (dc < 20) { 67 r600_context_dump_bof(&rctx->ctx, dname); 68 R600_ERR("dumped %s\n", dname); 69 } 70 dc++; 71#endif 72 r600_context_flush(&rctx->ctx); 73 74 /* XXX This shouldn't be really necessary, but removing it breaks some tests. 75 * Needless buffer reallocations may significantly increase memory consumption, 76 * so getting rid of this call is important. */ 77 u_upload_flush(rctx->vbuf_mgr->uploader); 78} 79 80static void r600_update_num_contexts(struct r600_screen *rscreen, int diff) 81{ 82 pipe_mutex_lock(rscreen->mutex_num_contexts); 83 if (diff > 0) { 84 rscreen->num_contexts++; 85 86 if (rscreen->num_contexts > 1) 87 util_slab_set_thread_safety(&rscreen->pool_buffers, 88 UTIL_SLAB_MULTITHREADED); 89 } else { 90 rscreen->num_contexts--; 91 92 if (rscreen->num_contexts <= 1) 93 util_slab_set_thread_safety(&rscreen->pool_buffers, 94 UTIL_SLAB_SINGLETHREADED); 95 } 96 pipe_mutex_unlock(rscreen->mutex_num_contexts); 97} 98 99static void r600_destroy_context(struct pipe_context *context) 100{ 101 struct r600_pipe_context *rctx = (struct r600_pipe_context *)context; 102 103 rctx->context.delete_depth_stencil_alpha_state(&rctx->context, rctx->custom_dsa_flush); 104 105 r600_context_fini(&rctx->ctx); 106 107 util_blitter_destroy(rctx->blitter); 108 109 for (int i = 0; i < R600_PIPE_NSTATES; i++) { 110 free(rctx->states[i]); 111 } 112 113 u_vbuf_mgr_destroy(rctx->vbuf_mgr); 114 util_slab_destroy(&rctx->pool_transfers); 115 116 r600_update_num_contexts(rctx->screen, -1); 117 118 FREE(rctx); 119} 120 121static struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv) 122{ 123 struct r600_pipe_context *rctx = CALLOC_STRUCT(r600_pipe_context); 124 struct r600_screen* rscreen = (struct r600_screen *)screen; 125 enum chip_class class; 126 127 if (rctx == NULL) 128 return NULL; 129 130 r600_update_num_contexts(rscreen, 1); 131 132 rctx->context.winsys = rscreen->screen.winsys; 133 rctx->context.screen = screen; 134 rctx->context.priv = priv; 135 rctx->context.destroy = r600_destroy_context; 136 rctx->context.flush = r600_flush; 137 138 /* Easy accessing of screen/winsys. */ 139 rctx->screen = rscreen; 140 rctx->radeon = rscreen->radeon; 141 rctx->family = r600_get_family(rctx->radeon); 142 143 r600_init_blit_functions(rctx); 144 r600_init_query_functions(rctx); 145 r600_init_context_resource_functions(rctx); 146 r600_init_surface_functions(rctx); 147 rctx->context.draw_vbo = r600_draw_vbo; 148 149 switch (r600_get_family(rctx->radeon)) { 150 case CHIP_R600: 151 case CHIP_RV610: 152 case CHIP_RV630: 153 case CHIP_RV670: 154 case CHIP_RV620: 155 case CHIP_RV635: 156 case CHIP_RS780: 157 case CHIP_RS880: 158 case CHIP_RV770: 159 case CHIP_RV730: 160 case CHIP_RV710: 161 case CHIP_RV740: 162 r600_init_state_functions(rctx); 163 if (r600_context_init(&rctx->ctx, rctx->radeon)) { 164 r600_destroy_context(&rctx->context); 165 return NULL; 166 } 167 r600_init_config(rctx); 168 break; 169 case CHIP_CEDAR: 170 case CHIP_REDWOOD: 171 case CHIP_JUNIPER: 172 case CHIP_CYPRESS: 173 case CHIP_HEMLOCK: 174 case CHIP_PALM: 175 case CHIP_BARTS: 176 case CHIP_TURKS: 177 case CHIP_CAICOS: 178 evergreen_init_state_functions(rctx); 179 if (evergreen_context_init(&rctx->ctx, rctx->radeon)) { 180 r600_destroy_context(&rctx->context); 181 return NULL; 182 } 183 evergreen_init_config(rctx); 184 break; 185 default: 186 R600_ERR("unsupported family %d\n", r600_get_family(rctx->radeon)); 187 r600_destroy_context(&rctx->context); 188 return NULL; 189 } 190 191 util_slab_create(&rctx->pool_transfers, 192 sizeof(struct pipe_transfer), 64, 193 UTIL_SLAB_SINGLETHREADED); 194 195 rctx->vbuf_mgr = u_vbuf_mgr_create(&rctx->context, 1024 * 1024, 256, 196 PIPE_BIND_VERTEX_BUFFER | 197 PIPE_BIND_INDEX_BUFFER | 198 PIPE_BIND_CONSTANT_BUFFER, 199 U_VERTEX_FETCH_DWORD_ALIGNED); 200 if (!rctx->vbuf_mgr) { 201 r600_destroy_context(&rctx->context); 202 return NULL; 203 } 204 205 rctx->blitter = util_blitter_create(&rctx->context); 206 if (rctx->blitter == NULL) { 207 r600_destroy_context(&rctx->context); 208 return NULL; 209 } 210 211 class = r600_get_family_class(rctx->radeon); 212 if (class == R600 || class == R700) 213 rctx->custom_dsa_flush = r600_create_db_flush_dsa(rctx); 214 else 215 rctx->custom_dsa_flush = evergreen_create_db_flush_dsa(rctx); 216 217 return &rctx->context; 218} 219 220/* 221 * pipe_screen 222 */ 223static const char* r600_get_vendor(struct pipe_screen* pscreen) 224{ 225 return "X.Org"; 226} 227 228static const char *r600_get_family_name(enum radeon_family family) 229{ 230 switch(family) { 231 case CHIP_R600: return "AMD R600"; 232 case CHIP_RV610: return "AMD RV610"; 233 case CHIP_RV630: return "AMD RV630"; 234 case CHIP_RV670: return "AMD RV670"; 235 case CHIP_RV620: return "AMD RV620"; 236 case CHIP_RV635: return "AMD RV635"; 237 case CHIP_RS780: return "AMD RS780"; 238 case CHIP_RS880: return "AMD RS880"; 239 case CHIP_RV770: return "AMD RV770"; 240 case CHIP_RV730: return "AMD RV730"; 241 case CHIP_RV710: return "AMD RV710"; 242 case CHIP_RV740: return "AMD RV740"; 243 case CHIP_CEDAR: return "AMD CEDAR"; 244 case CHIP_REDWOOD: return "AMD REDWOOD"; 245 case CHIP_JUNIPER: return "AMD JUNIPER"; 246 case CHIP_CYPRESS: return "AMD CYPRESS"; 247 case CHIP_HEMLOCK: return "AMD HEMLOCK"; 248 case CHIP_PALM: return "AMD PALM"; 249 case CHIP_BARTS: return "AMD BARTS"; 250 case CHIP_TURKS: return "AMD TURKS"; 251 case CHIP_CAICOS: return "AMD CAICOS"; 252 default: return "AMD unknown"; 253 } 254} 255 256static const char* r600_get_name(struct pipe_screen* pscreen) 257{ 258 struct r600_screen *rscreen = (struct r600_screen *)pscreen; 259 enum radeon_family family = r600_get_family(rscreen->radeon); 260 261 return r600_get_family_name(family); 262} 263 264static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) 265{ 266 struct r600_screen *rscreen = (struct r600_screen *)pscreen; 267 enum radeon_family family = r600_get_family(rscreen->radeon); 268 269 switch (param) { 270 /* Supported features (boolean caps). */ 271 case PIPE_CAP_NPOT_TEXTURES: 272 case PIPE_CAP_TWO_SIDED_STENCIL: 273 case PIPE_CAP_GLSL: 274 case PIPE_CAP_DUAL_SOURCE_BLEND: 275 case PIPE_CAP_ANISOTROPIC_FILTER: 276 case PIPE_CAP_POINT_SPRITE: 277 case PIPE_CAP_OCCLUSION_QUERY: 278 case PIPE_CAP_TEXTURE_SHADOW_MAP: 279 case PIPE_CAP_TEXTURE_MIRROR_CLAMP: 280 case PIPE_CAP_TEXTURE_MIRROR_REPEAT: 281 case PIPE_CAP_BLEND_EQUATION_SEPARATE: 282 case PIPE_CAP_SM3: 283 case PIPE_CAP_TEXTURE_SWIZZLE: 284 case PIPE_CAP_INDEP_BLEND_ENABLE: 285 case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: 286 case PIPE_CAP_DEPTH_CLAMP: 287 case PIPE_CAP_SHADER_STENCIL_EXPORT: 288 case PIPE_CAP_INSTANCED_DRAWING: 289 return 1; 290 291 /* Unsupported features (boolean caps). */ 292 case PIPE_CAP_STREAM_OUTPUT: 293 case PIPE_CAP_PRIMITIVE_RESTART: 294 case PIPE_CAP_INDEP_BLEND_FUNC: /* FIXME allow this */ 295 return 0; 296 297 case PIPE_CAP_ARRAY_TEXTURES: 298 /* fix once the CS checker upstream is fixed */ 299 return debug_get_bool_option("R600_ARRAY_TEXTURE", FALSE); 300 301 /* Texturing. */ 302 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: 303 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 304 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 305 if (family >= CHIP_CEDAR) 306 return 15; 307 else 308 return 14; 309 case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: 310 /* FIXME allow this once infrastructure is there */ 311 return 16; 312 case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: 313 case PIPE_CAP_MAX_COMBINED_SAMPLERS: 314 return 16; 315 316 /* Render targets. */ 317 case PIPE_CAP_MAX_RENDER_TARGETS: 318 /* FIXME some r6xx are buggy and can only do 4 */ 319 return 8; 320 321 /* Fragment coordinate conventions. */ 322 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 323 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 324 return 1; 325 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: 326 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: 327 return 0; 328 329 /* Timer queries, present when the clock frequency is non zero. */ 330 case PIPE_CAP_TIMER_QUERY: 331 return r600_get_clock_crystal_freq(rscreen->radeon) != 0; 332 333 default: 334 R600_ERR("r600: unknown param %d\n", param); 335 return 0; 336 } 337} 338 339static float r600_get_paramf(struct pipe_screen* pscreen, enum pipe_cap param) 340{ 341 struct r600_screen *rscreen = (struct r600_screen *)pscreen; 342 enum radeon_family family = r600_get_family(rscreen->radeon); 343 344 switch (param) { 345 case PIPE_CAP_MAX_LINE_WIDTH: 346 case PIPE_CAP_MAX_LINE_WIDTH_AA: 347 case PIPE_CAP_MAX_POINT_WIDTH: 348 case PIPE_CAP_MAX_POINT_WIDTH_AA: 349 if (family >= CHIP_CEDAR) 350 return 16384.0f; 351 else 352 return 8192.0f; 353 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: 354 return 16.0f; 355 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: 356 return 16.0f; 357 default: 358 R600_ERR("r600: unsupported paramf %d\n", param); 359 return 0.0f; 360 } 361} 362 363static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, enum pipe_shader_cap param) 364{ 365 switch(shader) 366 { 367 case PIPE_SHADER_FRAGMENT: 368 case PIPE_SHADER_VERTEX: 369 break; 370 case PIPE_SHADER_GEOMETRY: 371 /* TODO: support and enable geometry programs */ 372 return 0; 373 default: 374 /* TODO: support tessellation on Evergreen */ 375 return 0; 376 } 377 378 /* TODO: all these should be fixed, since r600 surely supports much more! */ 379 switch (param) { 380 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 381 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 382 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 383 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 384 return 16384; 385 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 386 return 8; /* FIXME */ 387 case PIPE_SHADER_CAP_MAX_INPUTS: 388 if(shader == PIPE_SHADER_FRAGMENT) 389 return 10; 390 else 391 return 16; 392 case PIPE_SHADER_CAP_MAX_TEMPS: 393 return 256; //max native temporaries 394 case PIPE_SHADER_CAP_MAX_ADDRS: 395 return 1; //max native address registers/* FIXME Isn't this equal to TEMPS? */ 396 case PIPE_SHADER_CAP_MAX_CONSTS: 397 return 256; //max native parameters 398 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 399 return R600_MAX_CONST_BUFFERS; 400 case PIPE_SHADER_CAP_MAX_PREDS: 401 return 0; /* FIXME */ 402 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: 403 return 1; 404 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 405 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 406 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 407 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 408 return 1; 409 case PIPE_SHADER_CAP_SUBROUTINES: 410 return 0; 411 default: 412 return 0; 413 } 414} 415 416static boolean r600_is_format_supported(struct pipe_screen* screen, 417 enum pipe_format format, 418 enum pipe_texture_target target, 419 unsigned sample_count, 420 unsigned usage, 421 unsigned geom_flags) 422{ 423 unsigned retval = 0; 424 if (target >= PIPE_MAX_TEXTURE_TYPES) { 425 R600_ERR("r600: unsupported texture type %d\n", target); 426 return FALSE; 427 } 428 429 /* Multisample */ 430 if (sample_count > 1) 431 return FALSE; 432 433 if ((usage & PIPE_BIND_SAMPLER_VIEW) && 434 r600_is_sampler_format_supported(format)) { 435 retval |= PIPE_BIND_SAMPLER_VIEW; 436 } 437 438 if ((usage & (PIPE_BIND_RENDER_TARGET | 439 PIPE_BIND_DISPLAY_TARGET | 440 PIPE_BIND_SCANOUT | 441 PIPE_BIND_SHARED)) && 442 r600_is_colorbuffer_format_supported(format)) { 443 retval |= usage & 444 (PIPE_BIND_RENDER_TARGET | 445 PIPE_BIND_DISPLAY_TARGET | 446 PIPE_BIND_SCANOUT | 447 PIPE_BIND_SHARED); 448 } 449 450 if ((usage & PIPE_BIND_DEPTH_STENCIL) && 451 r600_is_zs_format_supported(format)) { 452 retval |= PIPE_BIND_DEPTH_STENCIL; 453 } 454 455 if (usage & PIPE_BIND_VERTEX_BUFFER) { 456 struct r600_screen *rscreen = (struct r600_screen *)screen; 457 enum radeon_family family = r600_get_family(rscreen->radeon); 458 459 if (r600_is_vertex_format_supported(format, family)) { 460 retval |= PIPE_BIND_VERTEX_BUFFER; 461 } 462 } 463 464 if (usage & PIPE_BIND_TRANSFER_READ) 465 retval |= PIPE_BIND_TRANSFER_READ; 466 if (usage & PIPE_BIND_TRANSFER_WRITE) 467 retval |= PIPE_BIND_TRANSFER_WRITE; 468 469 return retval == usage; 470} 471 472static void r600_destroy_screen(struct pipe_screen* pscreen) 473{ 474 struct r600_screen *rscreen = (struct r600_screen *)pscreen; 475 476 if (rscreen == NULL) 477 return; 478 479 radeon_decref(rscreen->radeon); 480 481 util_slab_destroy(&rscreen->pool_buffers); 482 pipe_mutex_destroy(rscreen->mutex_num_contexts); 483 FREE(rscreen); 484} 485 486 487struct pipe_screen *r600_screen_create(struct radeon *radeon) 488{ 489 struct r600_screen *rscreen; 490 491 rscreen = CALLOC_STRUCT(r600_screen); 492 if (rscreen == NULL) { 493 return NULL; 494 } 495 496 rscreen->radeon = radeon; 497 rscreen->screen.winsys = (struct pipe_winsys*)radeon; 498 rscreen->screen.destroy = r600_destroy_screen; 499 rscreen->screen.get_name = r600_get_name; 500 rscreen->screen.get_vendor = r600_get_vendor; 501 rscreen->screen.get_param = r600_get_param; 502 rscreen->screen.get_shader_param = r600_get_shader_param; 503 rscreen->screen.get_paramf = r600_get_paramf; 504 rscreen->screen.is_format_supported = r600_is_format_supported; 505 rscreen->screen.context_create = r600_create_context; 506 rscreen->screen.video_context_create = r600_video_create; 507 r600_init_screen_resource_functions(&rscreen->screen); 508 509 rscreen->tiling_info = r600_get_tiling_info(radeon); 510 util_format_s3tc_init(); 511 512 util_slab_create(&rscreen->pool_buffers, 513 sizeof(struct r600_resource_buffer), 64, 514 UTIL_SLAB_SINGLETHREADED); 515 516 pipe_mutex_init(rscreen->mutex_num_contexts); 517 518 return &rscreen->screen; 519} 520