Home | History | Annotate | Download | only in r600
      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