1848b8605Smrg/* 2848b8605Smrg * Copyright 2010 Jerome Glisse <glisse@freedesktop.org> 3848b8605Smrg * 4848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5848b8605Smrg * copy of this software and associated documentation files (the "Software"), 6848b8605Smrg * to deal in the Software without restriction, including without limitation 7848b8605Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub 8848b8605Smrg * license, and/or sell copies of the Software, and to permit persons to whom 9848b8605Smrg * the Software is furnished to do so, subject to the following conditions: 10848b8605Smrg * 11848b8605Smrg * The above copyright notice and this permission notice (including the next 12848b8605Smrg * paragraph) shall be included in all copies or substantial portions of the 13848b8605Smrg * Software. 14848b8605Smrg * 15848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18848b8605Smrg * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19848b8605Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20848b8605Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21848b8605Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE. 22848b8605Smrg */ 23848b8605Smrg#include "r600_formats.h" 24848b8605Smrg#include "r600_shader.h" 25848b8605Smrg#include "r600d.h" 26848b8605Smrg 27848b8605Smrg#include "pipe/p_shader_tokens.h" 28848b8605Smrg#include "util/u_pack_color.h" 29848b8605Smrg#include "util/u_memory.h" 30848b8605Smrg#include "util/u_framebuffer.h" 31848b8605Smrg#include "util/u_dual_blend.h" 32848b8605Smrg 33848b8605Smrgstatic uint32_t r600_translate_blend_function(int blend_func) 34848b8605Smrg{ 35848b8605Smrg switch (blend_func) { 36848b8605Smrg case PIPE_BLEND_ADD: 37848b8605Smrg return V_028804_COMB_DST_PLUS_SRC; 38848b8605Smrg case PIPE_BLEND_SUBTRACT: 39848b8605Smrg return V_028804_COMB_SRC_MINUS_DST; 40848b8605Smrg case PIPE_BLEND_REVERSE_SUBTRACT: 41848b8605Smrg return V_028804_COMB_DST_MINUS_SRC; 42848b8605Smrg case PIPE_BLEND_MIN: 43848b8605Smrg return V_028804_COMB_MIN_DST_SRC; 44848b8605Smrg case PIPE_BLEND_MAX: 45848b8605Smrg return V_028804_COMB_MAX_DST_SRC; 46848b8605Smrg default: 47848b8605Smrg R600_ERR("Unknown blend function %d\n", blend_func); 48848b8605Smrg assert(0); 49848b8605Smrg break; 50848b8605Smrg } 51848b8605Smrg return 0; 52848b8605Smrg} 53848b8605Smrg 54848b8605Smrgstatic uint32_t r600_translate_blend_factor(int blend_fact) 55848b8605Smrg{ 56848b8605Smrg switch (blend_fact) { 57848b8605Smrg case PIPE_BLENDFACTOR_ONE: 58848b8605Smrg return V_028804_BLEND_ONE; 59848b8605Smrg case PIPE_BLENDFACTOR_SRC_COLOR: 60848b8605Smrg return V_028804_BLEND_SRC_COLOR; 61848b8605Smrg case PIPE_BLENDFACTOR_SRC_ALPHA: 62848b8605Smrg return V_028804_BLEND_SRC_ALPHA; 63848b8605Smrg case PIPE_BLENDFACTOR_DST_ALPHA: 64848b8605Smrg return V_028804_BLEND_DST_ALPHA; 65848b8605Smrg case PIPE_BLENDFACTOR_DST_COLOR: 66848b8605Smrg return V_028804_BLEND_DST_COLOR; 67848b8605Smrg case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: 68848b8605Smrg return V_028804_BLEND_SRC_ALPHA_SATURATE; 69848b8605Smrg case PIPE_BLENDFACTOR_CONST_COLOR: 70848b8605Smrg return V_028804_BLEND_CONST_COLOR; 71848b8605Smrg case PIPE_BLENDFACTOR_CONST_ALPHA: 72848b8605Smrg return V_028804_BLEND_CONST_ALPHA; 73848b8605Smrg case PIPE_BLENDFACTOR_ZERO: 74848b8605Smrg return V_028804_BLEND_ZERO; 75848b8605Smrg case PIPE_BLENDFACTOR_INV_SRC_COLOR: 76848b8605Smrg return V_028804_BLEND_ONE_MINUS_SRC_COLOR; 77848b8605Smrg case PIPE_BLENDFACTOR_INV_SRC_ALPHA: 78848b8605Smrg return V_028804_BLEND_ONE_MINUS_SRC_ALPHA; 79848b8605Smrg case PIPE_BLENDFACTOR_INV_DST_ALPHA: 80848b8605Smrg return V_028804_BLEND_ONE_MINUS_DST_ALPHA; 81848b8605Smrg case PIPE_BLENDFACTOR_INV_DST_COLOR: 82848b8605Smrg return V_028804_BLEND_ONE_MINUS_DST_COLOR; 83848b8605Smrg case PIPE_BLENDFACTOR_INV_CONST_COLOR: 84848b8605Smrg return V_028804_BLEND_ONE_MINUS_CONST_COLOR; 85848b8605Smrg case PIPE_BLENDFACTOR_INV_CONST_ALPHA: 86848b8605Smrg return V_028804_BLEND_ONE_MINUS_CONST_ALPHA; 87848b8605Smrg case PIPE_BLENDFACTOR_SRC1_COLOR: 88848b8605Smrg return V_028804_BLEND_SRC1_COLOR; 89848b8605Smrg case PIPE_BLENDFACTOR_SRC1_ALPHA: 90848b8605Smrg return V_028804_BLEND_SRC1_ALPHA; 91848b8605Smrg case PIPE_BLENDFACTOR_INV_SRC1_COLOR: 92848b8605Smrg return V_028804_BLEND_INV_SRC1_COLOR; 93848b8605Smrg case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: 94848b8605Smrg return V_028804_BLEND_INV_SRC1_ALPHA; 95848b8605Smrg default: 96848b8605Smrg R600_ERR("Bad blend factor %d not supported!\n", blend_fact); 97848b8605Smrg assert(0); 98848b8605Smrg break; 99848b8605Smrg } 100848b8605Smrg return 0; 101848b8605Smrg} 102848b8605Smrg 103848b8605Smrgstatic unsigned r600_tex_dim(unsigned dim, unsigned nr_samples) 104848b8605Smrg{ 105848b8605Smrg switch (dim) { 106848b8605Smrg default: 107848b8605Smrg case PIPE_TEXTURE_1D: 108848b8605Smrg return V_038000_SQ_TEX_DIM_1D; 109848b8605Smrg case PIPE_TEXTURE_1D_ARRAY: 110848b8605Smrg return V_038000_SQ_TEX_DIM_1D_ARRAY; 111848b8605Smrg case PIPE_TEXTURE_2D: 112848b8605Smrg case PIPE_TEXTURE_RECT: 113848b8605Smrg return nr_samples > 1 ? V_038000_SQ_TEX_DIM_2D_MSAA : 114848b8605Smrg V_038000_SQ_TEX_DIM_2D; 115848b8605Smrg case PIPE_TEXTURE_2D_ARRAY: 116848b8605Smrg return nr_samples > 1 ? V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA : 117848b8605Smrg V_038000_SQ_TEX_DIM_2D_ARRAY; 118848b8605Smrg case PIPE_TEXTURE_3D: 119848b8605Smrg return V_038000_SQ_TEX_DIM_3D; 120848b8605Smrg case PIPE_TEXTURE_CUBE: 121848b8605Smrg case PIPE_TEXTURE_CUBE_ARRAY: 122848b8605Smrg return V_038000_SQ_TEX_DIM_CUBEMAP; 123848b8605Smrg } 124848b8605Smrg} 125848b8605Smrg 126848b8605Smrgstatic uint32_t r600_translate_dbformat(enum pipe_format format) 127848b8605Smrg{ 128848b8605Smrg switch (format) { 129848b8605Smrg case PIPE_FORMAT_Z16_UNORM: 130848b8605Smrg return V_028010_DEPTH_16; 131848b8605Smrg case PIPE_FORMAT_Z24X8_UNORM: 132848b8605Smrg return V_028010_DEPTH_X8_24; 133848b8605Smrg case PIPE_FORMAT_Z24_UNORM_S8_UINT: 134848b8605Smrg return V_028010_DEPTH_8_24; 135848b8605Smrg case PIPE_FORMAT_Z32_FLOAT: 136848b8605Smrg return V_028010_DEPTH_32_FLOAT; 137848b8605Smrg case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: 138848b8605Smrg return V_028010_DEPTH_X24_8_32_FLOAT; 139848b8605Smrg default: 140848b8605Smrg return ~0U; 141848b8605Smrg } 142848b8605Smrg} 143848b8605Smrg 144848b8605Smrgstatic bool r600_is_sampler_format_supported(struct pipe_screen *screen, enum pipe_format format) 145848b8605Smrg{ 146b8e80941Smrg return r600_translate_texformat(screen, format, NULL, NULL, NULL, 147b8e80941Smrg FALSE) != ~0U; 148848b8605Smrg} 149848b8605Smrg 150848b8605Smrgstatic bool r600_is_colorbuffer_format_supported(enum chip_class chip, enum pipe_format format) 151848b8605Smrg{ 152b8e80941Smrg return r600_translate_colorformat(chip, format, FALSE) != ~0U && 153b8e80941Smrg r600_translate_colorswap(format, FALSE) != ~0U; 154848b8605Smrg} 155848b8605Smrg 156848b8605Smrgstatic bool r600_is_zs_format_supported(enum pipe_format format) 157848b8605Smrg{ 158848b8605Smrg return r600_translate_dbformat(format) != ~0U; 159848b8605Smrg} 160848b8605Smrg 161848b8605Smrgboolean r600_is_format_supported(struct pipe_screen *screen, 162848b8605Smrg enum pipe_format format, 163848b8605Smrg enum pipe_texture_target target, 164848b8605Smrg unsigned sample_count, 165b8e80941Smrg unsigned storage_sample_count, 166848b8605Smrg unsigned usage) 167848b8605Smrg{ 168848b8605Smrg struct r600_screen *rscreen = (struct r600_screen*)screen; 169848b8605Smrg unsigned retval = 0; 170848b8605Smrg 171848b8605Smrg if (target >= PIPE_MAX_TEXTURE_TYPES) { 172848b8605Smrg R600_ERR("r600: unsupported texture type %d\n", target); 173848b8605Smrg return FALSE; 174848b8605Smrg } 175848b8605Smrg 176b8e80941Smrg if (MAX2(1, sample_count) != MAX2(1, storage_sample_count)) 177b8e80941Smrg return false; 178848b8605Smrg 179848b8605Smrg if (sample_count > 1) { 180848b8605Smrg if (!rscreen->has_msaa) 181848b8605Smrg return FALSE; 182848b8605Smrg 183848b8605Smrg /* R11G11B10 is broken on R6xx. */ 184848b8605Smrg if (rscreen->b.chip_class == R600 && 185848b8605Smrg format == PIPE_FORMAT_R11G11B10_FLOAT) 186848b8605Smrg return FALSE; 187848b8605Smrg 188848b8605Smrg /* MSAA integer colorbuffers hang. */ 189848b8605Smrg if (util_format_is_pure_integer(format) && 190848b8605Smrg !util_format_is_depth_or_stencil(format)) 191848b8605Smrg return FALSE; 192848b8605Smrg 193848b8605Smrg switch (sample_count) { 194848b8605Smrg case 2: 195848b8605Smrg case 4: 196848b8605Smrg case 8: 197848b8605Smrg break; 198848b8605Smrg default: 199848b8605Smrg return FALSE; 200848b8605Smrg } 201848b8605Smrg } 202848b8605Smrg 203848b8605Smrg if (usage & PIPE_BIND_SAMPLER_VIEW) { 204848b8605Smrg if (target == PIPE_BUFFER) { 205848b8605Smrg if (r600_is_vertex_format_supported(format)) 206848b8605Smrg retval |= PIPE_BIND_SAMPLER_VIEW; 207848b8605Smrg } else { 208848b8605Smrg if (r600_is_sampler_format_supported(screen, format)) 209848b8605Smrg retval |= PIPE_BIND_SAMPLER_VIEW; 210848b8605Smrg } 211848b8605Smrg } 212848b8605Smrg 213848b8605Smrg if ((usage & (PIPE_BIND_RENDER_TARGET | 214848b8605Smrg PIPE_BIND_DISPLAY_TARGET | 215848b8605Smrg PIPE_BIND_SCANOUT | 216b8e80941Smrg PIPE_BIND_SHARED | 217b8e80941Smrg PIPE_BIND_BLENDABLE)) && 218848b8605Smrg r600_is_colorbuffer_format_supported(rscreen->b.chip_class, format)) { 219848b8605Smrg retval |= usage & 220848b8605Smrg (PIPE_BIND_RENDER_TARGET | 221848b8605Smrg PIPE_BIND_DISPLAY_TARGET | 222848b8605Smrg PIPE_BIND_SCANOUT | 223848b8605Smrg PIPE_BIND_SHARED); 224b8e80941Smrg if (!util_format_is_pure_integer(format) && 225b8e80941Smrg !util_format_is_depth_or_stencil(format)) 226b8e80941Smrg retval |= usage & PIPE_BIND_BLENDABLE; 227848b8605Smrg } 228848b8605Smrg 229848b8605Smrg if ((usage & PIPE_BIND_DEPTH_STENCIL) && 230848b8605Smrg r600_is_zs_format_supported(format)) { 231848b8605Smrg retval |= PIPE_BIND_DEPTH_STENCIL; 232848b8605Smrg } 233848b8605Smrg 234848b8605Smrg if ((usage & PIPE_BIND_VERTEX_BUFFER) && 235848b8605Smrg r600_is_vertex_format_supported(format)) { 236848b8605Smrg retval |= PIPE_BIND_VERTEX_BUFFER; 237848b8605Smrg } 238848b8605Smrg 239b8e80941Smrg if ((usage & PIPE_BIND_LINEAR) && 240b8e80941Smrg !util_format_is_compressed(format) && 241b8e80941Smrg !(usage & PIPE_BIND_DEPTH_STENCIL)) 242b8e80941Smrg retval |= PIPE_BIND_LINEAR; 243848b8605Smrg 244848b8605Smrg return retval == usage; 245848b8605Smrg} 246848b8605Smrg 247848b8605Smrgstatic void r600_emit_polygon_offset(struct r600_context *rctx, struct r600_atom *a) 248848b8605Smrg{ 249b8e80941Smrg struct radeon_cmdbuf *cs = rctx->b.gfx.cs; 250848b8605Smrg struct r600_poly_offset_state *state = (struct r600_poly_offset_state*)a; 251848b8605Smrg float offset_units = state->offset_units; 252848b8605Smrg float offset_scale = state->offset_scale; 253b8e80941Smrg uint32_t pa_su_poly_offset_db_fmt_cntl = 0; 254b8e80941Smrg 255b8e80941Smrg if (!state->offset_units_unscaled) { 256b8e80941Smrg switch (state->zs_format) { 257b8e80941Smrg case PIPE_FORMAT_Z24X8_UNORM: 258b8e80941Smrg case PIPE_FORMAT_Z24_UNORM_S8_UINT: 259b8e80941Smrg offset_units *= 2.0f; 260b8e80941Smrg pa_su_poly_offset_db_fmt_cntl = 261b8e80941Smrg S_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS((char)-24); 262b8e80941Smrg break; 263b8e80941Smrg case PIPE_FORMAT_Z16_UNORM: 264b8e80941Smrg offset_units *= 4.0f; 265b8e80941Smrg pa_su_poly_offset_db_fmt_cntl = 266b8e80941Smrg S_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS((char)-16); 267b8e80941Smrg break; 268b8e80941Smrg default: 269b8e80941Smrg pa_su_poly_offset_db_fmt_cntl = 270b8e80941Smrg S_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS((char)-23) | 271b8e80941Smrg S_028DF8_POLY_OFFSET_DB_IS_FLOAT_FMT(1); 272b8e80941Smrg } 273848b8605Smrg } 274848b8605Smrg 275b8e80941Smrg radeon_set_context_reg_seq(cs, R_028E00_PA_SU_POLY_OFFSET_FRONT_SCALE, 4); 276848b8605Smrg radeon_emit(cs, fui(offset_scale)); 277848b8605Smrg radeon_emit(cs, fui(offset_units)); 278848b8605Smrg radeon_emit(cs, fui(offset_scale)); 279848b8605Smrg radeon_emit(cs, fui(offset_units)); 280b8e80941Smrg 281b8e80941Smrg radeon_set_context_reg(cs, R_028DF8_PA_SU_POLY_OFFSET_DB_FMT_CNTL, 282b8e80941Smrg pa_su_poly_offset_db_fmt_cntl); 283848b8605Smrg} 284848b8605Smrg 285848b8605Smrgstatic uint32_t r600_get_blend_control(const struct pipe_blend_state *state, unsigned i) 286848b8605Smrg{ 287848b8605Smrg int j = state->independent_blend_enable ? i : 0; 288848b8605Smrg 289848b8605Smrg unsigned eqRGB = state->rt[j].rgb_func; 290848b8605Smrg unsigned srcRGB = state->rt[j].rgb_src_factor; 291848b8605Smrg unsigned dstRGB = state->rt[j].rgb_dst_factor; 292848b8605Smrg 293848b8605Smrg unsigned eqA = state->rt[j].alpha_func; 294848b8605Smrg unsigned srcA = state->rt[j].alpha_src_factor; 295848b8605Smrg unsigned dstA = state->rt[j].alpha_dst_factor; 296848b8605Smrg uint32_t bc = 0; 297848b8605Smrg 298848b8605Smrg if (!state->rt[j].blend_enable) 299848b8605Smrg return 0; 300848b8605Smrg 301848b8605Smrg bc |= S_028804_COLOR_COMB_FCN(r600_translate_blend_function(eqRGB)); 302848b8605Smrg bc |= S_028804_COLOR_SRCBLEND(r600_translate_blend_factor(srcRGB)); 303848b8605Smrg bc |= S_028804_COLOR_DESTBLEND(r600_translate_blend_factor(dstRGB)); 304848b8605Smrg 305848b8605Smrg if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) { 306848b8605Smrg bc |= S_028804_SEPARATE_ALPHA_BLEND(1); 307848b8605Smrg bc |= S_028804_ALPHA_COMB_FCN(r600_translate_blend_function(eqA)); 308848b8605Smrg bc |= S_028804_ALPHA_SRCBLEND(r600_translate_blend_factor(srcA)); 309848b8605Smrg bc |= S_028804_ALPHA_DESTBLEND(r600_translate_blend_factor(dstA)); 310848b8605Smrg } 311848b8605Smrg return bc; 312848b8605Smrg} 313848b8605Smrg 314848b8605Smrgstatic void *r600_create_blend_state_mode(struct pipe_context *ctx, 315848b8605Smrg const struct pipe_blend_state *state, 316848b8605Smrg int mode) 317848b8605Smrg{ 318848b8605Smrg struct r600_context *rctx = (struct r600_context *)ctx; 319848b8605Smrg uint32_t color_control = 0, target_mask = 0; 320848b8605Smrg struct r600_blend_state *blend = CALLOC_STRUCT(r600_blend_state); 321848b8605Smrg 322848b8605Smrg if (!blend) { 323848b8605Smrg return NULL; 324848b8605Smrg } 325848b8605Smrg 326848b8605Smrg r600_init_command_buffer(&blend->buffer, 20); 327848b8605Smrg r600_init_command_buffer(&blend->buffer_no_blend, 20); 328848b8605Smrg 329848b8605Smrg /* R600 does not support per-MRT blends */ 330848b8605Smrg if (rctx->b.family > CHIP_R600) 331848b8605Smrg color_control |= S_028808_PER_MRT_BLEND(1); 332848b8605Smrg 333848b8605Smrg if (state->logicop_enable) { 334848b8605Smrg color_control |= (state->logicop_func << 16) | (state->logicop_func << 20); 335848b8605Smrg } else { 336848b8605Smrg color_control |= (0xcc << 16); 337848b8605Smrg } 338848b8605Smrg /* we pretend 8 buffer are used, CB_SHADER_MASK will disable unused one */ 339848b8605Smrg if (state->independent_blend_enable) { 340848b8605Smrg for (int i = 0; i < 8; i++) { 341848b8605Smrg if (state->rt[i].blend_enable) { 342848b8605Smrg color_control |= S_028808_TARGET_BLEND_ENABLE(1 << i); 343848b8605Smrg } 344848b8605Smrg target_mask |= (state->rt[i].colormask << (4 * i)); 345848b8605Smrg } 346848b8605Smrg } else { 347848b8605Smrg for (int i = 0; i < 8; i++) { 348848b8605Smrg if (state->rt[0].blend_enable) { 349848b8605Smrg color_control |= S_028808_TARGET_BLEND_ENABLE(1 << i); 350848b8605Smrg } 351848b8605Smrg target_mask |= (state->rt[0].colormask << (4 * i)); 352848b8605Smrg } 353848b8605Smrg } 354848b8605Smrg 355848b8605Smrg if (target_mask) 356848b8605Smrg color_control |= S_028808_SPECIAL_OP(mode); 357848b8605Smrg else 358848b8605Smrg color_control |= S_028808_SPECIAL_OP(V_028808_DISABLE); 359848b8605Smrg 360848b8605Smrg /* only MRT0 has dual src blend */ 361848b8605Smrg blend->dual_src_blend = util_blend_state_is_dual(state, 0); 362848b8605Smrg blend->cb_target_mask = target_mask; 363848b8605Smrg blend->cb_color_control = color_control; 364848b8605Smrg blend->cb_color_control_no_blend = color_control & C_028808_TARGET_BLEND_ENABLE; 365848b8605Smrg blend->alpha_to_one = state->alpha_to_one; 366848b8605Smrg 367848b8605Smrg r600_store_context_reg(&blend->buffer, R_028D44_DB_ALPHA_TO_MASK, 368848b8605Smrg S_028D44_ALPHA_TO_MASK_ENABLE(state->alpha_to_coverage) | 369848b8605Smrg S_028D44_ALPHA_TO_MASK_OFFSET0(2) | 370848b8605Smrg S_028D44_ALPHA_TO_MASK_OFFSET1(2) | 371848b8605Smrg S_028D44_ALPHA_TO_MASK_OFFSET2(2) | 372848b8605Smrg S_028D44_ALPHA_TO_MASK_OFFSET3(2)); 373848b8605Smrg 374848b8605Smrg /* Copy over the registers set so far into buffer_no_blend. */ 375848b8605Smrg memcpy(blend->buffer_no_blend.buf, blend->buffer.buf, blend->buffer.num_dw * 4); 376848b8605Smrg blend->buffer_no_blend.num_dw = blend->buffer.num_dw; 377848b8605Smrg 378848b8605Smrg /* Only add blend registers if blending is enabled. */ 379848b8605Smrg if (!G_028808_TARGET_BLEND_ENABLE(color_control)) { 380848b8605Smrg return blend; 381848b8605Smrg } 382848b8605Smrg 383848b8605Smrg /* The first R600 does not support per-MRT blends */ 384848b8605Smrg r600_store_context_reg(&blend->buffer, R_028804_CB_BLEND_CONTROL, 385848b8605Smrg r600_get_blend_control(state, 0)); 386848b8605Smrg 387848b8605Smrg if (rctx->b.family > CHIP_R600) { 388848b8605Smrg r600_store_context_reg_seq(&blend->buffer, R_028780_CB_BLEND0_CONTROL, 8); 389848b8605Smrg for (int i = 0; i < 8; i++) { 390848b8605Smrg r600_store_value(&blend->buffer, r600_get_blend_control(state, i)); 391848b8605Smrg } 392848b8605Smrg } 393848b8605Smrg return blend; 394848b8605Smrg} 395848b8605Smrg 396848b8605Smrgstatic void *r600_create_blend_state(struct pipe_context *ctx, 397848b8605Smrg const struct pipe_blend_state *state) 398848b8605Smrg{ 399848b8605Smrg return r600_create_blend_state_mode(ctx, state, V_028808_SPECIAL_NORMAL); 400848b8605Smrg} 401848b8605Smrg 402848b8605Smrgstatic void *r600_create_dsa_state(struct pipe_context *ctx, 403848b8605Smrg const struct pipe_depth_stencil_alpha_state *state) 404848b8605Smrg{ 405848b8605Smrg unsigned db_depth_control, alpha_test_control, alpha_ref; 406848b8605Smrg struct r600_dsa_state *dsa = CALLOC_STRUCT(r600_dsa_state); 407848b8605Smrg 408b8e80941Smrg if (!dsa) { 409848b8605Smrg return NULL; 410848b8605Smrg } 411848b8605Smrg 412848b8605Smrg r600_init_command_buffer(&dsa->buffer, 3); 413848b8605Smrg 414848b8605Smrg dsa->valuemask[0] = state->stencil[0].valuemask; 415848b8605Smrg dsa->valuemask[1] = state->stencil[1].valuemask; 416848b8605Smrg dsa->writemask[0] = state->stencil[0].writemask; 417848b8605Smrg dsa->writemask[1] = state->stencil[1].writemask; 418848b8605Smrg dsa->zwritemask = state->depth.writemask; 419848b8605Smrg 420848b8605Smrg db_depth_control = S_028800_Z_ENABLE(state->depth.enabled) | 421848b8605Smrg S_028800_Z_WRITE_ENABLE(state->depth.writemask) | 422848b8605Smrg S_028800_ZFUNC(state->depth.func); 423848b8605Smrg 424848b8605Smrg /* stencil */ 425848b8605Smrg if (state->stencil[0].enabled) { 426848b8605Smrg db_depth_control |= S_028800_STENCIL_ENABLE(1); 427848b8605Smrg db_depth_control |= S_028800_STENCILFUNC(state->stencil[0].func); /* translates straight */ 428848b8605Smrg db_depth_control |= S_028800_STENCILFAIL(r600_translate_stencil_op(state->stencil[0].fail_op)); 429848b8605Smrg db_depth_control |= S_028800_STENCILZPASS(r600_translate_stencil_op(state->stencil[0].zpass_op)); 430848b8605Smrg db_depth_control |= S_028800_STENCILZFAIL(r600_translate_stencil_op(state->stencil[0].zfail_op)); 431848b8605Smrg 432848b8605Smrg if (state->stencil[1].enabled) { 433848b8605Smrg db_depth_control |= S_028800_BACKFACE_ENABLE(1); 434848b8605Smrg db_depth_control |= S_028800_STENCILFUNC_BF(state->stencil[1].func); /* translates straight */ 435848b8605Smrg db_depth_control |= S_028800_STENCILFAIL_BF(r600_translate_stencil_op(state->stencil[1].fail_op)); 436848b8605Smrg db_depth_control |= S_028800_STENCILZPASS_BF(r600_translate_stencil_op(state->stencil[1].zpass_op)); 437848b8605Smrg db_depth_control |= S_028800_STENCILZFAIL_BF(r600_translate_stencil_op(state->stencil[1].zfail_op)); 438848b8605Smrg } 439848b8605Smrg } 440848b8605Smrg 441848b8605Smrg /* alpha */ 442848b8605Smrg alpha_test_control = 0; 443848b8605Smrg alpha_ref = 0; 444848b8605Smrg if (state->alpha.enabled) { 445848b8605Smrg alpha_test_control = S_028410_ALPHA_FUNC(state->alpha.func); 446848b8605Smrg alpha_test_control |= S_028410_ALPHA_TEST_ENABLE(1); 447848b8605Smrg alpha_ref = fui(state->alpha.ref_value); 448848b8605Smrg } 449848b8605Smrg dsa->sx_alpha_test_control = alpha_test_control & 0xff; 450848b8605Smrg dsa->alpha_ref = alpha_ref; 451848b8605Smrg 452848b8605Smrg r600_store_context_reg(&dsa->buffer, R_028800_DB_DEPTH_CONTROL, db_depth_control); 453848b8605Smrg return dsa; 454848b8605Smrg} 455848b8605Smrg 456848b8605Smrgstatic void *r600_create_rs_state(struct pipe_context *ctx, 457848b8605Smrg const struct pipe_rasterizer_state *state) 458848b8605Smrg{ 459848b8605Smrg struct r600_context *rctx = (struct r600_context *)ctx; 460848b8605Smrg unsigned tmp, sc_mode_cntl, spi_interp; 461848b8605Smrg float psize_min, psize_max; 462848b8605Smrg struct r600_rasterizer_state *rs = CALLOC_STRUCT(r600_rasterizer_state); 463848b8605Smrg 464b8e80941Smrg if (!rs) { 465848b8605Smrg return NULL; 466848b8605Smrg } 467848b8605Smrg 468848b8605Smrg r600_init_command_buffer(&rs->buffer, 30); 469848b8605Smrg 470b8e80941Smrg rs->scissor_enable = state->scissor; 471b8e80941Smrg rs->clip_halfz = state->clip_halfz; 472848b8605Smrg rs->flatshade = state->flatshade; 473848b8605Smrg rs->sprite_coord_enable = state->sprite_coord_enable; 474b8e80941Smrg rs->rasterizer_discard = state->rasterizer_discard; 475848b8605Smrg rs->two_side = state->light_twoside; 476848b8605Smrg rs->clip_plane_enable = state->clip_plane_enable; 477848b8605Smrg rs->pa_sc_line_stipple = state->line_stipple_enable ? 478848b8605Smrg S_028A0C_LINE_PATTERN(state->line_stipple_pattern) | 479848b8605Smrg S_028A0C_REPEAT_COUNT(state->line_stipple_factor) : 0; 480848b8605Smrg rs->pa_cl_clip_cntl = 481b8e80941Smrg S_028810_DX_CLIP_SPACE_DEF(state->clip_halfz) | 482b8e80941Smrg S_028810_ZCLIP_NEAR_DISABLE(!state->depth_clip_near) | 483b8e80941Smrg S_028810_ZCLIP_FAR_DISABLE(!state->depth_clip_far) | 484848b8605Smrg S_028810_DX_LINEAR_ATTR_CLIP_ENA(1); 485848b8605Smrg if (rctx->b.chip_class == R700) { 486848b8605Smrg rs->pa_cl_clip_cntl |= 487848b8605Smrg S_028810_DX_RASTERIZATION_KILL(state->rasterizer_discard); 488848b8605Smrg } 489848b8605Smrg rs->multisample_enable = state->multisample; 490848b8605Smrg 491848b8605Smrg /* offset */ 492848b8605Smrg rs->offset_units = state->offset_units; 493b8e80941Smrg rs->offset_scale = state->offset_scale * 16.0f; 494848b8605Smrg rs->offset_enable = state->offset_point || state->offset_line || state->offset_tri; 495b8e80941Smrg rs->offset_units_unscaled = state->offset_units_unscaled; 496848b8605Smrg 497848b8605Smrg if (state->point_size_per_vertex) { 498848b8605Smrg psize_min = util_get_min_point_size(state); 499848b8605Smrg psize_max = 8192; 500848b8605Smrg } else { 501848b8605Smrg /* Force the point size to be as if the vertex output was disabled. */ 502848b8605Smrg psize_min = state->point_size; 503848b8605Smrg psize_max = state->point_size; 504848b8605Smrg } 505848b8605Smrg 506848b8605Smrg sc_mode_cntl = S_028A4C_MSAA_ENABLE(state->multisample) | 507848b8605Smrg S_028A4C_LINE_STIPPLE_ENABLE(state->line_stipple_enable) | 508b8e80941Smrg S_028A4C_FORCE_EOV_CNTDWN_ENABLE(1) | 509b8e80941Smrg S_028A4C_PS_ITER_SAMPLE(state->multisample && rctx->ps_iter_samples > 1); 510b8e80941Smrg if (rctx->b.family == CHIP_RV770) { 511b8e80941Smrg /* workaround possible rendering corruption on RV770 with hyperz together with sample shading */ 512b8e80941Smrg sc_mode_cntl |= S_028A4C_TILE_COVER_DISABLE(state->multisample && rctx->ps_iter_samples > 1); 513b8e80941Smrg } 514848b8605Smrg if (rctx->b.chip_class >= R700) { 515848b8605Smrg sc_mode_cntl |= S_028A4C_FORCE_EOV_REZ_ENABLE(1) | 516848b8605Smrg S_028A4C_R700_ZMM_LINE_OFFSET(1) | 517b8e80941Smrg S_028A4C_R700_VPORT_SCISSOR_ENABLE(1); 518848b8605Smrg } else { 519848b8605Smrg sc_mode_cntl |= S_028A4C_WALK_ALIGN8_PRIM_FITS_ST(1); 520848b8605Smrg } 521848b8605Smrg 522848b8605Smrg spi_interp = S_0286D4_FLAT_SHADE_ENA(1); 523848b8605Smrg if (state->sprite_coord_enable) { 524848b8605Smrg spi_interp |= S_0286D4_PNT_SPRITE_ENA(1) | 525848b8605Smrg S_0286D4_PNT_SPRITE_OVRD_X(2) | 526848b8605Smrg S_0286D4_PNT_SPRITE_OVRD_Y(3) | 527848b8605Smrg S_0286D4_PNT_SPRITE_OVRD_Z(0) | 528848b8605Smrg S_0286D4_PNT_SPRITE_OVRD_W(1); 529848b8605Smrg if (state->sprite_coord_mode != PIPE_SPRITE_COORD_UPPER_LEFT) { 530848b8605Smrg spi_interp |= S_0286D4_PNT_SPRITE_TOP_1(1); 531848b8605Smrg } 532848b8605Smrg } 533848b8605Smrg 534848b8605Smrg r600_store_context_reg_seq(&rs->buffer, R_028A00_PA_SU_POINT_SIZE, 3); 535848b8605Smrg /* point size 12.4 fixed point (divide by two, because 0.5 = 1 pixel. */ 536848b8605Smrg tmp = r600_pack_float_12p4(state->point_size/2); 537848b8605Smrg r600_store_value(&rs->buffer, /* R_028A00_PA_SU_POINT_SIZE */ 538848b8605Smrg S_028A00_HEIGHT(tmp) | S_028A00_WIDTH(tmp)); 539848b8605Smrg r600_store_value(&rs->buffer, /* R_028A04_PA_SU_POINT_MINMAX */ 540848b8605Smrg S_028A04_MIN_SIZE(r600_pack_float_12p4(psize_min/2)) | 541848b8605Smrg S_028A04_MAX_SIZE(r600_pack_float_12p4(psize_max/2))); 542848b8605Smrg r600_store_value(&rs->buffer, /* R_028A08_PA_SU_LINE_CNTL */ 543848b8605Smrg S_028A08_WIDTH(r600_pack_float_12p4(state->line_width/2))); 544848b8605Smrg 545848b8605Smrg r600_store_context_reg(&rs->buffer, R_0286D4_SPI_INTERP_CONTROL_0, spi_interp); 546848b8605Smrg r600_store_context_reg(&rs->buffer, R_028A4C_PA_SC_MODE_CNTL, sc_mode_cntl); 547848b8605Smrg r600_store_context_reg(&rs->buffer, R_028C08_PA_SU_VTX_CNTL, 548848b8605Smrg S_028C08_PIX_CENTER_HALF(state->half_pixel_center) | 549848b8605Smrg S_028C08_QUANT_MODE(V_028C08_X_1_256TH)); 550848b8605Smrg r600_store_context_reg(&rs->buffer, R_028DFC_PA_SU_POLY_OFFSET_CLAMP, fui(state->offset_clamp)); 551848b8605Smrg 552848b8605Smrg rs->pa_su_sc_mode_cntl = S_028814_PROVOKING_VTX_LAST(!state->flatshade_first) | 553848b8605Smrg S_028814_CULL_FRONT(state->cull_face & PIPE_FACE_FRONT ? 1 : 0) | 554848b8605Smrg S_028814_CULL_BACK(state->cull_face & PIPE_FACE_BACK ? 1 : 0) | 555848b8605Smrg S_028814_FACE(!state->front_ccw) | 556848b8605Smrg S_028814_POLY_OFFSET_FRONT_ENABLE(util_get_offset(state, state->fill_front)) | 557848b8605Smrg S_028814_POLY_OFFSET_BACK_ENABLE(util_get_offset(state, state->fill_back)) | 558848b8605Smrg S_028814_POLY_OFFSET_PARA_ENABLE(state->offset_point || state->offset_line) | 559848b8605Smrg S_028814_POLY_MODE(state->fill_front != PIPE_POLYGON_MODE_FILL || 560848b8605Smrg state->fill_back != PIPE_POLYGON_MODE_FILL) | 561848b8605Smrg S_028814_POLYMODE_FRONT_PTYPE(r600_translate_fill(state->fill_front)) | 562848b8605Smrg S_028814_POLYMODE_BACK_PTYPE(r600_translate_fill(state->fill_back)); 563848b8605Smrg if (rctx->b.chip_class == R700) { 564848b8605Smrg r600_store_context_reg(&rs->buffer, R_028814_PA_SU_SC_MODE_CNTL, rs->pa_su_sc_mode_cntl); 565848b8605Smrg } 566848b8605Smrg if (rctx->b.chip_class == R600) { 567848b8605Smrg r600_store_context_reg(&rs->buffer, R_028350_SX_MISC, 568848b8605Smrg S_028350_MULTIPASS(state->rasterizer_discard)); 569848b8605Smrg } 570848b8605Smrg return rs; 571848b8605Smrg} 572848b8605Smrg 573b8e80941Smrgstatic unsigned r600_tex_filter(unsigned filter, unsigned max_aniso) 574b8e80941Smrg{ 575b8e80941Smrg if (filter == PIPE_TEX_FILTER_LINEAR) 576b8e80941Smrg return max_aniso > 1 ? V_03C000_SQ_TEX_XY_FILTER_ANISO_BILINEAR 577b8e80941Smrg : V_03C000_SQ_TEX_XY_FILTER_BILINEAR; 578b8e80941Smrg else 579b8e80941Smrg return max_aniso > 1 ? V_03C000_SQ_TEX_XY_FILTER_ANISO_POINT 580b8e80941Smrg : V_03C000_SQ_TEX_XY_FILTER_POINT; 581b8e80941Smrg} 582b8e80941Smrg 583848b8605Smrgstatic void *r600_create_sampler_state(struct pipe_context *ctx, 584848b8605Smrg const struct pipe_sampler_state *state) 585848b8605Smrg{ 586b8e80941Smrg struct r600_common_screen *rscreen = (struct r600_common_screen*)ctx->screen; 587848b8605Smrg struct r600_pipe_sampler_state *ss = CALLOC_STRUCT(r600_pipe_sampler_state); 588b8e80941Smrg unsigned max_aniso = rscreen->force_aniso >= 0 ? rscreen->force_aniso 589b8e80941Smrg : state->max_anisotropy; 590b8e80941Smrg unsigned max_aniso_ratio = r600_tex_aniso_filter(max_aniso); 591848b8605Smrg 592b8e80941Smrg if (!ss) { 593848b8605Smrg return NULL; 594848b8605Smrg } 595848b8605Smrg 596848b8605Smrg ss->seamless_cube_map = state->seamless_cube_map; 597848b8605Smrg ss->border_color_use = sampler_state_needs_border_color(state); 598848b8605Smrg 599848b8605Smrg /* R_03C000_SQ_TEX_SAMPLER_WORD0_0 */ 600848b8605Smrg ss->tex_sampler_words[0] = 601848b8605Smrg S_03C000_CLAMP_X(r600_tex_wrap(state->wrap_s)) | 602848b8605Smrg S_03C000_CLAMP_Y(r600_tex_wrap(state->wrap_t)) | 603848b8605Smrg S_03C000_CLAMP_Z(r600_tex_wrap(state->wrap_r)) | 604b8e80941Smrg S_03C000_XY_MAG_FILTER(r600_tex_filter(state->mag_img_filter, max_aniso)) | 605b8e80941Smrg S_03C000_XY_MIN_FILTER(r600_tex_filter(state->min_img_filter, max_aniso)) | 606848b8605Smrg S_03C000_MIP_FILTER(r600_tex_mipfilter(state->min_mip_filter)) | 607b8e80941Smrg S_03C000_MAX_ANISO_RATIO(max_aniso_ratio) | 608848b8605Smrg S_03C000_DEPTH_COMPARE_FUNCTION(r600_tex_compare(state->compare_func)) | 609848b8605Smrg S_03C000_BORDER_COLOR_TYPE(ss->border_color_use ? V_03C000_SQ_TEX_BORDER_COLOR_REGISTER : 0); 610848b8605Smrg /* R_03C004_SQ_TEX_SAMPLER_WORD1_0 */ 611848b8605Smrg ss->tex_sampler_words[1] = 612848b8605Smrg S_03C004_MIN_LOD(S_FIXED(CLAMP(state->min_lod, 0, 15), 6)) | 613848b8605Smrg S_03C004_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 15), 6)) | 614848b8605Smrg S_03C004_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 6)); 615848b8605Smrg /* R_03C008_SQ_TEX_SAMPLER_WORD2_0 */ 616848b8605Smrg ss->tex_sampler_words[2] = S_03C008_TYPE(1); 617848b8605Smrg 618848b8605Smrg if (ss->border_color_use) { 619848b8605Smrg memcpy(&ss->border_color, &state->border_color, sizeof(state->border_color)); 620848b8605Smrg } 621848b8605Smrg return ss; 622848b8605Smrg} 623848b8605Smrg 624848b8605Smrgstatic struct pipe_sampler_view * 625848b8605Smrgtexture_buffer_sampler_view(struct r600_pipe_sampler_view *view, 626848b8605Smrg unsigned width0, unsigned height0) 627b8e80941Smrg 628848b8605Smrg{ 629848b8605Smrg struct r600_texture *tmp = (struct r600_texture*)view->base.texture; 630848b8605Smrg int stride = util_format_get_blocksize(view->base.format); 631848b8605Smrg unsigned format, num_format, format_comp, endian; 632b8e80941Smrg uint64_t offset = view->base.u.buf.offset; 633b8e80941Smrg unsigned size = view->base.u.buf.size; 634848b8605Smrg 635848b8605Smrg r600_vertex_data_type(view->base.format, 636848b8605Smrg &format, &num_format, &format_comp, 637848b8605Smrg &endian); 638848b8605Smrg 639848b8605Smrg view->tex_resource = &tmp->resource; 640848b8605Smrg view->skip_mip_address_reloc = true; 641848b8605Smrg 642848b8605Smrg view->tex_resource_words[0] = offset; 643848b8605Smrg view->tex_resource_words[1] = size - 1; 644848b8605Smrg view->tex_resource_words[2] = S_038008_BASE_ADDRESS_HI(offset >> 32UL) | 645848b8605Smrg S_038008_STRIDE(stride) | 646848b8605Smrg S_038008_DATA_FORMAT(format) | 647848b8605Smrg S_038008_NUM_FORMAT_ALL(num_format) | 648848b8605Smrg S_038008_FORMAT_COMP_ALL(format_comp) | 649848b8605Smrg S_038008_ENDIAN_SWAP(endian); 650848b8605Smrg view->tex_resource_words[3] = 0; 651848b8605Smrg /* 652848b8605Smrg * in theory dword 4 is for number of elements, for use with resinfo, 653848b8605Smrg * but it seems to utterly fail to work, the amd gpu shader analyser 654848b8605Smrg * uses a const buffer to store the element sizes for buffer txq 655848b8605Smrg */ 656848b8605Smrg view->tex_resource_words[4] = 0; 657848b8605Smrg view->tex_resource_words[5] = 0; 658848b8605Smrg view->tex_resource_words[6] = S_038018_TYPE(V_038010_SQ_TEX_VTX_VALID_BUFFER); 659848b8605Smrg return &view->base; 660848b8605Smrg} 661848b8605Smrg 662848b8605Smrgstruct pipe_sampler_view * 663848b8605Smrgr600_create_sampler_view_custom(struct pipe_context *ctx, 664848b8605Smrg struct pipe_resource *texture, 665848b8605Smrg const struct pipe_sampler_view *state, 666848b8605Smrg unsigned width_first_level, unsigned height_first_level) 667848b8605Smrg{ 668848b8605Smrg struct r600_pipe_sampler_view *view = CALLOC_STRUCT(r600_pipe_sampler_view); 669848b8605Smrg struct r600_texture *tmp = (struct r600_texture*)texture; 670848b8605Smrg unsigned format, endian; 671848b8605Smrg uint32_t word4 = 0, yuv_format = 0, pitch = 0; 672848b8605Smrg unsigned char swizzle[4], array_mode = 0; 673848b8605Smrg unsigned width, height, depth, offset_level, last_level; 674b8e80941Smrg bool do_endian_swap = FALSE; 675848b8605Smrg 676b8e80941Smrg if (!view) 677848b8605Smrg return NULL; 678848b8605Smrg 679848b8605Smrg /* initialize base object */ 680848b8605Smrg view->base = *state; 681848b8605Smrg view->base.texture = NULL; 682848b8605Smrg pipe_reference(NULL, &texture->reference); 683848b8605Smrg view->base.texture = texture; 684848b8605Smrg view->base.reference.count = 1; 685848b8605Smrg view->base.context = ctx; 686848b8605Smrg 687848b8605Smrg if (texture->target == PIPE_BUFFER) 688848b8605Smrg return texture_buffer_sampler_view(view, texture->width0, 1); 689848b8605Smrg 690848b8605Smrg swizzle[0] = state->swizzle_r; 691848b8605Smrg swizzle[1] = state->swizzle_g; 692848b8605Smrg swizzle[2] = state->swizzle_b; 693848b8605Smrg swizzle[3] = state->swizzle_a; 694848b8605Smrg 695b8e80941Smrg if (R600_BIG_ENDIAN) 696b8e80941Smrg do_endian_swap = !tmp->db_compatible; 697b8e80941Smrg 698848b8605Smrg format = r600_translate_texformat(ctx->screen, state->format, 699848b8605Smrg swizzle, 700b8e80941Smrg &word4, &yuv_format, do_endian_swap); 701848b8605Smrg assert(format != ~0); 702848b8605Smrg if (format == ~0) { 703848b8605Smrg FREE(view); 704848b8605Smrg return NULL; 705848b8605Smrg } 706848b8605Smrg 707b8e80941Smrg if (state->format == PIPE_FORMAT_X24S8_UINT || 708b8e80941Smrg state->format == PIPE_FORMAT_S8X24_UINT || 709b8e80941Smrg state->format == PIPE_FORMAT_X32_S8X24_UINT || 710b8e80941Smrg state->format == PIPE_FORMAT_S8_UINT) 711b8e80941Smrg view->is_stencil_sampler = true; 712b8e80941Smrg 713b8e80941Smrg if (tmp->is_depth && !r600_can_sample_zs(tmp, view->is_stencil_sampler)) { 714848b8605Smrg if (!r600_init_flushed_depth_texture(ctx, texture, NULL)) { 715848b8605Smrg FREE(view); 716848b8605Smrg return NULL; 717848b8605Smrg } 718848b8605Smrg tmp = tmp->flushed_depth_texture; 719848b8605Smrg } 720848b8605Smrg 721b8e80941Smrg endian = r600_colorformat_endian_swap(format, do_endian_swap); 722848b8605Smrg 723848b8605Smrg offset_level = state->u.tex.first_level; 724848b8605Smrg last_level = state->u.tex.last_level - offset_level; 725848b8605Smrg width = width_first_level; 726848b8605Smrg height = height_first_level; 727848b8605Smrg depth = u_minify(texture->depth0, offset_level); 728b8e80941Smrg pitch = tmp->surface.u.legacy.level[offset_level].nblk_x * util_format_get_blockwidth(state->format); 729848b8605Smrg 730848b8605Smrg if (texture->target == PIPE_TEXTURE_1D_ARRAY) { 731848b8605Smrg height = 1; 732848b8605Smrg depth = texture->array_size; 733848b8605Smrg } else if (texture->target == PIPE_TEXTURE_2D_ARRAY) { 734848b8605Smrg depth = texture->array_size; 735848b8605Smrg } else if (texture->target == PIPE_TEXTURE_CUBE_ARRAY) 736848b8605Smrg depth = texture->array_size / 6; 737b8e80941Smrg 738b8e80941Smrg switch (tmp->surface.u.legacy.level[offset_level].mode) { 739b8e80941Smrg default: 740848b8605Smrg case RADEON_SURF_MODE_LINEAR_ALIGNED: 741848b8605Smrg array_mode = V_038000_ARRAY_LINEAR_ALIGNED; 742848b8605Smrg break; 743848b8605Smrg case RADEON_SURF_MODE_1D: 744848b8605Smrg array_mode = V_038000_ARRAY_1D_TILED_THIN1; 745848b8605Smrg break; 746848b8605Smrg case RADEON_SURF_MODE_2D: 747848b8605Smrg array_mode = V_038000_ARRAY_2D_TILED_THIN1; 748848b8605Smrg break; 749848b8605Smrg } 750848b8605Smrg 751848b8605Smrg view->tex_resource = &tmp->resource; 752848b8605Smrg view->tex_resource_words[0] = (S_038000_DIM(r600_tex_dim(texture->target, texture->nr_samples)) | 753848b8605Smrg S_038000_TILE_MODE(array_mode) | 754848b8605Smrg S_038000_TILE_TYPE(tmp->non_disp_tiling) | 755848b8605Smrg S_038000_PITCH((pitch / 8) - 1) | 756848b8605Smrg S_038000_TEX_WIDTH(width - 1)); 757848b8605Smrg view->tex_resource_words[1] = (S_038004_TEX_HEIGHT(height - 1) | 758848b8605Smrg S_038004_TEX_DEPTH(depth - 1) | 759848b8605Smrg S_038004_DATA_FORMAT(format)); 760b8e80941Smrg view->tex_resource_words[2] = tmp->surface.u.legacy.level[offset_level].offset >> 8; 761b8e80941Smrg if (offset_level >= tmp->resource.b.b.last_level) { 762b8e80941Smrg view->tex_resource_words[3] = tmp->surface.u.legacy.level[offset_level].offset >> 8; 763848b8605Smrg } else { 764b8e80941Smrg view->tex_resource_words[3] = tmp->surface.u.legacy.level[offset_level + 1].offset >> 8; 765848b8605Smrg } 766848b8605Smrg view->tex_resource_words[4] = (word4 | 767848b8605Smrg S_038010_REQUEST_SIZE(1) | 768848b8605Smrg S_038010_ENDIAN_SWAP(endian) | 769848b8605Smrg S_038010_BASE_LEVEL(0)); 770848b8605Smrg view->tex_resource_words[5] = (S_038014_BASE_ARRAY(state->u.tex.first_layer) | 771848b8605Smrg S_038014_LAST_ARRAY(state->u.tex.last_layer)); 772848b8605Smrg if (texture->nr_samples > 1) { 773848b8605Smrg /* LAST_LEVEL holds log2(nr_samples) for multisample textures */ 774848b8605Smrg view->tex_resource_words[5] |= S_038014_LAST_LEVEL(util_logbase2(texture->nr_samples)); 775848b8605Smrg } else { 776848b8605Smrg view->tex_resource_words[5] |= S_038014_LAST_LEVEL(last_level); 777848b8605Smrg } 778848b8605Smrg view->tex_resource_words[6] = (S_038018_TYPE(V_038010_SQ_TEX_VTX_VALID_TEXTURE) | 779848b8605Smrg S_038018_MAX_ANISO(4 /* max 16 samples */)); 780848b8605Smrg return &view->base; 781848b8605Smrg} 782848b8605Smrg 783848b8605Smrgstatic struct pipe_sampler_view * 784848b8605Smrgr600_create_sampler_view(struct pipe_context *ctx, 785848b8605Smrg struct pipe_resource *tex, 786848b8605Smrg const struct pipe_sampler_view *state) 787848b8605Smrg{ 788848b8605Smrg return r600_create_sampler_view_custom(ctx, tex, state, 789848b8605Smrg u_minify(tex->width0, state->u.tex.first_level), 790848b8605Smrg u_minify(tex->height0, state->u.tex.first_level)); 791848b8605Smrg} 792848b8605Smrg 793848b8605Smrgstatic void r600_emit_clip_state(struct r600_context *rctx, struct r600_atom *atom) 794848b8605Smrg{ 795b8e80941Smrg struct radeon_cmdbuf *cs = rctx->b.gfx.cs; 796848b8605Smrg struct pipe_clip_state *state = &rctx->clip_state.state; 797848b8605Smrg 798b8e80941Smrg radeon_set_context_reg_seq(cs, R_028E20_PA_CL_UCP0_X, 6*4); 799848b8605Smrg radeon_emit_array(cs, (unsigned*)state, 6*4); 800848b8605Smrg} 801848b8605Smrg 802848b8605Smrgstatic void r600_set_polygon_stipple(struct pipe_context *ctx, 803848b8605Smrg const struct pipe_poly_stipple *state) 804848b8605Smrg{ 805848b8605Smrg} 806848b8605Smrg 807848b8605Smrgstatic void r600_init_color_surface(struct r600_context *rctx, 808848b8605Smrg struct r600_surface *surf, 809848b8605Smrg bool force_cmask_fmask) 810848b8605Smrg{ 811848b8605Smrg struct r600_screen *rscreen = rctx->screen; 812848b8605Smrg struct r600_texture *rtex = (struct r600_texture*)surf->base.texture; 813848b8605Smrg unsigned level = surf->base.u.tex.level; 814848b8605Smrg unsigned pitch, slice; 815848b8605Smrg unsigned color_info; 816848b8605Smrg unsigned color_view; 817848b8605Smrg unsigned format, swap, ntype, endian; 818848b8605Smrg unsigned offset; 819848b8605Smrg const struct util_format_description *desc; 820848b8605Smrg int i; 821b8e80941Smrg bool blend_bypass = 0, blend_clamp = 0, do_endian_swap = FALSE; 822848b8605Smrg 823b8e80941Smrg if (rtex->db_compatible && !r600_can_sample_zs(rtex, false)) { 824848b8605Smrg r600_init_flushed_depth_texture(&rctx->b.b, surf->base.texture, NULL); 825848b8605Smrg rtex = rtex->flushed_depth_texture; 826848b8605Smrg assert(rtex); 827848b8605Smrg } 828848b8605Smrg 829b8e80941Smrg offset = rtex->surface.u.legacy.level[level].offset; 830b8e80941Smrg color_view = S_028080_SLICE_START(surf->base.u.tex.first_layer) | 831b8e80941Smrg S_028080_SLICE_MAX(surf->base.u.tex.last_layer); 832848b8605Smrg 833b8e80941Smrg pitch = rtex->surface.u.legacy.level[level].nblk_x / 8 - 1; 834b8e80941Smrg slice = (rtex->surface.u.legacy.level[level].nblk_x * rtex->surface.u.legacy.level[level].nblk_y) / 64; 835848b8605Smrg if (slice) { 836848b8605Smrg slice = slice - 1; 837848b8605Smrg } 838848b8605Smrg color_info = 0; 839b8e80941Smrg switch (rtex->surface.u.legacy.level[level].mode) { 840b8e80941Smrg default: 841848b8605Smrg case RADEON_SURF_MODE_LINEAR_ALIGNED: 842848b8605Smrg color_info = S_0280A0_ARRAY_MODE(V_038000_ARRAY_LINEAR_ALIGNED); 843848b8605Smrg break; 844848b8605Smrg case RADEON_SURF_MODE_1D: 845848b8605Smrg color_info = S_0280A0_ARRAY_MODE(V_038000_ARRAY_1D_TILED_THIN1); 846848b8605Smrg break; 847848b8605Smrg case RADEON_SURF_MODE_2D: 848848b8605Smrg color_info = S_0280A0_ARRAY_MODE(V_038000_ARRAY_2D_TILED_THIN1); 849848b8605Smrg break; 850848b8605Smrg } 851848b8605Smrg 852848b8605Smrg desc = util_format_description(surf->base.format); 853848b8605Smrg 854848b8605Smrg for (i = 0; i < 4; i++) { 855848b8605Smrg if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) { 856848b8605Smrg break; 857848b8605Smrg } 858848b8605Smrg } 859848b8605Smrg 860848b8605Smrg ntype = V_0280A0_NUMBER_UNORM; 861848b8605Smrg if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) 862848b8605Smrg ntype = V_0280A0_NUMBER_SRGB; 863848b8605Smrg else if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { 864848b8605Smrg if (desc->channel[i].normalized) 865848b8605Smrg ntype = V_0280A0_NUMBER_SNORM; 866848b8605Smrg else if (desc->channel[i].pure_integer) 867848b8605Smrg ntype = V_0280A0_NUMBER_SINT; 868848b8605Smrg } else if (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED) { 869848b8605Smrg if (desc->channel[i].normalized) 870848b8605Smrg ntype = V_0280A0_NUMBER_UNORM; 871848b8605Smrg else if (desc->channel[i].pure_integer) 872848b8605Smrg ntype = V_0280A0_NUMBER_UINT; 873b8e80941Smrg } else if (desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT) { 874b8e80941Smrg ntype = V_0280A0_NUMBER_FLOAT; 875848b8605Smrg } 876848b8605Smrg 877b8e80941Smrg if (R600_BIG_ENDIAN) 878b8e80941Smrg do_endian_swap = !rtex->db_compatible; 879b8e80941Smrg 880b8e80941Smrg format = r600_translate_colorformat(rctx->b.chip_class, surf->base.format, 881b8e80941Smrg do_endian_swap); 882848b8605Smrg assert(format != ~0); 883848b8605Smrg 884b8e80941Smrg swap = r600_translate_colorswap(surf->base.format, do_endian_swap); 885848b8605Smrg assert(swap != ~0); 886848b8605Smrg 887b8e80941Smrg endian = r600_colorformat_endian_swap(format, do_endian_swap); 888b8e80941Smrg 889b8e80941Smrg /* blend clamp should be set for all NORM/SRGB types */ 890b8e80941Smrg if (ntype == V_0280A0_NUMBER_UNORM || ntype == V_0280A0_NUMBER_SNORM || 891b8e80941Smrg ntype == V_0280A0_NUMBER_SRGB) 892b8e80941Smrg blend_clamp = 1; 893848b8605Smrg 894848b8605Smrg /* set blend bypass according to docs if SINT/UINT or 895848b8605Smrg 8/24 COLOR variants */ 896848b8605Smrg if (ntype == V_0280A0_NUMBER_UINT || ntype == V_0280A0_NUMBER_SINT || 897848b8605Smrg format == V_0280A0_COLOR_8_24 || format == V_0280A0_COLOR_24_8 || 898848b8605Smrg format == V_0280A0_COLOR_X24_8_32_FLOAT) { 899848b8605Smrg blend_clamp = 0; 900848b8605Smrg blend_bypass = 1; 901848b8605Smrg } 902848b8605Smrg 903848b8605Smrg surf->alphatest_bypass = ntype == V_0280A0_NUMBER_UINT || ntype == V_0280A0_NUMBER_SINT; 904848b8605Smrg 905848b8605Smrg color_info |= S_0280A0_FORMAT(format) | 906848b8605Smrg S_0280A0_COMP_SWAP(swap) | 907848b8605Smrg S_0280A0_BLEND_BYPASS(blend_bypass) | 908848b8605Smrg S_0280A0_BLEND_CLAMP(blend_clamp) | 909b8e80941Smrg S_0280A0_SIMPLE_FLOAT(1) | 910848b8605Smrg S_0280A0_NUMBER_TYPE(ntype) | 911848b8605Smrg S_0280A0_ENDIAN(endian); 912848b8605Smrg 913848b8605Smrg /* EXPORT_NORM is an optimzation that can be enabled for better 914848b8605Smrg * performance in certain cases 915848b8605Smrg */ 916848b8605Smrg if (rctx->b.chip_class == R600) { 917848b8605Smrg /* EXPORT_NORM can be enabled if: 918848b8605Smrg * - 11-bit or smaller UNORM/SNORM/SRGB 919848b8605Smrg * - BLEND_CLAMP is enabled 920848b8605Smrg * - BLEND_FLOAT32 is disabled 921848b8605Smrg */ 922848b8605Smrg if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS && 923848b8605Smrg (desc->channel[i].size < 12 && 924848b8605Smrg desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT && 925848b8605Smrg ntype != V_0280A0_NUMBER_UINT && 926848b8605Smrg ntype != V_0280A0_NUMBER_SINT) && 927848b8605Smrg G_0280A0_BLEND_CLAMP(color_info) && 928b8e80941Smrg /* XXX this condition is always true since BLEND_FLOAT32 is never set (bug?). */ 929848b8605Smrg !G_0280A0_BLEND_FLOAT32(color_info)) { 930848b8605Smrg color_info |= S_0280A0_SOURCE_FORMAT(V_0280A0_EXPORT_NORM); 931848b8605Smrg surf->export_16bpc = true; 932848b8605Smrg } 933848b8605Smrg } else { 934848b8605Smrg /* EXPORT_NORM can be enabled if: 935848b8605Smrg * - 11-bit or smaller UNORM/SNORM/SRGB 936848b8605Smrg * - 16-bit or smaller FLOAT 937848b8605Smrg */ 938848b8605Smrg if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS && 939848b8605Smrg ((desc->channel[i].size < 12 && 940848b8605Smrg desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT && 941848b8605Smrg ntype != V_0280A0_NUMBER_UINT && ntype != V_0280A0_NUMBER_SINT) || 942848b8605Smrg (desc->channel[i].size < 17 && 943848b8605Smrg desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT))) { 944848b8605Smrg color_info |= S_0280A0_SOURCE_FORMAT(V_0280A0_EXPORT_NORM); 945848b8605Smrg surf->export_16bpc = true; 946848b8605Smrg } 947848b8605Smrg } 948848b8605Smrg 949848b8605Smrg /* These might not always be initialized to zero. */ 950848b8605Smrg surf->cb_color_base = offset >> 8; 951848b8605Smrg surf->cb_color_size = S_028060_PITCH_TILE_MAX(pitch) | 952848b8605Smrg S_028060_SLICE_TILE_MAX(slice); 953848b8605Smrg surf->cb_color_fmask = surf->cb_color_base; 954848b8605Smrg surf->cb_color_cmask = surf->cb_color_base; 955848b8605Smrg surf->cb_color_mask = 0; 956848b8605Smrg 957b8e80941Smrg r600_resource_reference(&surf->cb_buffer_cmask, &rtex->resource); 958b8e80941Smrg r600_resource_reference(&surf->cb_buffer_fmask, &rtex->resource); 959848b8605Smrg 960848b8605Smrg if (rtex->cmask.size) { 961848b8605Smrg surf->cb_color_cmask = rtex->cmask.offset >> 8; 962848b8605Smrg surf->cb_color_mask |= S_028100_CMASK_BLOCK_MAX(rtex->cmask.slice_tile_max); 963848b8605Smrg 964848b8605Smrg if (rtex->fmask.size) { 965848b8605Smrg color_info |= S_0280A0_TILE_MODE(V_0280A0_FRAG_ENABLE); 966848b8605Smrg surf->cb_color_fmask = rtex->fmask.offset >> 8; 967848b8605Smrg surf->cb_color_mask |= S_028100_FMASK_TILE_MAX(rtex->fmask.slice_tile_max); 968848b8605Smrg } else { /* cmask only */ 969848b8605Smrg color_info |= S_0280A0_TILE_MODE(V_0280A0_CLEAR_ENABLE); 970848b8605Smrg } 971848b8605Smrg } else if (force_cmask_fmask) { 972848b8605Smrg /* Allocate dummy FMASK and CMASK if they aren't allocated already. 973848b8605Smrg * 974848b8605Smrg * R6xx needs FMASK and CMASK for the destination buffer of color resolve, 975848b8605Smrg * otherwise it hangs. We don't have FMASK and CMASK pre-allocated, 976848b8605Smrg * because it's not an MSAA buffer. 977848b8605Smrg */ 978848b8605Smrg struct r600_cmask_info cmask; 979848b8605Smrg struct r600_fmask_info fmask; 980848b8605Smrg 981848b8605Smrg r600_texture_get_cmask_info(&rscreen->b, rtex, &cmask); 982848b8605Smrg r600_texture_get_fmask_info(&rscreen->b, rtex, 8, &fmask); 983848b8605Smrg 984848b8605Smrg /* CMASK. */ 985848b8605Smrg if (!rctx->dummy_cmask || 986b8e80941Smrg rctx->dummy_cmask->b.b.width0 < cmask.size || 987848b8605Smrg rctx->dummy_cmask->buf->alignment % cmask.alignment != 0) { 988848b8605Smrg struct pipe_transfer *transfer; 989848b8605Smrg void *ptr; 990848b8605Smrg 991b8e80941Smrg r600_resource_reference(&rctx->dummy_cmask, NULL); 992b8e80941Smrg rctx->dummy_cmask = (struct r600_resource*) 993b8e80941Smrg r600_aligned_buffer_create(&rscreen->b.b, 0, 994b8e80941Smrg PIPE_USAGE_DEFAULT, 995b8e80941Smrg cmask.size, cmask.alignment); 996b8e80941Smrg 997b8e80941Smrg if (unlikely(!rctx->dummy_cmask)) { 998b8e80941Smrg surf->color_initialized = false; 999b8e80941Smrg return; 1000b8e80941Smrg } 1001848b8605Smrg 1002848b8605Smrg /* Set the contents to 0xCC. */ 1003848b8605Smrg ptr = pipe_buffer_map(&rctx->b.b, &rctx->dummy_cmask->b.b, PIPE_TRANSFER_WRITE, &transfer); 1004848b8605Smrg memset(ptr, 0xCC, cmask.size); 1005848b8605Smrg pipe_buffer_unmap(&rctx->b.b, transfer); 1006848b8605Smrg } 1007b8e80941Smrg r600_resource_reference(&surf->cb_buffer_cmask, rctx->dummy_cmask); 1008848b8605Smrg 1009848b8605Smrg /* FMASK. */ 1010848b8605Smrg if (!rctx->dummy_fmask || 1011b8e80941Smrg rctx->dummy_fmask->b.b.width0 < fmask.size || 1012848b8605Smrg rctx->dummy_fmask->buf->alignment % fmask.alignment != 0) { 1013b8e80941Smrg r600_resource_reference(&rctx->dummy_fmask, NULL); 1014b8e80941Smrg rctx->dummy_fmask = (struct r600_resource*) 1015b8e80941Smrg r600_aligned_buffer_create(&rscreen->b.b, 0, 1016b8e80941Smrg PIPE_USAGE_DEFAULT, 1017b8e80941Smrg fmask.size, fmask.alignment); 1018848b8605Smrg 1019b8e80941Smrg if (unlikely(!rctx->dummy_fmask)) { 1020b8e80941Smrg surf->color_initialized = false; 1021b8e80941Smrg return; 1022b8e80941Smrg } 1023848b8605Smrg } 1024b8e80941Smrg r600_resource_reference(&surf->cb_buffer_fmask, rctx->dummy_fmask); 1025848b8605Smrg 1026848b8605Smrg /* Init the registers. */ 1027848b8605Smrg color_info |= S_0280A0_TILE_MODE(V_0280A0_FRAG_ENABLE); 1028848b8605Smrg surf->cb_color_cmask = 0; 1029848b8605Smrg surf->cb_color_fmask = 0; 1030848b8605Smrg surf->cb_color_mask = S_028100_CMASK_BLOCK_MAX(cmask.slice_tile_max) | 1031848b8605Smrg S_028100_FMASK_TILE_MAX(fmask.slice_tile_max); 1032848b8605Smrg } 1033848b8605Smrg 1034848b8605Smrg surf->cb_color_info = color_info; 1035848b8605Smrg surf->cb_color_view = color_view; 1036848b8605Smrg surf->color_initialized = true; 1037848b8605Smrg} 1038848b8605Smrg 1039848b8605Smrgstatic void r600_init_depth_surface(struct r600_context *rctx, 1040848b8605Smrg struct r600_surface *surf) 1041848b8605Smrg{ 1042848b8605Smrg struct r600_texture *rtex = (struct r600_texture*)surf->base.texture; 1043848b8605Smrg unsigned level, pitch, slice, format, offset, array_mode; 1044848b8605Smrg 1045848b8605Smrg level = surf->base.u.tex.level; 1046b8e80941Smrg offset = rtex->surface.u.legacy.level[level].offset; 1047b8e80941Smrg pitch = rtex->surface.u.legacy.level[level].nblk_x / 8 - 1; 1048b8e80941Smrg slice = (rtex->surface.u.legacy.level[level].nblk_x * rtex->surface.u.legacy.level[level].nblk_y) / 64; 1049848b8605Smrg if (slice) { 1050848b8605Smrg slice = slice - 1; 1051848b8605Smrg } 1052b8e80941Smrg switch (rtex->surface.u.legacy.level[level].mode) { 1053848b8605Smrg case RADEON_SURF_MODE_2D: 1054848b8605Smrg array_mode = V_0280A0_ARRAY_2D_TILED_THIN1; 1055848b8605Smrg break; 1056848b8605Smrg case RADEON_SURF_MODE_1D: 1057848b8605Smrg case RADEON_SURF_MODE_LINEAR_ALIGNED: 1058848b8605Smrg default: 1059848b8605Smrg array_mode = V_0280A0_ARRAY_1D_TILED_THIN1; 1060848b8605Smrg break; 1061848b8605Smrg } 1062848b8605Smrg 1063848b8605Smrg format = r600_translate_dbformat(surf->base.format); 1064848b8605Smrg assert(format != ~0); 1065848b8605Smrg 1066848b8605Smrg surf->db_depth_info = S_028010_ARRAY_MODE(array_mode) | S_028010_FORMAT(format); 1067848b8605Smrg surf->db_depth_base = offset >> 8; 1068848b8605Smrg surf->db_depth_view = S_028004_SLICE_START(surf->base.u.tex.first_layer) | 1069848b8605Smrg S_028004_SLICE_MAX(surf->base.u.tex.last_layer); 1070848b8605Smrg surf->db_depth_size = S_028000_PITCH_TILE_MAX(pitch) | S_028000_SLICE_TILE_MAX(slice); 1071b8e80941Smrg surf->db_prefetch_limit = (rtex->surface.u.legacy.level[level].nblk_y / 8) - 1; 1072848b8605Smrg 1073b8e80941Smrg if (r600_htile_enabled(rtex, level)) { 1074b8e80941Smrg surf->db_htile_data_base = rtex->htile_offset >> 8; 1075848b8605Smrg surf->db_htile_surface = S_028D24_HTILE_WIDTH(1) | 1076b8e80941Smrg S_028D24_HTILE_HEIGHT(1) | 1077b8e80941Smrg S_028D24_FULL_CACHE(1); 1078848b8605Smrg /* preload is not working properly on r6xx/r7xx */ 1079848b8605Smrg surf->db_depth_info |= S_028010_TILE_SURFACE_ENABLE(1); 1080848b8605Smrg } 1081848b8605Smrg 1082848b8605Smrg surf->depth_initialized = true; 1083848b8605Smrg} 1084848b8605Smrg 1085848b8605Smrgstatic void r600_set_framebuffer_state(struct pipe_context *ctx, 1086848b8605Smrg const struct pipe_framebuffer_state *state) 1087848b8605Smrg{ 1088848b8605Smrg struct r600_context *rctx = (struct r600_context *)ctx; 1089848b8605Smrg struct r600_surface *surf; 1090848b8605Smrg struct r600_texture *rtex; 1091848b8605Smrg unsigned i; 1092b8e80941Smrg uint32_t target_mask = 0; 1093848b8605Smrg 1094b8e80941Smrg /* Flush TC when changing the framebuffer state, because the only 1095b8e80941Smrg * client not using TC that can change textures is the framebuffer. 1096b8e80941Smrg * Other places don't typically have to flush TC. 1097b8e80941Smrg */ 1098b8e80941Smrg rctx->b.flags |= R600_CONTEXT_WAIT_3D_IDLE | 1099b8e80941Smrg R600_CONTEXT_FLUSH_AND_INV | 1100b8e80941Smrg R600_CONTEXT_FLUSH_AND_INV_CB | 1101b8e80941Smrg R600_CONTEXT_FLUSH_AND_INV_CB_META | 1102b8e80941Smrg R600_CONTEXT_FLUSH_AND_INV_DB | 1103b8e80941Smrg R600_CONTEXT_FLUSH_AND_INV_DB_META | 1104b8e80941Smrg R600_CONTEXT_INV_TEX_CACHE; 1105848b8605Smrg 1106848b8605Smrg /* Set the new state. */ 1107848b8605Smrg util_copy_framebuffer_state(&rctx->framebuffer.state, state); 1108848b8605Smrg 1109848b8605Smrg rctx->framebuffer.export_16bpc = state->nr_cbufs != 0; 1110848b8605Smrg rctx->framebuffer.cb0_is_integer = state->nr_cbufs && state->cbufs[0] && 1111848b8605Smrg util_format_is_pure_integer(state->cbufs[0]->format); 1112848b8605Smrg rctx->framebuffer.compressed_cb_mask = 0; 1113848b8605Smrg rctx->framebuffer.is_msaa_resolve = state->nr_cbufs == 2 && 1114848b8605Smrg state->cbufs[0] && state->cbufs[1] && 1115848b8605Smrg state->cbufs[0]->texture->nr_samples > 1 && 1116848b8605Smrg state->cbufs[1]->texture->nr_samples <= 1; 1117848b8605Smrg rctx->framebuffer.nr_samples = util_framebuffer_get_num_samples(state); 1118848b8605Smrg 1119848b8605Smrg /* Colorbuffers. */ 1120848b8605Smrg for (i = 0; i < state->nr_cbufs; i++) { 1121848b8605Smrg /* The resolve buffer must have CMASK and FMASK to prevent hardlocks on R6xx. */ 1122848b8605Smrg bool force_cmask_fmask = rctx->b.chip_class == R600 && 1123848b8605Smrg rctx->framebuffer.is_msaa_resolve && 1124848b8605Smrg i == 1; 1125848b8605Smrg 1126848b8605Smrg surf = (struct r600_surface*)state->cbufs[i]; 1127848b8605Smrg if (!surf) 1128848b8605Smrg continue; 1129848b8605Smrg 1130848b8605Smrg rtex = (struct r600_texture*)surf->base.texture; 1131848b8605Smrg r600_context_add_resource_size(ctx, state->cbufs[i]->texture); 1132848b8605Smrg 1133b8e80941Smrg target_mask |= (0xf << (i * 4)); 1134b8e80941Smrg 1135848b8605Smrg if (!surf->color_initialized || force_cmask_fmask) { 1136848b8605Smrg r600_init_color_surface(rctx, surf, force_cmask_fmask); 1137848b8605Smrg if (force_cmask_fmask) { 1138848b8605Smrg /* re-initialize later without compression */ 1139848b8605Smrg surf->color_initialized = false; 1140848b8605Smrg } 1141848b8605Smrg } 1142848b8605Smrg 1143848b8605Smrg if (!surf->export_16bpc) { 1144848b8605Smrg rctx->framebuffer.export_16bpc = false; 1145848b8605Smrg } 1146848b8605Smrg 1147b8e80941Smrg if (rtex->fmask.size) { 1148848b8605Smrg rctx->framebuffer.compressed_cb_mask |= 1 << i; 1149848b8605Smrg } 1150848b8605Smrg } 1151848b8605Smrg 1152848b8605Smrg /* Update alpha-test state dependencies. 1153848b8605Smrg * Alpha-test is done on the first colorbuffer only. */ 1154848b8605Smrg if (state->nr_cbufs) { 1155848b8605Smrg bool alphatest_bypass = false; 1156848b8605Smrg 1157848b8605Smrg surf = (struct r600_surface*)state->cbufs[0]; 1158848b8605Smrg if (surf) { 1159848b8605Smrg alphatest_bypass = surf->alphatest_bypass; 1160848b8605Smrg } 1161848b8605Smrg 1162848b8605Smrg if (rctx->alphatest_state.bypass != alphatest_bypass) { 1163848b8605Smrg rctx->alphatest_state.bypass = alphatest_bypass; 1164b8e80941Smrg r600_mark_atom_dirty(rctx, &rctx->alphatest_state.atom); 1165848b8605Smrg } 1166848b8605Smrg } 1167848b8605Smrg 1168848b8605Smrg /* ZS buffer. */ 1169848b8605Smrg if (state->zsbuf) { 1170848b8605Smrg surf = (struct r600_surface*)state->zsbuf; 1171848b8605Smrg 1172848b8605Smrg r600_context_add_resource_size(ctx, state->zsbuf->texture); 1173848b8605Smrg 1174848b8605Smrg if (!surf->depth_initialized) { 1175848b8605Smrg r600_init_depth_surface(rctx, surf); 1176848b8605Smrg } 1177848b8605Smrg 1178848b8605Smrg if (state->zsbuf->format != rctx->poly_offset_state.zs_format) { 1179848b8605Smrg rctx->poly_offset_state.zs_format = state->zsbuf->format; 1180b8e80941Smrg r600_mark_atom_dirty(rctx, &rctx->poly_offset_state.atom); 1181848b8605Smrg } 1182848b8605Smrg 1183848b8605Smrg if (rctx->db_state.rsurf != surf) { 1184848b8605Smrg rctx->db_state.rsurf = surf; 1185b8e80941Smrg r600_mark_atom_dirty(rctx, &rctx->db_state.atom); 1186b8e80941Smrg r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom); 1187848b8605Smrg } 1188848b8605Smrg } else if (rctx->db_state.rsurf) { 1189848b8605Smrg rctx->db_state.rsurf = NULL; 1190b8e80941Smrg r600_mark_atom_dirty(rctx, &rctx->db_state.atom); 1191b8e80941Smrg r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom); 1192848b8605Smrg } 1193848b8605Smrg 1194b8e80941Smrg if (rctx->cb_misc_state.nr_cbufs != state->nr_cbufs || 1195b8e80941Smrg rctx->cb_misc_state.bound_cbufs_target_mask != target_mask) { 1196b8e80941Smrg rctx->cb_misc_state.bound_cbufs_target_mask = target_mask; 1197848b8605Smrg rctx->cb_misc_state.nr_cbufs = state->nr_cbufs; 1198b8e80941Smrg r600_mark_atom_dirty(rctx, &rctx->cb_misc_state.atom); 1199848b8605Smrg } 1200848b8605Smrg 1201848b8605Smrg if (state->nr_cbufs == 0 && rctx->alphatest_state.bypass) { 1202848b8605Smrg rctx->alphatest_state.bypass = false; 1203b8e80941Smrg r600_mark_atom_dirty(rctx, &rctx->alphatest_state.atom); 1204848b8605Smrg } 1205848b8605Smrg 1206848b8605Smrg /* Calculate the CS size. */ 1207848b8605Smrg rctx->framebuffer.atom.num_dw = 1208848b8605Smrg 10 /*COLOR_INFO*/ + 4 /*SCISSOR*/ + 3 /*SHADER_CONTROL*/ + 8 /*MSAA*/; 1209848b8605Smrg 1210848b8605Smrg if (rctx->framebuffer.state.nr_cbufs) { 1211848b8605Smrg rctx->framebuffer.atom.num_dw += 15 * rctx->framebuffer.state.nr_cbufs; 1212848b8605Smrg rctx->framebuffer.atom.num_dw += 3 * (2 + rctx->framebuffer.state.nr_cbufs); 1213848b8605Smrg } 1214848b8605Smrg if (rctx->framebuffer.state.zsbuf) { 1215848b8605Smrg rctx->framebuffer.atom.num_dw += 16; 1216848b8605Smrg } else if (rctx->screen->b.info.drm_minor >= 18) { 1217848b8605Smrg rctx->framebuffer.atom.num_dw += 3; 1218848b8605Smrg } 1219848b8605Smrg if (rctx->b.family > CHIP_R600 && rctx->b.family < CHIP_RV770) { 1220848b8605Smrg rctx->framebuffer.atom.num_dw += 2; 1221848b8605Smrg } 1222848b8605Smrg 1223b8e80941Smrg r600_mark_atom_dirty(rctx, &rctx->framebuffer.atom); 1224b8e80941Smrg 1225b8e80941Smrg r600_set_sample_locations_constant_buffer(rctx); 1226b8e80941Smrg rctx->framebuffer.do_update_surf_dirtiness = true; 1227848b8605Smrg} 1228848b8605Smrg 1229b8e80941Smrgstatic const uint32_t sample_locs_2x[] = { 1230848b8605Smrg FILL_SREG(-4, 4, 4, -4, -4, 4, 4, -4), 1231848b8605Smrg FILL_SREG(-4, 4, 4, -4, -4, 4, 4, -4), 1232848b8605Smrg}; 1233b8e80941Smrgstatic const unsigned max_dist_2x = 4; 1234848b8605Smrg 1235b8e80941Smrgstatic const uint32_t sample_locs_4x[] = { 1236848b8605Smrg FILL_SREG(-2, -2, 2, 2, -6, 6, 6, -6), 1237848b8605Smrg FILL_SREG(-2, -2, 2, 2, -6, 6, 6, -6), 1238848b8605Smrg}; 1239b8e80941Smrgstatic const unsigned max_dist_4x = 6; 1240b8e80941Smrgstatic const uint32_t sample_locs_8x[] = { 1241848b8605Smrg FILL_SREG(-1, 1, 1, 5, 3, -5, 5, 3), 1242848b8605Smrg FILL_SREG(-7, -1, -3, -7, 7, -3, -5, 7), 1243848b8605Smrg}; 1244b8e80941Smrgstatic const unsigned max_dist_8x = 7; 1245848b8605Smrg 1246848b8605Smrgstatic void r600_get_sample_position(struct pipe_context *ctx, 1247848b8605Smrg unsigned sample_count, 1248848b8605Smrg unsigned sample_index, 1249848b8605Smrg float *out_value) 1250848b8605Smrg{ 1251848b8605Smrg int offset, index; 1252848b8605Smrg struct { 1253848b8605Smrg int idx:4; 1254848b8605Smrg } val; 1255848b8605Smrg switch (sample_count) { 1256848b8605Smrg case 1: 1257848b8605Smrg default: 1258848b8605Smrg out_value[0] = out_value[1] = 0.5; 1259848b8605Smrg break; 1260848b8605Smrg case 2: 1261848b8605Smrg offset = 4 * (sample_index * 2); 1262848b8605Smrg val.idx = (sample_locs_2x[0] >> offset) & 0xf; 1263848b8605Smrg out_value[0] = (float)(val.idx + 8) / 16.0f; 1264848b8605Smrg val.idx = (sample_locs_2x[0] >> (offset + 4)) & 0xf; 1265848b8605Smrg out_value[1] = (float)(val.idx + 8) / 16.0f; 1266848b8605Smrg break; 1267848b8605Smrg case 4: 1268848b8605Smrg offset = 4 * (sample_index * 2); 1269848b8605Smrg val.idx = (sample_locs_4x[0] >> offset) & 0xf; 1270848b8605Smrg out_value[0] = (float)(val.idx + 8) / 16.0f; 1271848b8605Smrg val.idx = (sample_locs_4x[0] >> (offset + 4)) & 0xf; 1272848b8605Smrg out_value[1] = (float)(val.idx + 8) / 16.0f; 1273848b8605Smrg break; 1274848b8605Smrg case 8: 1275848b8605Smrg offset = 4 * (sample_index % 4 * 2); 1276848b8605Smrg index = (sample_index / 4); 1277848b8605Smrg val.idx = (sample_locs_8x[index] >> offset) & 0xf; 1278848b8605Smrg out_value[0] = (float)(val.idx + 8) / 16.0f; 1279848b8605Smrg val.idx = (sample_locs_8x[index] >> (offset + 4)) & 0xf; 1280848b8605Smrg out_value[1] = (float)(val.idx + 8) / 16.0f; 1281848b8605Smrg break; 1282848b8605Smrg } 1283848b8605Smrg} 1284848b8605Smrg 1285848b8605Smrgstatic void r600_emit_msaa_state(struct r600_context *rctx, int nr_samples) 1286848b8605Smrg{ 1287b8e80941Smrg struct radeon_cmdbuf *cs = rctx->b.gfx.cs; 1288848b8605Smrg unsigned max_dist = 0; 1289848b8605Smrg 1290848b8605Smrg if (rctx->b.family == CHIP_R600) { 1291848b8605Smrg switch (nr_samples) { 1292848b8605Smrg default: 1293848b8605Smrg nr_samples = 0; 1294848b8605Smrg break; 1295848b8605Smrg case 2: 1296b8e80941Smrg radeon_set_config_reg(cs, R_008B40_PA_SC_AA_SAMPLE_LOCS_2S, sample_locs_2x[0]); 1297848b8605Smrg max_dist = max_dist_2x; 1298848b8605Smrg break; 1299848b8605Smrg case 4: 1300b8e80941Smrg radeon_set_config_reg(cs, R_008B44_PA_SC_AA_SAMPLE_LOCS_4S, sample_locs_4x[0]); 1301848b8605Smrg max_dist = max_dist_4x; 1302848b8605Smrg break; 1303848b8605Smrg case 8: 1304b8e80941Smrg radeon_set_config_reg_seq(cs, R_008B48_PA_SC_AA_SAMPLE_LOCS_8S_WD0, 2); 1305848b8605Smrg radeon_emit(cs, sample_locs_8x[0]); /* R_008B48_PA_SC_AA_SAMPLE_LOCS_8S_WD0 */ 1306848b8605Smrg radeon_emit(cs, sample_locs_8x[1]); /* R_008B4C_PA_SC_AA_SAMPLE_LOCS_8S_WD1 */ 1307848b8605Smrg max_dist = max_dist_8x; 1308848b8605Smrg break; 1309848b8605Smrg } 1310848b8605Smrg } else { 1311848b8605Smrg switch (nr_samples) { 1312848b8605Smrg default: 1313b8e80941Smrg radeon_set_context_reg_seq(cs, R_028C1C_PA_SC_AA_SAMPLE_LOCS_MCTX, 2); 1314848b8605Smrg radeon_emit(cs, 0); /* R_028C1C_PA_SC_AA_SAMPLE_LOCS_MCTX */ 1315848b8605Smrg radeon_emit(cs, 0); /* R_028C20_PA_SC_AA_SAMPLE_LOCS_8D_WD1_MCTX */ 1316848b8605Smrg nr_samples = 0; 1317848b8605Smrg break; 1318848b8605Smrg case 2: 1319b8e80941Smrg radeon_set_context_reg_seq(cs, R_028C1C_PA_SC_AA_SAMPLE_LOCS_MCTX, 2); 1320848b8605Smrg radeon_emit(cs, sample_locs_2x[0]); /* R_028C1C_PA_SC_AA_SAMPLE_LOCS_MCTX */ 1321848b8605Smrg radeon_emit(cs, sample_locs_2x[1]); /* R_028C20_PA_SC_AA_SAMPLE_LOCS_8D_WD1_MCTX */ 1322848b8605Smrg max_dist = max_dist_2x; 1323848b8605Smrg break; 1324848b8605Smrg case 4: 1325b8e80941Smrg radeon_set_context_reg_seq(cs, R_028C1C_PA_SC_AA_SAMPLE_LOCS_MCTX, 2); 1326848b8605Smrg radeon_emit(cs, sample_locs_4x[0]); /* R_028C1C_PA_SC_AA_SAMPLE_LOCS_MCTX */ 1327848b8605Smrg radeon_emit(cs, sample_locs_4x[1]); /* R_028C20_PA_SC_AA_SAMPLE_LOCS_8D_WD1_MCTX */ 1328848b8605Smrg max_dist = max_dist_4x; 1329848b8605Smrg break; 1330848b8605Smrg case 8: 1331b8e80941Smrg radeon_set_context_reg_seq(cs, R_028C1C_PA_SC_AA_SAMPLE_LOCS_MCTX, 2); 1332848b8605Smrg radeon_emit(cs, sample_locs_8x[0]); /* R_028C1C_PA_SC_AA_SAMPLE_LOCS_MCTX */ 1333848b8605Smrg radeon_emit(cs, sample_locs_8x[1]); /* R_028C20_PA_SC_AA_SAMPLE_LOCS_8D_WD1_MCTX */ 1334848b8605Smrg max_dist = max_dist_8x; 1335848b8605Smrg break; 1336848b8605Smrg } 1337848b8605Smrg } 1338848b8605Smrg 1339848b8605Smrg if (nr_samples > 1) { 1340b8e80941Smrg radeon_set_context_reg_seq(cs, R_028C00_PA_SC_LINE_CNTL, 2); 1341848b8605Smrg radeon_emit(cs, S_028C00_LAST_PIXEL(1) | 1342848b8605Smrg S_028C00_EXPAND_LINE_WIDTH(1)); /* R_028C00_PA_SC_LINE_CNTL */ 1343848b8605Smrg radeon_emit(cs, S_028C04_MSAA_NUM_SAMPLES(util_logbase2(nr_samples)) | 1344848b8605Smrg S_028C04_MAX_SAMPLE_DIST(max_dist)); /* R_028C04_PA_SC_AA_CONFIG */ 1345848b8605Smrg } else { 1346b8e80941Smrg radeon_set_context_reg_seq(cs, R_028C00_PA_SC_LINE_CNTL, 2); 1347848b8605Smrg radeon_emit(cs, S_028C00_LAST_PIXEL(1)); /* R_028C00_PA_SC_LINE_CNTL */ 1348848b8605Smrg radeon_emit(cs, 0); /* R_028C04_PA_SC_AA_CONFIG */ 1349848b8605Smrg } 1350848b8605Smrg} 1351848b8605Smrg 1352848b8605Smrgstatic void r600_emit_framebuffer_state(struct r600_context *rctx, struct r600_atom *atom) 1353848b8605Smrg{ 1354b8e80941Smrg struct radeon_cmdbuf *cs = rctx->b.gfx.cs; 1355848b8605Smrg struct pipe_framebuffer_state *state = &rctx->framebuffer.state; 1356848b8605Smrg unsigned nr_cbufs = state->nr_cbufs; 1357848b8605Smrg struct r600_surface **cb = (struct r600_surface**)&state->cbufs[0]; 1358848b8605Smrg unsigned i, sbu = 0; 1359848b8605Smrg 1360848b8605Smrg /* Colorbuffers. */ 1361b8e80941Smrg radeon_set_context_reg_seq(cs, R_0280A0_CB_COLOR0_INFO, 8); 1362848b8605Smrg for (i = 0; i < nr_cbufs; i++) { 1363848b8605Smrg radeon_emit(cs, cb[i] ? cb[i]->cb_color_info : 0); 1364848b8605Smrg } 1365848b8605Smrg /* set CB_COLOR1_INFO for possible dual-src blending */ 1366b8e80941Smrg if (rctx->framebuffer.dual_src_blend && i == 1 && cb[0]) { 1367848b8605Smrg radeon_emit(cs, cb[0]->cb_color_info); 1368848b8605Smrg i++; 1369848b8605Smrg } 1370848b8605Smrg for (; i < 8; i++) { 1371848b8605Smrg radeon_emit(cs, 0); 1372848b8605Smrg } 1373848b8605Smrg 1374848b8605Smrg if (nr_cbufs) { 1375848b8605Smrg for (i = 0; i < nr_cbufs; i++) { 1376848b8605Smrg unsigned reloc; 1377848b8605Smrg 1378848b8605Smrg if (!cb[i]) 1379848b8605Smrg continue; 1380848b8605Smrg 1381848b8605Smrg /* COLOR_BASE */ 1382b8e80941Smrg radeon_set_context_reg(cs, R_028040_CB_COLOR0_BASE + i*4, cb[i]->cb_color_base); 1383848b8605Smrg 1384b8e80941Smrg reloc = radeon_add_to_buffer_list(&rctx->b, 1385b8e80941Smrg &rctx->b.gfx, 1386848b8605Smrg (struct r600_resource*)cb[i]->base.texture, 1387848b8605Smrg RADEON_USAGE_READWRITE, 1388848b8605Smrg cb[i]->base.texture->nr_samples > 1 ? 1389848b8605Smrg RADEON_PRIO_COLOR_BUFFER_MSAA : 1390848b8605Smrg RADEON_PRIO_COLOR_BUFFER); 1391848b8605Smrg radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); 1392848b8605Smrg radeon_emit(cs, reloc); 1393848b8605Smrg 1394848b8605Smrg /* FMASK */ 1395b8e80941Smrg radeon_set_context_reg(cs, R_0280E0_CB_COLOR0_FRAG + i*4, cb[i]->cb_color_fmask); 1396848b8605Smrg 1397b8e80941Smrg reloc = radeon_add_to_buffer_list(&rctx->b, 1398b8e80941Smrg &rctx->b.gfx, 1399848b8605Smrg cb[i]->cb_buffer_fmask, 1400848b8605Smrg RADEON_USAGE_READWRITE, 1401848b8605Smrg cb[i]->base.texture->nr_samples > 1 ? 1402848b8605Smrg RADEON_PRIO_COLOR_BUFFER_MSAA : 1403848b8605Smrg RADEON_PRIO_COLOR_BUFFER); 1404848b8605Smrg radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); 1405848b8605Smrg radeon_emit(cs, reloc); 1406848b8605Smrg 1407848b8605Smrg /* CMASK */ 1408b8e80941Smrg radeon_set_context_reg(cs, R_0280C0_CB_COLOR0_TILE + i*4, cb[i]->cb_color_cmask); 1409848b8605Smrg 1410b8e80941Smrg reloc = radeon_add_to_buffer_list(&rctx->b, 1411b8e80941Smrg &rctx->b.gfx, 1412848b8605Smrg cb[i]->cb_buffer_cmask, 1413848b8605Smrg RADEON_USAGE_READWRITE, 1414848b8605Smrg cb[i]->base.texture->nr_samples > 1 ? 1415848b8605Smrg RADEON_PRIO_COLOR_BUFFER_MSAA : 1416848b8605Smrg RADEON_PRIO_COLOR_BUFFER); 1417848b8605Smrg radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); 1418848b8605Smrg radeon_emit(cs, reloc); 1419848b8605Smrg } 1420848b8605Smrg 1421b8e80941Smrg radeon_set_context_reg_seq(cs, R_028060_CB_COLOR0_SIZE, nr_cbufs); 1422848b8605Smrg for (i = 0; i < nr_cbufs; i++) { 1423848b8605Smrg radeon_emit(cs, cb[i] ? cb[i]->cb_color_size : 0); 1424848b8605Smrg } 1425848b8605Smrg 1426b8e80941Smrg radeon_set_context_reg_seq(cs, R_028080_CB_COLOR0_VIEW, nr_cbufs); 1427848b8605Smrg for (i = 0; i < nr_cbufs; i++) { 1428848b8605Smrg radeon_emit(cs, cb[i] ? cb[i]->cb_color_view : 0); 1429848b8605Smrg } 1430848b8605Smrg 1431b8e80941Smrg radeon_set_context_reg_seq(cs, R_028100_CB_COLOR0_MASK, nr_cbufs); 1432848b8605Smrg for (i = 0; i < nr_cbufs; i++) { 1433848b8605Smrg radeon_emit(cs, cb[i] ? cb[i]->cb_color_mask : 0); 1434848b8605Smrg } 1435848b8605Smrg 1436848b8605Smrg sbu |= SURFACE_BASE_UPDATE_COLOR_NUM(nr_cbufs); 1437848b8605Smrg } 1438848b8605Smrg 1439848b8605Smrg /* SURFACE_BASE_UPDATE */ 1440848b8605Smrg if (rctx->b.family > CHIP_R600 && rctx->b.family < CHIP_RV770 && sbu) { 1441848b8605Smrg radeon_emit(cs, PKT3(PKT3_SURFACE_BASE_UPDATE, 0, 0)); 1442848b8605Smrg radeon_emit(cs, sbu); 1443848b8605Smrg sbu = 0; 1444848b8605Smrg } 1445848b8605Smrg 1446848b8605Smrg /* Zbuffer. */ 1447848b8605Smrg if (state->zsbuf) { 1448848b8605Smrg struct r600_surface *surf = (struct r600_surface*)state->zsbuf; 1449b8e80941Smrg unsigned reloc = radeon_add_to_buffer_list(&rctx->b, 1450b8e80941Smrg &rctx->b.gfx, 1451848b8605Smrg (struct r600_resource*)state->zsbuf->texture, 1452848b8605Smrg RADEON_USAGE_READWRITE, 1453848b8605Smrg surf->base.texture->nr_samples > 1 ? 1454848b8605Smrg RADEON_PRIO_DEPTH_BUFFER_MSAA : 1455848b8605Smrg RADEON_PRIO_DEPTH_BUFFER); 1456848b8605Smrg 1457b8e80941Smrg radeon_set_context_reg_seq(cs, R_028000_DB_DEPTH_SIZE, 2); 1458848b8605Smrg radeon_emit(cs, surf->db_depth_size); /* R_028000_DB_DEPTH_SIZE */ 1459848b8605Smrg radeon_emit(cs, surf->db_depth_view); /* R_028004_DB_DEPTH_VIEW */ 1460b8e80941Smrg radeon_set_context_reg_seq(cs, R_02800C_DB_DEPTH_BASE, 2); 1461848b8605Smrg radeon_emit(cs, surf->db_depth_base); /* R_02800C_DB_DEPTH_BASE */ 1462848b8605Smrg radeon_emit(cs, surf->db_depth_info); /* R_028010_DB_DEPTH_INFO */ 1463848b8605Smrg 1464848b8605Smrg radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); 1465848b8605Smrg radeon_emit(cs, reloc); 1466848b8605Smrg 1467b8e80941Smrg radeon_set_context_reg(cs, R_028D34_DB_PREFETCH_LIMIT, surf->db_prefetch_limit); 1468848b8605Smrg 1469848b8605Smrg sbu |= SURFACE_BASE_UPDATE_DEPTH; 1470848b8605Smrg } else if (rctx->screen->b.info.drm_minor >= 18) { 1471848b8605Smrg /* DRM 2.6.18 allows the INVALID format to disable depth/stencil. 1472848b8605Smrg * Older kernels are out of luck. */ 1473b8e80941Smrg radeon_set_context_reg(cs, R_028010_DB_DEPTH_INFO, S_028010_FORMAT(V_028010_DEPTH_INVALID)); 1474848b8605Smrg } 1475848b8605Smrg 1476848b8605Smrg /* SURFACE_BASE_UPDATE */ 1477848b8605Smrg if (rctx->b.family > CHIP_R600 && rctx->b.family < CHIP_RV770 && sbu) { 1478848b8605Smrg radeon_emit(cs, PKT3(PKT3_SURFACE_BASE_UPDATE, 0, 0)); 1479848b8605Smrg radeon_emit(cs, sbu); 1480848b8605Smrg sbu = 0; 1481848b8605Smrg } 1482848b8605Smrg 1483848b8605Smrg /* Framebuffer dimensions. */ 1484b8e80941Smrg radeon_set_context_reg_seq(cs, R_028204_PA_SC_WINDOW_SCISSOR_TL, 2); 1485848b8605Smrg radeon_emit(cs, S_028240_TL_X(0) | S_028240_TL_Y(0) | 1486848b8605Smrg S_028240_WINDOW_OFFSET_DISABLE(1)); /* R_028204_PA_SC_WINDOW_SCISSOR_TL */ 1487848b8605Smrg radeon_emit(cs, S_028244_BR_X(state->width) | 1488848b8605Smrg S_028244_BR_Y(state->height)); /* R_028208_PA_SC_WINDOW_SCISSOR_BR */ 1489848b8605Smrg 1490848b8605Smrg if (rctx->framebuffer.is_msaa_resolve) { 1491b8e80941Smrg radeon_set_context_reg(cs, R_0287A0_CB_SHADER_CONTROL, 1); 1492848b8605Smrg } else { 1493848b8605Smrg /* Always enable the first colorbuffer in CB_SHADER_CONTROL. This 1494848b8605Smrg * will assure that the alpha-test will work even if there is 1495848b8605Smrg * no colorbuffer bound. */ 1496b8e80941Smrg radeon_set_context_reg(cs, R_0287A0_CB_SHADER_CONTROL, 1497848b8605Smrg (1ull << MAX2(nr_cbufs, 1)) - 1); 1498848b8605Smrg } 1499848b8605Smrg 1500848b8605Smrg r600_emit_msaa_state(rctx, rctx->framebuffer.nr_samples); 1501848b8605Smrg} 1502848b8605Smrg 1503b8e80941Smrgstatic void r600_set_min_samples(struct pipe_context *ctx, unsigned min_samples) 1504b8e80941Smrg{ 1505b8e80941Smrg struct r600_context *rctx = (struct r600_context *)ctx; 1506b8e80941Smrg 1507b8e80941Smrg if (rctx->ps_iter_samples == min_samples) 1508b8e80941Smrg return; 1509b8e80941Smrg 1510b8e80941Smrg rctx->ps_iter_samples = min_samples; 1511b8e80941Smrg if (rctx->framebuffer.nr_samples > 1) { 1512b8e80941Smrg r600_mark_atom_dirty(rctx, &rctx->rasterizer_state.atom); 1513b8e80941Smrg if (rctx->b.chip_class == R600) 1514b8e80941Smrg r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom); 1515b8e80941Smrg } 1516b8e80941Smrg} 1517b8e80941Smrg 1518848b8605Smrgstatic void r600_emit_cb_misc_state(struct r600_context *rctx, struct r600_atom *atom) 1519848b8605Smrg{ 1520b8e80941Smrg struct radeon_cmdbuf *cs = rctx->b.gfx.cs; 1521848b8605Smrg struct r600_cb_misc_state *a = (struct r600_cb_misc_state*)atom; 1522848b8605Smrg 1523848b8605Smrg if (G_028808_SPECIAL_OP(a->cb_color_control) == V_028808_SPECIAL_RESOLVE_BOX) { 1524b8e80941Smrg radeon_set_context_reg_seq(cs, R_028238_CB_TARGET_MASK, 2); 1525848b8605Smrg if (rctx->b.chip_class == R600) { 1526848b8605Smrg radeon_emit(cs, 0xff); /* R_028238_CB_TARGET_MASK */ 1527848b8605Smrg radeon_emit(cs, 0xff); /* R_02823C_CB_SHADER_MASK */ 1528848b8605Smrg } else { 1529848b8605Smrg radeon_emit(cs, 0xf); /* R_028238_CB_TARGET_MASK */ 1530848b8605Smrg radeon_emit(cs, 0xf); /* R_02823C_CB_SHADER_MASK */ 1531848b8605Smrg } 1532b8e80941Smrg radeon_set_context_reg(cs, R_028808_CB_COLOR_CONTROL, a->cb_color_control); 1533848b8605Smrg } else { 1534b8e80941Smrg unsigned fb_colormask = a->bound_cbufs_target_mask; 1535b8e80941Smrg unsigned ps_colormask = a->ps_color_export_mask; 1536848b8605Smrg unsigned multiwrite = a->multiwrite && a->nr_cbufs > 1; 1537848b8605Smrg 1538b8e80941Smrg radeon_set_context_reg_seq(cs, R_028238_CB_TARGET_MASK, 2); 1539848b8605Smrg radeon_emit(cs, a->blend_colormask & fb_colormask); /* R_028238_CB_TARGET_MASK */ 1540848b8605Smrg /* Always enable the first color output to make sure alpha-test works even without one. */ 1541848b8605Smrg radeon_emit(cs, 0xf | (multiwrite ? fb_colormask : ps_colormask)); /* R_02823C_CB_SHADER_MASK */ 1542b8e80941Smrg radeon_set_context_reg(cs, R_028808_CB_COLOR_CONTROL, 1543848b8605Smrg a->cb_color_control | 1544848b8605Smrg S_028808_MULTIWRITE_ENABLE(multiwrite)); 1545848b8605Smrg } 1546848b8605Smrg} 1547848b8605Smrg 1548848b8605Smrgstatic void r600_emit_db_state(struct r600_context *rctx, struct r600_atom *atom) 1549848b8605Smrg{ 1550b8e80941Smrg struct radeon_cmdbuf *cs = rctx->b.gfx.cs; 1551848b8605Smrg struct r600_db_state *a = (struct r600_db_state*)atom; 1552848b8605Smrg 1553848b8605Smrg if (a->rsurf && a->rsurf->db_htile_surface) { 1554848b8605Smrg struct r600_texture *rtex = (struct r600_texture *)a->rsurf->base.texture; 1555848b8605Smrg unsigned reloc_idx; 1556848b8605Smrg 1557b8e80941Smrg radeon_set_context_reg(cs, R_02802C_DB_DEPTH_CLEAR, fui(rtex->depth_clear_value)); 1558b8e80941Smrg radeon_set_context_reg(cs, R_028D24_DB_HTILE_SURFACE, a->rsurf->db_htile_surface); 1559b8e80941Smrg radeon_set_context_reg(cs, R_028014_DB_HTILE_DATA_BASE, a->rsurf->db_htile_data_base); 1560b8e80941Smrg reloc_idx = radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, &rtex->resource, 1561b8e80941Smrg RADEON_USAGE_READWRITE, RADEON_PRIO_SEPARATE_META); 1562b8e80941Smrg radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); 1563b8e80941Smrg radeon_emit(cs, reloc_idx); 1564848b8605Smrg } else { 1565b8e80941Smrg radeon_set_context_reg(cs, R_028D24_DB_HTILE_SURFACE, 0); 1566848b8605Smrg } 1567848b8605Smrg} 1568848b8605Smrg 1569848b8605Smrgstatic void r600_emit_db_misc_state(struct r600_context *rctx, struct r600_atom *atom) 1570848b8605Smrg{ 1571b8e80941Smrg struct radeon_cmdbuf *cs = rctx->b.gfx.cs; 1572848b8605Smrg struct r600_db_misc_state *a = (struct r600_db_misc_state*)atom; 1573848b8605Smrg unsigned db_render_control = 0; 1574848b8605Smrg unsigned db_render_override = 1575848b8605Smrg S_028D10_FORCE_HIS_ENABLE0(V_028D10_FORCE_DISABLE) | 1576848b8605Smrg S_028D10_FORCE_HIS_ENABLE1(V_028D10_FORCE_DISABLE); 1577848b8605Smrg 1578b8e80941Smrg if (rctx->b.chip_class >= R700) { 1579b8e80941Smrg switch (a->ps_conservative_z) { 1580b8e80941Smrg default: /* fall through */ 1581b8e80941Smrg case TGSI_FS_DEPTH_LAYOUT_ANY: 1582b8e80941Smrg db_render_control |= S_028D0C_CONSERVATIVE_Z_EXPORT(V_028D0C_EXPORT_ANY_Z); 1583b8e80941Smrg break; 1584b8e80941Smrg case TGSI_FS_DEPTH_LAYOUT_GREATER: 1585b8e80941Smrg db_render_control |= S_028D0C_CONSERVATIVE_Z_EXPORT(V_028D0C_EXPORT_GREATER_THAN_Z); 1586b8e80941Smrg break; 1587b8e80941Smrg case TGSI_FS_DEPTH_LAYOUT_LESS: 1588b8e80941Smrg db_render_control |= S_028D0C_CONSERVATIVE_Z_EXPORT(V_028D0C_EXPORT_LESS_THAN_Z); 1589b8e80941Smrg break; 1590b8e80941Smrg } 1591b8e80941Smrg } 1592b8e80941Smrg 1593b8e80941Smrg if (rctx->b.num_occlusion_queries > 0 && 1594b8e80941Smrg !a->occlusion_queries_disabled) { 1595848b8605Smrg if (rctx->b.chip_class >= R700) { 1596848b8605Smrg db_render_control |= S_028D0C_R700_PERFECT_ZPASS_COUNTS(1); 1597848b8605Smrg } 1598848b8605Smrg db_render_override |= S_028D10_NOOP_CULL_DISABLE(1); 1599b8e80941Smrg } else { 1600b8e80941Smrg db_render_control |= S_028D0C_ZPASS_INCREMENT_DISABLE(1); 1601848b8605Smrg } 1602b8e80941Smrg 1603848b8605Smrg if (rctx->db_state.rsurf && rctx->db_state.rsurf->db_htile_surface) { 1604848b8605Smrg /* FORCE_OFF means HiZ/HiS are determined by DB_SHADER_CONTROL */ 1605848b8605Smrg db_render_override |= S_028D10_FORCE_HIZ_ENABLE(V_028D10_FORCE_OFF); 1606848b8605Smrg /* This is to fix a lockup when hyperz and alpha test are enabled at 1607848b8605Smrg * the same time somehow GPU get confuse on which order to pick for 1608848b8605Smrg * z test 1609848b8605Smrg */ 1610848b8605Smrg if (rctx->alphatest_state.sx_alpha_test_control) { 1611848b8605Smrg db_render_override |= S_028D10_FORCE_SHADER_Z_ORDER(1); 1612848b8605Smrg } 1613848b8605Smrg } else { 1614848b8605Smrg db_render_override |= S_028D10_FORCE_HIZ_ENABLE(V_028D10_FORCE_DISABLE); 1615848b8605Smrg } 1616b8e80941Smrg if (rctx->b.chip_class == R600 && rctx->framebuffer.nr_samples > 1 && rctx->ps_iter_samples > 0) { 1617b8e80941Smrg /* sample shading and hyperz causes lockups on R6xx chips */ 1618b8e80941Smrg db_render_override |= S_028D10_FORCE_HIZ_ENABLE(V_028D10_FORCE_DISABLE); 1619b8e80941Smrg } 1620848b8605Smrg if (a->flush_depthstencil_through_cb) { 1621848b8605Smrg assert(a->copy_depth || a->copy_stencil); 1622848b8605Smrg 1623848b8605Smrg db_render_control |= S_028D0C_DEPTH_COPY_ENABLE(a->copy_depth) | 1624848b8605Smrg S_028D0C_STENCIL_COPY_ENABLE(a->copy_stencil) | 1625848b8605Smrg S_028D0C_COPY_CENTROID(1) | 1626848b8605Smrg S_028D0C_COPY_SAMPLE(a->copy_sample); 1627b8e80941Smrg 1628b8e80941Smrg if (rctx->b.chip_class == R600) 1629b8e80941Smrg db_render_override |= S_028D10_NOOP_CULL_DISABLE(1); 1630b8e80941Smrg 1631b8e80941Smrg if (rctx->b.family == CHIP_RV610 || rctx->b.family == CHIP_RV630 || 1632b8e80941Smrg rctx->b.family == CHIP_RV620 || rctx->b.family == CHIP_RV635) 1633b8e80941Smrg db_render_override |= S_028D10_FORCE_HIZ_ENABLE(V_028D10_FORCE_DISABLE); 1634b8e80941Smrg } else if (a->flush_depth_inplace || a->flush_stencil_inplace) { 1635b8e80941Smrg db_render_control |= S_028D0C_DEPTH_COMPRESS_DISABLE(a->flush_depth_inplace) | 1636b8e80941Smrg S_028D0C_STENCIL_COMPRESS_DISABLE(a->flush_stencil_inplace); 1637848b8605Smrg db_render_override |= S_028D10_NOOP_CULL_DISABLE(1); 1638848b8605Smrg } 1639848b8605Smrg if (a->htile_clear) { 1640848b8605Smrg db_render_control |= S_028D0C_DEPTH_CLEAR_ENABLE(1); 1641848b8605Smrg } 1642848b8605Smrg 1643848b8605Smrg /* RV770 workaround for a hang with 8x MSAA. */ 1644848b8605Smrg if (rctx->b.family == CHIP_RV770 && a->log_samples == 3) { 1645848b8605Smrg db_render_override |= S_028D10_MAX_TILES_IN_DTT(6); 1646848b8605Smrg } 1647848b8605Smrg 1648b8e80941Smrg radeon_set_context_reg_seq(cs, R_028D0C_DB_RENDER_CONTROL, 2); 1649848b8605Smrg radeon_emit(cs, db_render_control); /* R_028D0C_DB_RENDER_CONTROL */ 1650848b8605Smrg radeon_emit(cs, db_render_override); /* R_028D10_DB_RENDER_OVERRIDE */ 1651b8e80941Smrg radeon_set_context_reg(cs, R_02880C_DB_SHADER_CONTROL, a->db_shader_control); 1652848b8605Smrg} 1653848b8605Smrg 1654848b8605Smrgstatic void r600_emit_config_state(struct r600_context *rctx, struct r600_atom *atom) 1655848b8605Smrg{ 1656b8e80941Smrg struct radeon_cmdbuf *cs = rctx->b.gfx.cs; 1657848b8605Smrg struct r600_config_state *a = (struct r600_config_state*)atom; 1658848b8605Smrg 1659b8e80941Smrg radeon_set_config_reg(cs, R_008C04_SQ_GPR_RESOURCE_MGMT_1, a->sq_gpr_resource_mgmt_1); 1660b8e80941Smrg radeon_set_config_reg(cs, R_008C08_SQ_GPR_RESOURCE_MGMT_2, a->sq_gpr_resource_mgmt_2); 1661848b8605Smrg} 1662848b8605Smrg 1663848b8605Smrgstatic void r600_emit_vertex_buffers(struct r600_context *rctx, struct r600_atom *atom) 1664848b8605Smrg{ 1665b8e80941Smrg struct radeon_cmdbuf *cs = rctx->b.gfx.cs; 1666848b8605Smrg uint32_t dirty_mask = rctx->vertex_buffer_state.dirty_mask; 1667848b8605Smrg 1668848b8605Smrg while (dirty_mask) { 1669848b8605Smrg struct pipe_vertex_buffer *vb; 1670848b8605Smrg struct r600_resource *rbuffer; 1671848b8605Smrg unsigned offset; 1672848b8605Smrg unsigned buffer_index = u_bit_scan(&dirty_mask); 1673848b8605Smrg 1674848b8605Smrg vb = &rctx->vertex_buffer_state.vb[buffer_index]; 1675b8e80941Smrg rbuffer = (struct r600_resource*)vb->buffer.resource; 1676848b8605Smrg assert(rbuffer); 1677848b8605Smrg 1678848b8605Smrg offset = vb->buffer_offset; 1679848b8605Smrg 1680b8e80941Smrg /* fetch resources start at index 320 (OFFSET_FS) */ 1681848b8605Smrg radeon_emit(cs, PKT3(PKT3_SET_RESOURCE, 7, 0)); 1682b8e80941Smrg radeon_emit(cs, (R600_FETCH_CONSTANTS_OFFSET_FS + buffer_index) * 7); 1683848b8605Smrg radeon_emit(cs, offset); /* RESOURCEi_WORD0 */ 1684b8e80941Smrg radeon_emit(cs, rbuffer->b.b.width0 - offset - 1); /* RESOURCEi_WORD1 */ 1685848b8605Smrg radeon_emit(cs, /* RESOURCEi_WORD2 */ 1686848b8605Smrg S_038008_ENDIAN_SWAP(r600_endian_swap(32)) | 1687848b8605Smrg S_038008_STRIDE(vb->stride)); 1688848b8605Smrg radeon_emit(cs, 0); /* RESOURCEi_WORD3 */ 1689848b8605Smrg radeon_emit(cs, 0); /* RESOURCEi_WORD4 */ 1690848b8605Smrg radeon_emit(cs, 0); /* RESOURCEi_WORD5 */ 1691848b8605Smrg radeon_emit(cs, 0xc0000000); /* RESOURCEi_WORD6 */ 1692848b8605Smrg 1693848b8605Smrg radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); 1694b8e80941Smrg radeon_emit(cs, radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, rbuffer, 1695b8e80941Smrg RADEON_USAGE_READ, RADEON_PRIO_VERTEX_BUFFER)); 1696848b8605Smrg } 1697848b8605Smrg} 1698848b8605Smrg 1699848b8605Smrgstatic void r600_emit_constant_buffers(struct r600_context *rctx, 1700848b8605Smrg struct r600_constbuf_state *state, 1701848b8605Smrg unsigned buffer_id_base, 1702848b8605Smrg unsigned reg_alu_constbuf_size, 1703848b8605Smrg unsigned reg_alu_const_cache) 1704848b8605Smrg{ 1705b8e80941Smrg struct radeon_cmdbuf *cs = rctx->b.gfx.cs; 1706848b8605Smrg uint32_t dirty_mask = state->dirty_mask; 1707848b8605Smrg 1708848b8605Smrg while (dirty_mask) { 1709848b8605Smrg struct pipe_constant_buffer *cb; 1710848b8605Smrg struct r600_resource *rbuffer; 1711848b8605Smrg unsigned offset; 1712848b8605Smrg unsigned buffer_index = ffs(dirty_mask) - 1; 1713848b8605Smrg unsigned gs_ring_buffer = (buffer_index == R600_GS_RING_CONST_BUFFER); 1714848b8605Smrg cb = &state->cb[buffer_index]; 1715848b8605Smrg rbuffer = (struct r600_resource*)cb->buffer; 1716848b8605Smrg assert(rbuffer); 1717848b8605Smrg 1718848b8605Smrg offset = cb->buffer_offset; 1719848b8605Smrg 1720848b8605Smrg if (!gs_ring_buffer) { 1721b8e80941Smrg assert(buffer_index < R600_MAX_HW_CONST_BUFFERS); 1722b8e80941Smrg radeon_set_context_reg(cs, reg_alu_constbuf_size + buffer_index * 4, 1723b8e80941Smrg DIV_ROUND_UP(cb->buffer_size, 256)); 1724b8e80941Smrg radeon_set_context_reg(cs, reg_alu_const_cache + buffer_index * 4, offset >> 8); 1725b8e80941Smrg radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); 1726b8e80941Smrg radeon_emit(cs, radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, rbuffer, 1727b8e80941Smrg RADEON_USAGE_READ, RADEON_PRIO_CONST_BUFFER)); 1728848b8605Smrg } 1729848b8605Smrg 1730848b8605Smrg radeon_emit(cs, PKT3(PKT3_SET_RESOURCE, 7, 0)); 1731848b8605Smrg radeon_emit(cs, (buffer_id_base + buffer_index) * 7); 1732848b8605Smrg radeon_emit(cs, offset); /* RESOURCEi_WORD0 */ 1733b8e80941Smrg radeon_emit(cs, cb->buffer_size - 1); /* RESOURCEi_WORD1 */ 1734848b8605Smrg radeon_emit(cs, /* RESOURCEi_WORD2 */ 1735848b8605Smrg S_038008_ENDIAN_SWAP(gs_ring_buffer ? ENDIAN_NONE : r600_endian_swap(32)) | 1736848b8605Smrg S_038008_STRIDE(gs_ring_buffer ? 4 : 16)); 1737848b8605Smrg radeon_emit(cs, 0); /* RESOURCEi_WORD3 */ 1738848b8605Smrg radeon_emit(cs, 0); /* RESOURCEi_WORD4 */ 1739848b8605Smrg radeon_emit(cs, 0); /* RESOURCEi_WORD5 */ 1740848b8605Smrg radeon_emit(cs, 0xc0000000); /* RESOURCEi_WORD6 */ 1741848b8605Smrg 1742848b8605Smrg radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); 1743b8e80941Smrg radeon_emit(cs, radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, rbuffer, 1744b8e80941Smrg RADEON_USAGE_READ, RADEON_PRIO_CONST_BUFFER)); 1745848b8605Smrg 1746848b8605Smrg dirty_mask &= ~(1 << buffer_index); 1747848b8605Smrg } 1748848b8605Smrg state->dirty_mask = 0; 1749848b8605Smrg} 1750848b8605Smrg 1751848b8605Smrgstatic void r600_emit_vs_constant_buffers(struct r600_context *rctx, struct r600_atom *atom) 1752848b8605Smrg{ 1753b8e80941Smrg r600_emit_constant_buffers(rctx, &rctx->constbuf_state[PIPE_SHADER_VERTEX], 1754b8e80941Smrg R600_FETCH_CONSTANTS_OFFSET_VS, 1755848b8605Smrg R_028180_ALU_CONST_BUFFER_SIZE_VS_0, 1756848b8605Smrg R_028980_ALU_CONST_CACHE_VS_0); 1757848b8605Smrg} 1758848b8605Smrg 1759848b8605Smrgstatic void r600_emit_gs_constant_buffers(struct r600_context *rctx, struct r600_atom *atom) 1760848b8605Smrg{ 1761b8e80941Smrg r600_emit_constant_buffers(rctx, &rctx->constbuf_state[PIPE_SHADER_GEOMETRY], 1762b8e80941Smrg R600_FETCH_CONSTANTS_OFFSET_GS, 1763848b8605Smrg R_0281C0_ALU_CONST_BUFFER_SIZE_GS_0, 1764848b8605Smrg R_0289C0_ALU_CONST_CACHE_GS_0); 1765848b8605Smrg} 1766848b8605Smrg 1767848b8605Smrgstatic void r600_emit_ps_constant_buffers(struct r600_context *rctx, struct r600_atom *atom) 1768848b8605Smrg{ 1769b8e80941Smrg r600_emit_constant_buffers(rctx, &rctx->constbuf_state[PIPE_SHADER_FRAGMENT], 1770b8e80941Smrg R600_FETCH_CONSTANTS_OFFSET_PS, 1771848b8605Smrg R_028140_ALU_CONST_BUFFER_SIZE_PS_0, 1772848b8605Smrg R_028940_ALU_CONST_CACHE_PS_0); 1773848b8605Smrg} 1774848b8605Smrg 1775848b8605Smrgstatic void r600_emit_sampler_views(struct r600_context *rctx, 1776848b8605Smrg struct r600_samplerview_state *state, 1777848b8605Smrg unsigned resource_id_base) 1778848b8605Smrg{ 1779b8e80941Smrg struct radeon_cmdbuf *cs = rctx->b.gfx.cs; 1780848b8605Smrg uint32_t dirty_mask = state->dirty_mask; 1781848b8605Smrg 1782848b8605Smrg while (dirty_mask) { 1783848b8605Smrg struct r600_pipe_sampler_view *rview; 1784848b8605Smrg unsigned resource_index = u_bit_scan(&dirty_mask); 1785848b8605Smrg unsigned reloc; 1786848b8605Smrg 1787848b8605Smrg rview = state->views[resource_index]; 1788848b8605Smrg assert(rview); 1789848b8605Smrg 1790848b8605Smrg radeon_emit(cs, PKT3(PKT3_SET_RESOURCE, 7, 0)); 1791848b8605Smrg radeon_emit(cs, (resource_id_base + resource_index) * 7); 1792848b8605Smrg radeon_emit_array(cs, rview->tex_resource_words, 7); 1793848b8605Smrg 1794b8e80941Smrg reloc = radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, rview->tex_resource, 1795848b8605Smrg RADEON_USAGE_READ, 1796b8e80941Smrg r600_get_sampler_view_priority(rview->tex_resource)); 1797848b8605Smrg radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); 1798848b8605Smrg radeon_emit(cs, reloc); 1799848b8605Smrg radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); 1800848b8605Smrg radeon_emit(cs, reloc); 1801848b8605Smrg } 1802848b8605Smrg state->dirty_mask = 0; 1803848b8605Smrg} 1804848b8605Smrg 1805848b8605Smrg 1806848b8605Smrgstatic void r600_emit_vs_sampler_views(struct r600_context *rctx, struct r600_atom *atom) 1807848b8605Smrg{ 1808b8e80941Smrg r600_emit_sampler_views(rctx, &rctx->samplers[PIPE_SHADER_VERTEX].views, R600_FETCH_CONSTANTS_OFFSET_VS + R600_MAX_CONST_BUFFERS); 1809848b8605Smrg} 1810848b8605Smrg 1811848b8605Smrgstatic void r600_emit_gs_sampler_views(struct r600_context *rctx, struct r600_atom *atom) 1812848b8605Smrg{ 1813b8e80941Smrg r600_emit_sampler_views(rctx, &rctx->samplers[PIPE_SHADER_GEOMETRY].views, R600_FETCH_CONSTANTS_OFFSET_GS + R600_MAX_CONST_BUFFERS); 1814848b8605Smrg} 1815848b8605Smrg 1816848b8605Smrgstatic void r600_emit_ps_sampler_views(struct r600_context *rctx, struct r600_atom *atom) 1817848b8605Smrg{ 1818b8e80941Smrg r600_emit_sampler_views(rctx, &rctx->samplers[PIPE_SHADER_FRAGMENT].views, R600_FETCH_CONSTANTS_OFFSET_PS + R600_MAX_CONST_BUFFERS); 1819848b8605Smrg} 1820848b8605Smrg 1821848b8605Smrgstatic void r600_emit_sampler_states(struct r600_context *rctx, 1822848b8605Smrg struct r600_textures_info *texinfo, 1823848b8605Smrg unsigned resource_id_base, 1824848b8605Smrg unsigned border_color_reg) 1825848b8605Smrg{ 1826b8e80941Smrg struct radeon_cmdbuf *cs = rctx->b.gfx.cs; 1827848b8605Smrg uint32_t dirty_mask = texinfo->states.dirty_mask; 1828848b8605Smrg 1829848b8605Smrg while (dirty_mask) { 1830848b8605Smrg struct r600_pipe_sampler_state *rstate; 1831848b8605Smrg struct r600_pipe_sampler_view *rview; 1832848b8605Smrg unsigned i = u_bit_scan(&dirty_mask); 1833848b8605Smrg 1834848b8605Smrg rstate = texinfo->states.states[i]; 1835848b8605Smrg assert(rstate); 1836848b8605Smrg rview = texinfo->views.views[i]; 1837848b8605Smrg 1838848b8605Smrg /* TEX_ARRAY_OVERRIDE must be set for array textures to disable 1839848b8605Smrg * filtering between layers. 1840848b8605Smrg */ 1841b8e80941Smrg enum pipe_texture_target target = PIPE_BUFFER; 1842b8e80941Smrg if (rview) 1843b8e80941Smrg target = rview->base.texture->target; 1844b8e80941Smrg if (target == PIPE_TEXTURE_1D_ARRAY || 1845b8e80941Smrg target == PIPE_TEXTURE_2D_ARRAY) { 1846b8e80941Smrg rstate->tex_sampler_words[0] |= S_03C000_TEX_ARRAY_OVERRIDE(1); 1847b8e80941Smrg texinfo->is_array_sampler[i] = true; 1848b8e80941Smrg } else { 1849b8e80941Smrg rstate->tex_sampler_words[0] &= C_03C000_TEX_ARRAY_OVERRIDE; 1850b8e80941Smrg texinfo->is_array_sampler[i] = false; 1851848b8605Smrg } 1852848b8605Smrg 1853848b8605Smrg radeon_emit(cs, PKT3(PKT3_SET_SAMPLER, 3, 0)); 1854848b8605Smrg radeon_emit(cs, (resource_id_base + i) * 3); 1855848b8605Smrg radeon_emit_array(cs, rstate->tex_sampler_words, 3); 1856848b8605Smrg 1857848b8605Smrg if (rstate->border_color_use) { 1858848b8605Smrg unsigned offset; 1859848b8605Smrg 1860848b8605Smrg offset = border_color_reg; 1861848b8605Smrg offset += i * 16; 1862b8e80941Smrg radeon_set_config_reg_seq(cs, offset, 4); 1863848b8605Smrg radeon_emit_array(cs, rstate->border_color.ui, 4); 1864848b8605Smrg } 1865848b8605Smrg } 1866848b8605Smrg texinfo->states.dirty_mask = 0; 1867848b8605Smrg} 1868848b8605Smrg 1869848b8605Smrgstatic void r600_emit_vs_sampler_states(struct r600_context *rctx, struct r600_atom *atom) 1870848b8605Smrg{ 1871848b8605Smrg r600_emit_sampler_states(rctx, &rctx->samplers[PIPE_SHADER_VERTEX], 18, R_00A600_TD_VS_SAMPLER0_BORDER_RED); 1872848b8605Smrg} 1873848b8605Smrg 1874848b8605Smrgstatic void r600_emit_gs_sampler_states(struct r600_context *rctx, struct r600_atom *atom) 1875848b8605Smrg{ 1876848b8605Smrg r600_emit_sampler_states(rctx, &rctx->samplers[PIPE_SHADER_GEOMETRY], 36, R_00A800_TD_GS_SAMPLER0_BORDER_RED); 1877848b8605Smrg} 1878848b8605Smrg 1879848b8605Smrgstatic void r600_emit_ps_sampler_states(struct r600_context *rctx, struct r600_atom *atom) 1880848b8605Smrg{ 1881848b8605Smrg r600_emit_sampler_states(rctx, &rctx->samplers[PIPE_SHADER_FRAGMENT], 0, R_00A400_TD_PS_SAMPLER0_BORDER_RED); 1882848b8605Smrg} 1883848b8605Smrg 1884848b8605Smrgstatic void r600_emit_seamless_cube_map(struct r600_context *rctx, struct r600_atom *atom) 1885848b8605Smrg{ 1886b8e80941Smrg struct radeon_cmdbuf *cs = rctx->b.gfx.cs; 1887848b8605Smrg unsigned tmp; 1888848b8605Smrg 1889848b8605Smrg tmp = S_009508_DISABLE_CUBE_ANISO(1) | 1890848b8605Smrg S_009508_SYNC_GRADIENT(1) | 1891848b8605Smrg S_009508_SYNC_WALKER(1) | 1892848b8605Smrg S_009508_SYNC_ALIGNER(1); 1893848b8605Smrg if (!rctx->seamless_cube_map.enabled) { 1894848b8605Smrg tmp |= S_009508_DISABLE_CUBE_WRAP(1); 1895848b8605Smrg } 1896b8e80941Smrg radeon_set_config_reg(cs, R_009508_TA_CNTL_AUX, tmp); 1897848b8605Smrg} 1898848b8605Smrg 1899848b8605Smrgstatic void r600_emit_sample_mask(struct r600_context *rctx, struct r600_atom *a) 1900848b8605Smrg{ 1901848b8605Smrg struct r600_sample_mask *s = (struct r600_sample_mask*)a; 1902848b8605Smrg uint8_t mask = s->sample_mask; 1903848b8605Smrg 1904b8e80941Smrg radeon_set_context_reg(rctx->b.gfx.cs, R_028C48_PA_SC_AA_MASK, 1905848b8605Smrg mask | (mask << 8) | (mask << 16) | (mask << 24)); 1906848b8605Smrg} 1907848b8605Smrg 1908848b8605Smrgstatic void r600_emit_vertex_fetch_shader(struct r600_context *rctx, struct r600_atom *a) 1909848b8605Smrg{ 1910b8e80941Smrg struct radeon_cmdbuf *cs = rctx->b.gfx.cs; 1911848b8605Smrg struct r600_cso_state *state = (struct r600_cso_state*)a; 1912848b8605Smrg struct r600_fetch_shader *shader = (struct r600_fetch_shader*)state->cso; 1913848b8605Smrg 1914b8e80941Smrg if (!shader) 1915b8e80941Smrg return; 1916b8e80941Smrg 1917b8e80941Smrg radeon_set_context_reg(cs, R_028894_SQ_PGM_START_FS, shader->offset >> 8); 1918848b8605Smrg radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); 1919b8e80941Smrg radeon_emit(cs, radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, shader->buffer, 1920b8e80941Smrg RADEON_USAGE_READ, 1921b8e80941Smrg RADEON_PRIO_SHADER_BINARY)); 1922848b8605Smrg} 1923848b8605Smrg 1924848b8605Smrgstatic void r600_emit_shader_stages(struct r600_context *rctx, struct r600_atom *a) 1925848b8605Smrg{ 1926b8e80941Smrg struct radeon_cmdbuf *cs = rctx->b.gfx.cs; 1927848b8605Smrg struct r600_shader_stages_state *state = (struct r600_shader_stages_state*)a; 1928848b8605Smrg 1929848b8605Smrg uint32_t v2 = 0, primid = 0; 1930848b8605Smrg 1931b8e80941Smrg if (rctx->vs_shader->current->shader.vs_as_gs_a) { 1932b8e80941Smrg v2 = S_028A40_MODE(V_028A40_GS_SCENARIO_A); 1933b8e80941Smrg primid = 1; 1934b8e80941Smrg } 1935b8e80941Smrg 1936848b8605Smrg if (state->geom_enable) { 1937848b8605Smrg uint32_t cut_val; 1938848b8605Smrg 1939b8e80941Smrg if (rctx->gs_shader->gs_max_out_vertices <= 128) 1940848b8605Smrg cut_val = V_028A40_GS_CUT_128; 1941b8e80941Smrg else if (rctx->gs_shader->gs_max_out_vertices <= 256) 1942848b8605Smrg cut_val = V_028A40_GS_CUT_256; 1943b8e80941Smrg else if (rctx->gs_shader->gs_max_out_vertices <= 512) 1944848b8605Smrg cut_val = V_028A40_GS_CUT_512; 1945848b8605Smrg else 1946848b8605Smrg cut_val = V_028A40_GS_CUT_1024; 1947848b8605Smrg 1948848b8605Smrg v2 = S_028A40_MODE(V_028A40_GS_SCENARIO_G) | 1949848b8605Smrg S_028A40_CUT_MODE(cut_val); 1950848b8605Smrg 1951848b8605Smrg if (rctx->gs_shader->current->shader.gs_prim_id_input) 1952848b8605Smrg primid = 1; 1953848b8605Smrg } 1954848b8605Smrg 1955b8e80941Smrg radeon_set_context_reg(cs, R_028A40_VGT_GS_MODE, v2); 1956b8e80941Smrg radeon_set_context_reg(cs, R_028A84_VGT_PRIMITIVEID_EN, primid); 1957848b8605Smrg} 1958848b8605Smrg 1959848b8605Smrgstatic void r600_emit_gs_rings(struct r600_context *rctx, struct r600_atom *a) 1960848b8605Smrg{ 1961b8e80941Smrg struct radeon_cmdbuf *cs = rctx->b.gfx.cs; 1962848b8605Smrg struct r600_gs_rings_state *state = (struct r600_gs_rings_state*)a; 1963848b8605Smrg struct r600_resource *rbuffer; 1964848b8605Smrg 1965b8e80941Smrg radeon_set_config_reg(cs, R_008040_WAIT_UNTIL, S_008040_WAIT_3D_IDLE(1)); 1966848b8605Smrg radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 0, 0)); 1967848b8605Smrg radeon_emit(cs, EVENT_TYPE(EVENT_TYPE_VGT_FLUSH)); 1968848b8605Smrg 1969848b8605Smrg if (state->enable) { 1970848b8605Smrg rbuffer =(struct r600_resource*)state->esgs_ring.buffer; 1971b8e80941Smrg radeon_set_config_reg(cs, R_008C40_SQ_ESGS_RING_BASE, 0); 1972848b8605Smrg radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); 1973b8e80941Smrg radeon_emit(cs, radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, rbuffer, 1974848b8605Smrg RADEON_USAGE_READWRITE, 1975b8e80941Smrg RADEON_PRIO_SHADER_RINGS)); 1976b8e80941Smrg radeon_set_config_reg(cs, R_008C44_SQ_ESGS_RING_SIZE, 1977848b8605Smrg state->esgs_ring.buffer_size >> 8); 1978848b8605Smrg 1979848b8605Smrg rbuffer =(struct r600_resource*)state->gsvs_ring.buffer; 1980b8e80941Smrg radeon_set_config_reg(cs, R_008C48_SQ_GSVS_RING_BASE, 0); 1981848b8605Smrg radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); 1982b8e80941Smrg radeon_emit(cs, radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, rbuffer, 1983848b8605Smrg RADEON_USAGE_READWRITE, 1984b8e80941Smrg RADEON_PRIO_SHADER_RINGS)); 1985b8e80941Smrg radeon_set_config_reg(cs, R_008C4C_SQ_GSVS_RING_SIZE, 1986848b8605Smrg state->gsvs_ring.buffer_size >> 8); 1987848b8605Smrg } else { 1988b8e80941Smrg radeon_set_config_reg(cs, R_008C44_SQ_ESGS_RING_SIZE, 0); 1989b8e80941Smrg radeon_set_config_reg(cs, R_008C4C_SQ_GSVS_RING_SIZE, 0); 1990848b8605Smrg } 1991848b8605Smrg 1992b8e80941Smrg radeon_set_config_reg(cs, R_008040_WAIT_UNTIL, S_008040_WAIT_3D_IDLE(1)); 1993848b8605Smrg radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 0, 0)); 1994848b8605Smrg radeon_emit(cs, EVENT_TYPE(EVENT_TYPE_VGT_FLUSH)); 1995848b8605Smrg} 1996848b8605Smrg 1997848b8605Smrg/* Adjust GPR allocation on R6xx/R7xx */ 1998848b8605Smrgbool r600_adjust_gprs(struct r600_context *rctx) 1999848b8605Smrg{ 2000b8e80941Smrg unsigned num_gprs[R600_NUM_HW_STAGES]; 2001b8e80941Smrg unsigned new_gprs[R600_NUM_HW_STAGES]; 2002b8e80941Smrg unsigned cur_gprs[R600_NUM_HW_STAGES]; 2003b8e80941Smrg unsigned def_gprs[R600_NUM_HW_STAGES]; 2004848b8605Smrg unsigned def_num_clause_temp_gprs = rctx->r6xx_num_clause_temp_gprs; 2005b8e80941Smrg unsigned max_gprs; 2006848b8605Smrg unsigned tmp, tmp2; 2007b8e80941Smrg unsigned i; 2008b8e80941Smrg bool need_recalc = false, use_default = true; 2009848b8605Smrg 2010b8e80941Smrg /* hardware will reserve twice num_clause_temp_gprs */ 2011b8e80941Smrg max_gprs = def_num_clause_temp_gprs * 2; 2012b8e80941Smrg for (i = 0; i < R600_NUM_HW_STAGES; i++) { 2013b8e80941Smrg def_gprs[i] = rctx->default_gprs[i]; 2014b8e80941Smrg max_gprs += def_gprs[i]; 2015b8e80941Smrg } 2016b8e80941Smrg 2017b8e80941Smrg cur_gprs[R600_HW_STAGE_PS] = G_008C04_NUM_PS_GPRS(rctx->config_state.sq_gpr_resource_mgmt_1); 2018b8e80941Smrg cur_gprs[R600_HW_STAGE_VS] = G_008C04_NUM_VS_GPRS(rctx->config_state.sq_gpr_resource_mgmt_1); 2019b8e80941Smrg cur_gprs[R600_HW_STAGE_GS] = G_008C08_NUM_GS_GPRS(rctx->config_state.sq_gpr_resource_mgmt_2); 2020b8e80941Smrg cur_gprs[R600_HW_STAGE_ES] = G_008C08_NUM_ES_GPRS(rctx->config_state.sq_gpr_resource_mgmt_2); 2021b8e80941Smrg 2022b8e80941Smrg num_gprs[R600_HW_STAGE_PS] = rctx->ps_shader->current->shader.bc.ngpr; 2023848b8605Smrg if (rctx->gs_shader) { 2024b8e80941Smrg num_gprs[R600_HW_STAGE_ES] = rctx->vs_shader->current->shader.bc.ngpr; 2025b8e80941Smrg num_gprs[R600_HW_STAGE_GS] = rctx->gs_shader->current->shader.bc.ngpr; 2026b8e80941Smrg num_gprs[R600_HW_STAGE_VS] = rctx->gs_shader->current->gs_copy_shader->shader.bc.ngpr; 2027848b8605Smrg } else { 2028b8e80941Smrg num_gprs[R600_HW_STAGE_ES] = 0; 2029b8e80941Smrg num_gprs[R600_HW_STAGE_GS] = 0; 2030b8e80941Smrg num_gprs[R600_HW_STAGE_VS] = rctx->vs_shader->current->shader.bc.ngpr; 2031b8e80941Smrg } 2032b8e80941Smrg 2033b8e80941Smrg for (i = 0; i < R600_NUM_HW_STAGES; i++) { 2034b8e80941Smrg new_gprs[i] = num_gprs[i]; 2035b8e80941Smrg if (new_gprs[i] > cur_gprs[i]) 2036b8e80941Smrg need_recalc = true; 2037b8e80941Smrg if (new_gprs[i] > def_gprs[i]) 2038b8e80941Smrg use_default = false; 2039848b8605Smrg } 2040848b8605Smrg 2041848b8605Smrg /* the sum of all SQ_GPR_RESOURCE_MGMT*.NUM_*_GPRS must <= to max_gprs */ 2042b8e80941Smrg if (!need_recalc) 2043848b8605Smrg return true; 2044b8e80941Smrg 2045b8e80941Smrg /* try to use switch back to default */ 2046b8e80941Smrg if (!use_default) { 2047b8e80941Smrg /* always privilege vs stage so that at worst we have the 2048b8e80941Smrg * pixel stage producing wrong output (not the vertex 2049b8e80941Smrg * stage) */ 2050b8e80941Smrg new_gprs[R600_HW_STAGE_PS] = max_gprs - def_num_clause_temp_gprs * 2; 2051b8e80941Smrg for (i = R600_HW_STAGE_VS; i < R600_NUM_HW_STAGES; i++) 2052b8e80941Smrg new_gprs[R600_HW_STAGE_PS] -= new_gprs[i]; 2053b8e80941Smrg } else { 2054b8e80941Smrg for (i = 0; i < R600_NUM_HW_STAGES; i++) 2055b8e80941Smrg new_gprs[i] = def_gprs[i]; 2056848b8605Smrg } 2057848b8605Smrg 2058848b8605Smrg /* SQ_PGM_RESOURCES_*.NUM_GPRS must always be program to a value <= 2059848b8605Smrg * SQ_GPR_RESOURCE_MGMT*.NUM_*_GPRS otherwise the GPU will lockup 2060848b8605Smrg * Also if a shader use more gpr than SQ_GPR_RESOURCE_MGMT*.NUM_*_GPRS 2061848b8605Smrg * it will lockup. So in this case just discard the draw command 2062848b8605Smrg * and don't change the current gprs repartitions. 2063848b8605Smrg */ 2064b8e80941Smrg for (i = 0; i < R600_NUM_HW_STAGES; i++) { 2065b8e80941Smrg if (num_gprs[i] > new_gprs[i]) { 2066b8e80941Smrg R600_ERR("shaders require too many register (%d + %d + %d + %d) " 2067b8e80941Smrg "for a combined maximum of %d\n", 2068b8e80941Smrg num_gprs[R600_HW_STAGE_PS], num_gprs[R600_HW_STAGE_VS], num_gprs[R600_HW_STAGE_ES], num_gprs[R600_HW_STAGE_GS], max_gprs); 2069b8e80941Smrg return false; 2070b8e80941Smrg } 2071848b8605Smrg } 2072848b8605Smrg 2073848b8605Smrg /* in some case we endup recomputing the current value */ 2074b8e80941Smrg tmp = S_008C04_NUM_PS_GPRS(new_gprs[R600_HW_STAGE_PS]) | 2075b8e80941Smrg S_008C04_NUM_VS_GPRS(new_gprs[R600_HW_STAGE_VS]) | 2076848b8605Smrg S_008C04_NUM_CLAUSE_TEMP_GPRS(def_num_clause_temp_gprs); 2077848b8605Smrg 2078b8e80941Smrg tmp2 = S_008C08_NUM_ES_GPRS(new_gprs[R600_HW_STAGE_ES]) | 2079b8e80941Smrg S_008C08_NUM_GS_GPRS(new_gprs[R600_HW_STAGE_GS]); 2080848b8605Smrg if (rctx->config_state.sq_gpr_resource_mgmt_1 != tmp || rctx->config_state.sq_gpr_resource_mgmt_2 != tmp2) { 2081848b8605Smrg rctx->config_state.sq_gpr_resource_mgmt_1 = tmp; 2082848b8605Smrg rctx->config_state.sq_gpr_resource_mgmt_2 = tmp2; 2083b8e80941Smrg r600_mark_atom_dirty(rctx, &rctx->config_state.atom); 2084848b8605Smrg rctx->b.flags |= R600_CONTEXT_WAIT_3D_IDLE; 2085848b8605Smrg } 2086848b8605Smrg return true; 2087848b8605Smrg} 2088848b8605Smrg 2089848b8605Smrgvoid r600_init_atom_start_cs(struct r600_context *rctx) 2090848b8605Smrg{ 2091848b8605Smrg int ps_prio; 2092848b8605Smrg int vs_prio; 2093848b8605Smrg int gs_prio; 2094848b8605Smrg int es_prio; 2095848b8605Smrg int num_ps_gprs; 2096848b8605Smrg int num_vs_gprs; 2097848b8605Smrg int num_gs_gprs; 2098848b8605Smrg int num_es_gprs; 2099848b8605Smrg int num_temp_gprs; 2100848b8605Smrg int num_ps_threads; 2101848b8605Smrg int num_vs_threads; 2102848b8605Smrg int num_gs_threads; 2103848b8605Smrg int num_es_threads; 2104848b8605Smrg int num_ps_stack_entries; 2105848b8605Smrg int num_vs_stack_entries; 2106848b8605Smrg int num_gs_stack_entries; 2107848b8605Smrg int num_es_stack_entries; 2108848b8605Smrg enum radeon_family family; 2109848b8605Smrg struct r600_command_buffer *cb = &rctx->start_cs_cmd; 2110848b8605Smrg uint32_t tmp, i; 2111848b8605Smrg 2112848b8605Smrg r600_init_command_buffer(cb, 256); 2113848b8605Smrg 2114848b8605Smrg /* R6xx requires this packet at the start of each command buffer */ 2115848b8605Smrg if (rctx->b.chip_class == R600) { 2116848b8605Smrg r600_store_value(cb, PKT3(PKT3_START_3D_CMDBUF, 0, 0)); 2117848b8605Smrg r600_store_value(cb, 0); 2118848b8605Smrg } 2119848b8605Smrg /* All asics require this one */ 2120848b8605Smrg r600_store_value(cb, PKT3(PKT3_CONTEXT_CONTROL, 1, 0)); 2121848b8605Smrg r600_store_value(cb, 0x80000000); 2122848b8605Smrg r600_store_value(cb, 0x80000000); 2123848b8605Smrg 2124848b8605Smrg /* We're setting config registers here. */ 2125848b8605Smrg r600_store_value(cb, PKT3(PKT3_EVENT_WRITE, 0, 0)); 2126848b8605Smrg r600_store_value(cb, EVENT_TYPE(EVENT_TYPE_PS_PARTIAL_FLUSH) | EVENT_INDEX(4)); 2127848b8605Smrg 2128b8e80941Smrg /* This enables pipeline stat & streamout queries. 2129b8e80941Smrg * They are only disabled by blits. 2130b8e80941Smrg */ 2131b8e80941Smrg r600_store_value(cb, PKT3(PKT3_EVENT_WRITE, 0, 0)); 2132b8e80941Smrg r600_store_value(cb, EVENT_TYPE(EVENT_TYPE_PIPELINESTAT_START) | EVENT_INDEX(0)); 2133b8e80941Smrg 2134848b8605Smrg family = rctx->b.family; 2135848b8605Smrg ps_prio = 0; 2136848b8605Smrg vs_prio = 1; 2137848b8605Smrg gs_prio = 2; 2138848b8605Smrg es_prio = 3; 2139848b8605Smrg switch (family) { 2140848b8605Smrg case CHIP_R600: 2141848b8605Smrg num_ps_gprs = 192; 2142848b8605Smrg num_vs_gprs = 56; 2143848b8605Smrg num_temp_gprs = 4; 2144848b8605Smrg num_gs_gprs = 0; 2145848b8605Smrg num_es_gprs = 0; 2146848b8605Smrg num_ps_threads = 136; 2147848b8605Smrg num_vs_threads = 48; 2148848b8605Smrg num_gs_threads = 4; 2149848b8605Smrg num_es_threads = 4; 2150848b8605Smrg num_ps_stack_entries = 128; 2151848b8605Smrg num_vs_stack_entries = 128; 2152848b8605Smrg num_gs_stack_entries = 0; 2153848b8605Smrg num_es_stack_entries = 0; 2154848b8605Smrg break; 2155848b8605Smrg case CHIP_RV630: 2156848b8605Smrg case CHIP_RV635: 2157848b8605Smrg num_ps_gprs = 84; 2158848b8605Smrg num_vs_gprs = 36; 2159848b8605Smrg num_temp_gprs = 4; 2160848b8605Smrg num_gs_gprs = 0; 2161848b8605Smrg num_es_gprs = 0; 2162848b8605Smrg num_ps_threads = 144; 2163848b8605Smrg num_vs_threads = 40; 2164848b8605Smrg num_gs_threads = 4; 2165848b8605Smrg num_es_threads = 4; 2166848b8605Smrg num_ps_stack_entries = 40; 2167848b8605Smrg num_vs_stack_entries = 40; 2168848b8605Smrg num_gs_stack_entries = 32; 2169848b8605Smrg num_es_stack_entries = 16; 2170848b8605Smrg break; 2171848b8605Smrg case CHIP_RV610: 2172848b8605Smrg case CHIP_RV620: 2173848b8605Smrg case CHIP_RS780: 2174848b8605Smrg case CHIP_RS880: 2175848b8605Smrg default: 2176848b8605Smrg num_ps_gprs = 84; 2177848b8605Smrg num_vs_gprs = 36; 2178848b8605Smrg num_temp_gprs = 4; 2179848b8605Smrg num_gs_gprs = 0; 2180848b8605Smrg num_es_gprs = 0; 2181b8e80941Smrg /* use limits 40 VS and at least 16 ES/GS */ 2182b8e80941Smrg num_ps_threads = 120; 2183b8e80941Smrg num_vs_threads = 40; 2184b8e80941Smrg num_gs_threads = 16; 2185b8e80941Smrg num_es_threads = 16; 2186848b8605Smrg num_ps_stack_entries = 40; 2187848b8605Smrg num_vs_stack_entries = 40; 2188848b8605Smrg num_gs_stack_entries = 32; 2189848b8605Smrg num_es_stack_entries = 16; 2190848b8605Smrg break; 2191848b8605Smrg case CHIP_RV670: 2192848b8605Smrg num_ps_gprs = 144; 2193848b8605Smrg num_vs_gprs = 40; 2194848b8605Smrg num_temp_gprs = 4; 2195848b8605Smrg num_gs_gprs = 0; 2196848b8605Smrg num_es_gprs = 0; 2197848b8605Smrg num_ps_threads = 136; 2198848b8605Smrg num_vs_threads = 48; 2199848b8605Smrg num_gs_threads = 4; 2200848b8605Smrg num_es_threads = 4; 2201848b8605Smrg num_ps_stack_entries = 40; 2202848b8605Smrg num_vs_stack_entries = 40; 2203848b8605Smrg num_gs_stack_entries = 32; 2204848b8605Smrg num_es_stack_entries = 16; 2205848b8605Smrg break; 2206848b8605Smrg case CHIP_RV770: 2207848b8605Smrg num_ps_gprs = 130; 2208848b8605Smrg num_vs_gprs = 56; 2209848b8605Smrg num_temp_gprs = 4; 2210848b8605Smrg num_gs_gprs = 31; 2211848b8605Smrg num_es_gprs = 31; 2212848b8605Smrg num_ps_threads = 180; 2213848b8605Smrg num_vs_threads = 60; 2214848b8605Smrg num_gs_threads = 4; 2215848b8605Smrg num_es_threads = 4; 2216848b8605Smrg num_ps_stack_entries = 128; 2217848b8605Smrg num_vs_stack_entries = 128; 2218848b8605Smrg num_gs_stack_entries = 128; 2219848b8605Smrg num_es_stack_entries = 128; 2220848b8605Smrg break; 2221848b8605Smrg case CHIP_RV730: 2222848b8605Smrg case CHIP_RV740: 2223848b8605Smrg num_ps_gprs = 84; 2224848b8605Smrg num_vs_gprs = 36; 2225848b8605Smrg num_temp_gprs = 4; 2226848b8605Smrg num_gs_gprs = 0; 2227848b8605Smrg num_es_gprs = 0; 2228848b8605Smrg num_ps_threads = 180; 2229848b8605Smrg num_vs_threads = 60; 2230848b8605Smrg num_gs_threads = 4; 2231848b8605Smrg num_es_threads = 4; 2232848b8605Smrg num_ps_stack_entries = 128; 2233848b8605Smrg num_vs_stack_entries = 128; 2234848b8605Smrg num_gs_stack_entries = 0; 2235848b8605Smrg num_es_stack_entries = 0; 2236848b8605Smrg break; 2237848b8605Smrg case CHIP_RV710: 2238848b8605Smrg num_ps_gprs = 192; 2239848b8605Smrg num_vs_gprs = 56; 2240848b8605Smrg num_temp_gprs = 4; 2241848b8605Smrg num_gs_gprs = 0; 2242848b8605Smrg num_es_gprs = 0; 2243848b8605Smrg num_ps_threads = 136; 2244848b8605Smrg num_vs_threads = 48; 2245848b8605Smrg num_gs_threads = 4; 2246848b8605Smrg num_es_threads = 4; 2247848b8605Smrg num_ps_stack_entries = 128; 2248848b8605Smrg num_vs_stack_entries = 128; 2249848b8605Smrg num_gs_stack_entries = 0; 2250848b8605Smrg num_es_stack_entries = 0; 2251848b8605Smrg break; 2252848b8605Smrg } 2253848b8605Smrg 2254b8e80941Smrg rctx->default_gprs[R600_HW_STAGE_PS] = num_ps_gprs; 2255b8e80941Smrg rctx->default_gprs[R600_HW_STAGE_VS] = num_vs_gprs; 2256b8e80941Smrg rctx->default_gprs[R600_HW_STAGE_GS] = 0; 2257b8e80941Smrg rctx->default_gprs[R600_HW_STAGE_ES] = 0; 2258b8e80941Smrg 2259848b8605Smrg rctx->r6xx_num_clause_temp_gprs = num_temp_gprs; 2260848b8605Smrg 2261848b8605Smrg /* SQ_CONFIG */ 2262848b8605Smrg tmp = 0; 2263848b8605Smrg switch (family) { 2264848b8605Smrg case CHIP_RV610: 2265848b8605Smrg case CHIP_RV620: 2266848b8605Smrg case CHIP_RS780: 2267848b8605Smrg case CHIP_RS880: 2268848b8605Smrg case CHIP_RV710: 2269848b8605Smrg break; 2270848b8605Smrg default: 2271848b8605Smrg tmp |= S_008C00_VC_ENABLE(1); 2272848b8605Smrg break; 2273848b8605Smrg } 2274848b8605Smrg tmp |= S_008C00_DX9_CONSTS(0); 2275848b8605Smrg tmp |= S_008C00_ALU_INST_PREFER_VECTOR(1); 2276848b8605Smrg tmp |= S_008C00_PS_PRIO(ps_prio); 2277848b8605Smrg tmp |= S_008C00_VS_PRIO(vs_prio); 2278848b8605Smrg tmp |= S_008C00_GS_PRIO(gs_prio); 2279848b8605Smrg tmp |= S_008C00_ES_PRIO(es_prio); 2280848b8605Smrg r600_store_config_reg(cb, R_008C00_SQ_CONFIG, tmp); 2281848b8605Smrg 2282848b8605Smrg /* SQ_GPR_RESOURCE_MGMT_2 */ 2283848b8605Smrg tmp = S_008C08_NUM_GS_GPRS(num_gs_gprs); 2284848b8605Smrg tmp |= S_008C08_NUM_ES_GPRS(num_es_gprs); 2285848b8605Smrg r600_store_config_reg_seq(cb, R_008C08_SQ_GPR_RESOURCE_MGMT_2, 4); 2286848b8605Smrg r600_store_value(cb, tmp); 2287848b8605Smrg 2288848b8605Smrg /* SQ_THREAD_RESOURCE_MGMT */ 2289848b8605Smrg tmp = S_008C0C_NUM_PS_THREADS(num_ps_threads); 2290848b8605Smrg tmp |= S_008C0C_NUM_VS_THREADS(num_vs_threads); 2291848b8605Smrg tmp |= S_008C0C_NUM_GS_THREADS(num_gs_threads); 2292848b8605Smrg tmp |= S_008C0C_NUM_ES_THREADS(num_es_threads); 2293848b8605Smrg r600_store_value(cb, tmp); /* R_008C0C_SQ_THREAD_RESOURCE_MGMT */ 2294848b8605Smrg 2295848b8605Smrg /* SQ_STACK_RESOURCE_MGMT_1 */ 2296848b8605Smrg tmp = S_008C10_NUM_PS_STACK_ENTRIES(num_ps_stack_entries); 2297848b8605Smrg tmp |= S_008C10_NUM_VS_STACK_ENTRIES(num_vs_stack_entries); 2298848b8605Smrg r600_store_value(cb, tmp); /* R_008C10_SQ_STACK_RESOURCE_MGMT_1 */ 2299848b8605Smrg 2300848b8605Smrg /* SQ_STACK_RESOURCE_MGMT_2 */ 2301848b8605Smrg tmp = S_008C14_NUM_GS_STACK_ENTRIES(num_gs_stack_entries); 2302848b8605Smrg tmp |= S_008C14_NUM_ES_STACK_ENTRIES(num_es_stack_entries); 2303848b8605Smrg r600_store_value(cb, tmp); /* R_008C14_SQ_STACK_RESOURCE_MGMT_2 */ 2304848b8605Smrg 2305848b8605Smrg r600_store_config_reg(cb, R_009714_VC_ENHANCE, 0); 2306848b8605Smrg 2307848b8605Smrg if (rctx->b.chip_class >= R700) { 2308b8e80941Smrg r600_store_context_reg(cb, R_028A50_VGT_ENHANCE, 4); 2309848b8605Smrg r600_store_config_reg(cb, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0x00004000); 2310848b8605Smrg r600_store_config_reg(cb, R_009830_DB_DEBUG, 0); 2311848b8605Smrg r600_store_config_reg(cb, R_009838_DB_WATERMARKS, 0x00420204); 2312848b8605Smrg r600_store_context_reg(cb, R_0286C8_SPI_THREAD_GROUPING, 0); 2313848b8605Smrg } else { 2314848b8605Smrg r600_store_config_reg(cb, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0); 2315848b8605Smrg r600_store_config_reg(cb, R_009830_DB_DEBUG, 0x82000000); 2316848b8605Smrg r600_store_config_reg(cb, R_009838_DB_WATERMARKS, 0x01020204); 2317848b8605Smrg r600_store_context_reg(cb, R_0286C8_SPI_THREAD_GROUPING, 1); 2318848b8605Smrg } 2319848b8605Smrg r600_store_context_reg_seq(cb, R_0288A8_SQ_ESGS_RING_ITEMSIZE, 9); 2320848b8605Smrg r600_store_value(cb, 0); /* R_0288A8_SQ_ESGS_RING_ITEMSIZE */ 2321848b8605Smrg r600_store_value(cb, 0); /* R_0288AC_SQ_GSVS_RING_ITEMSIZE */ 2322848b8605Smrg r600_store_value(cb, 0); /* R_0288B0_SQ_ESTMP_RING_ITEMSIZE */ 2323848b8605Smrg r600_store_value(cb, 0); /* R_0288B4_SQ_GSTMP_RING_ITEMSIZE */ 2324848b8605Smrg r600_store_value(cb, 0); /* R_0288B8_SQ_VSTMP_RING_ITEMSIZE */ 2325848b8605Smrg r600_store_value(cb, 0); /* R_0288BC_SQ_PSTMP_RING_ITEMSIZE */ 2326848b8605Smrg r600_store_value(cb, 0); /* R_0288C0_SQ_FBUF_RING_ITEMSIZE */ 2327848b8605Smrg r600_store_value(cb, 0); /* R_0288C4_SQ_REDUC_RING_ITEMSIZE */ 2328848b8605Smrg r600_store_value(cb, 0); /* R_0288C8_SQ_GS_VERT_ITEMSIZE */ 2329848b8605Smrg 2330848b8605Smrg /* to avoid GPU doing any preloading of constant from random address */ 2331848b8605Smrg r600_store_context_reg_seq(cb, R_028140_ALU_CONST_BUFFER_SIZE_PS_0, 16); 2332848b8605Smrg for (i = 0; i < 16; i++) 2333848b8605Smrg r600_store_value(cb, 0); 2334848b8605Smrg 2335848b8605Smrg r600_store_context_reg_seq(cb, R_028180_ALU_CONST_BUFFER_SIZE_VS_0, 16); 2336848b8605Smrg for (i = 0; i < 16; i++) 2337848b8605Smrg r600_store_value(cb, 0); 2338848b8605Smrg 2339848b8605Smrg r600_store_context_reg_seq(cb, R_0281C0_ALU_CONST_BUFFER_SIZE_GS_0, 16); 2340848b8605Smrg for (i = 0; i < 16; i++) 2341848b8605Smrg r600_store_value(cb, 0); 2342848b8605Smrg 2343848b8605Smrg r600_store_context_reg_seq(cb, R_028A10_VGT_OUTPUT_PATH_CNTL, 13); 2344848b8605Smrg r600_store_value(cb, 0); /* R_028A10_VGT_OUTPUT_PATH_CNTL */ 2345848b8605Smrg r600_store_value(cb, 0); /* R_028A14_VGT_HOS_CNTL */ 2346848b8605Smrg r600_store_value(cb, 0); /* R_028A18_VGT_HOS_MAX_TESS_LEVEL */ 2347848b8605Smrg r600_store_value(cb, 0); /* R_028A1C_VGT_HOS_MIN_TESS_LEVEL */ 2348848b8605Smrg r600_store_value(cb, 0); /* R_028A20_VGT_HOS_REUSE_DEPTH */ 2349848b8605Smrg r600_store_value(cb, 0); /* R_028A24_VGT_GROUP_PRIM_TYPE */ 2350848b8605Smrg r600_store_value(cb, 0); /* R_028A28_VGT_GROUP_FIRST_DECR */ 2351848b8605Smrg r600_store_value(cb, 0); /* R_028A2C_VGT_GROUP_DECR */ 2352848b8605Smrg r600_store_value(cb, 0); /* R_028A30_VGT_GROUP_VECT_0_CNTL */ 2353848b8605Smrg r600_store_value(cb, 0); /* R_028A34_VGT_GROUP_VECT_1_CNTL */ 2354848b8605Smrg r600_store_value(cb, 0); /* R_028A38_VGT_GROUP_VECT_0_FMT_CNTL */ 2355848b8605Smrg r600_store_value(cb, 0); /* R_028A3C_VGT_GROUP_VECT_1_FMT_CNTL */ 2356848b8605Smrg r600_store_value(cb, 0); /* R_028A40_VGT_GS_MODE, 0); */ 2357848b8605Smrg 2358848b8605Smrg r600_store_context_reg(cb, R_028A84_VGT_PRIMITIVEID_EN, 0); 2359848b8605Smrg r600_store_context_reg(cb, R_028AA0_VGT_INSTANCE_STEP_RATE_0, 0); 2360848b8605Smrg r600_store_context_reg(cb, R_028AA4_VGT_INSTANCE_STEP_RATE_1, 0); 2361848b8605Smrg 2362848b8605Smrg r600_store_context_reg_seq(cb, R_028AB4_VGT_REUSE_OFF, 2); 2363848b8605Smrg r600_store_value(cb, 1); /* R_028AB4_VGT_REUSE_OFF */ 2364848b8605Smrg r600_store_value(cb, 0); /* R_028AB8_VGT_VTX_CNT_EN */ 2365848b8605Smrg 2366848b8605Smrg r600_store_context_reg(cb, R_028B20_VGT_STRMOUT_BUFFER_EN, 0); 2367848b8605Smrg 2368848b8605Smrg r600_store_ctl_const(cb, R_03CFF0_SQ_VTX_BASE_VTX_LOC, 0); 2369848b8605Smrg 2370848b8605Smrg r600_store_context_reg(cb, R_028028_DB_STENCIL_CLEAR, 0); 2371848b8605Smrg 2372848b8605Smrg r600_store_context_reg_seq(cb, R_0286DC_SPI_FOG_CNTL, 3); 2373848b8605Smrg r600_store_value(cb, 0); /* R_0286DC_SPI_FOG_CNTL */ 2374848b8605Smrg r600_store_value(cb, 0); /* R_0286E0_SPI_FOG_FUNC_SCALE */ 2375848b8605Smrg r600_store_value(cb, 0); /* R_0286E4_SPI_FOG_FUNC_BIAS */ 2376848b8605Smrg 2377848b8605Smrg r600_store_context_reg_seq(cb, R_028D28_DB_SRESULTS_COMPARE_STATE0, 3); 2378848b8605Smrg r600_store_value(cb, 0); /* R_028D28_DB_SRESULTS_COMPARE_STATE0 */ 2379848b8605Smrg r600_store_value(cb, 0); /* R_028D2C_DB_SRESULTS_COMPARE_STATE1 */ 2380848b8605Smrg r600_store_value(cb, 0); /* R_028D30_DB_PRELOAD_CONTROL */ 2381848b8605Smrg 2382848b8605Smrg r600_store_context_reg(cb, R_028820_PA_CL_NANINF_CNTL, 0); 2383848b8605Smrg r600_store_context_reg(cb, R_028A48_PA_SC_MPASS_PS_CNTL, 0); 2384848b8605Smrg 2385848b8605Smrg r600_store_context_reg(cb, R_028200_PA_SC_WINDOW_OFFSET, 0); 2386848b8605Smrg r600_store_context_reg(cb, R_02820C_PA_SC_CLIPRECT_RULE, 0xFFFF); 2387848b8605Smrg 2388848b8605Smrg if (rctx->b.chip_class >= R700) { 2389848b8605Smrg r600_store_context_reg(cb, R_028230_PA_SC_EDGERULE, 0xAAAAAAAA); 2390848b8605Smrg } 2391848b8605Smrg 2392848b8605Smrg r600_store_context_reg_seq(cb, R_028C30_CB_CLRCMP_CONTROL, 4); 2393848b8605Smrg r600_store_value(cb, 0x1000000); /* R_028C30_CB_CLRCMP_CONTROL */ 2394848b8605Smrg r600_store_value(cb, 0); /* R_028C34_CB_CLRCMP_SRC */ 2395848b8605Smrg r600_store_value(cb, 0xFF); /* R_028C38_CB_CLRCMP_DST */ 2396848b8605Smrg r600_store_value(cb, 0xFFFFFFFF); /* R_028C3C_CB_CLRCMP_MSK */ 2397848b8605Smrg 2398848b8605Smrg r600_store_context_reg_seq(cb, R_028030_PA_SC_SCREEN_SCISSOR_TL, 2); 2399848b8605Smrg r600_store_value(cb, 0); /* R_028030_PA_SC_SCREEN_SCISSOR_TL */ 2400848b8605Smrg r600_store_value(cb, S_028034_BR_X(8192) | S_028034_BR_Y(8192)); /* R_028034_PA_SC_SCREEN_SCISSOR_BR */ 2401848b8605Smrg 2402848b8605Smrg r600_store_context_reg_seq(cb, R_028240_PA_SC_GENERIC_SCISSOR_TL, 2); 2403848b8605Smrg r600_store_value(cb, 0); /* R_028240_PA_SC_GENERIC_SCISSOR_TL */ 2404848b8605Smrg r600_store_value(cb, S_028244_BR_X(8192) | S_028244_BR_Y(8192)); /* R_028244_PA_SC_GENERIC_SCISSOR_BR */ 2405848b8605Smrg 2406848b8605Smrg r600_store_context_reg_seq(cb, R_0288CC_SQ_PGM_CF_OFFSET_PS, 5); 2407848b8605Smrg r600_store_value(cb, 0); /* R_0288CC_SQ_PGM_CF_OFFSET_PS */ 2408848b8605Smrg r600_store_value(cb, 0); /* R_0288D0_SQ_PGM_CF_OFFSET_VS */ 2409848b8605Smrg r600_store_value(cb, 0); /* R_0288D4_SQ_PGM_CF_OFFSET_GS */ 2410848b8605Smrg r600_store_value(cb, 0); /* R_0288D8_SQ_PGM_CF_OFFSET_ES */ 2411848b8605Smrg r600_store_value(cb, 0); /* R_0288DC_SQ_PGM_CF_OFFSET_FS */ 2412848b8605Smrg 2413848b8605Smrg r600_store_context_reg(cb, R_0288E0_SQ_VTX_SEMANTIC_CLEAR, ~0); 2414848b8605Smrg 2415848b8605Smrg r600_store_context_reg_seq(cb, R_028400_VGT_MAX_VTX_INDX, 2); 2416848b8605Smrg r600_store_value(cb, ~0); /* R_028400_VGT_MAX_VTX_INDX */ 2417848b8605Smrg r600_store_value(cb, 0); /* R_028404_VGT_MIN_VTX_INDX */ 2418848b8605Smrg 2419848b8605Smrg r600_store_context_reg(cb, R_0288A4_SQ_PGM_RESOURCES_FS, 0); 2420848b8605Smrg 2421848b8605Smrg if (rctx->b.chip_class == R700) 2422848b8605Smrg r600_store_context_reg(cb, R_028350_SX_MISC, 0); 2423848b8605Smrg if (rctx->b.chip_class == R700 && rctx->screen->b.has_streamout) 2424848b8605Smrg r600_store_context_reg(cb, R_028354_SX_SURFACE_SYNC, S_028354_SURFACE_SYNC_MASK(0xf)); 2425848b8605Smrg 2426848b8605Smrg r600_store_context_reg(cb, R_028800_DB_DEPTH_CONTROL, 0); 2427848b8605Smrg if (rctx->screen->b.has_streamout) { 2428848b8605Smrg r600_store_context_reg(cb, R_028B28_VGT_STRMOUT_DRAW_OPAQUE_OFFSET, 0); 2429848b8605Smrg } 2430848b8605Smrg 2431848b8605Smrg r600_store_loop_const(cb, R_03E200_SQ_LOOP_CONST_0, 0x1000FFF); 2432848b8605Smrg r600_store_loop_const(cb, R_03E200_SQ_LOOP_CONST_0 + (32 * 4), 0x1000FFF); 2433848b8605Smrg r600_store_loop_const(cb, R_03E200_SQ_LOOP_CONST_0 + (64 * 4), 0x1000FFF); 2434848b8605Smrg} 2435848b8605Smrg 2436848b8605Smrgvoid r600_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader *shader) 2437848b8605Smrg{ 2438848b8605Smrg struct r600_context *rctx = (struct r600_context *)ctx; 2439848b8605Smrg struct r600_command_buffer *cb = &shader->command_buffer; 2440848b8605Smrg struct r600_shader *rshader = &shader->shader; 2441848b8605Smrg unsigned i, exports_ps, num_cout, spi_ps_in_control_0, spi_input_z, spi_ps_in_control_1, db_shader_control; 2442b8e80941Smrg int pos_index = -1, face_index = -1, fixed_pt_position_index = -1; 2443848b8605Smrg unsigned tmp, sid, ufi = 0; 2444848b8605Smrg int need_linear = 0; 2445b8e80941Smrg unsigned z_export = 0, stencil_export = 0, mask_export = 0; 2446848b8605Smrg unsigned sprite_coord_enable = rctx->rasterizer ? rctx->rasterizer->sprite_coord_enable : 0; 2447848b8605Smrg 2448848b8605Smrg if (!cb->buf) { 2449848b8605Smrg r600_init_command_buffer(cb, 64); 2450848b8605Smrg } else { 2451848b8605Smrg cb->num_dw = 0; 2452848b8605Smrg } 2453848b8605Smrg 2454848b8605Smrg r600_store_context_reg_seq(cb, R_028644_SPI_PS_INPUT_CNTL_0, rshader->ninput); 2455848b8605Smrg for (i = 0; i < rshader->ninput; i++) { 2456848b8605Smrg if (rshader->input[i].name == TGSI_SEMANTIC_POSITION) 2457848b8605Smrg pos_index = i; 2458b8e80941Smrg if (rshader->input[i].name == TGSI_SEMANTIC_FACE && face_index == -1) 2459848b8605Smrg face_index = i; 2460b8e80941Smrg if (rshader->input[i].name == TGSI_SEMANTIC_SAMPLEID) 2461b8e80941Smrg fixed_pt_position_index = i; 2462848b8605Smrg 2463848b8605Smrg sid = rshader->input[i].spi_sid; 2464848b8605Smrg 2465848b8605Smrg tmp = S_028644_SEMANTIC(sid); 2466848b8605Smrg 2467b8e80941Smrg /* D3D 9 behaviour. GL is undefined */ 2468b8e80941Smrg if (rshader->input[i].name == TGSI_SEMANTIC_COLOR && rshader->input[i].sid == 0) 2469b8e80941Smrg tmp |= S_028644_DEFAULT_VAL(3); 2470b8e80941Smrg 2471848b8605Smrg if (rshader->input[i].name == TGSI_SEMANTIC_POSITION || 2472848b8605Smrg rshader->input[i].interpolate == TGSI_INTERPOLATE_CONSTANT || 2473848b8605Smrg (rshader->input[i].interpolate == TGSI_INTERPOLATE_COLOR && 2474848b8605Smrg rctx->rasterizer && rctx->rasterizer->flatshade)) 2475848b8605Smrg tmp |= S_028644_FLAT_SHADE(1); 2476848b8605Smrg 2477848b8605Smrg if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC && 2478848b8605Smrg sprite_coord_enable & (1 << rshader->input[i].sid)) { 2479848b8605Smrg tmp |= S_028644_PT_SPRITE_TEX(1); 2480848b8605Smrg } 2481848b8605Smrg 2482b8e80941Smrg if (rshader->input[i].interpolate_location == TGSI_INTERPOLATE_LOC_CENTROID) 2483848b8605Smrg tmp |= S_028644_SEL_CENTROID(1); 2484848b8605Smrg 2485b8e80941Smrg if (rshader->input[i].interpolate_location == TGSI_INTERPOLATE_LOC_SAMPLE) 2486b8e80941Smrg tmp |= S_028644_SEL_SAMPLE(1); 2487b8e80941Smrg 2488848b8605Smrg if (rshader->input[i].interpolate == TGSI_INTERPOLATE_LINEAR) { 2489848b8605Smrg need_linear = 1; 2490848b8605Smrg tmp |= S_028644_SEL_LINEAR(1); 2491848b8605Smrg } 2492848b8605Smrg 2493848b8605Smrg r600_store_value(cb, tmp); 2494848b8605Smrg } 2495848b8605Smrg 2496848b8605Smrg db_shader_control = 0; 2497848b8605Smrg for (i = 0; i < rshader->noutput; i++) { 2498848b8605Smrg if (rshader->output[i].name == TGSI_SEMANTIC_POSITION) 2499848b8605Smrg z_export = 1; 2500848b8605Smrg if (rshader->output[i].name == TGSI_SEMANTIC_STENCIL) 2501848b8605Smrg stencil_export = 1; 2502b8e80941Smrg if (rshader->output[i].name == TGSI_SEMANTIC_SAMPLEMASK && 2503b8e80941Smrg rctx->framebuffer.nr_samples > 1 && rctx->ps_iter_samples > 0) 2504b8e80941Smrg mask_export = 1; 2505848b8605Smrg } 2506848b8605Smrg db_shader_control |= S_02880C_Z_EXPORT_ENABLE(z_export); 2507848b8605Smrg db_shader_control |= S_02880C_STENCIL_REF_EXPORT_ENABLE(stencil_export); 2508b8e80941Smrg db_shader_control |= S_02880C_MASK_EXPORT_ENABLE(mask_export); 2509848b8605Smrg if (rshader->uses_kill) 2510848b8605Smrg db_shader_control |= S_02880C_KILL_ENABLE(1); 2511848b8605Smrg 2512848b8605Smrg exports_ps = 0; 2513848b8605Smrg for (i = 0; i < rshader->noutput; i++) { 2514848b8605Smrg if (rshader->output[i].name == TGSI_SEMANTIC_POSITION || 2515b8e80941Smrg rshader->output[i].name == TGSI_SEMANTIC_STENCIL || 2516b8e80941Smrg rshader->output[i].name == TGSI_SEMANTIC_SAMPLEMASK) { 2517848b8605Smrg exports_ps |= 1; 2518848b8605Smrg } 2519848b8605Smrg } 2520848b8605Smrg num_cout = rshader->nr_ps_color_exports; 2521848b8605Smrg exports_ps |= S_028854_EXPORT_COLORS(num_cout); 2522848b8605Smrg if (!exports_ps) { 2523848b8605Smrg /* always at least export 1 component per pixel */ 2524848b8605Smrg exports_ps = 2; 2525848b8605Smrg } 2526848b8605Smrg 2527848b8605Smrg shader->nr_ps_color_outputs = num_cout; 2528b8e80941Smrg shader->ps_color_export_mask = rshader->ps_color_export_mask; 2529848b8605Smrg 2530848b8605Smrg spi_ps_in_control_0 = S_0286CC_NUM_INTERP(rshader->ninput) | 2531848b8605Smrg S_0286CC_PERSP_GRADIENT_ENA(1)| 2532848b8605Smrg S_0286CC_LINEAR_GRADIENT_ENA(need_linear); 2533848b8605Smrg spi_input_z = 0; 2534848b8605Smrg if (pos_index != -1) { 2535848b8605Smrg spi_ps_in_control_0 |= (S_0286CC_POSITION_ENA(1) | 2536b8e80941Smrg S_0286CC_POSITION_CENTROID(rshader->input[pos_index].interpolate_location == TGSI_INTERPOLATE_LOC_CENTROID) | 2537848b8605Smrg S_0286CC_POSITION_ADDR(rshader->input[pos_index].gpr) | 2538b8e80941Smrg S_0286CC_BARYC_SAMPLE_CNTL(1)) | 2539b8e80941Smrg S_0286CC_POSITION_SAMPLE(rshader->input[pos_index].interpolate_location == TGSI_INTERPOLATE_LOC_SAMPLE); 2540848b8605Smrg spi_input_z |= S_0286D8_PROVIDE_Z_TO_SPI(1); 2541848b8605Smrg } 2542848b8605Smrg 2543848b8605Smrg spi_ps_in_control_1 = 0; 2544848b8605Smrg if (face_index != -1) { 2545848b8605Smrg spi_ps_in_control_1 |= S_0286D0_FRONT_FACE_ENA(1) | 2546848b8605Smrg S_0286D0_FRONT_FACE_ADDR(rshader->input[face_index].gpr); 2547848b8605Smrg } 2548b8e80941Smrg if (fixed_pt_position_index != -1) { 2549b8e80941Smrg spi_ps_in_control_1 |= S_0286D0_FIXED_PT_POSITION_ENA(1) | 2550b8e80941Smrg S_0286D0_FIXED_PT_POSITION_ADDR(rshader->input[fixed_pt_position_index].gpr); 2551b8e80941Smrg } 2552848b8605Smrg 2553848b8605Smrg /* HW bug in original R600 */ 2554848b8605Smrg if (rctx->b.family == CHIP_R600) 2555848b8605Smrg ufi = 1; 2556848b8605Smrg 2557848b8605Smrg r600_store_context_reg_seq(cb, R_0286CC_SPI_PS_IN_CONTROL_0, 2); 2558848b8605Smrg r600_store_value(cb, spi_ps_in_control_0); /* R_0286CC_SPI_PS_IN_CONTROL_0 */ 2559848b8605Smrg r600_store_value(cb, spi_ps_in_control_1); /* R_0286D0_SPI_PS_IN_CONTROL_1 */ 2560848b8605Smrg 2561848b8605Smrg r600_store_context_reg(cb, R_0286D8_SPI_INPUT_Z, spi_input_z); 2562848b8605Smrg 2563848b8605Smrg r600_store_context_reg_seq(cb, R_028850_SQ_PGM_RESOURCES_PS, 2); 2564848b8605Smrg r600_store_value(cb, /* R_028850_SQ_PGM_RESOURCES_PS*/ 2565848b8605Smrg S_028850_NUM_GPRS(rshader->bc.ngpr) | 2566b8e80941Smrg /* 2567b8e80941Smrg * docs are misleading about the dx10_clamp bit. This only affects 2568b8e80941Smrg * instructions using CLAMP dst modifier, in which case they will 2569b8e80941Smrg * return 0 with this set for a NaN (otherwise NaN). 2570b8e80941Smrg */ 2571b8e80941Smrg S_028850_DX10_CLAMP(1) | 2572848b8605Smrg S_028850_STACK_SIZE(rshader->bc.nstack) | 2573848b8605Smrg S_028850_UNCACHED_FIRST_INST(ufi)); 2574848b8605Smrg r600_store_value(cb, exports_ps); /* R_028854_SQ_PGM_EXPORTS_PS */ 2575848b8605Smrg 2576848b8605Smrg r600_store_context_reg(cb, R_028840_SQ_PGM_START_PS, 0); 2577848b8605Smrg /* After that, the NOP relocation packet must be emitted (shader->bo, RADEON_USAGE_READ). */ 2578848b8605Smrg 2579848b8605Smrg /* only set some bits here, the other bits are set in the dsa state */ 2580848b8605Smrg shader->db_shader_control = db_shader_control; 2581b8e80941Smrg shader->ps_depth_export = z_export | stencil_export | mask_export; 2582848b8605Smrg 2583848b8605Smrg shader->sprite_coord_enable = sprite_coord_enable; 2584848b8605Smrg if (rctx->rasterizer) 2585848b8605Smrg shader->flatshade = rctx->rasterizer->flatshade; 2586848b8605Smrg} 2587848b8605Smrg 2588848b8605Smrgvoid r600_update_vs_state(struct pipe_context *ctx, struct r600_pipe_shader *shader) 2589848b8605Smrg{ 2590848b8605Smrg struct r600_command_buffer *cb = &shader->command_buffer; 2591848b8605Smrg struct r600_shader *rshader = &shader->shader; 2592848b8605Smrg unsigned spi_vs_out_id[10] = {}; 2593848b8605Smrg unsigned i, tmp, nparams = 0; 2594848b8605Smrg 2595848b8605Smrg for (i = 0; i < rshader->noutput; i++) { 2596848b8605Smrg if (rshader->output[i].spi_sid) { 2597848b8605Smrg tmp = rshader->output[i].spi_sid << ((nparams & 3) * 8); 2598848b8605Smrg spi_vs_out_id[nparams / 4] |= tmp; 2599848b8605Smrg nparams++; 2600848b8605Smrg } 2601848b8605Smrg } 2602848b8605Smrg 2603848b8605Smrg r600_init_command_buffer(cb, 32); 2604848b8605Smrg 2605848b8605Smrg r600_store_context_reg_seq(cb, R_028614_SPI_VS_OUT_ID_0, 10); 2606848b8605Smrg for (i = 0; i < 10; i++) { 2607848b8605Smrg r600_store_value(cb, spi_vs_out_id[i]); 2608848b8605Smrg } 2609848b8605Smrg 2610848b8605Smrg /* Certain attributes (position, psize, etc.) don't count as params. 2611848b8605Smrg * VS is required to export at least one param and r600_shader_from_tgsi() 2612848b8605Smrg * takes care of adding a dummy export. 2613848b8605Smrg */ 2614848b8605Smrg if (nparams < 1) 2615848b8605Smrg nparams = 1; 2616848b8605Smrg 2617848b8605Smrg r600_store_context_reg(cb, R_0286C4_SPI_VS_OUT_CONFIG, 2618848b8605Smrg S_0286C4_VS_EXPORT_COUNT(nparams - 1)); 2619848b8605Smrg r600_store_context_reg(cb, R_028868_SQ_PGM_RESOURCES_VS, 2620848b8605Smrg S_028868_NUM_GPRS(rshader->bc.ngpr) | 2621b8e80941Smrg S_028868_DX10_CLAMP(1) | 2622848b8605Smrg S_028868_STACK_SIZE(rshader->bc.nstack)); 2623848b8605Smrg if (rshader->vs_position_window_space) { 2624848b8605Smrg r600_store_context_reg(cb, R_028818_PA_CL_VTE_CNTL, 2625848b8605Smrg S_028818_VTX_XY_FMT(1) | S_028818_VTX_Z_FMT(1)); 2626848b8605Smrg } else { 2627848b8605Smrg r600_store_context_reg(cb, R_028818_PA_CL_VTE_CNTL, 2628848b8605Smrg S_028818_VTX_W0_FMT(1) | 2629848b8605Smrg S_028818_VPORT_X_SCALE_ENA(1) | S_028818_VPORT_X_OFFSET_ENA(1) | 2630848b8605Smrg S_028818_VPORT_Y_SCALE_ENA(1) | S_028818_VPORT_Y_OFFSET_ENA(1) | 2631848b8605Smrg S_028818_VPORT_Z_SCALE_ENA(1) | S_028818_VPORT_Z_OFFSET_ENA(1)); 2632848b8605Smrg 2633848b8605Smrg } 2634848b8605Smrg r600_store_context_reg(cb, R_028858_SQ_PGM_START_VS, 0); 2635848b8605Smrg /* After that, the NOP relocation packet must be emitted (shader->bo, RADEON_USAGE_READ). */ 2636848b8605Smrg 2637848b8605Smrg shader->pa_cl_vs_out_cntl = 2638848b8605Smrg S_02881C_VS_OUT_CCDIST0_VEC_ENA((rshader->clip_dist_write & 0x0F) != 0) | 2639848b8605Smrg S_02881C_VS_OUT_CCDIST1_VEC_ENA((rshader->clip_dist_write & 0xF0) != 0) | 2640848b8605Smrg S_02881C_VS_OUT_MISC_VEC_ENA(rshader->vs_out_misc_write) | 2641848b8605Smrg S_02881C_USE_VTX_POINT_SIZE(rshader->vs_out_point_size) | 2642848b8605Smrg S_02881C_USE_VTX_EDGE_FLAG(rshader->vs_out_edgeflag) | 2643848b8605Smrg S_02881C_USE_VTX_RENDER_TARGET_INDX(rshader->vs_out_layer) | 2644848b8605Smrg S_02881C_USE_VTX_VIEWPORT_INDX(rshader->vs_out_viewport); 2645848b8605Smrg} 2646848b8605Smrg 2647b8e80941Smrg#define RV610_GSVS_ALIGN 32 2648b8e80941Smrg#define R600_GSVS_ALIGN 16 2649b8e80941Smrg 2650848b8605Smrgvoid r600_update_gs_state(struct pipe_context *ctx, struct r600_pipe_shader *shader) 2651848b8605Smrg{ 2652848b8605Smrg struct r600_context *rctx = (struct r600_context *)ctx; 2653848b8605Smrg struct r600_command_buffer *cb = &shader->command_buffer; 2654848b8605Smrg struct r600_shader *rshader = &shader->shader; 2655848b8605Smrg struct r600_shader *cp_shader = &shader->gs_copy_shader->shader; 2656848b8605Smrg unsigned gsvs_itemsize = 2657b8e80941Smrg (cp_shader->ring_item_sizes[0] * shader->selector->gs_max_out_vertices) >> 2; 2658b8e80941Smrg 2659b8e80941Smrg /* some r600s needs gsvs itemsize aligned to cacheline size 2660b8e80941Smrg this was fixed in rs780 and above. */ 2661b8e80941Smrg switch (rctx->b.family) { 2662b8e80941Smrg case CHIP_RV610: 2663b8e80941Smrg gsvs_itemsize = align(gsvs_itemsize, RV610_GSVS_ALIGN); 2664b8e80941Smrg break; 2665b8e80941Smrg case CHIP_R600: 2666b8e80941Smrg case CHIP_RV630: 2667b8e80941Smrg case CHIP_RV670: 2668b8e80941Smrg case CHIP_RV620: 2669b8e80941Smrg case CHIP_RV635: 2670b8e80941Smrg gsvs_itemsize = align(gsvs_itemsize, R600_GSVS_ALIGN); 2671b8e80941Smrg break; 2672b8e80941Smrg default: 2673b8e80941Smrg break; 2674b8e80941Smrg } 2675848b8605Smrg 2676848b8605Smrg r600_init_command_buffer(cb, 64); 2677848b8605Smrg 2678848b8605Smrg /* VGT_GS_MODE is written by r600_emit_shader_stages */ 2679848b8605Smrg r600_store_context_reg(cb, R_028AB8_VGT_VTX_CNT_EN, 1); 2680848b8605Smrg 2681848b8605Smrg if (rctx->b.chip_class >= R700) { 2682848b8605Smrg r600_store_context_reg(cb, R_028B38_VGT_GS_MAX_VERT_OUT, 2683b8e80941Smrg S_028B38_MAX_VERT_OUT(shader->selector->gs_max_out_vertices)); 2684848b8605Smrg } 2685848b8605Smrg r600_store_context_reg(cb, R_028A6C_VGT_GS_OUT_PRIM_TYPE, 2686b8e80941Smrg r600_conv_prim_to_gs_out(shader->selector->gs_output_prim)); 2687848b8605Smrg 2688b8e80941Smrg r600_store_context_reg(cb, R_0288C8_SQ_GS_VERT_ITEMSIZE, 2689b8e80941Smrg cp_shader->ring_item_sizes[0] >> 2); 2690848b8605Smrg 2691848b8605Smrg r600_store_context_reg(cb, R_0288A8_SQ_ESGS_RING_ITEMSIZE, 2692b8e80941Smrg (rshader->ring_item_sizes[0]) >> 2); 2693848b8605Smrg 2694848b8605Smrg r600_store_context_reg(cb, R_0288AC_SQ_GSVS_RING_ITEMSIZE, 2695848b8605Smrg gsvs_itemsize); 2696848b8605Smrg 2697848b8605Smrg /* FIXME calculate these values somehow ??? */ 2698848b8605Smrg r600_store_config_reg_seq(cb, R_0088C8_VGT_GS_PER_ES, 2); 2699848b8605Smrg r600_store_value(cb, 0x80); /* GS_PER_ES */ 2700848b8605Smrg r600_store_value(cb, 0x100); /* ES_PER_GS */ 2701848b8605Smrg r600_store_config_reg_seq(cb, R_0088E8_VGT_GS_PER_VS, 1); 2702848b8605Smrg r600_store_value(cb, 0x2); /* GS_PER_VS */ 2703848b8605Smrg 2704848b8605Smrg r600_store_context_reg(cb, R_02887C_SQ_PGM_RESOURCES_GS, 2705848b8605Smrg S_02887C_NUM_GPRS(rshader->bc.ngpr) | 2706b8e80941Smrg S_02887C_DX10_CLAMP(1) | 2707848b8605Smrg S_02887C_STACK_SIZE(rshader->bc.nstack)); 2708848b8605Smrg r600_store_context_reg(cb, R_02886C_SQ_PGM_START_GS, 0); 2709848b8605Smrg /* After that, the NOP relocation packet must be emitted (shader->bo, RADEON_USAGE_READ). */ 2710848b8605Smrg} 2711848b8605Smrg 2712848b8605Smrgvoid r600_update_es_state(struct pipe_context *ctx, struct r600_pipe_shader *shader) 2713848b8605Smrg{ 2714848b8605Smrg struct r600_command_buffer *cb = &shader->command_buffer; 2715848b8605Smrg struct r600_shader *rshader = &shader->shader; 2716848b8605Smrg 2717848b8605Smrg r600_init_command_buffer(cb, 32); 2718848b8605Smrg 2719848b8605Smrg r600_store_context_reg(cb, R_028890_SQ_PGM_RESOURCES_ES, 2720848b8605Smrg S_028890_NUM_GPRS(rshader->bc.ngpr) | 2721b8e80941Smrg S_028890_DX10_CLAMP(1) | 2722848b8605Smrg S_028890_STACK_SIZE(rshader->bc.nstack)); 2723848b8605Smrg r600_store_context_reg(cb, R_028880_SQ_PGM_START_ES, 0); 2724848b8605Smrg /* After that, the NOP relocation packet must be emitted (shader->bo, RADEON_USAGE_READ). */ 2725848b8605Smrg} 2726848b8605Smrg 2727848b8605Smrg 2728848b8605Smrgvoid *r600_create_resolve_blend(struct r600_context *rctx) 2729848b8605Smrg{ 2730848b8605Smrg struct pipe_blend_state blend; 2731848b8605Smrg unsigned i; 2732848b8605Smrg 2733848b8605Smrg memset(&blend, 0, sizeof(blend)); 2734848b8605Smrg blend.independent_blend_enable = true; 2735848b8605Smrg for (i = 0; i < 2; i++) { 2736848b8605Smrg blend.rt[i].colormask = 0xf; 2737848b8605Smrg blend.rt[i].blend_enable = 1; 2738848b8605Smrg blend.rt[i].rgb_func = PIPE_BLEND_ADD; 2739848b8605Smrg blend.rt[i].alpha_func = PIPE_BLEND_ADD; 2740848b8605Smrg blend.rt[i].rgb_src_factor = PIPE_BLENDFACTOR_ZERO; 2741848b8605Smrg blend.rt[i].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; 2742848b8605Smrg blend.rt[i].alpha_src_factor = PIPE_BLENDFACTOR_ZERO; 2743848b8605Smrg blend.rt[i].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; 2744848b8605Smrg } 2745848b8605Smrg return r600_create_blend_state_mode(&rctx->b.b, &blend, V_028808_SPECIAL_RESOLVE_BOX); 2746848b8605Smrg} 2747848b8605Smrg 2748848b8605Smrgvoid *r700_create_resolve_blend(struct r600_context *rctx) 2749848b8605Smrg{ 2750848b8605Smrg struct pipe_blend_state blend; 2751848b8605Smrg 2752848b8605Smrg memset(&blend, 0, sizeof(blend)); 2753848b8605Smrg blend.independent_blend_enable = true; 2754848b8605Smrg blend.rt[0].colormask = 0xf; 2755848b8605Smrg return r600_create_blend_state_mode(&rctx->b.b, &blend, V_028808_SPECIAL_RESOLVE_BOX); 2756848b8605Smrg} 2757848b8605Smrg 2758848b8605Smrgvoid *r600_create_decompress_blend(struct r600_context *rctx) 2759848b8605Smrg{ 2760848b8605Smrg struct pipe_blend_state blend; 2761848b8605Smrg 2762848b8605Smrg memset(&blend, 0, sizeof(blend)); 2763848b8605Smrg blend.independent_blend_enable = true; 2764848b8605Smrg blend.rt[0].colormask = 0xf; 2765848b8605Smrg return r600_create_blend_state_mode(&rctx->b.b, &blend, V_028808_SPECIAL_EXPAND_SAMPLES); 2766848b8605Smrg} 2767848b8605Smrg 2768848b8605Smrgvoid *r600_create_db_flush_dsa(struct r600_context *rctx) 2769848b8605Smrg{ 2770848b8605Smrg struct pipe_depth_stencil_alpha_state dsa; 2771848b8605Smrg boolean quirk = false; 2772848b8605Smrg 2773848b8605Smrg if (rctx->b.family == CHIP_RV610 || rctx->b.family == CHIP_RV630 || 2774848b8605Smrg rctx->b.family == CHIP_RV620 || rctx->b.family == CHIP_RV635) 2775848b8605Smrg quirk = true; 2776848b8605Smrg 2777848b8605Smrg memset(&dsa, 0, sizeof(dsa)); 2778848b8605Smrg 2779848b8605Smrg if (quirk) { 2780848b8605Smrg dsa.depth.enabled = 1; 2781848b8605Smrg dsa.depth.func = PIPE_FUNC_LEQUAL; 2782848b8605Smrg dsa.stencil[0].enabled = 1; 2783848b8605Smrg dsa.stencil[0].func = PIPE_FUNC_ALWAYS; 2784848b8605Smrg dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_KEEP; 2785848b8605Smrg dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_INCR; 2786848b8605Smrg dsa.stencil[0].writemask = 0xff; 2787848b8605Smrg } 2788848b8605Smrg 2789848b8605Smrg return rctx->b.b.create_depth_stencil_alpha_state(&rctx->b.b, &dsa); 2790848b8605Smrg} 2791848b8605Smrg 2792848b8605Smrgvoid r600_update_db_shader_control(struct r600_context * rctx) 2793848b8605Smrg{ 2794848b8605Smrg bool dual_export; 2795848b8605Smrg unsigned db_shader_control; 2796b8e80941Smrg uint8_t ps_conservative_z; 2797848b8605Smrg 2798848b8605Smrg if (!rctx->ps_shader) { 2799848b8605Smrg return; 2800848b8605Smrg } 2801848b8605Smrg 2802848b8605Smrg dual_export = rctx->framebuffer.export_16bpc && 2803848b8605Smrg !rctx->ps_shader->current->ps_depth_export; 2804848b8605Smrg 2805848b8605Smrg db_shader_control = rctx->ps_shader->current->db_shader_control | 2806848b8605Smrg S_02880C_DUAL_EXPORT_ENABLE(dual_export); 2807848b8605Smrg 2808b8e80941Smrg ps_conservative_z = rctx->ps_shader->current->shader.ps_conservative_z; 2809b8e80941Smrg 2810848b8605Smrg /* When alpha test is enabled we can't trust the hw to make the proper 2811848b8605Smrg * decision on the order in which ztest should be run related to fragment 2812848b8605Smrg * shader execution. 2813848b8605Smrg * 2814848b8605Smrg * If alpha test is enabled perform z test after fragment. RE_Z (early 2815848b8605Smrg * z test but no write to the zbuffer) seems to cause lockup on r6xx/r7xx 2816848b8605Smrg */ 2817848b8605Smrg if (rctx->alphatest_state.sx_alpha_test_control) { 2818848b8605Smrg db_shader_control |= S_02880C_Z_ORDER(V_02880C_LATE_Z); 2819848b8605Smrg } else { 2820848b8605Smrg db_shader_control |= S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z); 2821848b8605Smrg } 2822848b8605Smrg 2823b8e80941Smrg if (db_shader_control != rctx->db_misc_state.db_shader_control || 2824b8e80941Smrg ps_conservative_z != rctx->db_misc_state.ps_conservative_z) { 2825848b8605Smrg rctx->db_misc_state.db_shader_control = db_shader_control; 2826b8e80941Smrg rctx->db_misc_state.ps_conservative_z = ps_conservative_z; 2827b8e80941Smrg r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom); 2828848b8605Smrg } 2829848b8605Smrg} 2830848b8605Smrg 2831b8e80941Smrgstatic inline unsigned r600_array_mode(unsigned mode) 2832848b8605Smrg{ 2833848b8605Smrg switch (mode) { 2834b8e80941Smrg default: 2835848b8605Smrg case RADEON_SURF_MODE_LINEAR_ALIGNED: return V_0280A0_ARRAY_LINEAR_ALIGNED; 2836848b8605Smrg break; 2837848b8605Smrg case RADEON_SURF_MODE_1D: return V_0280A0_ARRAY_1D_TILED_THIN1; 2838848b8605Smrg break; 2839848b8605Smrg case RADEON_SURF_MODE_2D: return V_0280A0_ARRAY_2D_TILED_THIN1; 2840848b8605Smrg } 2841848b8605Smrg} 2842848b8605Smrg 2843848b8605Smrgstatic boolean r600_dma_copy_tile(struct r600_context *rctx, 2844848b8605Smrg struct pipe_resource *dst, 2845848b8605Smrg unsigned dst_level, 2846848b8605Smrg unsigned dst_x, 2847848b8605Smrg unsigned dst_y, 2848848b8605Smrg unsigned dst_z, 2849848b8605Smrg struct pipe_resource *src, 2850848b8605Smrg unsigned src_level, 2851848b8605Smrg unsigned src_x, 2852848b8605Smrg unsigned src_y, 2853848b8605Smrg unsigned src_z, 2854848b8605Smrg unsigned copy_height, 2855848b8605Smrg unsigned pitch, 2856848b8605Smrg unsigned bpp) 2857848b8605Smrg{ 2858b8e80941Smrg struct radeon_cmdbuf *cs = rctx->b.dma.cs; 2859848b8605Smrg struct r600_texture *rsrc = (struct r600_texture*)src; 2860848b8605Smrg struct r600_texture *rdst = (struct r600_texture*)dst; 2861848b8605Smrg unsigned array_mode, lbpp, pitch_tile_max, slice_tile_max, size; 2862848b8605Smrg unsigned ncopy, height, cheight, detile, i, x, y, z, src_mode, dst_mode; 2863848b8605Smrg uint64_t base, addr; 2864848b8605Smrg 2865b8e80941Smrg dst_mode = rdst->surface.u.legacy.level[dst_level].mode; 2866b8e80941Smrg src_mode = rsrc->surface.u.legacy.level[src_level].mode; 2867848b8605Smrg assert(dst_mode != src_mode); 2868848b8605Smrg 2869848b8605Smrg y = 0; 2870848b8605Smrg lbpp = util_logbase2(bpp); 2871848b8605Smrg pitch_tile_max = ((pitch / bpp) / 8) - 1; 2872848b8605Smrg 2873b8e80941Smrg if (dst_mode == RADEON_SURF_MODE_LINEAR_ALIGNED) { 2874848b8605Smrg /* T2L */ 2875848b8605Smrg array_mode = r600_array_mode(src_mode); 2876b8e80941Smrg slice_tile_max = (rsrc->surface.u.legacy.level[src_level].nblk_x * rsrc->surface.u.legacy.level[src_level].nblk_y) / (8*8); 2877848b8605Smrg slice_tile_max = slice_tile_max ? slice_tile_max - 1 : 0; 2878848b8605Smrg /* linear height must be the same as the slice tile max height, it's ok even 2879848b8605Smrg * if the linear destination/source have smaller heigh as the size of the 2880848b8605Smrg * dma packet will be using the copy_height which is always smaller or equal 2881848b8605Smrg * to the linear height 2882848b8605Smrg */ 2883b8e80941Smrg height = u_minify(rsrc->resource.b.b.height0, src_level); 2884848b8605Smrg detile = 1; 2885848b8605Smrg x = src_x; 2886848b8605Smrg y = src_y; 2887848b8605Smrg z = src_z; 2888b8e80941Smrg base = rsrc->surface.u.legacy.level[src_level].offset; 2889b8e80941Smrg addr = rdst->surface.u.legacy.level[dst_level].offset; 2890b8e80941Smrg addr += (uint64_t)rdst->surface.u.legacy.level[dst_level].slice_size_dw * 4 * dst_z; 2891848b8605Smrg addr += dst_y * pitch + dst_x * bpp; 2892848b8605Smrg } else { 2893848b8605Smrg /* L2T */ 2894848b8605Smrg array_mode = r600_array_mode(dst_mode); 2895b8e80941Smrg slice_tile_max = (rdst->surface.u.legacy.level[dst_level].nblk_x * rdst->surface.u.legacy.level[dst_level].nblk_y) / (8*8); 2896848b8605Smrg slice_tile_max = slice_tile_max ? slice_tile_max - 1 : 0; 2897848b8605Smrg /* linear height must be the same as the slice tile max height, it's ok even 2898848b8605Smrg * if the linear destination/source have smaller heigh as the size of the 2899848b8605Smrg * dma packet will be using the copy_height which is always smaller or equal 2900848b8605Smrg * to the linear height 2901848b8605Smrg */ 2902b8e80941Smrg height = u_minify(rdst->resource.b.b.height0, dst_level); 2903848b8605Smrg detile = 0; 2904848b8605Smrg x = dst_x; 2905848b8605Smrg y = dst_y; 2906848b8605Smrg z = dst_z; 2907b8e80941Smrg base = rdst->surface.u.legacy.level[dst_level].offset; 2908b8e80941Smrg addr = rsrc->surface.u.legacy.level[src_level].offset; 2909b8e80941Smrg addr += (uint64_t)rsrc->surface.u.legacy.level[src_level].slice_size_dw * 4 * src_z; 2910848b8605Smrg addr += src_y * pitch + src_x * bpp; 2911848b8605Smrg } 2912848b8605Smrg /* check that we are in dw/base alignment constraint */ 2913848b8605Smrg if (addr % 4 || base % 256) { 2914848b8605Smrg return FALSE; 2915848b8605Smrg } 2916848b8605Smrg 2917848b8605Smrg /* It's a r6xx/r7xx limitation, the blit must be on 8 boundary for number 2918848b8605Smrg * line in the blit. Compute max 8 line we can copy in the size limit 2919848b8605Smrg */ 2920848b8605Smrg cheight = ((R600_DMA_COPY_MAX_SIZE_DW * 4) / pitch) & 0xfffffff8; 2921848b8605Smrg ncopy = (copy_height / cheight) + !!(copy_height % cheight); 2922b8e80941Smrg r600_need_dma_space(&rctx->b, ncopy * 7, &rdst->resource, &rsrc->resource); 2923848b8605Smrg 2924848b8605Smrg for (i = 0; i < ncopy; i++) { 2925848b8605Smrg cheight = cheight > copy_height ? copy_height : cheight; 2926848b8605Smrg size = (cheight * pitch) / 4; 2927b8e80941Smrg /* emit reloc before writing cs so that cs is always in consistent state */ 2928b8e80941Smrg radeon_add_to_buffer_list(&rctx->b, &rctx->b.dma, &rsrc->resource, RADEON_USAGE_READ, 0); 2929b8e80941Smrg radeon_add_to_buffer_list(&rctx->b, &rctx->b.dma, &rdst->resource, RADEON_USAGE_WRITE, 0); 2930b8e80941Smrg radeon_emit(cs, DMA_PACKET(DMA_PACKET_COPY, 1, 0, size)); 2931b8e80941Smrg radeon_emit(cs, base >> 8); 2932b8e80941Smrg radeon_emit(cs, (detile << 31) | (array_mode << 27) | 2933b8e80941Smrg (lbpp << 24) | ((height - 1) << 10) | 2934b8e80941Smrg pitch_tile_max); 2935b8e80941Smrg radeon_emit(cs, (slice_tile_max << 12) | (z << 0)); 2936b8e80941Smrg radeon_emit(cs, (x << 3) | (y << 17)); 2937b8e80941Smrg radeon_emit(cs, addr & 0xfffffffc); 2938b8e80941Smrg radeon_emit(cs, (addr >> 32UL) & 0xff); 2939848b8605Smrg copy_height -= cheight; 2940848b8605Smrg addr += cheight * pitch; 2941848b8605Smrg y += cheight; 2942848b8605Smrg } 2943848b8605Smrg return TRUE; 2944848b8605Smrg} 2945848b8605Smrg 2946848b8605Smrgstatic void r600_dma_copy(struct pipe_context *ctx, 2947848b8605Smrg struct pipe_resource *dst, 2948848b8605Smrg unsigned dst_level, 2949848b8605Smrg unsigned dstx, unsigned dsty, unsigned dstz, 2950848b8605Smrg struct pipe_resource *src, 2951848b8605Smrg unsigned src_level, 2952848b8605Smrg const struct pipe_box *src_box) 2953848b8605Smrg{ 2954848b8605Smrg struct r600_context *rctx = (struct r600_context *)ctx; 2955848b8605Smrg struct r600_texture *rsrc = (struct r600_texture*)src; 2956848b8605Smrg struct r600_texture *rdst = (struct r600_texture*)dst; 2957848b8605Smrg unsigned dst_pitch, src_pitch, bpp, dst_mode, src_mode, copy_height; 2958848b8605Smrg unsigned src_w, dst_w; 2959848b8605Smrg unsigned src_x, src_y; 2960848b8605Smrg unsigned dst_x = dstx, dst_y = dsty, dst_z = dstz; 2961848b8605Smrg 2962b8e80941Smrg if (rctx->b.dma.cs == NULL) { 2963848b8605Smrg goto fallback; 2964848b8605Smrg } 2965848b8605Smrg 2966848b8605Smrg if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { 2967848b8605Smrg if (dst_x % 4 || src_box->x % 4 || src_box->width % 4) 2968848b8605Smrg goto fallback; 2969848b8605Smrg 2970848b8605Smrg r600_dma_copy_buffer(rctx, dst, src, dst_x, src_box->x, src_box->width); 2971848b8605Smrg return; 2972848b8605Smrg } 2973848b8605Smrg 2974b8e80941Smrg if (src_box->depth > 1 || 2975b8e80941Smrg !r600_prepare_for_dma_blit(&rctx->b, rdst, dst_level, dstx, dsty, 2976b8e80941Smrg dstz, rsrc, src_level, src_box)) 2977848b8605Smrg goto fallback; 2978848b8605Smrg 2979848b8605Smrg src_x = util_format_get_nblocksx(src->format, src_box->x); 2980848b8605Smrg dst_x = util_format_get_nblocksx(src->format, dst_x); 2981848b8605Smrg src_y = util_format_get_nblocksy(src->format, src_box->y); 2982848b8605Smrg dst_y = util_format_get_nblocksy(src->format, dst_y); 2983848b8605Smrg 2984848b8605Smrg bpp = rdst->surface.bpe; 2985b8e80941Smrg dst_pitch = rdst->surface.u.legacy.level[dst_level].nblk_x * rdst->surface.bpe; 2986b8e80941Smrg src_pitch = rsrc->surface.u.legacy.level[src_level].nblk_x * rsrc->surface.bpe; 2987b8e80941Smrg src_w = u_minify(rsrc->resource.b.b.width0, src_level); 2988b8e80941Smrg dst_w = u_minify(rdst->resource.b.b.width0, dst_level); 2989848b8605Smrg copy_height = src_box->height / rsrc->surface.blk_h; 2990848b8605Smrg 2991b8e80941Smrg dst_mode = rdst->surface.u.legacy.level[dst_level].mode; 2992b8e80941Smrg src_mode = rsrc->surface.u.legacy.level[src_level].mode; 2993848b8605Smrg 2994848b8605Smrg if (src_pitch != dst_pitch || src_box->x || dst_x || src_w != dst_w) { 2995848b8605Smrg /* strict requirement on r6xx/r7xx */ 2996848b8605Smrg goto fallback; 2997848b8605Smrg } 2998848b8605Smrg /* lot of constraint on alignment this should capture them all */ 2999848b8605Smrg if (src_pitch % 8 || src_box->y % 8 || dst_y % 8) { 3000848b8605Smrg goto fallback; 3001848b8605Smrg } 3002848b8605Smrg 3003848b8605Smrg if (src_mode == dst_mode) { 3004848b8605Smrg uint64_t dst_offset, src_offset, size; 3005848b8605Smrg 3006848b8605Smrg /* simple dma blit would do NOTE code here assume : 3007848b8605Smrg * src_box.x/y == 0 3008848b8605Smrg * dst_x/y == 0 3009848b8605Smrg * dst_pitch == src_pitch 3010848b8605Smrg */ 3011b8e80941Smrg src_offset= rsrc->surface.u.legacy.level[src_level].offset; 3012b8e80941Smrg src_offset += (uint64_t)rsrc->surface.u.legacy.level[src_level].slice_size_dw * 4 * src_box->z; 3013848b8605Smrg src_offset += src_y * src_pitch + src_x * bpp; 3014b8e80941Smrg dst_offset = rdst->surface.u.legacy.level[dst_level].offset; 3015b8e80941Smrg dst_offset += (uint64_t)rdst->surface.u.legacy.level[dst_level].slice_size_dw * 4 * dst_z; 3016848b8605Smrg dst_offset += dst_y * dst_pitch + dst_x * bpp; 3017848b8605Smrg size = src_box->height * src_pitch; 3018848b8605Smrg /* must be dw aligned */ 3019848b8605Smrg if (dst_offset % 4 || src_offset % 4 || size % 4) { 3020848b8605Smrg goto fallback; 3021848b8605Smrg } 3022848b8605Smrg r600_dma_copy_buffer(rctx, dst, src, dst_offset, src_offset, size); 3023848b8605Smrg } else { 3024848b8605Smrg if (!r600_dma_copy_tile(rctx, dst, dst_level, dst_x, dst_y, dst_z, 3025848b8605Smrg src, src_level, src_x, src_y, src_box->z, 3026848b8605Smrg copy_height, dst_pitch, bpp)) { 3027848b8605Smrg goto fallback; 3028848b8605Smrg } 3029848b8605Smrg } 3030848b8605Smrg return; 3031848b8605Smrg 3032848b8605Smrgfallback: 3033b8e80941Smrg r600_resource_copy_region(ctx, dst, dst_level, dstx, dsty, dstz, 3034848b8605Smrg src, src_level, src_box); 3035848b8605Smrg} 3036848b8605Smrg 3037848b8605Smrgvoid r600_init_state_functions(struct r600_context *rctx) 3038848b8605Smrg{ 3039b8e80941Smrg unsigned id = 1; 3040b8e80941Smrg unsigned i; 3041848b8605Smrg /* !!! 3042848b8605Smrg * To avoid GPU lockup registers must be emited in a specific order 3043848b8605Smrg * (no kidding ...). The order below is important and have been 3044848b8605Smrg * partialy infered from analyzing fglrx command stream. 3045848b8605Smrg * 3046848b8605Smrg * Don't reorder atom without carefully checking the effect (GPU lockup 3047848b8605Smrg * or piglit regression). 3048848b8605Smrg * !!! 3049848b8605Smrg */ 3050848b8605Smrg 3051848b8605Smrg r600_init_atom(rctx, &rctx->framebuffer.atom, id++, r600_emit_framebuffer_state, 0); 3052848b8605Smrg 3053848b8605Smrg /* shader const */ 3054848b8605Smrg r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_VERTEX].atom, id++, r600_emit_vs_constant_buffers, 0); 3055848b8605Smrg r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_GEOMETRY].atom, id++, r600_emit_gs_constant_buffers, 0); 3056848b8605Smrg r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_FRAGMENT].atom, id++, r600_emit_ps_constant_buffers, 0); 3057848b8605Smrg 3058848b8605Smrg /* sampler must be emited before TA_CNTL_AUX otherwise DISABLE_CUBE_WRAP change 3059848b8605Smrg * does not take effect (TA_CNTL_AUX emited by r600_emit_seamless_cube_map) 3060848b8605Smrg */ 3061848b8605Smrg r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_VERTEX].states.atom, id++, r600_emit_vs_sampler_states, 0); 3062848b8605Smrg r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_GEOMETRY].states.atom, id++, r600_emit_gs_sampler_states, 0); 3063848b8605Smrg r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_FRAGMENT].states.atom, id++, r600_emit_ps_sampler_states, 0); 3064848b8605Smrg /* resource */ 3065848b8605Smrg r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_VERTEX].views.atom, id++, r600_emit_vs_sampler_views, 0); 3066848b8605Smrg r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_GEOMETRY].views.atom, id++, r600_emit_gs_sampler_views, 0); 3067848b8605Smrg r600_init_atom(rctx, &rctx->samplers[PIPE_SHADER_FRAGMENT].views.atom, id++, r600_emit_ps_sampler_views, 0); 3068848b8605Smrg r600_init_atom(rctx, &rctx->vertex_buffer_state.atom, id++, r600_emit_vertex_buffers, 0); 3069848b8605Smrg 3070b8e80941Smrg r600_init_atom(rctx, &rctx->vgt_state.atom, id++, r600_emit_vgt_state, 10); 3071848b8605Smrg 3072848b8605Smrg r600_init_atom(rctx, &rctx->seamless_cube_map.atom, id++, r600_emit_seamless_cube_map, 3); 3073848b8605Smrg r600_init_atom(rctx, &rctx->sample_mask.atom, id++, r600_emit_sample_mask, 3); 3074848b8605Smrg rctx->sample_mask.sample_mask = ~0; 3075848b8605Smrg 3076848b8605Smrg r600_init_atom(rctx, &rctx->alphatest_state.atom, id++, r600_emit_alphatest_state, 6); 3077848b8605Smrg r600_init_atom(rctx, &rctx->blend_color.atom, id++, r600_emit_blend_color, 6); 3078848b8605Smrg r600_init_atom(rctx, &rctx->blend_state.atom, id++, r600_emit_cso_state, 0); 3079848b8605Smrg r600_init_atom(rctx, &rctx->cb_misc_state.atom, id++, r600_emit_cb_misc_state, 7); 3080848b8605Smrg r600_init_atom(rctx, &rctx->clip_misc_state.atom, id++, r600_emit_clip_misc_state, 6); 3081848b8605Smrg r600_init_atom(rctx, &rctx->clip_state.atom, id++, r600_emit_clip_state, 26); 3082848b8605Smrg r600_init_atom(rctx, &rctx->db_misc_state.atom, id++, r600_emit_db_misc_state, 7); 3083848b8605Smrg r600_init_atom(rctx, &rctx->db_state.atom, id++, r600_emit_db_state, 11); 3084848b8605Smrg r600_init_atom(rctx, &rctx->dsa_state.atom, id++, r600_emit_cso_state, 0); 3085b8e80941Smrg r600_init_atom(rctx, &rctx->poly_offset_state.atom, id++, r600_emit_polygon_offset, 9); 3086848b8605Smrg r600_init_atom(rctx, &rctx->rasterizer_state.atom, id++, r600_emit_cso_state, 0); 3087b8e80941Smrg r600_add_atom(rctx, &rctx->b.scissors.atom, id++); 3088b8e80941Smrg r600_add_atom(rctx, &rctx->b.viewports.atom, id++); 3089848b8605Smrg r600_init_atom(rctx, &rctx->config_state.atom, id++, r600_emit_config_state, 3); 3090848b8605Smrg r600_init_atom(rctx, &rctx->stencil_ref.atom, id++, r600_emit_stencil_ref, 4); 3091848b8605Smrg r600_init_atom(rctx, &rctx->vertex_fetch_shader.atom, id++, r600_emit_vertex_fetch_shader, 5); 3092b8e80941Smrg r600_add_atom(rctx, &rctx->b.render_cond_atom, id++); 3093b8e80941Smrg r600_add_atom(rctx, &rctx->b.streamout.begin_atom, id++); 3094b8e80941Smrg r600_add_atom(rctx, &rctx->b.streamout.enable_atom, id++); 3095b8e80941Smrg for (i = 0; i < R600_NUM_HW_STAGES; i++) 3096b8e80941Smrg r600_init_atom(rctx, &rctx->hw_shader_stages[i].atom, id++, r600_emit_shader, 0); 3097848b8605Smrg r600_init_atom(rctx, &rctx->shader_stages.atom, id++, r600_emit_shader_stages, 0); 3098848b8605Smrg r600_init_atom(rctx, &rctx->gs_rings.atom, id++, r600_emit_gs_rings, 0); 3099848b8605Smrg 3100848b8605Smrg rctx->b.b.create_blend_state = r600_create_blend_state; 3101848b8605Smrg rctx->b.b.create_depth_stencil_alpha_state = r600_create_dsa_state; 3102848b8605Smrg rctx->b.b.create_rasterizer_state = r600_create_rs_state; 3103848b8605Smrg rctx->b.b.create_sampler_state = r600_create_sampler_state; 3104848b8605Smrg rctx->b.b.create_sampler_view = r600_create_sampler_view; 3105848b8605Smrg rctx->b.b.set_framebuffer_state = r600_set_framebuffer_state; 3106848b8605Smrg rctx->b.b.set_polygon_stipple = r600_set_polygon_stipple; 3107b8e80941Smrg rctx->b.b.set_min_samples = r600_set_min_samples; 3108848b8605Smrg rctx->b.b.get_sample_position = r600_get_sample_position; 3109848b8605Smrg rctx->b.dma_copy = r600_dma_copy; 3110848b8605Smrg} 3111848b8605Smrg/* this function must be last */ 3112