r600_state_common.c 105 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/*
 * Copyright 2010 Red Hat Inc.
 *           2010 Jerome Glisse
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * on the rights to use, copy, modify, merge, publish, distribute, sub
 * license, and/or sell copies of the Software, and to permit persons to whom
 * the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: Dave Airlie <airlied@redhat.com>
 *          Jerome Glisse <jglisse@redhat.com>
 */
27
#include "r600_formats.h"
28
#include "r600_shader.h"
29
#include "r600d.h"
30

31
#include "util/format/u_format_s3tc.h"
32
#include "util/u_index_modify.h"
33
#include "util/u_memory.h"
34
#include "util/u_upload_mgr.h"
35
#include "util/u_math.h"
Marek Olšák's avatar
Marek Olšák committed
36
#include "tgsi/tgsi_parse.h"
37
#include "tgsi/tgsi_scan.h"
38
#include "tgsi/tgsi_ureg.h"
Marek Olšák's avatar
Marek Olšák committed
39

40 41 42 43
#include "nir.h"
#include "nir/nir_to_tgsi_info.h"
#include "tgsi/tgsi_from_mesa.h"

44
void r600_init_command_buffer(struct r600_command_buffer *cb, unsigned num_dw)
45
{
Marek Olšák's avatar
Marek Olšák committed
46
	assert(!cb->buf);
47 48 49 50 51 52 53 54 55
	cb->buf = CALLOC(1, 4 * num_dw);
	cb->max_num_dw = num_dw;
}

void r600_release_command_buffer(struct r600_command_buffer *cb)
{
	FREE(cb->buf);
}

56 57 58 59 60 61 62
void r600_add_atom(struct r600_context *rctx,
		   struct r600_atom *atom,
		   unsigned id)
{
	assert(id < R600_NUM_ATOMS);
	assert(rctx->atoms[id] == NULL);
	rctx->atoms[id] = atom;
63
	atom->id = id;
64 65
}

Jerome Glisse's avatar
Jerome Glisse committed
66 67 68
void r600_init_atom(struct r600_context *rctx,
		    struct r600_atom *atom,
		    unsigned id,
69
		    void (*emit)(struct r600_context *ctx, struct r600_atom *state),
Jerome Glisse's avatar
Jerome Glisse committed
70
		    unsigned num_dw)
Marek Olšák's avatar
Marek Olšák committed
71
{
72
	atom->emit = (void*)emit;
Marek Olšák's avatar
Marek Olšák committed
73
	atom->num_dw = num_dw;
74
	r600_add_atom(rctx, atom, id);
Marek Olšák's avatar
Marek Olšák committed
75 76
}

Marek Olšák's avatar
Marek Olšák committed
77 78
void r600_emit_cso_state(struct r600_context *rctx, struct r600_atom *atom)
{
79
	r600_emit_command_buffer(rctx->b.gfx.cs, ((struct r600_cso_state*)atom)->cb);
Marek Olšák's avatar
Marek Olšák committed
80 81
}

Jerome Glisse's avatar
Jerome Glisse committed
82
void r600_emit_alphatest_state(struct r600_context *rctx, struct r600_atom *atom)
Marek Olšák's avatar
Marek Olšák committed
83
{
84
	struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
Marek Olšák's avatar
Marek Olšák committed
85 86 87
	struct r600_alphatest_state *a = (struct r600_alphatest_state*)atom;
	unsigned alpha_ref = a->sx_alpha_ref;

88
	if (rctx->b.chip_class >= EVERGREEN && a->cb0_export_16bpc) {
Marek Olšák's avatar
Marek Olšák committed
89 90 91
		alpha_ref &= ~0x1FFF;
	}

92
	radeon_set_context_reg(cs, R_028410_SX_ALPHA_TEST_CONTROL,
Marek Olšák's avatar
Marek Olšák committed
93 94
			       a->sx_alpha_test_control |
			       S_028410_ALPHA_TEST_BYPASS(a->bypass));
95
	radeon_set_context_reg(cs, R_028438_SX_ALPHA_REF, alpha_ref);
Marek Olšák's avatar
Marek Olšák committed
96 97
}

98 99 100
static void r600_memory_barrier(struct pipe_context *ctx, unsigned flags)
{
	struct r600_context *rctx = (struct r600_context *)ctx;
101 102 103 104

	if (!(flags & ~PIPE_BARRIER_UPDATE))
		return;

105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
	if (flags & PIPE_BARRIER_CONSTANT_BUFFER)
		rctx->b.flags |= R600_CONTEXT_INV_CONST_CACHE;

	if (flags & (PIPE_BARRIER_VERTEX_BUFFER |
		     PIPE_BARRIER_SHADER_BUFFER |
		     PIPE_BARRIER_TEXTURE |
		     PIPE_BARRIER_IMAGE |
		     PIPE_BARRIER_STREAMOUT_BUFFER |
		     PIPE_BARRIER_GLOBAL_BUFFER)) {
		rctx->b.flags |= R600_CONTEXT_INV_VERTEX_CACHE|
			R600_CONTEXT_INV_TEX_CACHE;
	}

	if (flags & (PIPE_BARRIER_FRAMEBUFFER|
		     PIPE_BARRIER_IMAGE))
		rctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV;

	rctx->b.flags |= R600_CONTEXT_WAIT_3D_IDLE;
}

