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 
get_compute_resource_num(void)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 
evergreen_emit_raw_value(struct evergreen_compute_resource * res,unsigned value)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 
evergreen_emit_ctx_value(struct r600_context * ctx,unsigned value)64 void evergreen_emit_ctx_value(struct r600_context *ctx, unsigned value)
65 {
66 	ctx->cs->buf[ctx->cs->cdw++] = value;
67 }
68 
evergreen_mult_reg_set_(struct evergreen_compute_resource * res,int index,u32 * array,int size)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 
evergreen_reg_set(struct evergreen_compute_resource * res,unsigned index,unsigned value)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 
get_empty_res(struct r600_pipe_compute * pipe,enum evergreen_compute_resources res_code,int offset_index)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 
evergreen_emit_raw_reg_set(struct evergreen_compute_resource * res,unsigned index,int num)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 
evergreen_emit_force_reloc(struct evergreen_compute_resource * res)167 void evergreen_emit_force_reloc(struct evergreen_compute_resource* res)
168 {
169 	res->do_reloc[res->cs_end] += 1;
170 }
171 
evergreen_emit_ctx_reg_set(struct r600_context * ctx,unsigned index,int num)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 
evergreen_emit_ctx_reloc(struct r600_context * ctx,struct r600_resource * bo,enum radeon_bo_usage usage)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 
evergreen_compute_get_gpu_format(struct number_type_and_format * fmt,struct r600_resource * bo)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 
evergreen_set_rat(struct r600_pipe_compute * pipe,int id,struct r600_resource * bo,int start,int size)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 
evergreen_set_gds(struct r600_pipe_compute * pipe,uint32_t addr,uint32_t size)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 
evergreen_set_export(struct r600_pipe_compute * pipe,struct r600_resource * bo,int offset,int size)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 
evergreen_set_loop_const(struct r600_pipe_compute * pipe,int id,int count,int init,int inc)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 
evergreen_set_tmp_ring(struct r600_pipe_compute * pipe,struct r600_resource * bo,int offset,int size,int se)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 
r600_colorformat_endian_swap(uint32_t colorformat)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 
r600_tex_dim(unsigned dim)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 
evergreen_set_tex_resource(struct r600_pipe_compute * pipe,struct r600_pipe_sampler_view * view,int id)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 
evergreen_set_sampler_resource(struct r600_pipe_compute * pipe,struct compute_sampler_state * sampler,int id)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 
evergreen_set_const_cache(struct r600_pipe_compute * pipe,int cache_id,struct r600_resource * cbo,int size,int offset)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 
r600_compute_buffer_alloc_vram(struct r600_screen * screen,unsigned size)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