evergreen_compute_internal.c revision cb922b63eba1d75706354614bc5de4d39dbe9ad3
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
48int 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
57void evergreen_emit_raw_value(
58	struct evergreen_compute_resource* res,
59	unsigned value)
60{
61	res->cs[res->cs_end++] = value;
62}
63
64void evergreen_emit_ctx_value(struct r600_context *ctx, unsigned value)
65{
66	ctx->cs->buf[ctx->cs->cdw++] = value;
67}
68
69void 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
84void 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
93struct 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
123void 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
167void evergreen_emit_force_reloc(struct evergreen_compute_resource* res)
168{
169	res->do_reloc[res->cs_end] += 1;
170}
171
172void 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
211void 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
223int 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
256void 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
324void 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
337void 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
359void 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
377void 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
420static 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
473static 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
493void 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_resource_texture *tmp =
501		(struct r600_resource_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->real_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->offset[0] >> 8);
544	evergreen_emit_raw_value(res, tmp->offset[0] >> 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->offset[0] + util_format_get_blockwidth(tmp->real_format)*view->base.texture->width0*height*depth;
562
563	r600_inval_texture_cache(pipe->ctx);
564
565	evergreen_emit_force_reloc(res);
566	evergreen_emit_force_reloc(res);
567}
568
569void evergreen_set_sampler_resource(
570	struct r600_pipe_compute *pipe,
571	struct compute_sampler_state *sampler,
572	int id)
573{
574	struct evergreen_compute_resource* res =
575		get_empty_res(pipe, COMPUTE_RESOURCE_SAMPLER, id);
576
577	unsigned aniso_flag_offset = sampler->state.max_anisotropy > 1 ? 2 : 0;
578
579	evergreen_emit_raw_value(res, PKT3C(PKT3_SET_SAMPLER, 3, 0));
580	evergreen_emit_raw_value(res, (id + 90)*3);
581	evergreen_emit_raw_value(res,
582		S_03C000_CLAMP_X(r600_tex_wrap(sampler->state.wrap_s)) |
583		S_03C000_CLAMP_Y(r600_tex_wrap(sampler->state.wrap_t)) |
584		S_03C000_CLAMP_Z(r600_tex_wrap(sampler->state.wrap_r)) |
585		S_03C000_XY_MAG_FILTER(r600_tex_filter(sampler->state.mag_img_filter) | aniso_flag_offset) |
586		S_03C000_XY_MIN_FILTER(r600_tex_filter(sampler->state.min_img_filter) | aniso_flag_offset) |
587		S_03C000_BORDER_COLOR_TYPE(V_03C000_SQ_TEX_BORDER_COLOR_OPAQUE_BLACK)
588	);
589	evergreen_emit_raw_value(res,
590		S_03C004_MIN_LOD(S_FIXED(CLAMP(sampler->state.min_lod, 0, 15), 8)) |
591		S_03C004_MAX_LOD(S_FIXED(CLAMP(sampler->state.max_lod, 0, 15), 8))
592	);
593	evergreen_emit_raw_value(res,
594		S_03C008_LOD_BIAS(S_FIXED(CLAMP(sampler->state.lod_bias, -16, 16), 8)) |
595		(sampler->state.seamless_cube_map ? 0 : S_03C008_DISABLE_CUBE_WRAP(1)) |
596		S_03C008_TYPE(1)
597	);
598}
599
600void evergreen_set_const_cache(
601	struct r600_pipe_compute *pipe,
602	int cache_id,
603	struct r600_resource* cbo,
604	int size, int offset)
605{
606	#define SQ_ALU_CONST_BUFFER_SIZE_LS_0 0x00028fc0
607	#define SQ_ALU_CONST_CACHE_LS_0 0x00028f40
608
609	struct evergreen_compute_resource* res =
610		get_empty_res(pipe, COMPUTE_RESOURCE_CONST_MEM, cache_id);
611
612	assert(size < 0x200);
613	assert((offset & 0xFF) == 0);
614	assert(cache_id < 16);
615
616	evergreen_reg_set(res, SQ_ALU_CONST_BUFFER_SIZE_LS_0 + cache_id*4, size);
617	evergreen_reg_set(res, SQ_ALU_CONST_CACHE_LS_0 + cache_id*4, offset >> 8);
618	res->bo = cbo;
619	res->usage = RADEON_USAGE_READ;
620	res->coher_bo_size = size;
621
622	r600_inval_shader_cache(pipe->ctx);
623}
624
625struct r600_resource* r600_compute_buffer_alloc_vram(
626	struct r600_screen *screen,
627	unsigned size)
628{
629	assert(size);
630
631	struct pipe_resource * buffer = pipe_buffer_create(
632			(struct pipe_screen*) screen,
633			PIPE_BIND_CUSTOM,
634			PIPE_USAGE_IMMUTABLE,
635			size);
636
637	return (struct r600_resource *)buffer;
638}
639