125
static void r600_texture_barrier(struct pipe_context *ctx, unsigned flags)
Marek Olšák's avatar
Marek Olšák committed
126 127 128
{
	struct r600_context *rctx = (struct r600_context *)ctx;

129
	rctx->b.flags |= R600_CONTEXT_INV_TEX_CACHE |
Alex Deucher's avatar
Alex Deucher committed
130 131 132
		       R600_CONTEXT_FLUSH_AND_INV_CB |
		       R600_CONTEXT_FLUSH_AND_INV |
		       R600_CONTEXT_WAIT_3D_IDLE;
133
	rctx->framebuffer.do_update_surf_dirtiness = true;
Marek Olšák's avatar
Marek Olšák committed
134 135
}

136
static unsigned r600_conv_pipe_prim(unsigned prim)
137
{
138
	static const unsigned prim_conv[] = {
139 140 141 142 143 144 145 146 147 148 149 150 151 152
		[PIPE_PRIM_POINTS]			= V_008958_DI_PT_POINTLIST,
		[PIPE_PRIM_LINES]			= V_008958_DI_PT_LINELIST,
		[PIPE_PRIM_LINE_LOOP]			= V_008958_DI_PT_LINELOOP,
		[PIPE_PRIM_LINE_STRIP]			= V_008958_DI_PT_LINESTRIP,
		[PIPE_PRIM_TRIANGLES]			= V_008958_DI_PT_TRILIST,
		[PIPE_PRIM_TRIANGLE_STRIP]		= V_008958_DI_PT_TRISTRIP,
		[PIPE_PRIM_TRIANGLE_FAN]		= V_008958_DI_PT_TRIFAN,
		[PIPE_PRIM_QUADS]			= V_008958_DI_PT_QUADLIST,
		[PIPE_PRIM_QUAD_STRIP]			= V_008958_DI_PT_QUADSTRIP,
		[PIPE_PRIM_POLYGON]			= V_008958_DI_PT_POLYGON,
		[PIPE_PRIM_LINES_ADJACENCY]		= V_008958_DI_PT_LINELIST_ADJ,
		[PIPE_PRIM_LINE_STRIP_ADJACENCY]	= V_008958_DI_PT_LINESTRIP_ADJ,
		[PIPE_PRIM_TRIANGLES_ADJACENCY]		= V_008958_DI_PT_TRILIST_ADJ,
		[PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY]	= V_008958_DI_PT_TRISTRIP_ADJ,
153
		[PIPE_PRIM_PATCHES]                     = V_008958_DI_PT_PATCH,
154
		[R600_PRIM_RECTANGLE_LIST]		= V_008958_DI_PT_RECTLIST
155
	};
Jan Vesely's avatar
Jan Vesely committed
156
	assert(prim < ARRAY_SIZE(prim_conv));
157
	return prim_conv[prim];
158 159
}

160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
unsigned r600_conv_prim_to_gs_out(unsigned mode)
{
	static const int prim_conv[] = {
		[PIPE_PRIM_POINTS]			= V_028A6C_OUTPRIM_TYPE_POINTLIST,
		[PIPE_PRIM_LINES]			= V_028A6C_OUTPRIM_TYPE_LINESTRIP,
		[PIPE_PRIM_LINE_LOOP]			= V_028A6C_OUTPRIM_TYPE_LINESTRIP,
		[PIPE_PRIM_LINE_STRIP]			= V_028A6C_OUTPRIM_TYPE_LINESTRIP,
		[PIPE_PRIM_TRIANGLES]			= V_028A6C_OUTPRIM_TYPE_TRISTRIP,
		[PIPE_PRIM_TRIANGLE_STRIP]		= V_028A6C_OUTPRIM_TYPE_TRISTRIP,
		[PIPE_PRIM_TRIANGLE_FAN]		= V_028A6C_OUTPRIM_TYPE_TRISTRIP,
		[PIPE_PRIM_QUADS]			= V_028A6C_OUTPRIM_TYPE_TRISTRIP,
		[PIPE_PRIM_QUAD_STRIP]			= V_028A6C_OUTPRIM_TYPE_TRISTRIP,
		[PIPE_PRIM_POLYGON]			= V_028A6C_OUTPRIM_TYPE_TRISTRIP,
		[PIPE_PRIM_LINES_ADJACENCY]		= V_028A6C_OUTPRIM_TYPE_LINESTRIP,
		[PIPE_PRIM_LINE_STRIP_ADJACENCY]	= V_028A6C_OUTPRIM_TYPE_LINESTRIP,
		[PIPE_PRIM_TRIANGLES_ADJACENCY]		= V_028A6C_OUTPRIM_TYPE_TRISTRIP,
		[PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY]	= V_028A6C_OUTPRIM_TYPE_TRISTRIP,
		[PIPE_PRIM_PATCHES]			= V_028A6C_OUTPRIM_TYPE_POINTLIST,
		[R600_PRIM_RECTANGLE_LIST]		= V_028A6C_OUTPRIM_TYPE_TRISTRIP
	};
Jan Vesely's avatar
Jan Vesely committed
180
	assert(mode < ARRAY_SIZE(prim_conv));
181 182 183 184

	return prim_conv[mode];
}

