1 /* 2 * Permission is hereby granted, free of charge, to any person obtaining a 3 * copy of this software and associated documentation files (the "Software"), 4 * to deal in the Software without restriction, including without limitation 5 * on the rights to use, copy, modify, merge, publish, distribute, sub 6 * license, and/or sell copies of the Software, and to permit persons to whom 7 * the Software is furnished to do so, subject to the following conditions: 8 * 9 * The above copyright notice and this permission notice (including the next 10 * paragraph) shall be included in all copies or substantial portions of the 11 * Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 16 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 17 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 18 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 19 * USE OR OTHER DEALINGS IN THE SOFTWARE. 20 * 21 * Authors: 22 * Adam Rak <adam.rak (at) streamnovation.com> 23 */ 24 25 #include <stdlib.h> 26 #include <stdio.h> 27 28 #include "pipe/p_defines.h" 29 #include "pipe/p_state.h" 30 #include "pipe/p_context.h" 31 #include "util/u_blitter.h" 32 #include "util/u_double_list.h" 33 #include "util/u_transfer.h" 34 #include "util/u_surface.h" 35 #include "util/u_pack_color.h" 36 #include "util/u_memory.h" 37 #include "util/u_inlines.h" 38 #include "util/u_framebuffer.h" 39 #include "r600.h" 40 #include "r600_resource.h" 41 #include "r600_shader.h" 42 #include "r600_pipe.h" 43 #include "r600_formats.h" 44 #include "evergreend.h" 45 #include "evergreen_compute_internal.h" 46 #include "r600_hw_context_priv.h" 47 48 int get_compute_resource_num(void) 49 { 50 int num = 0; 51 #define DECL_COMPUTE_RESOURCE(name, n) num += n; 52 #include "compute_resource.def" 53 #undef DECL_COMPUTE_RESOURCE 54 return num; 55 } 56 57 void evergreen_emit_raw_value( 58 struct evergreen_compute_resource* res, 59 unsigned value) 60 { 61 res->cs[res->cs_end++] = value; 62 } 63 64 void evergreen_emit_ctx_value(struct r600_context *ctx, unsigned value) 65 { 66 ctx->cs->buf[ctx->cs->cdw++] = value; 67 } 68 69 void evergreen_mult_reg_set_( 70 struct evergreen_compute_resource* res, 71 int index, 72 u32* array, 73 int size) 74 { 75 int i = 0; 76 77 evergreen_emit_raw_reg_set(res, index, size / 4); 78 79 for (i = 0; i < size; i+=4) { 80 res->cs[res->cs_end++] = array[i / 4]; 81 } 82 } 83 84 void evergreen_reg_set( 85 struct evergreen_compute_resource* res, 86 unsigned index, 87 unsigned value) 88 { 89 evergreen_emit_raw_reg_set(res, index, 1); 90 res->cs[res->cs_end++] = value; 91 } 92 93 struct evergreen_compute_resource* get_empty_res( 94 struct r600_pipe_compute* pipe, 95 enum evergreen_compute_resources res_code, 96 int offset_index) 97 { 98 int code_index = -1; 99 int code_size = -1; 100 101 { 102 int i = 0; 103 #define DECL_COMPUTE_RESOURCE(name, n) if (COMPUTE_RESOURCE_ ## name == res_code) {code_index = i; code_size = n;} i += n; 104 #include "compute_resource.def" 105 #undef DECL_COMPUTE_RESOURCE 106 } 107 108 assert(code_index != -1 && "internal error: resouce index not found"); 109 assert(offset_index < code_size && "internal error: overindexing resource"); 110 111 int index = code_index + offset_index; 112 113 struct evergreen_compute_resource* res = &pipe->resources[index]; 114 115 res->enabled = true; 116 res->bo = NULL; 117 res->cs_end = 0; 118 bzero(&res->do_reloc, sizeof(res->do_reloc)); 119 120 return res; 121 } 122 123 void evergreen_emit_raw_reg_set( 124 struct evergreen_compute_resource* res, 125 unsigned index, 126 int num) 127 { 128 res->enabled = 1; 129 int cs_end = res->cs_end; 130 131 if (index >= EVERGREEN_CONFIG_REG_OFFSET 132 && index < EVERGREEN_CONFIG_REG_END) { 133 res->cs[cs_end] = PKT3C(PKT3_SET_CONFIG_REG, num, 0); 134 res->cs[cs_end+1] = (index - EVERGREEN_CONFIG_REG_OFFSET) >> 2; 135 } else if (index >= EVERGREEN_CONTEXT_REG_OFFSET 136 && index < EVERGREEN_CONTEXT_REG_END) { 137 res->cs[cs_end] = PKT3C(PKT3_SET_CONTEXT_REG, num, 0); 138 res->cs[cs_end+1] = (index - EVERGREEN_CONTEXT_REG_OFFSET) >> 2; 139 } else if (index >= EVERGREEN_RESOURCE_OFFSET 140 && index < EVERGREEN_RESOURCE_END) { 141 res->cs[cs_end] = PKT3C(PKT3_SET_RESOURCE, num, 0); 142 res->cs[cs_end+1] = (index - EVERGREEN_RESOURCE_OFFSET) >> 2; 143 } else if (index >= EVERGREEN_SAMPLER_OFFSET 144 && index < EVERGREEN_SAMPLER_END) { 145 res->cs[cs_end] = PKT3C(PKT3_SET_SAMPLER, num, 0); 146 res->cs[cs_end+1] = (index - EVERGREEN_SAMPLER_OFFSET) >> 2; 147 } else if (index >= EVERGREEN_CTL_CONST_OFFSET 148 && index < EVERGREEN_CTL_CONST_END) { 149 res->cs[cs_end] = PKT3C(PKT3_SET_CTL_CONST, num, 0); 150 res->cs[cs_end+1] = (index - EVERGREEN_CTL_CONST_OFFSET) >> 2; 151 } else if (index >= EVERGREEN_LOOP_CONST_OFFSET 152 && index < EVERGREEN_LOOP_CONST_END) { 153 res->cs[cs_end] = PKT3C(PKT3_SET_LOOP_CONST, num, 0); 154 res->cs[cs_end+1] = (index - EVERGREEN_LOOP_CONST_OFFSET) >> 2; 155 } else if (index >= EVERGREEN_BOOL_CONST_OFFSET 156 && index < EVERGREEN_BOOL_CONST_END) { 157 res->cs[cs_end] = PKT3C(PKT3_SET_BOOL_CONST, num, 0); 158 res->cs[cs_end+1] = (index - EVERGREEN_BOOL_CONST_OFFSET) >> 2; 159 } else { 160 res->cs[cs_end] = PKT0(index, num-1); 161 res->cs_end--; 162 } 163 164 res->cs_end += 2; 165 } 166 167 void evergreen_emit_force_reloc(struct evergreen_compute_resource* res) 168 { 169 res->do_reloc[res->cs_end] += 1; 170 } 171 172 void evergreen_emit_ctx_reg_set( 173 struct r600_context *ctx, 174 unsigned index, 175 int num) 176 { 177 178 if (index >= EVERGREEN_CONFIG_REG_OFFSET 179 && index < EVERGREEN_CONFIG_REG_END) { 180 ctx->cs->buf[ctx->cs->cdw++] = PKT3C(PKT3_SET_CONFIG_REG, num, 0); 181 ctx->cs->buf[ctx->cs->cdw++] = (index - EVERGREEN_CONFIG_REG_OFFSET) >> 2; 182 } else if (index >= EVERGREEN_CONTEXT_REG_OFFSET 183 && index < EVERGREEN_CONTEXT_REG_END) { 184 ctx->cs->buf[ctx->cs->cdw++] = PKT3C(PKT3_SET_CONTEXT_REG, num, 0); 185 ctx->cs->buf[ctx->cs->cdw++] = (index - EVERGREEN_CONTEXT_REG_OFFSET) >> 2; 186 } else if (index >= EVERGREEN_RESOURCE_OFFSET 187 && index < EVERGREEN_RESOURCE_END) { 188 ctx->cs->buf[ctx->cs->cdw++] = PKT3C(PKT3_SET_RESOURCE, num, 0); 189 ctx->cs->buf[ctx->cs->cdw++] = (index - EVERGREEN_RESOURCE_OFFSET) >> 2; 190 } else if (index >= EVERGREEN_SAMPLER_OFFSET 191 && index < EVERGREEN_SAMPLER_END) { 192 ctx->cs->buf[ctx->cs->cdw++] = PKT3C(PKT3_SET_SAMPLER, num, 0); 193 ctx->cs->buf[ctx->cs->cdw++] = (index - EVERGREEN_SAMPLER_OFFSET) >> 2; 194 } else if (index >= EVERGREEN_CTL_CONST_OFFSET 195 && index < EVERGREEN_CTL_CONST_END) { 196 ctx->cs->buf[ctx->cs->cdw++] = PKT3C(PKT3_SET_CTL_CONST, num, 0); 197 ctx->cs->buf[ctx->cs->cdw++] = (index - EVERGREEN_CTL_CONST_OFFSET) >> 2; 198 } else if (index >= EVERGREEN_LOOP_CONST_OFFSET 199 && index < EVERGREEN_LOOP_CONST_END) { 200 ctx->cs->buf[ctx->cs->cdw++] = PKT3C(PKT3_SET_LOOP_CONST, num, 0); 201 ctx->cs->buf[ctx->cs->cdw++] = (index - EVERGREEN_LOOP_CONST_OFFSET) >> 2; 202 } else if (index >= EVERGREEN_BOOL_CONST_OFFSET 203 && index < EVERGREEN_BOOL_CONST_END) { 204 ctx->cs->buf[ctx->cs->cdw++] = PKT3C(PKT3_SET_BOOL_CONST, num, 0); 205 ctx->cs->buf[ctx->cs->cdw++] = (index - EVERGREEN_BOOL_CONST_OFFSET) >> 2; 206 } else { 207 ctx->cs->buf[ctx->cs->cdw++] = PKT0(index, num-1); 208 } 209 } 210 211 void evergreen_emit_ctx_reloc( 212 struct r600_context *ctx, 213 struct r600_resource *bo, 214 enum radeon_bo_usage usage) 215 { 216 assert(bo); 217 218 ctx->cs->buf[ctx->cs->cdw++] = PKT3(PKT3_NOP, 0, 0); 219 u32 rr = r600_context_bo_reloc(ctx, bo, usage); 220 ctx->cs->buf[ctx->cs->cdw++] = rr; 221 } 222 223 int evergreen_compute_get_gpu_format( 224 struct number_type_and_format* fmt, 225 struct r600_resource *bo) 226 { 227 switch (bo->b.b.format) 228 { 229 case PIPE_FORMAT_R8_UNORM: 230 case PIPE_FORMAT_R32_UNORM: 231 case PIPE_FORMAT_R32_UINT: 232 fmt->format = V_028C70_COLOR_32; 233 fmt->number_type = V_028C70_NUMBER_UNORM; 234 fmt->num_format_all = 0; 235 break; 236 case PIPE_FORMAT_R32_FLOAT: 237 fmt->format = V_028C70_COLOR_32_FLOAT; 238 fmt->number_type = V_028C70_NUMBER_FLOAT; 239 fmt->num_format_all = 0; 240 break; 241 case PIPE_FORMAT_R32G32B32A32_FLOAT: 242 fmt->format = V_028C70_COLOR_32_32_32_32_FLOAT; 243 fmt->number_type = V_028C70_NUMBER_FLOAT; 244 fmt->num_format_all = 0; 245 break; 246 247 ///TODO: other formats... 248 249 default: 250 return 0; 251 } 252 253 return 1; 254 } 255 256 void evergreen_set_rat( 257 struct r600_pipe_compute *pipe, 258 int id, 259 struct r600_resource* bo, 260 int start, 261 int size) 262 { 263 assert(id < 12); 264 assert((size & 3) == 0); 265 assert((start & 0xFF) == 0); 266 267 struct r600_pipe_state * state = CALLOC_STRUCT(r600_pipe_state); 268 struct pipe_surface rat_templ; 269 struct r600_surface *surf; 270 struct r600_resource *res; 271 struct r600_context *rctx = pipe->ctx; 272 273 COMPUTE_DBG("bind rat: %i \n", id); 274 275 /* Create the RAT surface */ 276 memset(&rat_templ, 0, sizeof(rat_templ)); 277 rat_templ.usage = RADEON_USAGE_READWRITE; 278 rat_templ.format = PIPE_FORMAT_R32_UINT; 279 rat_templ.u.tex.level = 0; 280 rat_templ.u.tex.first_layer = 0; 281 rat_templ.u.tex.last_layer = 0; 282 283 /* Add the RAT the list of color buffers */ 284 pipe->ctx->framebuffer.cbufs[id] = pipe->ctx->context.create_surface( 285 (struct pipe_context *)pipe->ctx, 286 (struct pipe_resource *)bo, &rat_templ); 287 288 /* Update the number of color buffers */ 289 pipe->ctx->nr_cbufs = MAX2(id + 1, pipe->ctx->nr_cbufs); 290 291 /* Update the cb_target_mask 292 * XXX: I think this is a potential spot for bugs once we start doing 293 * GL interop. cb_target_mask may be modified in the 3D sections 294 * of this driver. */ 295 pipe->ctx->compute_cb_target_mask |= (0xf << (id * 4)); 296 297 surf = (struct r600_surface*)pipe->ctx->framebuffer.cbufs[id]; 298 res = (struct r600_resource*)surf->base.texture; 299 300 evergreen_init_color_surface(rctx, surf); 301 302 /* Get the CB register writes for the RAT */ 303 r600_pipe_state_add_reg_bo(state, R_028C60_CB_COLOR0_BASE + id * 0x3C, 304 surf->cb_color_base, res, RADEON_USAGE_READWRITE); 305 r600_pipe_state_add_reg(state, R_028C78_CB_COLOR0_DIM + id * 0x3C, 306 surf->cb_color_dim); 307 r600_pipe_state_add_reg_bo(state, R_028C70_CB_COLOR0_INFO + id * 0x3C, 308 surf->cb_color_info, res, RADEON_USAGE_READWRITE); 309 r600_pipe_state_add_reg(state, R_028C64_CB_COLOR0_PITCH + id * 0x3C, 310 surf->cb_color_pitch); 311 r600_pipe_state_add_reg(state, R_028C68_CB_COLOR0_SLICE + id * 0x3C, 312 surf->cb_color_slice); 313 r600_pipe_state_add_reg(state, R_028C6C_CB_COLOR0_VIEW + id * 0x3C, 314 surf->cb_color_view); 315 r600_pipe_state_add_reg_bo(state, R_028C74_CB_COLOR0_ATTRIB + id * 0x3C, 316 surf->cb_color_attrib, res, RADEON_USAGE_READWRITE); 317 318 /* Add the register blocks to the dirty list */ 319 free(pipe->ctx->states[R600_PIPE_STATE_FRAMEBUFFER]); 320 pipe->ctx->states[R600_PIPE_STATE_FRAMEBUFFER] = state; 321 r600_context_pipe_state_set(pipe->ctx, state); 322 } 323 324 void evergreen_set_gds( 325 struct r600_pipe_compute *pipe, 326 uint32_t addr, 327 uint32_t size) 328 { 329 struct evergreen_compute_resource* res = 330 get_empty_res(pipe, COMPUTE_RESOURCE_GDS, 0); 331 332 evergreen_reg_set(res, R_028728_GDS_ORDERED_WAVE_PER_SE, 1); 333 evergreen_reg_set(res, R_028720_GDS_ADDR_BASE, addr); 334 evergreen_reg_set(res, R_028724_GDS_ADDR_SIZE, size); 335 } 336 337 void evergreen_set_export( 338 struct r600_pipe_compute *pipe, 339 struct r600_resource* bo, 340 int offset, int size) 341 { 342 #define SX_MEMORY_EXPORT_BASE 0x9010 343 #define SX_MEMORY_EXPORT_SIZE 0x9014 344 345 struct evergreen_compute_resource* res = 346 get_empty_res(pipe, COMPUTE_RESOURCE_EXPORT, 0); 347 348 evergreen_reg_set(res, SX_MEMORY_EXPORT_SIZE, size); 349 350 if (size) { 351 evergreen_reg_set(res, SX_MEMORY_EXPORT_BASE, offset); 352 res->bo = bo; 353 res->usage = RADEON_USAGE_WRITE; 354 res->coher_bo_size = size; 355 res->flags = 0; 356 } 357 } 358 359 void evergreen_set_loop_const( 360 struct r600_pipe_compute *pipe, 361 int id, int count, int init, int inc) { 362 363 struct evergreen_compute_resource* res = 364 get_empty_res(pipe, COMPUTE_RESOURCE_LOOP, id); 365 366 assert(id < 32); 367 assert(count <= 0xFFF); 368 assert(init <= 0xFF); 369 assert(inc <= 0xFF); 370 371 /* Compute shaders use LOOP_CONST registers SQ_LOOP_CONST_160 to 372 * SQ_LOOP_CONST_191 */ 373 evergreen_reg_set(res, R_03A200_SQ_LOOP_CONST_0 + (160 * 4) + (id * 4), 374 count | init << 12 | inc << 24); 375 } 376 377 void evergreen_set_tmp_ring( 378 struct r600_pipe_compute *pipe, 379 struct r600_resource* bo, 380 int offset, int size, int se) 381 { 382 #define SQ_LSTMP_RING_BASE 0x00008e10 383 #define SQ_LSTMP_RING_SIZE 0x00008e14 384 #define GRBM_GFX_INDEX 0x802C 385 #define INSTANCE_INDEX(x) ((x) << 0) 386 #define SE_INDEX(x) ((x) << 16) 387 #define INSTANCE_BROADCAST_WRITES (1 << 30) 388 #define SE_BROADCAST_WRITES (1 << 31) 389 390 struct evergreen_compute_resource* res = 391 get_empty_res(pipe, COMPUTE_RESOURCE_TMPRING, se); 392 393 evergreen_reg_set(res, 394 GRBM_GFX_INDEX,INSTANCE_INDEX(0) 395 | SE_INDEX(se) 396 | INSTANCE_BROADCAST_WRITES); 397 evergreen_reg_set(res, SQ_LSTMP_RING_SIZE, size); 398 399 if (size) { 400 assert(bo); 401 402 evergreen_reg_set(res, SQ_LSTMP_RING_BASE, offset); 403 res->bo = bo; 404 res->usage = RADEON_USAGE_WRITE; 405 res->coher_bo_size = 0; 406 res->flags = 0; 407 } 408 409 if (size) { 410 evergreen_emit_force_reloc(res); 411 } 412 413 evergreen_reg_set(res, 414 GRBM_GFX_INDEX,INSTANCE_INDEX(0) 415 | SE_INDEX(0) 416 | INSTANCE_BROADCAST_WRITES 417 | SE_BROADCAST_WRITES); 418 } 419 420 static uint32_t r600_colorformat_endian_swap(uint32_t colorformat) 421 { 422 if (R600_BIG_ENDIAN) { 423 switch(colorformat) { 424 case V_028C70_COLOR_4_4: 425 return ENDIAN_NONE; 426 427 /* 8-bit buffers. */ 428 case V_028C70_COLOR_8: 429 return ENDIAN_NONE; 430 431 /* 16-bit buffers. */ 432 case V_028C70_COLOR_5_6_5: 433 case V_028C70_COLOR_1_5_5_5: 434 case V_028C70_COLOR_4_4_4_4: 435 case V_028C70_COLOR_16: 436 case V_028C70_COLOR_8_8: 437 return ENDIAN_8IN16; 438 439 /* 32-bit buffers. */ 440 case V_028C70_COLOR_8_8_8_8: 441 case V_028C70_COLOR_2_10_10_10: 442 case V_028C70_COLOR_8_24: 443 case V_028C70_COLOR_24_8: 444 case V_028C70_COLOR_32_FLOAT: 445 case V_028C70_COLOR_16_16_FLOAT: 446 case V_028C70_COLOR_16_16: 447 return ENDIAN_8IN32; 448 449 /* 64-bit buffers. */ 450 case V_028C70_COLOR_16_16_16_16: 451 case V_028C70_COLOR_16_16_16_16_FLOAT: 452 return ENDIAN_8IN16; 453 454 case V_028C70_COLOR_32_32_FLOAT: 455 case V_028C70_COLOR_32_32: 456 case V_028C70_COLOR_X24_8_32_FLOAT: 457 return ENDIAN_8IN32; 458 459 /* 96-bit buffers. */ 460 case V_028C70_COLOR_32_32_32_FLOAT: 461 /* 128-bit buffers. */ 462 case V_028C70_COLOR_32_32_32_32_FLOAT: 463 case V_028C70_COLOR_32_32_32_32: 464 return ENDIAN_8IN32; 465 default: 466 return ENDIAN_NONE; /* Unsupported. */ 467 } 468 } else { 469 return ENDIAN_NONE; 470 } 471 } 472 473 static unsigned r600_tex_dim(unsigned dim) 474 { 475 switch (dim) { 476 default: 477 case PIPE_TEXTURE_1D: 478 return V_030000_SQ_TEX_DIM_1D; 479 case PIPE_TEXTURE_1D_ARRAY: 480 return V_030000_SQ_TEX_DIM_1D_ARRAY; 481 case PIPE_TEXTURE_2D: 482 case PIPE_TEXTURE_RECT: 483 return V_030000_SQ_TEX_DIM_2D; 484 case PIPE_TEXTURE_2D_ARRAY: 485 return V_030000_SQ_TEX_DIM_2D_ARRAY; 486 case PIPE_TEXTURE_3D: 487 return V_030000_SQ_TEX_DIM_3D; 488 case PIPE_TEXTURE_CUBE: 489 return V_030000_SQ_TEX_DIM_CUBEMAP; 490 } 491 } 492 493 void evergreen_set_tex_resource( 494 struct r600_pipe_compute *pipe, 495 struct r600_pipe_sampler_view* view, 496 int id) 497 { 498 struct evergreen_compute_resource* res = 499 get_empty_res(pipe, COMPUTE_RESOURCE_TEX, id); 500 struct r600_texture *tmp = 501 (struct r600_texture*)view->base.texture; 502 503 unsigned format, endian; 504 uint32_t word4 = 0, yuv_format = 0, pitch = 0; 505 unsigned char swizzle[4], array_mode = 0, tile_type = 0; 506 unsigned height, depth; 507 508 swizzle[0] = 0; 509 swizzle[1] = 1; 510 swizzle[2] = 2; 511 swizzle[3] = 3; 512 513 format = r600_translate_texformat((struct pipe_screen *)pipe->ctx->screen, 514 view->base.format, swizzle, &word4, &yuv_format); 515 516 if (format == ~0) { 517 format = 0; 518 } 519 520 endian = r600_colorformat_endian_swap(format); 521 522 height = view->base.texture->height0; 523 depth = view->base.texture->depth0; 524 525 pitch = align(tmp->surface.level[0].nblk_x * 526 util_format_get_blockwidth(tmp->resource.b.b.format), 8); 527 array_mode = tmp->array_mode[0]; 528 tile_type = tmp->tile_type; 529 530 assert(view->base.texture->target != PIPE_TEXTURE_1D_ARRAY); 531 assert(view->base.texture->target != PIPE_TEXTURE_2D_ARRAY); 532 533 evergreen_emit_raw_value(res, PKT3C(PKT3_SET_RESOURCE, 8, 0)); 534 evergreen_emit_raw_value(res, (id+816)*32 >> 2); ///TODO: check this line 535 evergreen_emit_raw_value(res, 536 (S_030000_DIM(r600_tex_dim(view->base.texture->target)) | 537 S_030000_PITCH((pitch / 8) - 1) | 538 S_030000_NON_DISP_TILING_ORDER(tile_type) | 539 S_030000_TEX_WIDTH(view->base.texture->width0 - 1))); 540 evergreen_emit_raw_value(res, (S_030004_TEX_HEIGHT(height - 1) | 541 S_030004_TEX_DEPTH(depth - 1) | 542 S_030004_ARRAY_MODE(array_mode))); 543 evergreen_emit_raw_value(res, tmp->surface.level[0].offset >> 8); 544 evergreen_emit_raw_value(res, tmp->surface.level[0].offset >> 8); 545 evergreen_emit_raw_value(res, (word4 | 546 S_030010_SRF_MODE_ALL(V_030010_SRF_MODE_ZERO_CLAMP_MINUS_ONE) | 547 S_030010_ENDIAN_SWAP(endian) | 548 S_030010_BASE_LEVEL(0))); 549 evergreen_emit_raw_value(res, (S_030014_LAST_LEVEL(0) | 550 S_030014_BASE_ARRAY(0) | 551 S_030014_LAST_ARRAY(0))); 552 evergreen_emit_raw_value(res, (S_030018_MAX_ANISO(4 /* max 16 samples */))); 553 evergreen_emit_raw_value(res, 554 S_03001C_TYPE(V_03001C_SQ_TEX_VTX_VALID_TEXTURE) 555 | S_03001C_DATA_FORMAT(format)); 556 557 res->bo = (struct r600_resource*)view->base.texture; 558 559 res->usage = RADEON_USAGE_READ; 560 561 res->coher_bo_size = tmp->surface.level[0].offset + 562 util_format_get_blockwidth(tmp->resource.b.b.format) * 563 view->base.texture->width0*height*depth; 564 565 r600_inval_texture_cache(pipe->ctx); 566 567 evergreen_emit_force_reloc(res); 568 evergreen_emit_force_reloc(res); 569 } 570 571 void evergreen_set_sampler_resource( 572 struct r600_pipe_compute *pipe, 573 struct compute_sampler_state *sampler, 574 int id) 575 { 576 struct evergreen_compute_resource* res = 577 get_empty_res(pipe, COMPUTE_RESOURCE_SAMPLER, id); 578 579 unsigned aniso_flag_offset = sampler->state.max_anisotropy > 1 ? 2 : 0; 580 581 evergreen_emit_raw_value(res, PKT3C(PKT3_SET_SAMPLER, 3, 0)); 582 evergreen_emit_raw_value(res, (id + 90)*3); 583 evergreen_emit_raw_value(res, 584 S_03C000_CLAMP_X(r600_tex_wrap(sampler->state.wrap_s)) | 585 S_03C000_CLAMP_Y(r600_tex_wrap(sampler->state.wrap_t)) | 586 S_03C000_CLAMP_Z(r600_tex_wrap(sampler->state.wrap_r)) | 587 S_03C000_XY_MAG_FILTER(r600_tex_filter(sampler->state.mag_img_filter) | aniso_flag_offset) | 588 S_03C000_XY_MIN_FILTER(r600_tex_filter(sampler->state.min_img_filter) | aniso_flag_offset) | 589 S_03C000_BORDER_COLOR_TYPE(V_03C000_SQ_TEX_BORDER_COLOR_OPAQUE_BLACK) 590 ); 591 evergreen_emit_raw_value(res, 592 S_03C004_MIN_LOD(S_FIXED(CLAMP(sampler->state.min_lod, 0, 15), 8)) | 593 S_03C004_MAX_LOD(S_FIXED(CLAMP(sampler->state.max_lod, 0, 15), 8)) 594 ); 595 evergreen_emit_raw_value(res, 596 S_03C008_LOD_BIAS(S_FIXED(CLAMP(sampler->state.lod_bias, -16, 16), 8)) | 597 (sampler->state.seamless_cube_map ? 0 : S_03C008_DISABLE_CUBE_WRAP(1)) | 598 S_03C008_TYPE(1) 599 ); 600 } 601 602 void evergreen_set_const_cache( 603 struct r600_pipe_compute *pipe, 604 int cache_id, 605 struct r600_resource* cbo, 606 int size, int offset) 607 { 608 #define SQ_ALU_CONST_BUFFER_SIZE_LS_0 0x00028fc0 609 #define SQ_ALU_CONST_CACHE_LS_0 0x00028f40 610 611 struct evergreen_compute_resource* res = 612 get_empty_res(pipe, COMPUTE_RESOURCE_CONST_MEM, cache_id); 613 614 assert(size < 0x200); 615 assert((offset & 0xFF) == 0); 616 assert(cache_id < 16); 617 618 evergreen_reg_set(res, SQ_ALU_CONST_BUFFER_SIZE_LS_0 + cache_id*4, size); 619 evergreen_reg_set(res, SQ_ALU_CONST_CACHE_LS_0 + cache_id*4, offset >> 8); 620 res->bo = cbo; 621 res->usage = RADEON_USAGE_READ; 622 res->coher_bo_size = size; 623 624 r600_inval_shader_cache(pipe->ctx); 625 } 626 627 struct r600_resource* r600_compute_buffer_alloc_vram( 628 struct r600_screen *screen, 629 unsigned size) 630 { 631 assert(size); 632 633 struct pipe_resource * buffer = pipe_buffer_create( 634 (struct pipe_screen*) screen, 635 PIPE_BIND_CUSTOM, 636 PIPE_USAGE_IMMUTABLE, 637 size); 638 639 return (struct r600_resource *)buffer; 640 } 641