7bc7fb43f6c37934836c032dd0b6a4a50cbb97ae
[mesa.git] / src / gallium / drivers / r600 / evergreen_compute_internal.c
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@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 pipe_surface rat_templ;
268 struct r600_surface *surf;
269 struct r600_context *rctx = pipe->ctx;
270
271 COMPUTE_DBG("bind rat: %i \n", id);
272
273 /* Create the RAT surface */
274 memset(&rat_templ, 0, sizeof(rat_templ));
275 rat_templ.usage = RADEON_USAGE_READWRITE;
276 rat_templ.format = PIPE_FORMAT_R32_UINT;
277 rat_templ.u.tex.level = 0;
278 rat_templ.u.tex.first_layer = 0;
279 rat_templ.u.tex.last_layer = 0;
280
281 /* Add the RAT the list of color buffers */
282 pipe->ctx->framebuffer.state.cbufs[id] = pipe->ctx->context.create_surface(
283 (struct pipe_context *)pipe->ctx,
284 (struct pipe_resource *)bo, &rat_templ);
285
286 /* Update the number of color buffers */
287 pipe->ctx->framebuffer.state.nr_cbufs =
288 MAX2(id + 1, pipe->ctx->framebuffer.state.nr_cbufs);
289
290 /* Update the cb_target_mask
291 * XXX: I think this is a potential spot for bugs once we start doing
292 * GL interop. cb_target_mask may be modified in the 3D sections
293 * of this driver. */
294 pipe->ctx->compute_cb_target_mask |= (0xf << (id * 4));
295
296 surf = (struct r600_surface*)pipe->ctx->framebuffer.state.cbufs[id];
297 evergreen_init_color_surface_rat(rctx, surf);
298 }
299
300 void evergreen_set_gds(
301 struct r600_pipe_compute *pipe,
302 uint32_t addr,
303 uint32_t size)
304 {
305 struct evergreen_compute_resource* res =
306 get_empty_res(pipe, COMPUTE_RESOURCE_GDS, 0);
307
308 evergreen_reg_set(res, R_028728_GDS_ORDERED_WAVE_PER_SE, 1);
309 evergreen_reg_set(res, R_028720_GDS_ADDR_BASE, addr);
310 evergreen_reg_set(res, R_028724_GDS_ADDR_SIZE, size);
311 }
312
313 void evergreen_set_export(
314 struct r600_pipe_compute *pipe,
315 struct r600_resource* bo,
316 int offset, int size)
317 {
318 #define SX_MEMORY_EXPORT_BASE 0x9010
319 #define SX_MEMORY_EXPORT_SIZE 0x9014
320
321 struct evergreen_compute_resource* res =
322 get_empty_res(pipe, COMPUTE_RESOURCE_EXPORT, 0);
323
324 evergreen_reg_set(res, SX_MEMORY_EXPORT_SIZE, size);
325
326 if (size) {
327 evergreen_reg_set(res, SX_MEMORY_EXPORT_BASE, offset);
328 res->bo = bo;
329 res->usage = RADEON_USAGE_WRITE;
330 res->coher_bo_size = size;
331 res->flags = 0;
332 }
333 }
334
335 void evergreen_set_loop_const(
336 struct r600_pipe_compute *pipe,
337 int id, int count, int init, int inc) {
338
339 struct evergreen_compute_resource* res =
340 get_empty_res(pipe, COMPUTE_RESOURCE_LOOP, id);
341
342 assert(id < 32);
343 assert(count <= 0xFFF);
344 assert(init <= 0xFF);
345 assert(inc <= 0xFF);
346
347 /* Compute shaders use LOOP_CONST registers SQ_LOOP_CONST_160 to
348 * SQ_LOOP_CONST_191 */
349 evergreen_reg_set(res, R_03A200_SQ_LOOP_CONST_0 + (160 * 4) + (id * 4),
350 count | init << 12 | inc << 24);
351 }
352
353 void evergreen_set_tmp_ring(
354 struct r600_pipe_compute *pipe,
355 struct r600_resource* bo,
356 int offset, int size, int se)
357 {
358 #define SQ_LSTMP_RING_BASE 0x00008e10
359 #define SQ_LSTMP_RING_SIZE 0x00008e14
360 #define GRBM_GFX_INDEX 0x802C
361 #define INSTANCE_INDEX(x) ((x) << 0)
362 #define SE_INDEX(x) ((x) << 16)
363 #define INSTANCE_BROADCAST_WRITES (1 << 30)
364 #define SE_BROADCAST_WRITES (1 << 31)
365
366 struct evergreen_compute_resource* res =
367 get_empty_res(pipe, COMPUTE_RESOURCE_TMPRING, se);
368
369 evergreen_reg_set(res,
370 GRBM_GFX_INDEX,INSTANCE_INDEX(0)
371 | SE_INDEX(se)
372 | INSTANCE_BROADCAST_WRITES);
373 evergreen_reg_set(res, SQ_LSTMP_RING_SIZE, size);
374
375 if (size) {
376 assert(bo);
377
378 evergreen_reg_set(res, SQ_LSTMP_RING_BASE, offset);
379 res->bo = bo;
380 res->usage = RADEON_USAGE_WRITE;
381 res->coher_bo_size = 0;
382 res->flags = 0;
383 }
384
385 if (size) {
386 evergreen_emit_force_reloc(res);
387 }
388
389 evergreen_reg_set(res,
390 GRBM_GFX_INDEX,INSTANCE_INDEX(0)
391 | SE_INDEX(0)
392 | INSTANCE_BROADCAST_WRITES
393 | SE_BROADCAST_WRITES);
394 }
395
396 static uint32_t r600_colorformat_endian_swap(uint32_t colorformat)
397 {
398 if (R600_BIG_ENDIAN) {
399 switch(colorformat) {
400 case V_028C70_COLOR_4_4:
401 return ENDIAN_NONE;
402
403 /* 8-bit buffers. */
404 case V_028C70_COLOR_8:
405 return ENDIAN_NONE;
406
407 /* 16-bit buffers. */
408 case V_028C70_COLOR_5_6_5:
409 case V_028C70_COLOR_1_5_5_5:
410 case V_028C70_COLOR_4_4_4_4:
411 case V_028C70_COLOR_16:
412 case V_028C70_COLOR_8_8:
413 return ENDIAN_8IN16;
414
415 /* 32-bit buffers. */
416 case V_028C70_COLOR_8_8_8_8:
417 case V_028C70_COLOR_2_10_10_10:
418 case V_028C70_COLOR_8_24:
419 case V_028C70_COLOR_24_8:
420 case V_028C70_COLOR_32_FLOAT:
421 case V_028C70_COLOR_16_16_FLOAT:
422 case V_028C70_COLOR_16_16:
423 return ENDIAN_8IN32;
424
425 /* 64-bit buffers. */
426 case V_028C70_COLOR_16_16_16_16:
427 case V_028C70_COLOR_16_16_16_16_FLOAT:
428 return ENDIAN_8IN16;
429
430 case V_028C70_COLOR_32_32_FLOAT:
431 case V_028C70_COLOR_32_32:
432 case V_028C70_COLOR_X24_8_32_FLOAT:
433 return ENDIAN_8IN32;
434
435 /* 96-bit buffers. */
436 case V_028C70_COLOR_32_32_32_FLOAT:
437 /* 128-bit buffers. */
438 case V_028C70_COLOR_32_32_32_32_FLOAT:
439 case V_028C70_COLOR_32_32_32_32:
440 return ENDIAN_8IN32;
441 default:
442 return ENDIAN_NONE; /* Unsupported. */
443 }
444 } else {
445 return ENDIAN_NONE;
446 }
447 }
448
449 static unsigned r600_tex_dim(unsigned dim)
450 {
451 switch (dim) {
452 default:
453 case PIPE_TEXTURE_1D:
454 return V_030000_SQ_TEX_DIM_1D;
455 case PIPE_TEXTURE_1D_ARRAY:
456 return V_030000_SQ_TEX_DIM_1D_ARRAY;
457 case PIPE_TEXTURE_2D:
458 case PIPE_TEXTURE_RECT:
459 return V_030000_SQ_TEX_DIM_2D;
460 case PIPE_TEXTURE_2D_ARRAY:
461 return V_030000_SQ_TEX_DIM_2D_ARRAY;
462 case PIPE_TEXTURE_3D:
463 return V_030000_SQ_TEX_DIM_3D;
464 case PIPE_TEXTURE_CUBE:
465 return V_030000_SQ_TEX_DIM_CUBEMAP;
466 }
467 }
468
469 void evergreen_set_tex_resource(
470 struct r600_pipe_compute *pipe,
471 struct r600_pipe_sampler_view* view,
472 int id)
473 {
474 struct evergreen_compute_resource* res =
475 get_empty_res(pipe, COMPUTE_RESOURCE_TEX, id);
476 struct r600_texture *tmp =
477 (struct r600_texture*)view->base.texture;
478
479 unsigned format, endian;
480 uint32_t word4 = 0, yuv_format = 0, pitch = 0;
481 unsigned char swizzle[4], array_mode = 0, non_disp_tiling = 0;
482 unsigned height, depth;
483
484 swizzle[0] = 0;
485 swizzle[1] = 1;
486 swizzle[2] = 2;
487 swizzle[3] = 3;
488
489 format = r600_translate_texformat((struct pipe_screen *)pipe->ctx->screen,
490 view->base.format, swizzle, &word4, &yuv_format);
491
492 if (format == ~0) {
493 format = 0;
494 }
495
496 endian = r600_colorformat_endian_swap(format);
497
498 height = view->base.texture->height0;
499 depth = view->base.texture->depth0;
500
501 pitch = align(tmp->surface.level[0].nblk_x *
502 util_format_get_blockwidth(tmp->resource.b.b.format), 8);
503 array_mode = tmp->array_mode[0];
504 non_disp_tiling = tmp->non_disp_tiling;
505
506 assert(view->base.texture->target != PIPE_TEXTURE_1D_ARRAY);
507 assert(view->base.texture->target != PIPE_TEXTURE_2D_ARRAY);
508
509 evergreen_emit_raw_value(res, PKT3C(PKT3_SET_RESOURCE, 8, 0));
510 evergreen_emit_raw_value(res, (id+816)*32 >> 2); ///TODO: check this line
511 evergreen_emit_raw_value(res,
512 (S_030000_DIM(r600_tex_dim(view->base.texture->target)) |
513 S_030000_PITCH((pitch / 8) - 1) |
514 S_030000_NON_DISP_TILING_ORDER(non_disp_tiling) |
515 S_030000_TEX_WIDTH(view->base.texture->width0 - 1)));
516 evergreen_emit_raw_value(res, (S_030004_TEX_HEIGHT(height - 1) |
517 S_030004_TEX_DEPTH(depth - 1) |
518 S_030004_ARRAY_MODE(array_mode)));
519 evergreen_emit_raw_value(res, tmp->surface.level[0].offset >> 8);
520 evergreen_emit_raw_value(res, tmp->surface.level[0].offset >> 8);
521 evergreen_emit_raw_value(res, (word4 |
522 S_030010_SRF_MODE_ALL(V_030010_SRF_MODE_ZERO_CLAMP_MINUS_ONE) |
523 S_030010_ENDIAN_SWAP(endian) |
524 S_030010_BASE_LEVEL(0)));
525 evergreen_emit_raw_value(res, (S_030014_LAST_LEVEL(0) |
526 S_030014_BASE_ARRAY(0) |
527 S_030014_LAST_ARRAY(0)));
528 evergreen_emit_raw_value(res, (S_030018_MAX_ANISO(4 /* max 16 samples */)));
529 evergreen_emit_raw_value(res,
530 S_03001C_TYPE(V_03001C_SQ_TEX_VTX_VALID_TEXTURE)
531 | S_03001C_DATA_FORMAT(format));
532
533 res->bo = (struct r600_resource*)view->base.texture;
534
535 res->usage = RADEON_USAGE_READ;
536
537 res->coher_bo_size = tmp->surface.level[0].offset +
538 util_format_get_blockwidth(tmp->resource.b.b.format) *
539 view->base.texture->width0*height*depth;
540
541 pipe->ctx->flags |= R600_CONTEXT_TEX_FLUSH;
542
543 evergreen_emit_force_reloc(res);
544 evergreen_emit_force_reloc(res);
545 }
546
547 void evergreen_set_sampler_resource(
548 struct r600_pipe_compute *pipe,
549 struct compute_sampler_state *sampler,
550 int id)
551 {
552 struct evergreen_compute_resource* res =
553 get_empty_res(pipe, COMPUTE_RESOURCE_SAMPLER, id);
554
555 unsigned aniso_flag_offset = sampler->state.max_anisotropy > 1 ? 2 : 0;
556
557 evergreen_emit_raw_value(res, PKT3C(PKT3_SET_SAMPLER, 3, 0));
558 evergreen_emit_raw_value(res, (id + 90)*3);
559 evergreen_emit_raw_value(res,
560 S_03C000_CLAMP_X(r600_tex_wrap(sampler->state.wrap_s)) |
561 S_03C000_CLAMP_Y(r600_tex_wrap(sampler->state.wrap_t)) |
562 S_03C000_CLAMP_Z(r600_tex_wrap(sampler->state.wrap_r)) |
563 S_03C000_XY_MAG_FILTER(r600_tex_filter(sampler->state.mag_img_filter) | aniso_flag_offset) |
564 S_03C000_XY_MIN_FILTER(r600_tex_filter(sampler->state.min_img_filter) | aniso_flag_offset) |
565 S_03C000_BORDER_COLOR_TYPE(V_03C000_SQ_TEX_BORDER_COLOR_OPAQUE_BLACK)
566 );
567 evergreen_emit_raw_value(res,
568 S_03C004_MIN_LOD(S_FIXED(CLAMP(sampler->state.min_lod, 0, 15), 8)) |
569 S_03C004_MAX_LOD(S_FIXED(CLAMP(sampler->state.max_lod, 0, 15), 8))
570 );
571 evergreen_emit_raw_value(res,
572 S_03C008_LOD_BIAS(S_FIXED(CLAMP(sampler->state.lod_bias, -16, 16), 8)) |
573 (sampler->state.seamless_cube_map ? 0 : S_03C008_DISABLE_CUBE_WRAP(1)) |
574 S_03C008_TYPE(1)
575 );
576 }
577
578 void evergreen_set_const_cache(
579 struct r600_pipe_compute *pipe,
580 int cache_id,
581 struct r600_resource* cbo,
582 int size, int offset)
583 {
584 #define SQ_ALU_CONST_BUFFER_SIZE_LS_0 0x00028fc0
585 #define SQ_ALU_CONST_CACHE_LS_0 0x00028f40
586
587 struct evergreen_compute_resource* res =
588 get_empty_res(pipe, COMPUTE_RESOURCE_CONST_MEM, cache_id);
589
590 assert(size < 0x200);
591 assert((offset & 0xFF) == 0);
592 assert(cache_id < 16);
593
594 evergreen_reg_set(res, SQ_ALU_CONST_BUFFER_SIZE_LS_0 + cache_id*4, size);
595 evergreen_reg_set(res, SQ_ALU_CONST_CACHE_LS_0 + cache_id*4, offset >> 8);
596 res->bo = cbo;
597 res->usage = RADEON_USAGE_READ;
598 res->coher_bo_size = size;
599
600 pipe->ctx->flags |= R600_CONTEXT_SHADERCONST_FLUSH;
601 }
602
603 struct r600_resource* r600_compute_buffer_alloc_vram(
604 struct r600_screen *screen,
605 unsigned size)
606 {
607 assert(size);
608
609 struct pipe_resource * buffer = pipe_buffer_create(
610 (struct pipe_screen*) screen,
611 PIPE_BIND_CUSTOM,
612 PIPE_USAGE_IMMUTABLE,
613 size);
614
615 return (struct r600_resource *)buffer;
616 }