185
/* common state between evergreen and r600 */
186 187

static void r600_bind_blend_state_internal(struct r600_context *rctx,
Marek Olšák's avatar
Marek Olšák committed
188
		struct r600_blend_state *blend, bool blend_disable)
189
{
Marek Olšák's avatar
Marek Olšák committed
190
	unsigned color_control;
191
	bool update_cb = false;
192

Marek Olšák's avatar
Marek Olšák committed
193 194 195 196
	rctx->alpha_to_one = blend->alpha_to_one;
	rctx->dual_src_blend = blend->dual_src_blend;

	if (!blend_disable) {
197
		r600_set_cso_state_with_cb(rctx, &rctx->blend_state, blend, &blend->buffer);
Marek Olšák's avatar
Marek Olšák committed
198 199 200
		color_control = blend->cb_color_control;
	} else {
		/* Blending is disabled. */
201
		r600_set_cso_state_with_cb(rctx, &rctx->blend_state, blend, &blend->buffer_no_blend);
Marek Olšák's avatar
Marek Olšák committed
202 203
		color_control = blend->cb_color_control_no_blend;
	}
204

Marek Olšák's avatar
Marek Olšák committed
205
	/* Update derived states. */
206 207
	if (rctx->cb_misc_state.blend_colormask != blend->cb_target_mask) {
		rctx->cb_misc_state.blend_colormask = blend->cb_target_mask;
208
		update_cb = true;
209
	}
210
	if (rctx->b.chip_class <= R700 &&
Marek Olšák's avatar
Marek Olšák committed
211 212
	    rctx->cb_misc_state.cb_color_control != color_control) {
		rctx->cb_misc_state.cb_color_control = color_control;
213 214 215 216 217 218 219
		update_cb = true;
	}
	if (rctx->cb_misc_state.dual_src_blend != blend->dual_src_blend) {
		rctx->cb_misc_state.dual_src_blend = blend->dual_src_blend;
		update_cb = true;
	}
	if (update_cb) {
220
		r600_mark_atom_dirty(rctx, &rctx->cb_misc_state.atom);
221
	}
222 223 224 225
	if (rctx->framebuffer.dual_src_blend != blend->dual_src_blend) {
		rctx->framebuffer.dual_src_blend = blend->dual_src_blend;
		r600_mark_atom_dirty(rctx, &rctx->framebuffer.atom);
	}
226 227
}

228
static void r600_bind_blend_state(struct pipe_context *ctx, void *state)
229 230
{
	struct r600_context *rctx = (struct r600_context *)ctx;
Marek Olšák's avatar
Marek Olšák committed
231
	struct r600_blend_state *blend = (struct r600_blend_state *)state;
232

233
	if (!blend) {
234
		r600_set_cso_state_with_cb(rctx, &rctx->blend_state, NULL, NULL);
235
		return;
236
	}
237

Marek Olšák's avatar
Marek Olšák committed
238
	r600_bind_blend_state_internal(rctx, blend, rctx->force_blend_disable);
239 240
}

241 242
static void r600_set_blend_color(struct pipe_context *ctx,
				 const struct pipe_blend_color *state)
243 244 245
{
	struct r600_context *rctx = (struct r600_context *)ctx;

Marek Olšák's avatar
Marek Olšák committed
246
	rctx->blend_color.state = *state;
247
	r600_mark_atom_dirty(rctx, &rctx->blend_color.atom);
Marek Olšák's avatar
Marek Olšák committed
248
}
249

Marek Olšák's avatar
Marek Olšák committed
250 251
void r600_emit_blend_color(struct r600_context *rctx, struct r600_atom *atom)
{
252
	struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
Marek Olšák's avatar
Marek Olšák committed
253
	struct pipe_blend_color *state = &rctx->blend_color.state;
254

255
	radeon_set_context_reg_seq(cs, R_028414_CB_BLEND_RED, 4);
256 257 258 259
	radeon_emit(cs, fui(state->color[0])); /* R_028414_CB_BLEND_RED */
	radeon_emit(cs, fui(state->color[1])); /* R_028418_CB_BLEND_GREEN */
	radeon_emit(cs, fui(state->color[2])); /* R_02841C_CB_BLEND_BLUE */
	radeon_emit(cs, fui(state->color[3])); /* R_028420_CB_BLEND_ALPHA */
260 261
}

262 263
void r600_emit_vgt_state(struct r600_context *rctx, struct r600_atom *atom)
{
264
	struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
265 266
	struct r600_vgt_state *a = (struct r600_vgt_state *)atom;

267 268
	radeon_set_context_reg(cs, R_028A94_VGT_MULTI_PRIM_IB_RESET_EN, a->vgt_multi_prim_ib_reset_en);
	radeon_set_context_reg_seq(cs, R_028408_VGT_INDX_OFFSET, 2);
269 270
	radeon_emit(cs, a->vgt_indx_offset); /* R_028408_VGT_INDX_OFFSET */
	radeon_emit(cs, a->vgt_multi_prim_ib_reset_indx); /* R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX */
271 272
	if (a->last_draw_was_indirect) {
		a->last_draw_was_indirect = false;
273
		radeon_set_ctl_const(cs, R_03CFF0_SQ_VTX_BASE_VTX_LOC, 0);
274
	}
275 276
}

Marek Olšák's avatar
Marek Olšák committed
277 278 279 280 281 282
static void r600_set_clip_state(struct pipe_context *ctx,
				const struct pipe_clip_state *state)
{
	struct r600_context *rctx = (struct r600_context *)ctx;

	rctx->clip_state.state = *state;
283
	r600_mark_atom_dirty(rctx, &rctx->clip_state.atom);
284
	rctx->driver_consts[PIPE_SHADER_VERTEX].vs_ucp_dirty = true;
Marek Olšák's avatar
Marek Olšák committed
285 286
}

287 288 289
static void r600_set_stencil_ref(struct pipe_context *ctx,
				 const struct r600_stencil_ref *state)
{
290
	struct r600_context *rctx = (struct r600_context *)ctx;
291

292
	rctx->stencil_ref.state = *state;
293
	r600_mark_atom_dirty(rctx, &rctx->stencil_ref.atom);
294
}
295

296 297
void r600_emit_stencil_ref(struct r600_context *rctx, struct r600_atom *atom)
{
298
	struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
299 300
	struct r600_stencil_ref_state *a = (struct r600_stencil_ref_state*)atom;

301
	radeon_set_context_reg_seq(cs, R_028430_DB_STENCILREFMASK, 2);
302
	radeon_emit(cs, /* R_028430_DB_STENCILREFMASK */
303 304 305
			 S_028430_STENCILREF(a->state.ref_value[0]) |
			 S_028430_STENCILMASK(a->state.valuemask[0]) |
			 S_028430_STENCILWRITEMASK(a->state.writemask[0]));
306
	radeon_emit(cs, /* R_028434_DB_STENCILREFMASK_BF */
307 308 309
			 S_028434_STENCILREF_BF(a->state.ref_value[1]) |
			 S_028434_STENCILMASK_BF(a->state.valuemask[1]) |
			 S_028434_STENCILWRITEMASK_BF(a->state.writemask[1]));
310 311
}

312 313
static void r600_set_pipe_stencil_ref(struct pipe_context *ctx,
				      const struct pipe_stencil_ref *state)
314
{
315
	struct r600_context *rctx = (struct r600_context *)ctx;
316
	struct r600_dsa_state *dsa = (struct r600_dsa_state*)rctx->dsa_state.cso;
317 318
	struct r600_stencil_ref ref;

319
	rctx->stencil_ref.pipe_state = *state;
320 321 322 323 324 325 326 327 328 329 330 331 332 333

	if (!dsa)
		return;

	ref.ref_value[0] = state->ref_value[0];
	ref.ref_value[1] = state->ref_value[1];
	ref.valuemask[0] = dsa->valuemask[0];
	ref.valuemask[1] = dsa->valuemask[1];
	ref.writemask[0] = dsa->writemask[0];
	ref.writemask[1] = dsa->writemask[1];

	r600_set_stencil_ref(ctx, &ref);
}

334
static void r600_bind_dsa_state(struct pipe_context *ctx, void *state)
335
{
336
	struct r600_context *rctx = (struct r600_context *)ctx;
337
	struct r600_dsa_state *dsa = state;
338
	struct r600_stencil_ref ref;
339

340
	if (!state) {
341
		r600_set_cso_state_with_cb(rctx, &rctx->dsa_state, NULL, NULL);
342
		return;
343
	}
344

345
	r600_set_cso_state_with_cb(rctx, &rctx->dsa_state, dsa, &dsa->buffer);
346

347 348
	ref.ref_value[0] = rctx->stencil_ref.pipe_state.ref_value[0];
	ref.ref_value[1] = rctx->stencil_ref.pipe_state.ref_value[1];
349 350 351 352
	ref.valuemask[0] = dsa->valuemask[0];
	ref.valuemask[1] = dsa->valuemask[1];
	ref.writemask[0] = dsa->writemask[0];
	ref.writemask[1] = dsa->writemask[1];
353 354
	if (rctx->zwritemask != dsa->zwritemask) {
		rctx->zwritemask = dsa->zwritemask;
355
		if (rctx->b.chip_class >= EVERGREEN) {
Zoë Blade's avatar
Zoë Blade committed
356
			/* work around some issue when not writing to zbuffer
357
			 * we are having lockup on evergreen so do not enable
Zoë Blade's avatar
Zoë Blade committed
358
			 * hyperz when not writing zbuffer
359
			 */
360
			r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom);
361 362
		}
	}
363 364

	r600_set_stencil_ref(ctx, &ref);
Marek Olšák's avatar
Marek Olšák committed
365 366 367 368 369 370

	/* Update alphatest state. */
	if (rctx->alphatest_state.sx_alpha_test_control != dsa->sx_alpha_test_control ||
	    rctx->alphatest_state.sx_alpha_ref != dsa->alpha_ref) {
		rctx->alphatest_state.sx_alpha_test_control = dsa->sx_alpha_test_control;
		rctx->alphatest_state.sx_alpha_ref = dsa->alpha_ref;
371
		r600_mark_atom_dirty(rctx, &rctx->alphatest_state.atom);
Marek Olšák's avatar
Marek Olšák committed
372
	}
373 374
}

375
static void r600_bind_rs_state(struct pipe_context *ctx, void *state)
376
{
377
	struct r600_rasterizer_state *rs = (struct r600_rasterizer_state *)state;
378
	struct r600_context *rctx = (struct r600_context *)ctx;
379

380
	if (!state)
381 382 383 384
		return;

	rctx->rasterizer = rs;

385
	r600_set_cso_state_with_cb(rctx, &rctx->rasterizer_state, rs, &rs->buffer);
386

387 388
	if (rs->offset_enable &&
	    (rs->offset_units != rctx->poly_offset_state.offset_units ||
389 390
	     rs->offset_scale != rctx->poly_offset_state.offset_scale ||
	     rs->offset_units_unscaled != rctx->poly_offset_state.offset_units_unscaled)) {
391 392
		rctx->poly_offset_state.offset_units = rs->offset_units;
		rctx->poly_offset_state.offset_scale = rs->offset_scale;
393
		rctx->poly_offset_state.offset_units_unscaled = rs->offset_units_unscaled;
394
		r600_mark_atom_dirty(rctx, &rctx->poly_offset_state.atom);
395
	}
396

397 398 399 400 401
	/* Update clip_misc_state. */
	if (rctx->clip_misc_state.pa_cl_clip_cntl != rs->pa_cl_clip_cntl ||
	    rctx->clip_misc_state.clip_plane_enable != rs->clip_plane_enable) {
		rctx->clip_misc_state.pa_cl_clip_cntl = rs->pa_cl_clip_cntl;
		rctx->clip_misc_state.clip_plane_enable = rs->clip_plane_enable;
402
		r600_mark_atom_dirty(rctx, &rctx->clip_misc_state.atom);
403 404
	}

405
	r600_viewport_set_rast_deps(&rctx->b, rs->scissor_enable, rs->clip_halfz);
406 407 408

	/* Re-emit PA_SC_LINE_STIPPLE. */
	rctx->last_primitive_type = -1;
409 410
}

411
static void r600_delete_rs_state(struct pipe_context *ctx, void *state)
412
{
413
	struct r600_rasterizer_state *rs = (struct r600_rasterizer_state *)state;
414

415 416
	r600_release_command_buffer(&rs->buffer);
	FREE(rs);
417 418
}

419 420
static void r600_sampler_view_destroy(struct pipe_context *ctx,
				      struct pipe_sampler_view *state)
421
{
422 423 424 425
	struct r600_pipe_sampler_view *view = (struct r600_pipe_sampler_view *)state;

	if (view->tex_resource->gpu_address &&
	    view->tex_resource->b.b.target == PIPE_BUFFER)
426
		list_delinit(&view->list);
427 428

	pipe_resource_reference(&state->texture, NULL);
429
	FREE(view);
430 431
}

432 433 434 435 436
void r600_sampler_states_dirty(struct r600_context *rctx,
			       struct r600_sampler_states *state)
{
	if (state->dirty_mask) {
		if (state->dirty_mask & state->has_bordercolor_mask) {
437
			rctx->b.flags |= R600_CONTEXT_WAIT_3D_IDLE;
438 439 440 441
		}
		state->atom.num_dw =
			util_bitcount(state->dirty_mask & state->has_bordercolor_mask) * 11 +
			util_bitcount(state->dirty_mask & ~state->has_bordercolor_mask) * 5;
442
		r600_mark_atom_dirty(rctx, &state->atom);
443 444 445
	}
}

446
static void r600_bind_sampler_states(struct pipe_context *pipe,
447
			       enum pipe_shader_type shader,
448
			       unsigned start,
449 450
			       unsigned count, void **states)
{
451
	struct r600_context *rctx = (struct r600_context *)pipe;
452
	struct r600_textures_info *dst = &rctx->samplers[shader];
453
	struct r600_pipe_sampler_state **rstates = (struct r600_pipe_sampler_state**)states;
454 455
	int seamless_cube_map = -1;
	unsigned i;
456 457 458 459
	/* This sets 1-bit for states with index >= count. */
	uint32_t disable_mask = ~((1ull << count) - 1);
	/* These are the new states set by this function. */
	uint32_t new_mask = 0;
460

461 462
	assert(start == 0); /* XXX fix below */

463 464 465 466 467
	if (!states) {
		disable_mask = ~0u;
		count = 0;
	}

468
	for (i = 0; i < count; i++) {
469
		struct r600_pipe_sampler_state *rstate = rstates[i];
470

471
		if (rstate == dst->states.states[i]) {
472 473
			continue;
		}
474 475 476 477 478 479 480 481 482 483

		if (rstate) {
			if (rstate->border_color_use) {
				dst->states.has_bordercolor_mask |= 1 << i;
			} else {
				dst->states.has_bordercolor_mask &= ~(1 << i);
			}
			seamless_cube_map = rstate->seamless_cube_map;

			new_mask |= 1 << i;
484
		} else {
485
			disable_mask |= 1 << i;
486 487
		}
	}
488 489 490 491 492 493 494 495 496 497 498 499 500

	memcpy(dst->states.states, rstates, sizeof(void*) * count);
	memset(dst->states.states + count, 0, sizeof(void*) * (NUM_TEX_UNITS - count));

	dst->states.enabled_mask &= ~disable_mask;
	dst->states.dirty_mask &= dst->states.enabled_mask;
	dst->states.enabled_mask |= new_mask;
	dst->states.dirty_mask |= new_mask;
	dst->states.has_bordercolor_mask &= dst->states.enabled_mask;

	r600_sampler_states_dirty(rctx, &dst->states);

	/* Seamless cubemap state. */
501
	if (rctx->b.chip_class <= R700 &&
502 503
	    seamless_cube_map != -1 &&
	    seamless_cube_map != rctx->seamless_cube_map.enabled) {
504
		/* change in TA_CNTL_AUX need a pipeline flush */
505
		rctx->b.flags |= R600_CONTEXT_WAIT_3D_IDLE;
506
		rctx->seamless_cube_map.enabled = seamless_cube_map;
507
		r600_mark_atom_dirty(rctx, &rctx->seamless_cube_map.atom);
508 509 510
	}
}

511
static void r600_delete_sampler_state(struct pipe_context *ctx, void *state)
512 513 514 515
{
	free(state);
}

Marek Olšák's avatar
Marek Olšák committed
516 517
static void r600_delete_blend_state(struct pipe_context *ctx, void *state)
{
518
	struct r600_context *rctx = (struct r600_context *)ctx;
Marek Olšák's avatar
Marek Olšák committed
519 520
	struct r600_blend_state *blend = (struct r600_blend_state*)state;

521 522 523 524
	if (rctx->blend_state.cso == state) {
		ctx->bind_blend_state(ctx, NULL);
	}

Marek Olšák's avatar
Marek Olšák committed
525 526 527 528 529
	r600_release_command_buffer(&blend->buffer);
	r600_release_command_buffer(&blend->buffer_no_blend);
	FREE(blend);
}

530
static void r600_delete_dsa_state(struct pipe_context *ctx, void *state)
531
{
532
	struct r600_context *rctx = (struct r600_context *)ctx;
533
	struct r600_dsa_state *dsa = (struct r600_dsa_state *)state;
534

535 536 537 538
	if (rctx->dsa_state.cso == state) {
		ctx->bind_depth_stencil_alpha_state(ctx, NULL);
	}

539 540
	r600_release_command_buffer(&dsa->buffer);
	free(dsa);
541 542
}

543
static void r600_bind_vertex_elements(struct pipe_context *ctx, void *state)
544
{
545
	struct r600_context *rctx = (struct r600_context *)ctx;
546

547
	r600_set_cso_state(rctx, &rctx->vertex_fetch_shader, state);
548 549
}

550
static void r600_delete_vertex_elements(struct pipe_context *ctx, void *state)
551
{
552
	struct r600_fetch_shader *shader = (struct r600_fetch_shader*)state;
553 554
	if (shader)
		r600_resource_reference(&shader->buffer, NULL);
555
	FREE(shader);
556 557
}

558 559 560
void r600_vertex_buffers_dirty(struct r600_context *rctx)
{
	if (rctx->vertex_buffer_state.dirty_mask) {
561
		rctx->vertex_buffer_state.atom.num_dw = (rctx->b.chip_class >= EVERGREEN ? 12 : 11) *
562
					       util_bitcount(rctx->vertex_buffer_state.dirty_mask);
563
		r600_mark_atom_dirty(rctx, &rctx->vertex_buffer_state.atom);
564 565 566
	}
}

567 568 569
static void r600_set_vertex_buffers(struct pipe_context *ctx,
				    unsigned start_slot, unsigned count,
				    const struct pipe_vertex_buffer *input)
570
{
571
	struct r600_context *rctx = (struct r600_context *)ctx;
572
	struct r600_vertexbuf_state *state = &rctx->vertex_buffer_state;
573
	struct pipe_vertex_buffer *vb = state->vb + start_slot;
574
	unsigned i;
575
	uint32_t disable_mask = 0;
576 577 578 579
	/* These are the new buffers set by this function. */
	uint32_t new_buffer_mask = 0;

	/* Set vertex buffers. */
580 581
	if (input) {
		for (i = 0; i < count; i++) {
582 583 584 585
			if ((input[i].buffer.resource != vb[i].buffer.resource) ||
			    (vb[i].stride != input[i].stride) ||
			    (vb[i].buffer_offset != input[i].buffer_offset) ||
			    (vb[i].is_user_buffer != input[i].is_user_buffer)) {
586
				if (input[i].buffer.resource) {
587 588
					vb[i].stride = input[i].stride;
					vb[i].buffer_offset = input[i].buffer_offset;
589
					pipe_resource_reference(&vb[i].buffer.resource, input[i].buffer.resource);
590
					new_buffer_mask |= 1 << i;
591
					r600_context_add_resource_size(ctx, input[i].buffer.resource);
592
				} else {
593
					pipe_resource_reference(&vb[i].buffer.resource, NULL);
594 595
					disable_mask |= 1 << i;
				}
596 597
			}
		}
598 599
	} else {
		for (i = 0; i < count; i++) {
600
			pipe_resource_reference(&vb[i].buffer.resource, NULL);
601 602 603 604 605 606
		}
		disable_mask = ((1ull << count) - 1);
	}

	disable_mask <<= start_slot;
	new_buffer_mask <<= start_slot;
607

608 609 610 611 612 613
	rctx->vertex_buffer_state.enabled_mask &= ~disable_mask;
	rctx->vertex_buffer_state.dirty_mask &= rctx->vertex_buffer_state.enabled_mask;
	rctx->vertex_buffer_state.enabled_mask |= new_buffer_mask;
	rctx->vertex_buffer_state.dirty_mask |= new_buffer_mask;

	r600_vertex_buffers_dirty(rctx);
614 615
}

616 617 618 619
void r600_sampler_views_dirty(struct r600_context *rctx,
			      struct r600_samplerview_state *state)
{
	if (state->dirty_mask) {
620
		state->atom.num_dw = (rctx->b.chip_class >= EVERGREEN ? 14 : 13) *
621
				     util_bitcount(state->dirty_mask);
622
		r600_mark_atom_dirty(rctx, &state->atom);
623 624 625
	}
}

626 627
static void r600_set_sampler_views(struct pipe_context *pipe,
				   enum pipe_shader_type shader,
628 629
				   unsigned start, unsigned count,
				   struct pipe_sampler_view **views)
630
{
631
	struct r600_context *rctx = (struct r600_context *) pipe;
632
	struct r600_textures_info *dst = &rctx->samplers[shader];
633
	struct r600_pipe_sampler_view **rviews = (struct r600_pipe_sampler_view **)views;
634
	uint32_t dirty_sampler_states_mask = 0;
635
	unsigned i;
636 637 638 639
	/* This sets 1-bit for textures with index >= count. */
	uint32_t disable_mask = ~((1ull << count) - 1);
	/* These are the new textures set by this function. */
	uint32_t new_mask = 0;
640

641
	/* Set textures with index >= count to NULL. */
642 643 644 645
	uint32_t remaining_mask;

	assert(start == 0); /* XXX fix below */

646 647 648
	if (!views) {
		disable_mask = ~0u;
		count = 0;
649 650
	}

651
	remaining_mask = dst->views.enabled_mask & disable_mask;
652 653 654 655 656 657 658

	while (remaining_mask) {
		i = u_bit_scan(&remaining_mask);
		assert(dst->views.views[i]);

		pipe_sampler_view_reference((struct pipe_sampler_view **)&dst->views.views[i], NULL);
	}
659 660

	for (i = 0; i < count; i++) {
661
		if (rviews[i] == dst->views.views[i]) {
662 663 664 665
			continue;
		}

		if (rviews[i]) {
666 667
			struct r600_texture *rtex =
				(struct r600_texture*)rviews[i]->base.texture;
668
			bool is_buffer = rviews[i]->base.texture->target == PIPE_BUFFER;
669

670
			if (!is_buffer && rtex->db_compatible) {
671 672 673 674
				dst->views.compressed_depthtex_mask |= 1 << i;
			} else {
				dst->views.compressed_depthtex_mask &= ~(1 << i);
			}
675

676 677 678 679 680
			/* Track compressed colorbuffers. */
			if (!is_buffer && rtex->cmask.size) {
				dst->views.compressed_colortex_mask |= 1 << i;
			} else {
				dst->views.compressed_colortex_mask &= ~(1 << i);
681
			}
682

683 684
			/* Changing from array to non-arrays textures and vice versa requires
			 * updating TEX_ARRAY_OVERRIDE in sampler states on R6xx-R7xx. */
685
			if (rctx->b.chip_class <= R700 &&
686
			    (dst->states.enabled_mask & (1 << i)) &&
687 688
			    (rviews[i]->base.texture->target == PIPE_TEXTURE_1D_ARRAY ||
			     rviews[i]->base.texture->target == PIPE_TEXTURE_2D_ARRAY) != dst->is_array_sampler[i]) {
689
				dirty_sampler_states_mask |= 1 << i;
690 691
			}

692 693
			pipe_sampler_view_reference((struct pipe_sampler_view **)&dst->views.views[i], views[i]);
			new_mask |= 1 << i;
694
			r600_context_add_resource_size(pipe, views[i]->texture);
695
		} else {
696 697
			pipe_sampler_view_reference((struct pipe_sampler_view **)&dst->views.views[i], NULL);
			disable_mask |= 1 << i;
698 699 700
		}
	}

701 702 703 704
	dst->views.enabled_mask &= ~disable_mask;
	dst->views.dirty_mask &= dst->views.enabled_mask;
	dst->views.enabled_mask |= new_mask;
	dst->views.dirty_mask |= new_mask;
705
	dst->views.compressed_depthtex_mask &= dst->views.enabled_mask;
706
	dst->views.compressed_colortex_mask &= dst->views.enabled_mask;
707
	dst->views.dirty_buffer_constants = TRUE;
708
	r600_sampler_views_dirty(rctx, &dst->views);
709 710 711 712 713

	if (dirty_sampler_states_mask) {
		dst->states.dirty_mask |= dirty_sampler_states_mask;
		r600_sampler_states_dirty(rctx, &dst->states);
	}
714 715
}

716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735
static void r600_update_compressed_colortex_mask(struct r600_samplerview_state *views)
{
	uint32_t mask = views->enabled_mask;

	while (mask) {
		unsigned i = u_bit_scan(&mask);
		struct pipe_resource *res = views->views[i]->base.texture;

		if (res && res->target != PIPE_BUFFER) {
			struct r600_texture *rtex = (struct r600_texture *)res;

			if (rtex->cmask.size) {
				views->compressed_colortex_mask |= 1 << i;
			} else {
				views->compressed_colortex_mask &= ~(1 << i);
			}
		}
	}
}

736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767
static int r600_get_hw_atomic_count(const struct pipe_context *ctx,
				    enum pipe_shader_type shader)
{
	const struct r600_context *rctx = (struct r600_context *)ctx;
	int value = 0;
	switch (shader) {
	case PIPE_SHADER_FRAGMENT:
	case PIPE_SHADER_COMPUTE:
	default:
		break;
	case PIPE_SHADER_VERTEX:
		value = rctx->ps_shader->info.file_count[TGSI_FILE_HW_ATOMIC];
		break;
	case PIPE_SHADER_GEOMETRY:
		value = rctx->ps_shader->info.file_count[TGSI_FILE_HW_ATOMIC] +
			rctx->vs_shader->info.file_count[TGSI_FILE_HW_ATOMIC];
		break;
	case PIPE_SHADER_TESS_EVAL:
		value = rctx->ps_shader->info.file_count[TGSI_FILE_HW_ATOMIC] +
			rctx->vs_shader->info.file_count[TGSI_FILE_HW_ATOMIC] +
			(rctx->gs_shader ? rctx->gs_shader->info.file_count[TGSI_FILE_HW_ATOMIC] : 0);
		break;
	case PIPE_SHADER_TESS_CTRL:
		value = rctx->ps_shader->info.file_count[TGSI_FILE_HW_ATOMIC] +
			rctx->vs_shader->info.file_count[TGSI_FILE_HW_ATOMIC] +
			(rctx->gs_shader ? rctx->gs_shader->info.file_count[TGSI_FILE_HW_ATOMIC] : 0) +
			rctx->tes_shader->info.file_count[TGSI_FILE_HW_ATOMIC];
		break;
	}
	return value;
}

768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787
static void r600_update_compressed_colortex_mask_images(struct r600_image_state *images)
{
	uint32_t mask = images->enabled_mask;

	while (mask) {
		unsigned i = u_bit_scan(&mask);
		struct pipe_resource *res = images->views[i].base.resource;

		if (res && res->target != PIPE_BUFFER) {
			struct r600_texture *rtex = (struct r600_texture *)res;

			if (rtex->cmask.size) {
				images->compressed_colortex_mask |= 1 << i;
			} else {
				images->compressed_colortex_mask &= ~(1 << i);
			}
		}
	}
}

788
/* Compute the key for the hw shader variant */
789 790 791
static inline void r600_shader_selector_key(const struct pipe_context *ctx,
		const struct r600_pipe_shader_selector *sel,
		union r600_shader_key *key)
792
{
793 794
	const struct r600_context *rctx = (struct r600_context *)ctx;
	memset(key, 0, sizeof(*key));
795

796 797
	switch (sel->type) {
	case PIPE_SHADER_VERTEX: {
798 799 800
		key->vs.as_ls = (rctx->tes_shader != NULL);
		if (!key->vs.as_ls)
			key->vs.as_es = (rctx->gs_shader != NULL);
801

802
		if (rctx->ps_shader->current->shader.gs_prim_id_input && !rctx->gs_shader) {
803 804
			key->vs.as_gs_a = true;
			key->vs.prim_id_out = rctx->ps_shader->current->shader.input[rctx->ps_shader->current->shader.ps_prim_id_input].spi_sid;
805
		}
806
		key->vs.first_atomic_counter = r600_get_hw_atomic_count(ctx, PIPE_SHADER_VERTEX);
807 808 809
		break;
	}
	case PIPE_SHADER_GEOMETRY:
810
		key->gs.first_atomic_counter = r600_get_hw_atomic_count(ctx, PIPE_SHADER_GEOMETRY);
811
		key->gs.tri_strip_adj_fix = rctx->gs_tri_strip_adj_fix;
812 813
		break;
	case PIPE_SHADER_FRAGMENT: {
Dave Airlie's avatar
Dave Airlie committed
814 815
		if (rctx->ps_shader->info.images_declared)
			key->ps.image_size_const_offset = util_last_bit(rctx->samplers[PIPE_SHADER_FRAGMENT].views.enabled_mask);
816
		key->ps.first_atomic_counter = r600_get_hw_atomic_count(ctx, PIPE_SHADER_FRAGMENT);
817 818
		key->ps.color_two_side = rctx->rasterizer && rctx->rasterizer->two_side;
		key->ps.alpha_to_one = rctx->alpha_to_one &&
819 820
				      rctx->rasterizer && rctx->rasterizer->multisample_enable &&
				      !rctx->framebuffer.cb0_is_integer;
821
		key->ps.nr_cbufs = rctx->framebuffer.state.nr_cbufs;
822
                key->ps.apply_sample_id_mask = (rctx->ps_iter_samples > 1) || !rctx->