1848b8605Smrg/* 2848b8605Smrg * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> 3848b8605Smrg * Copyright 2009 Marek Olšák <maraeo@gmail.com> 4848b8605Smrg * 5848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 6848b8605Smrg * copy of this software and associated documentation files (the "Software"), 7848b8605Smrg * to deal in the Software without restriction, including without limitation 8848b8605Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub 9848b8605Smrg * license, and/or sell copies of the Software, and to permit persons to whom 10848b8605Smrg * the Software is furnished to do so, subject to the following conditions: 11848b8605Smrg * 12848b8605Smrg * The above copyright notice and this permission notice (including the next 13848b8605Smrg * paragraph) shall be included in all copies or substantial portions of the 14848b8605Smrg * Software. 15848b8605Smrg * 16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19848b8605Smrg * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20848b8605Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21848b8605Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22848b8605Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23848b8605Smrg 24848b8605Smrg/* r300_emit: Functions for emitting state. */ 25848b8605Smrg 26848b8605Smrg#include "util/u_format.h" 27848b8605Smrg#include "util/u_math.h" 28848b8605Smrg 29848b8605Smrg#include "r300_context.h" 30848b8605Smrg#include "r300_cb.h" 31848b8605Smrg#include "r300_cs.h" 32848b8605Smrg#include "r300_emit.h" 33848b8605Smrg#include "r300_fs.h" 34848b8605Smrg#include "r300_screen.h" 35848b8605Smrg#include "r300_screen_buffer.h" 36848b8605Smrg#include "r300_vs.h" 37848b8605Smrg 38848b8605Smrgvoid r300_emit_blend_state(struct r300_context* r300, 39848b8605Smrg unsigned size, void* state) 40848b8605Smrg{ 41848b8605Smrg struct r300_blend_state* blend = (struct r300_blend_state*)state; 42848b8605Smrg struct pipe_framebuffer_state* fb = 43848b8605Smrg (struct pipe_framebuffer_state*)r300->fb_state.state; 44848b8605Smrg struct pipe_surface *cb; 45848b8605Smrg CS_LOCALS(r300); 46848b8605Smrg 47848b8605Smrg cb = fb->nr_cbufs ? r300_get_nonnull_cb(fb, 0) : NULL; 48848b8605Smrg 49848b8605Smrg if (cb) { 50848b8605Smrg if (cb->format == PIPE_FORMAT_R16G16B16A16_FLOAT) { 51848b8605Smrg WRITE_CS_TABLE(blend->cb_noclamp, size); 52848b8605Smrg } else if (cb->format == PIPE_FORMAT_R16G16B16X16_FLOAT) { 53848b8605Smrg WRITE_CS_TABLE(blend->cb_noclamp_noalpha, size); 54848b8605Smrg } else { 55848b8605Smrg unsigned swz = r300_surface(cb)->colormask_swizzle; 56848b8605Smrg WRITE_CS_TABLE(blend->cb_clamp[swz], size); 57848b8605Smrg } 58848b8605Smrg } else { 59848b8605Smrg WRITE_CS_TABLE(blend->cb_no_readwrite, size); 60848b8605Smrg } 61848b8605Smrg} 62848b8605Smrg 63848b8605Smrgvoid r300_emit_blend_color_state(struct r300_context* r300, 64848b8605Smrg unsigned size, void* state) 65848b8605Smrg{ 66848b8605Smrg struct r300_blend_color_state* bc = (struct r300_blend_color_state*)state; 67848b8605Smrg CS_LOCALS(r300); 68848b8605Smrg 69848b8605Smrg WRITE_CS_TABLE(bc->cb, size); 70848b8605Smrg} 71848b8605Smrg 72848b8605Smrgvoid r300_emit_clip_state(struct r300_context* r300, 73848b8605Smrg unsigned size, void* state) 74848b8605Smrg{ 75848b8605Smrg struct r300_clip_state* clip = (struct r300_clip_state*)state; 76848b8605Smrg CS_LOCALS(r300); 77848b8605Smrg 78848b8605Smrg WRITE_CS_TABLE(clip->cb, size); 79848b8605Smrg} 80848b8605Smrg 81848b8605Smrgvoid r300_emit_dsa_state(struct r300_context* r300, unsigned size, void* state) 82848b8605Smrg{ 83848b8605Smrg struct r300_dsa_state* dsa = (struct r300_dsa_state*)state; 84848b8605Smrg struct pipe_framebuffer_state* fb = 85848b8605Smrg (struct pipe_framebuffer_state*)r300->fb_state.state; 86848b8605Smrg boolean is_r500 = r300->screen->caps.is_r500; 87848b8605Smrg CS_LOCALS(r300); 88848b8605Smrg uint32_t alpha_func = dsa->alpha_function; 89848b8605Smrg 90848b8605Smrg /* Choose the alpha ref value between 8-bit (FG_ALPHA_FUNC.AM_VAL) and 91848b8605Smrg * 16-bit (FG_ALPHA_VALUE). */ 92848b8605Smrg if (is_r500 && (alpha_func & R300_FG_ALPHA_FUNC_ENABLE)) { 93848b8605Smrg struct pipe_surface *cb = fb->nr_cbufs ? r300_get_nonnull_cb(fb, 0) : NULL; 94848b8605Smrg 95848b8605Smrg if (cb && 96848b8605Smrg (cb->format == PIPE_FORMAT_R16G16B16A16_FLOAT || 97848b8605Smrg cb->format == PIPE_FORMAT_R16G16B16X16_FLOAT)) { 98848b8605Smrg alpha_func |= R500_FG_ALPHA_FUNC_FP16_ENABLE; 99848b8605Smrg } else { 100848b8605Smrg alpha_func |= R500_FG_ALPHA_FUNC_8BIT; 101848b8605Smrg } 102848b8605Smrg } 103848b8605Smrg 104848b8605Smrg /* Setup alpha-to-coverage. */ 105848b8605Smrg if (r300->alpha_to_coverage && r300->msaa_enable) { 106848b8605Smrg /* Always set 3/6, it improves precision even for 2x and 4x MSAA. */ 107848b8605Smrg alpha_func |= R300_FG_ALPHA_FUNC_MASK_ENABLE | 108848b8605Smrg R300_FG_ALPHA_FUNC_CFG_3_OF_6; 109848b8605Smrg } 110848b8605Smrg 111848b8605Smrg BEGIN_CS(size); 112848b8605Smrg OUT_CS_REG(R300_FG_ALPHA_FUNC, alpha_func); 113848b8605Smrg OUT_CS_TABLE(fb->zsbuf ? &dsa->cb_begin : dsa->cb_zb_no_readwrite, size-2); 114848b8605Smrg END_CS; 115848b8605Smrg} 116848b8605Smrg 117848b8605Smrgstatic void get_rc_constant_state( 118848b8605Smrg float vec[4], 119848b8605Smrg struct r300_context * r300, 120848b8605Smrg struct rc_constant * constant) 121848b8605Smrg{ 122848b8605Smrg struct r300_textures_state* texstate = r300->textures_state.state; 123848b8605Smrg struct r300_resource *tex; 124848b8605Smrg 125848b8605Smrg assert(constant->Type == RC_CONSTANT_STATE); 126848b8605Smrg 127848b8605Smrg /* vec should either be (0, 0, 0, 1), which should be a relatively safe 128848b8605Smrg * RGBA or STRQ value, or it could be one of the RC_CONSTANT_STATE 129848b8605Smrg * state factors. */ 130848b8605Smrg 131848b8605Smrg switch (constant->u.State[0]) { 132848b8605Smrg /* Factor for converting rectangle coords to 133848b8605Smrg * normalized coords. Should only show up on non-r500. */ 134848b8605Smrg case RC_STATE_R300_TEXRECT_FACTOR: 135848b8605Smrg tex = r300_resource(texstate->sampler_views[constant->u.State[1]]->base.texture); 136848b8605Smrg vec[0] = 1.0 / tex->tex.width0; 137848b8605Smrg vec[1] = 1.0 / tex->tex.height0; 138848b8605Smrg vec[2] = 0; 139848b8605Smrg vec[3] = 1; 140848b8605Smrg break; 141848b8605Smrg 142848b8605Smrg case RC_STATE_R300_TEXSCALE_FACTOR: 143848b8605Smrg tex = r300_resource(texstate->sampler_views[constant->u.State[1]]->base.texture); 144848b8605Smrg /* Add a small number to the texture size to work around rounding errors in hw. */ 145848b8605Smrg vec[0] = tex->b.b.width0 / (tex->tex.width0 + 0.001f); 146848b8605Smrg vec[1] = tex->b.b.height0 / (tex->tex.height0 + 0.001f); 147848b8605Smrg vec[2] = tex->b.b.depth0 / (tex->tex.depth0 + 0.001f); 148848b8605Smrg vec[3] = 1; 149848b8605Smrg break; 150848b8605Smrg 151848b8605Smrg case RC_STATE_R300_VIEWPORT_SCALE: 152848b8605Smrg vec[0] = r300->viewport.scale[0]; 153848b8605Smrg vec[1] = r300->viewport.scale[1]; 154848b8605Smrg vec[2] = r300->viewport.scale[2]; 155848b8605Smrg vec[3] = 1; 156848b8605Smrg break; 157848b8605Smrg 158848b8605Smrg case RC_STATE_R300_VIEWPORT_OFFSET: 159848b8605Smrg vec[0] = r300->viewport.translate[0]; 160848b8605Smrg vec[1] = r300->viewport.translate[1]; 161848b8605Smrg vec[2] = r300->viewport.translate[2]; 162848b8605Smrg vec[3] = 1; 163848b8605Smrg break; 164848b8605Smrg 165848b8605Smrg default: 166848b8605Smrg fprintf(stderr, "r300: Implementation error: " 167848b8605Smrg "Unknown RC_CONSTANT type %d\n", constant->u.State[0]); 168848b8605Smrg vec[0] = 0; 169848b8605Smrg vec[1] = 0; 170848b8605Smrg vec[2] = 0; 171848b8605Smrg vec[3] = 1; 172848b8605Smrg } 173848b8605Smrg} 174848b8605Smrg 175848b8605Smrg/* Convert a normal single-precision float into the 7.16 format 176848b8605Smrg * used by the R300 fragment shader. 177848b8605Smrg */ 178848b8605Smrguint32_t pack_float24(float f) 179848b8605Smrg{ 180848b8605Smrg union { 181848b8605Smrg float fl; 182848b8605Smrg uint32_t u; 183848b8605Smrg } u; 184848b8605Smrg float mantissa; 185848b8605Smrg int exponent; 186848b8605Smrg uint32_t float24 = 0; 187848b8605Smrg 188848b8605Smrg if (f == 0.0) 189848b8605Smrg return 0; 190848b8605Smrg 191848b8605Smrg u.fl = f; 192848b8605Smrg 193848b8605Smrg mantissa = frexpf(f, &exponent); 194848b8605Smrg 195848b8605Smrg /* Handle -ve */ 196848b8605Smrg if (mantissa < 0) { 197848b8605Smrg float24 |= (1 << 23); 198848b8605Smrg mantissa = mantissa * -1.0; 199848b8605Smrg } 200848b8605Smrg /* Handle exponent, bias of 63 */ 201848b8605Smrg exponent += 62; 202848b8605Smrg float24 |= (exponent << 16); 203848b8605Smrg /* Kill 7 LSB of mantissa */ 204848b8605Smrg float24 |= (u.u & 0x7FFFFF) >> 7; 205848b8605Smrg 206848b8605Smrg return float24; 207848b8605Smrg} 208848b8605Smrg 209848b8605Smrgvoid r300_emit_fs(struct r300_context* r300, unsigned size, void *state) 210848b8605Smrg{ 211848b8605Smrg struct r300_fragment_shader *fs = r300_fs(r300); 212848b8605Smrg CS_LOCALS(r300); 213848b8605Smrg 214848b8605Smrg WRITE_CS_TABLE(fs->shader->cb_code, fs->shader->cb_code_size); 215848b8605Smrg} 216848b8605Smrg 217848b8605Smrgvoid r300_emit_fs_constants(struct r300_context* r300, unsigned size, void *state) 218848b8605Smrg{ 219848b8605Smrg struct r300_fragment_shader *fs = r300_fs(r300); 220848b8605Smrg struct r300_constant_buffer *buf = (struct r300_constant_buffer*)state; 221848b8605Smrg unsigned count = fs->shader->externals_count; 222848b8605Smrg unsigned i, j; 223848b8605Smrg CS_LOCALS(r300); 224848b8605Smrg 225848b8605Smrg if (count == 0) 226848b8605Smrg return; 227848b8605Smrg 228848b8605Smrg BEGIN_CS(size); 229848b8605Smrg OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X, count * 4); 230848b8605Smrg if (buf->remap_table){ 231848b8605Smrg for (i = 0; i < count; i++) { 232848b8605Smrg float *data = (float*)&buf->ptr[buf->remap_table[i]*4]; 233848b8605Smrg for (j = 0; j < 4; j++) 234848b8605Smrg OUT_CS(pack_float24(data[j])); 235848b8605Smrg } 236848b8605Smrg } else { 237848b8605Smrg for (i = 0; i < count; i++) 238848b8605Smrg for (j = 0; j < 4; j++) 239848b8605Smrg OUT_CS(pack_float24(*(float*)&buf->ptr[i*4+j])); 240848b8605Smrg } 241848b8605Smrg 242848b8605Smrg END_CS; 243848b8605Smrg} 244848b8605Smrg 245848b8605Smrgvoid r300_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, void *state) 246848b8605Smrg{ 247848b8605Smrg struct r300_fragment_shader *fs = r300_fs(r300); 248848b8605Smrg struct rc_constant_list *constants = &fs->shader->code.constants; 249848b8605Smrg unsigned i; 250848b8605Smrg unsigned count = fs->shader->rc_state_count; 251848b8605Smrg unsigned first = fs->shader->externals_count; 252848b8605Smrg unsigned end = constants->Count; 253848b8605Smrg unsigned j; 254848b8605Smrg CS_LOCALS(r300); 255848b8605Smrg 256848b8605Smrg if (count == 0) 257848b8605Smrg return; 258848b8605Smrg 259848b8605Smrg BEGIN_CS(size); 260848b8605Smrg for(i = first; i < end; ++i) { 261848b8605Smrg if (constants->Constants[i].Type == RC_CONSTANT_STATE) { 262848b8605Smrg float data[4]; 263848b8605Smrg 264848b8605Smrg get_rc_constant_state(data, r300, &constants->Constants[i]); 265848b8605Smrg 266848b8605Smrg OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X + i * 16, 4); 267848b8605Smrg for (j = 0; j < 4; j++) 268848b8605Smrg OUT_CS(pack_float24(data[j])); 269848b8605Smrg } 270848b8605Smrg } 271848b8605Smrg END_CS; 272848b8605Smrg} 273848b8605Smrg 274848b8605Smrgvoid r500_emit_fs(struct r300_context* r300, unsigned size, void *state) 275848b8605Smrg{ 276848b8605Smrg struct r300_fragment_shader *fs = r300_fs(r300); 277848b8605Smrg CS_LOCALS(r300); 278848b8605Smrg 279848b8605Smrg WRITE_CS_TABLE(fs->shader->cb_code, fs->shader->cb_code_size); 280848b8605Smrg} 281848b8605Smrg 282848b8605Smrgvoid r500_emit_fs_constants(struct r300_context* r300, unsigned size, void *state) 283848b8605Smrg{ 284848b8605Smrg struct r300_fragment_shader *fs = r300_fs(r300); 285848b8605Smrg struct r300_constant_buffer *buf = (struct r300_constant_buffer*)state; 286848b8605Smrg unsigned count = fs->shader->externals_count; 287848b8605Smrg CS_LOCALS(r300); 288848b8605Smrg 289848b8605Smrg if (count == 0) 290848b8605Smrg return; 291848b8605Smrg 292848b8605Smrg BEGIN_CS(size); 293848b8605Smrg OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_CONST); 294848b8605Smrg OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, count * 4); 295848b8605Smrg if (buf->remap_table){ 296848b8605Smrg for (unsigned i = 0; i < count; i++) { 297848b8605Smrg uint32_t *data = &buf->ptr[buf->remap_table[i]*4]; 298848b8605Smrg OUT_CS_TABLE(data, 4); 299848b8605Smrg } 300848b8605Smrg } else { 301848b8605Smrg OUT_CS_TABLE(buf->ptr, count * 4); 302848b8605Smrg } 303848b8605Smrg END_CS; 304848b8605Smrg} 305848b8605Smrg 306848b8605Smrgvoid r500_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, void *state) 307848b8605Smrg{ 308848b8605Smrg struct r300_fragment_shader *fs = r300_fs(r300); 309848b8605Smrg struct rc_constant_list *constants = &fs->shader->code.constants; 310848b8605Smrg unsigned i; 311848b8605Smrg unsigned count = fs->shader->rc_state_count; 312848b8605Smrg unsigned first = fs->shader->externals_count; 313848b8605Smrg unsigned end = constants->Count; 314848b8605Smrg CS_LOCALS(r300); 315848b8605Smrg 316848b8605Smrg if (count == 0) 317848b8605Smrg return; 318848b8605Smrg 319848b8605Smrg BEGIN_CS(size); 320848b8605Smrg for(i = first; i < end; ++i) { 321848b8605Smrg if (constants->Constants[i].Type == RC_CONSTANT_STATE) { 322848b8605Smrg float data[4]; 323848b8605Smrg 324848b8605Smrg get_rc_constant_state(data, r300, &constants->Constants[i]); 325848b8605Smrg 326848b8605Smrg OUT_CS_REG(R500_GA_US_VECTOR_INDEX, 327848b8605Smrg R500_GA_US_VECTOR_INDEX_TYPE_CONST | 328848b8605Smrg (i & R500_GA_US_VECTOR_INDEX_MASK)); 329848b8605Smrg OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, 4); 330848b8605Smrg OUT_CS_TABLE(data, 4); 331848b8605Smrg } 332848b8605Smrg } 333848b8605Smrg END_CS; 334848b8605Smrg} 335848b8605Smrg 336848b8605Smrgvoid r300_emit_gpu_flush(struct r300_context *r300, unsigned size, void *state) 337848b8605Smrg{ 338848b8605Smrg struct r300_gpu_flush *gpuflush = (struct r300_gpu_flush*)state; 339848b8605Smrg struct pipe_framebuffer_state* fb = 340848b8605Smrg (struct pipe_framebuffer_state*)r300->fb_state.state; 341848b8605Smrg uint32_t height = fb->height; 342848b8605Smrg uint32_t width = fb->width; 343848b8605Smrg CS_LOCALS(r300); 344848b8605Smrg 345848b8605Smrg if (r300->cbzb_clear) { 346848b8605Smrg struct r300_surface *surf = r300_surface(fb->cbufs[0]); 347848b8605Smrg 348848b8605Smrg height = surf->cbzb_height; 349848b8605Smrg width = surf->cbzb_width; 350848b8605Smrg } 351848b8605Smrg 352848b8605Smrg DBG(r300, DBG_SCISSOR, 353848b8605Smrg "r300: Scissor width: %i, height: %i, CBZB clear: %s\n", 354848b8605Smrg width, height, r300->cbzb_clear ? "YES" : "NO"); 355848b8605Smrg 356848b8605Smrg BEGIN_CS(size); 357848b8605Smrg 358848b8605Smrg /* Set up scissors. 359848b8605Smrg * By writing to the SC registers, SC & US assert idle. */ 360848b8605Smrg OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2); 361848b8605Smrg if (r300->screen->caps.is_r500) { 362848b8605Smrg OUT_CS(0); 363848b8605Smrg OUT_CS(((width - 1) << R300_SCISSORS_X_SHIFT) | 364848b8605Smrg ((height - 1) << R300_SCISSORS_Y_SHIFT)); 365848b8605Smrg } else { 366848b8605Smrg OUT_CS((1440 << R300_SCISSORS_X_SHIFT) | 367848b8605Smrg (1440 << R300_SCISSORS_Y_SHIFT)); 368848b8605Smrg OUT_CS(((width + 1440-1) << R300_SCISSORS_X_SHIFT) | 369848b8605Smrg ((height + 1440-1) << R300_SCISSORS_Y_SHIFT)); 370848b8605Smrg } 371848b8605Smrg 372848b8605Smrg /* Flush CB & ZB caches and wait until the 3D engine is idle and clean. */ 373848b8605Smrg OUT_CS_TABLE(gpuflush->cb_flush_clean, 6); 374848b8605Smrg END_CS; 375848b8605Smrg} 376848b8605Smrg 377848b8605Smrgvoid r300_emit_aa_state(struct r300_context *r300, unsigned size, void *state) 378848b8605Smrg{ 379848b8605Smrg struct r300_aa_state *aa = (struct r300_aa_state*)state; 380848b8605Smrg CS_LOCALS(r300); 381848b8605Smrg 382848b8605Smrg BEGIN_CS(size); 383848b8605Smrg OUT_CS_REG(R300_GB_AA_CONFIG, aa->aa_config); 384848b8605Smrg 385848b8605Smrg if (aa->dest) { 386848b8605Smrg OUT_CS_REG_SEQ(R300_RB3D_AARESOLVE_OFFSET, 3); 387848b8605Smrg OUT_CS(aa->dest->offset); 388848b8605Smrg OUT_CS(aa->dest->pitch & R300_RB3D_AARESOLVE_PITCH_MASK); 389848b8605Smrg OUT_CS(R300_RB3D_AARESOLVE_CTL_AARESOLVE_MODE_RESOLVE | 390848b8605Smrg R300_RB3D_AARESOLVE_CTL_AARESOLVE_ALPHA_AVERAGE); 391848b8605Smrg OUT_CS_RELOC(aa->dest); 392848b8605Smrg } else { 393848b8605Smrg OUT_CS_REG(R300_RB3D_AARESOLVE_CTL, 0); 394848b8605Smrg } 395848b8605Smrg 396848b8605Smrg END_CS; 397848b8605Smrg} 398848b8605Smrg 399848b8605Smrgvoid r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) 400848b8605Smrg{ 401848b8605Smrg struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state; 402848b8605Smrg struct r300_surface* surf; 403848b8605Smrg unsigned i; 404848b8605Smrg uint32_t rb3d_cctl = 0; 405848b8605Smrg 406848b8605Smrg CS_LOCALS(r300); 407848b8605Smrg 408848b8605Smrg BEGIN_CS(size); 409848b8605Smrg 410848b8605Smrg if (r300->screen->caps.is_r500) { 411848b8605Smrg rb3d_cctl = R300_RB3D_CCTL_INDEPENDENT_COLORFORMAT_ENABLE_ENABLE; 412848b8605Smrg } 413848b8605Smrg /* NUM_MULTIWRITES replicates COLOR[0] to all colorbuffers. */ 414848b8605Smrg if (fb->nr_cbufs && r300->fb_multiwrite) { 415848b8605Smrg rb3d_cctl |= R300_RB3D_CCTL_NUM_MULTIWRITES(fb->nr_cbufs); 416848b8605Smrg } 417848b8605Smrg if (r300->cmask_in_use) { 418848b8605Smrg rb3d_cctl |= R300_RB3D_CCTL_AA_COMPRESSION_ENABLE | 419848b8605Smrg R300_RB3D_CCTL_CMASK_ENABLE; 420848b8605Smrg } 421848b8605Smrg 422848b8605Smrg OUT_CS_REG(R300_RB3D_CCTL, rb3d_cctl); 423848b8605Smrg 424848b8605Smrg /* Set up colorbuffers. */ 425848b8605Smrg for (i = 0; i < fb->nr_cbufs; i++) { 426848b8605Smrg surf = r300_surface(r300_get_nonnull_cb(fb, i)); 427848b8605Smrg 428848b8605Smrg OUT_CS_REG(R300_RB3D_COLOROFFSET0 + (4 * i), surf->offset); 429848b8605Smrg OUT_CS_RELOC(surf); 430848b8605Smrg 431848b8605Smrg OUT_CS_REG(R300_RB3D_COLORPITCH0 + (4 * i), surf->pitch); 432848b8605Smrg OUT_CS_RELOC(surf); 433848b8605Smrg 434848b8605Smrg if (r300->cmask_in_use && i == 0) { 435848b8605Smrg OUT_CS_REG(R300_RB3D_CMASK_OFFSET0, 0); 436848b8605Smrg OUT_CS_REG(R300_RB3D_CMASK_PITCH0, surf->pitch_cmask); 437848b8605Smrg OUT_CS_REG(R300_RB3D_COLOR_CLEAR_VALUE, r300->color_clear_value); 438848b8605Smrg if (r300->screen->caps.is_r500 && r300->screen->info.drm_minor >= 29) { 439848b8605Smrg OUT_CS_REG_SEQ(R500_RB3D_COLOR_CLEAR_VALUE_AR, 2); 440848b8605Smrg OUT_CS(r300->color_clear_value_ar); 441848b8605Smrg OUT_CS(r300->color_clear_value_gb); 442848b8605Smrg } 443848b8605Smrg } 444848b8605Smrg } 445848b8605Smrg 446848b8605Smrg /* Set up the ZB part of the CBZB clear. */ 447848b8605Smrg if (r300->cbzb_clear) { 448848b8605Smrg surf = r300_surface(fb->cbufs[0]); 449848b8605Smrg 450848b8605Smrg OUT_CS_REG(R300_ZB_FORMAT, surf->cbzb_format); 451848b8605Smrg 452848b8605Smrg OUT_CS_REG(R300_ZB_DEPTHOFFSET, surf->cbzb_midpoint_offset); 453848b8605Smrg OUT_CS_RELOC(surf); 454848b8605Smrg 455848b8605Smrg OUT_CS_REG(R300_ZB_DEPTHPITCH, surf->cbzb_pitch); 456848b8605Smrg OUT_CS_RELOC(surf); 457848b8605Smrg 458848b8605Smrg DBG(r300, DBG_CBZB, 459848b8605Smrg "CBZB clearing cbuf %08x %08x\n", surf->cbzb_format, 460848b8605Smrg surf->cbzb_pitch); 461848b8605Smrg } 462848b8605Smrg /* Set up a zbuffer. */ 463848b8605Smrg else if (fb->zsbuf) { 464848b8605Smrg surf = r300_surface(fb->zsbuf); 465848b8605Smrg 466848b8605Smrg OUT_CS_REG(R300_ZB_FORMAT, surf->format); 467848b8605Smrg 468848b8605Smrg OUT_CS_REG(R300_ZB_DEPTHOFFSET, surf->offset); 469848b8605Smrg OUT_CS_RELOC(surf); 470848b8605Smrg 471848b8605Smrg OUT_CS_REG(R300_ZB_DEPTHPITCH, surf->pitch); 472848b8605Smrg OUT_CS_RELOC(surf); 473848b8605Smrg 474848b8605Smrg if (r300->hyperz_enabled) { 475848b8605Smrg /* HiZ RAM. */ 476848b8605Smrg OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0); 477848b8605Smrg OUT_CS_REG(R300_ZB_HIZ_PITCH, surf->pitch_hiz); 478848b8605Smrg /* Z Mask RAM. (compressed zbuffer) */ 479848b8605Smrg OUT_CS_REG(R300_ZB_ZMASK_OFFSET, 0); 480848b8605Smrg OUT_CS_REG(R300_ZB_ZMASK_PITCH, surf->pitch_zmask); 481848b8605Smrg } 482848b8605Smrg } 483848b8605Smrg 484848b8605Smrg END_CS; 485848b8605Smrg} 486848b8605Smrg 487848b8605Smrgvoid r300_emit_hyperz_state(struct r300_context *r300, 488848b8605Smrg unsigned size, void *state) 489848b8605Smrg{ 490848b8605Smrg struct r300_hyperz_state *z = state; 491848b8605Smrg CS_LOCALS(r300); 492848b8605Smrg 493848b8605Smrg if (z->flush) 494848b8605Smrg WRITE_CS_TABLE(&z->cb_flush_begin, size); 495848b8605Smrg else 496848b8605Smrg WRITE_CS_TABLE(&z->cb_begin, size - 2); 497848b8605Smrg} 498848b8605Smrg 499848b8605Smrgvoid r300_emit_hyperz_end(struct r300_context *r300) 500848b8605Smrg{ 501848b8605Smrg struct r300_hyperz_state z = 502848b8605Smrg *(struct r300_hyperz_state*)r300->hyperz_state.state; 503848b8605Smrg 504848b8605Smrg z.flush = 1; 505848b8605Smrg z.zb_bw_cntl = 0; 506848b8605Smrg z.zb_depthclearvalue = 0; 507848b8605Smrg z.sc_hyperz = R300_SC_HYPERZ_ADJ_2; 508848b8605Smrg z.gb_z_peq_config = 0; 509848b8605Smrg 510848b8605Smrg r300_emit_hyperz_state(r300, r300->hyperz_state.size, &z); 511848b8605Smrg} 512848b8605Smrg 513848b8605Smrg#define R300_NIBBLES(x0, y0, x1, y1, x2, y2, d0y, d0x) \ 514848b8605Smrg (((x0) & 0xf) | (((y0) & 0xf) << 4) | \ 515848b8605Smrg (((x1) & 0xf) << 8) | (((y1) & 0xf) << 12) | \ 516848b8605Smrg (((x2) & 0xf) << 16) | (((y2) & 0xf) << 20) | \ 517848b8605Smrg (((d0y) & 0xf) << 24) | (((d0x) & 0xf) << 28)) 518848b8605Smrg 519848b8605Smrgstatic unsigned r300_get_mspos(int index, unsigned *p) 520848b8605Smrg{ 521848b8605Smrg unsigned reg, i, distx, disty, dist; 522848b8605Smrg 523848b8605Smrg if (index == 0) { 524848b8605Smrg /* MSPOS0 contains positions for samples 0,1,2 as (X,Y) pairs of nibbles, 525848b8605Smrg * followed by a (Y,X) pair containing the minimum distance from the pixel 526848b8605Smrg * edge: 527848b8605Smrg * X0, Y0, X1, Y1, X2, Y2, D0_Y, D0_X 528848b8605Smrg * 529848b8605Smrg * There is a quirk when setting D0_X. The value represents the distance 530848b8605Smrg * from the left edge of the pixel quad to the first sample in subpixels. 531848b8605Smrg * All values less than eight should use the actual value, but „7‟ should 532848b8605Smrg * be used for the distance „8‟. The hardware will convert 7 into 8 internally. 533848b8605Smrg */ 534848b8605Smrg distx = 11; 535848b8605Smrg for (i = 0; i < 12; i += 2) { 536848b8605Smrg if (p[i] < distx) 537848b8605Smrg distx = p[i]; 538848b8605Smrg } 539848b8605Smrg 540848b8605Smrg disty = 11; 541848b8605Smrg for (i = 1; i < 12; i += 2) { 542848b8605Smrg if (p[i] < disty) 543848b8605Smrg disty = p[i]; 544848b8605Smrg } 545848b8605Smrg 546848b8605Smrg if (distx == 8) 547848b8605Smrg distx = 7; 548848b8605Smrg 549848b8605Smrg reg = R300_NIBBLES(p[0], p[1], p[2], p[3], p[4], p[5], disty, distx); 550848b8605Smrg } else { 551848b8605Smrg /* MSPOS1 contains positions for samples 3,4,5 as (X,Y) pairs of nibbles, 552848b8605Smrg * followed by the minimum distance from the pixel edge (not sure if X or Y): 553848b8605Smrg * X3, Y3, X4, Y4, X5, Y5, D1 554848b8605Smrg */ 555848b8605Smrg dist = 11; 556848b8605Smrg for (i = 0; i < 12; i++) { 557848b8605Smrg if (p[i] < dist) 558848b8605Smrg dist = p[i]; 559848b8605Smrg } 560848b8605Smrg 561848b8605Smrg reg = R300_NIBBLES(p[6], p[7], p[8], p[9], p[10], p[11], dist, 0); 562848b8605Smrg } 563848b8605Smrg return reg; 564848b8605Smrg} 565848b8605Smrg 566848b8605Smrgvoid r300_emit_fb_state_pipelined(struct r300_context *r300, 567848b8605Smrg unsigned size, void *state) 568848b8605Smrg{ 569848b8605Smrg /* The sample coordinates are in the range [0,11], because 570848b8605Smrg * GB_TILE_CONFIG.SUBPIXEL is set to the 1/12 subpixel precision. 571848b8605Smrg * 572848b8605Smrg * Some sample coordinates reach to neighboring pixels and should not be used. 573848b8605Smrg * (e.g. Y=11) 574848b8605Smrg * 575848b8605Smrg * The unused samples must be set to the positions of other valid samples. */ 576848b8605Smrg static unsigned sample_locs_1x[12] = { 577848b8605Smrg 6,6, 6,6, 6,6, 6,6, 6,6, 6,6 578848b8605Smrg }; 579848b8605Smrg static unsigned sample_locs_2x[12] = { 580848b8605Smrg 3,9, 9,3, 9,3, 9,3, 9,3, 9,3 581848b8605Smrg }; 582848b8605Smrg static unsigned sample_locs_4x[12] = { 583848b8605Smrg 4,4, 8,8, 2,10, 10,2, 10,2, 10,2 584848b8605Smrg }; 585848b8605Smrg static unsigned sample_locs_6x[12] = { 586848b8605Smrg 3,1, 7,3, 11,5, 1,7, 5,9, 9,10 587848b8605Smrg }; 588848b8605Smrg 589848b8605Smrg struct pipe_framebuffer_state* fb = 590848b8605Smrg (struct pipe_framebuffer_state*)r300->fb_state.state; 591848b8605Smrg unsigned i, num_cbufs = fb->nr_cbufs; 592848b8605Smrg unsigned mspos0, mspos1; 593848b8605Smrg CS_LOCALS(r300); 594848b8605Smrg 595848b8605Smrg /* If we use the multiwrite feature, the colorbuffers 2,3,4 must be 596848b8605Smrg * marked as UNUSED in the US block. */ 597848b8605Smrg if (r300->fb_multiwrite) { 598848b8605Smrg num_cbufs = MIN2(num_cbufs, 1); 599848b8605Smrg } 600848b8605Smrg 601848b8605Smrg BEGIN_CS(size); 602848b8605Smrg 603848b8605Smrg /* Colorbuffer format in the US block. 604848b8605Smrg * (must be written after unpipelined regs) */ 605848b8605Smrg OUT_CS_REG_SEQ(R300_US_OUT_FMT_0, 4); 606848b8605Smrg for (i = 0; i < num_cbufs; i++) { 607848b8605Smrg OUT_CS(r300_surface(r300_get_nonnull_cb(fb, i))->format); 608848b8605Smrg } 609848b8605Smrg for (; i < 1; i++) { 610848b8605Smrg OUT_CS(R300_US_OUT_FMT_C4_8 | 611848b8605Smrg R300_C0_SEL_B | R300_C1_SEL_G | 612848b8605Smrg R300_C2_SEL_R | R300_C3_SEL_A); 613848b8605Smrg } 614848b8605Smrg for (; i < 4; i++) { 615848b8605Smrg OUT_CS(R300_US_OUT_FMT_UNUSED); 616848b8605Smrg } 617848b8605Smrg 618848b8605Smrg /* Set sample positions. It depends on the framebuffer sample count. 619848b8605Smrg * These are pipelined regs and as such cannot be moved to the AA state. 620848b8605Smrg */ 621848b8605Smrg switch (r300->num_samples) { 622848b8605Smrg default: 623848b8605Smrg mspos0 = r300_get_mspos(0, sample_locs_1x); 624848b8605Smrg mspos1 = r300_get_mspos(1, sample_locs_1x); 625848b8605Smrg break; 626848b8605Smrg case 2: 627848b8605Smrg mspos0 = r300_get_mspos(0, sample_locs_2x); 628848b8605Smrg mspos1 = r300_get_mspos(1, sample_locs_2x); 629848b8605Smrg break; 630848b8605Smrg case 4: 631848b8605Smrg mspos0 = r300_get_mspos(0, sample_locs_4x); 632848b8605Smrg mspos1 = r300_get_mspos(1, sample_locs_4x); 633848b8605Smrg break; 634848b8605Smrg case 6: 635848b8605Smrg mspos0 = r300_get_mspos(0, sample_locs_6x); 636848b8605Smrg mspos1 = r300_get_mspos(1, sample_locs_6x); 637848b8605Smrg break; 638848b8605Smrg } 639848b8605Smrg 640848b8605Smrg OUT_CS_REG_SEQ(R300_GB_MSPOS0, 2); 641848b8605Smrg OUT_CS(mspos0); 642848b8605Smrg OUT_CS(mspos1); 643848b8605Smrg END_CS; 644848b8605Smrg} 645848b8605Smrg 646848b8605Smrgvoid r300_emit_query_start(struct r300_context *r300, unsigned size, void*state) 647848b8605Smrg{ 648848b8605Smrg struct r300_query *query = r300->query_current; 649848b8605Smrg CS_LOCALS(r300); 650848b8605Smrg 651848b8605Smrg if (!query) 652848b8605Smrg return; 653848b8605Smrg 654848b8605Smrg BEGIN_CS(size); 655848b8605Smrg if (r300->screen->caps.family == CHIP_RV530) { 656848b8605Smrg OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL); 657848b8605Smrg } else { 658848b8605Smrg OUT_CS_REG(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_ALL); 659848b8605Smrg } 660848b8605Smrg OUT_CS_REG(R300_ZB_ZPASS_DATA, 0); 661848b8605Smrg END_CS; 662848b8605Smrg query->begin_emitted = TRUE; 663848b8605Smrg} 664848b8605Smrg 665848b8605Smrgstatic void r300_emit_query_end_frag_pipes(struct r300_context *r300, 666848b8605Smrg struct r300_query *query) 667848b8605Smrg{ 668848b8605Smrg struct r300_capabilities* caps = &r300->screen->caps; 669848b8605Smrg uint32_t gb_pipes = r300->screen->info.r300_num_gb_pipes; 670848b8605Smrg CS_LOCALS(r300); 671848b8605Smrg 672848b8605Smrg assert(gb_pipes); 673848b8605Smrg 674848b8605Smrg BEGIN_CS(6 * gb_pipes + 2); 675848b8605Smrg /* I'm not so sure I like this switch, but it's hard to be elegant 676848b8605Smrg * when there's so many special cases... 677848b8605Smrg * 678848b8605Smrg * So here's the basic idea. For each pipe, enable writes to it only, 679848b8605Smrg * then put out the relocation for ZPASS_ADDR, taking into account a 680848b8605Smrg * 4-byte offset for each pipe. RV380 and older are special; they have 681848b8605Smrg * only two pipes, and the second pipe's enable is on bit 3, not bit 1, 682848b8605Smrg * so there's a chipset cap for that. */ 683848b8605Smrg switch (gb_pipes) { 684848b8605Smrg case 4: 685848b8605Smrg /* pipe 3 only */ 686848b8605Smrg OUT_CS_REG(R300_SU_REG_DEST, 1 << 3); 687848b8605Smrg OUT_CS_REG(R300_ZB_ZPASS_ADDR, (query->num_results + 3) * 4); 688848b8605Smrg OUT_CS_RELOC(r300->query_current); 689848b8605Smrg case 3: 690848b8605Smrg /* pipe 2 only */ 691848b8605Smrg OUT_CS_REG(R300_SU_REG_DEST, 1 << 2); 692848b8605Smrg OUT_CS_REG(R300_ZB_ZPASS_ADDR, (query->num_results + 2) * 4); 693848b8605Smrg OUT_CS_RELOC(r300->query_current); 694848b8605Smrg case 2: 695848b8605Smrg /* pipe 1 only */ 696b8e80941Smrg /* As mentioned above, accommodate RV380 and older. */ 697848b8605Smrg OUT_CS_REG(R300_SU_REG_DEST, 698848b8605Smrg 1 << (caps->high_second_pipe ? 3 : 1)); 699848b8605Smrg OUT_CS_REG(R300_ZB_ZPASS_ADDR, (query->num_results + 1) * 4); 700848b8605Smrg OUT_CS_RELOC(r300->query_current); 701848b8605Smrg case 1: 702848b8605Smrg /* pipe 0 only */ 703848b8605Smrg OUT_CS_REG(R300_SU_REG_DEST, 1 << 0); 704848b8605Smrg OUT_CS_REG(R300_ZB_ZPASS_ADDR, (query->num_results + 0) * 4); 705848b8605Smrg OUT_CS_RELOC(r300->query_current); 706848b8605Smrg break; 707848b8605Smrg default: 708848b8605Smrg fprintf(stderr, "r300: Implementation error: Chipset reports %d" 709848b8605Smrg " pixel pipes!\n", gb_pipes); 710848b8605Smrg abort(); 711848b8605Smrg } 712848b8605Smrg 713848b8605Smrg /* And, finally, reset it to normal... */ 714848b8605Smrg OUT_CS_REG(R300_SU_REG_DEST, 0xF); 715848b8605Smrg END_CS; 716848b8605Smrg} 717848b8605Smrg 718848b8605Smrgstatic void rv530_emit_query_end_single_z(struct r300_context *r300, 719848b8605Smrg struct r300_query *query) 720848b8605Smrg{ 721848b8605Smrg CS_LOCALS(r300); 722848b8605Smrg 723848b8605Smrg BEGIN_CS(8); 724848b8605Smrg OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0); 725848b8605Smrg OUT_CS_REG(R300_ZB_ZPASS_ADDR, query->num_results * 4); 726848b8605Smrg OUT_CS_RELOC(r300->query_current); 727848b8605Smrg OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL); 728848b8605Smrg END_CS; 729848b8605Smrg} 730848b8605Smrg 731848b8605Smrgstatic void rv530_emit_query_end_double_z(struct r300_context *r300, 732848b8605Smrg struct r300_query *query) 733848b8605Smrg{ 734848b8605Smrg CS_LOCALS(r300); 735848b8605Smrg 736848b8605Smrg BEGIN_CS(14); 737848b8605Smrg OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0); 738848b8605Smrg OUT_CS_REG(R300_ZB_ZPASS_ADDR, (query->num_results + 0) * 4); 739848b8605Smrg OUT_CS_RELOC(r300->query_current); 740848b8605Smrg OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_1); 741848b8605Smrg OUT_CS_REG(R300_ZB_ZPASS_ADDR, (query->num_results + 1) * 4); 742848b8605Smrg OUT_CS_RELOC(r300->query_current); 743848b8605Smrg OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL); 744848b8605Smrg END_CS; 745848b8605Smrg} 746848b8605Smrg 747848b8605Smrgvoid r300_emit_query_end(struct r300_context* r300) 748848b8605Smrg{ 749848b8605Smrg struct r300_capabilities *caps = &r300->screen->caps; 750848b8605Smrg struct r300_query *query = r300->query_current; 751848b8605Smrg 752848b8605Smrg if (!query) 753848b8605Smrg return; 754848b8605Smrg 755848b8605Smrg if (query->begin_emitted == FALSE) 756848b8605Smrg return; 757848b8605Smrg 758848b8605Smrg if (caps->family == CHIP_RV530) { 759848b8605Smrg if (r300->screen->info.r300_num_z_pipes == 2) 760848b8605Smrg rv530_emit_query_end_double_z(r300, query); 761848b8605Smrg else 762848b8605Smrg rv530_emit_query_end_single_z(r300, query); 763848b8605Smrg } else 764848b8605Smrg r300_emit_query_end_frag_pipes(r300, query); 765848b8605Smrg 766848b8605Smrg query->begin_emitted = FALSE; 767848b8605Smrg query->num_results += query->num_pipes; 768848b8605Smrg 769848b8605Smrg /* XXX grab all the results and reset the counter. */ 770848b8605Smrg if (query->num_results >= query->buf->size / 4 - 4) { 771848b8605Smrg query->num_results = (query->buf->size / 4) / 2; 772848b8605Smrg fprintf(stderr, "r300: Rewinding OQBO...\n"); 773848b8605Smrg } 774848b8605Smrg} 775848b8605Smrg 776848b8605Smrgvoid r300_emit_invariant_state(struct r300_context *r300, 777848b8605Smrg unsigned size, void *state) 778848b8605Smrg{ 779848b8605Smrg CS_LOCALS(r300); 780848b8605Smrg WRITE_CS_TABLE(state, size); 781848b8605Smrg} 782848b8605Smrg 783848b8605Smrgvoid r300_emit_rs_state(struct r300_context* r300, unsigned size, void* state) 784848b8605Smrg{ 785848b8605Smrg struct r300_rs_state* rs = state; 786848b8605Smrg CS_LOCALS(r300); 787848b8605Smrg 788848b8605Smrg BEGIN_CS(size); 789848b8605Smrg OUT_CS_TABLE(rs->cb_main, RS_STATE_MAIN_SIZE); 790848b8605Smrg if (rs->polygon_offset_enable) { 791848b8605Smrg if (r300->zbuffer_bpp == 16) { 792848b8605Smrg OUT_CS_TABLE(rs->cb_poly_offset_zb16, 5); 793848b8605Smrg } else { 794848b8605Smrg OUT_CS_TABLE(rs->cb_poly_offset_zb24, 5); 795848b8605Smrg } 796848b8605Smrg } 797848b8605Smrg END_CS; 798848b8605Smrg} 799848b8605Smrg 800848b8605Smrgvoid r300_emit_rs_block_state(struct r300_context* r300, 801848b8605Smrg unsigned size, void* state) 802848b8605Smrg{ 803848b8605Smrg struct r300_rs_block* rs = (struct r300_rs_block*)state; 804848b8605Smrg unsigned i; 805848b8605Smrg /* It's the same for both INST and IP tables */ 806848b8605Smrg unsigned count = (rs->inst_count & R300_RS_INST_COUNT_MASK) + 1; 807848b8605Smrg CS_LOCALS(r300); 808848b8605Smrg 809848b8605Smrg if (DBG_ON(r300, DBG_RS_BLOCK)) { 810848b8605Smrg r500_dump_rs_block(rs); 811848b8605Smrg 812848b8605Smrg fprintf(stderr, "r300: RS emit:\n"); 813848b8605Smrg 814848b8605Smrg for (i = 0; i < count; i++) 815848b8605Smrg fprintf(stderr, " : ip %d: 0x%08x\n", i, rs->ip[i]); 816848b8605Smrg 817848b8605Smrg for (i = 0; i < count; i++) 818848b8605Smrg fprintf(stderr, " : inst %d: 0x%08x\n", i, rs->inst[i]); 819848b8605Smrg 820848b8605Smrg fprintf(stderr, " : count: 0x%08x inst_count: 0x%08x\n", 821848b8605Smrg rs->count, rs->inst_count); 822848b8605Smrg } 823848b8605Smrg 824848b8605Smrg BEGIN_CS(size); 825848b8605Smrg OUT_CS_REG_SEQ(R300_VAP_VTX_STATE_CNTL, 2); 826848b8605Smrg OUT_CS(rs->vap_vtx_state_cntl); 827848b8605Smrg OUT_CS(rs->vap_vsm_vtx_assm); 828848b8605Smrg OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2); 829848b8605Smrg OUT_CS(rs->vap_out_vtx_fmt[0]); 830848b8605Smrg OUT_CS(rs->vap_out_vtx_fmt[1]); 831848b8605Smrg OUT_CS_REG_SEQ(R300_GB_ENABLE, 1); 832848b8605Smrg OUT_CS(rs->gb_enable); 833848b8605Smrg 834848b8605Smrg if (r300->screen->caps.is_r500) { 835848b8605Smrg OUT_CS_REG_SEQ(R500_RS_IP_0, count); 836848b8605Smrg } else { 837848b8605Smrg OUT_CS_REG_SEQ(R300_RS_IP_0, count); 838848b8605Smrg } 839848b8605Smrg OUT_CS_TABLE(rs->ip, count); 840848b8605Smrg 841848b8605Smrg OUT_CS_REG_SEQ(R300_RS_COUNT, 2); 842848b8605Smrg OUT_CS(rs->count); 843848b8605Smrg OUT_CS(rs->inst_count); 844848b8605Smrg 845848b8605Smrg if (r300->screen->caps.is_r500) { 846848b8605Smrg OUT_CS_REG_SEQ(R500_RS_INST_0, count); 847848b8605Smrg } else { 848848b8605Smrg OUT_CS_REG_SEQ(R300_RS_INST_0, count); 849848b8605Smrg } 850848b8605Smrg OUT_CS_TABLE(rs->inst, count); 851848b8605Smrg END_CS; 852848b8605Smrg} 853848b8605Smrg 854848b8605Smrgvoid r300_emit_sample_mask(struct r300_context *r300, 855848b8605Smrg unsigned size, void *state) 856848b8605Smrg{ 857848b8605Smrg unsigned mask = (*(unsigned*)state) & ((1 << 6)-1); 858848b8605Smrg CS_LOCALS(r300); 859848b8605Smrg 860848b8605Smrg BEGIN_CS(size); 861848b8605Smrg OUT_CS_REG(R300_SC_SCREENDOOR, 862848b8605Smrg mask | (mask << 6) | (mask << 12) | (mask << 18)); 863848b8605Smrg END_CS; 864848b8605Smrg} 865848b8605Smrg 866848b8605Smrgvoid r300_emit_scissor_state(struct r300_context* r300, 867848b8605Smrg unsigned size, void* state) 868848b8605Smrg{ 869848b8605Smrg struct pipe_scissor_state* scissor = (struct pipe_scissor_state*)state; 870848b8605Smrg CS_LOCALS(r300); 871848b8605Smrg 872848b8605Smrg BEGIN_CS(size); 873848b8605Smrg OUT_CS_REG_SEQ(R300_SC_CLIPRECT_TL_0, 2); 874848b8605Smrg if (r300->screen->caps.is_r500) { 875848b8605Smrg OUT_CS((scissor->minx << R300_CLIPRECT_X_SHIFT) | 876848b8605Smrg (scissor->miny << R300_CLIPRECT_Y_SHIFT)); 877848b8605Smrg OUT_CS(((scissor->maxx - 1) << R300_CLIPRECT_X_SHIFT) | 878848b8605Smrg ((scissor->maxy - 1) << R300_CLIPRECT_Y_SHIFT)); 879848b8605Smrg } else { 880848b8605Smrg OUT_CS(((scissor->minx + 1440) << R300_CLIPRECT_X_SHIFT) | 881848b8605Smrg ((scissor->miny + 1440) << R300_CLIPRECT_Y_SHIFT)); 882848b8605Smrg OUT_CS(((scissor->maxx + 1440-1) << R300_CLIPRECT_X_SHIFT) | 883848b8605Smrg ((scissor->maxy + 1440-1) << R300_CLIPRECT_Y_SHIFT)); 884848b8605Smrg } 885848b8605Smrg END_CS; 886848b8605Smrg} 887848b8605Smrg 888848b8605Smrgvoid r300_emit_textures_state(struct r300_context *r300, 889848b8605Smrg unsigned size, void *state) 890848b8605Smrg{ 891848b8605Smrg struct r300_textures_state *allstate = (struct r300_textures_state*)state; 892848b8605Smrg struct r300_texture_sampler_state *texstate; 893848b8605Smrg struct r300_resource *tex; 894848b8605Smrg unsigned i; 895848b8605Smrg boolean has_us_format = r300->screen->caps.has_us_format; 896848b8605Smrg CS_LOCALS(r300); 897848b8605Smrg 898848b8605Smrg BEGIN_CS(size); 899848b8605Smrg OUT_CS_REG(R300_TX_ENABLE, allstate->tx_enable); 900848b8605Smrg 901848b8605Smrg for (i = 0; i < allstate->count; i++) { 902848b8605Smrg if ((1 << i) & allstate->tx_enable) { 903848b8605Smrg texstate = &allstate->regs[i]; 904848b8605Smrg tex = r300_resource(allstate->sampler_views[i]->base.texture); 905848b8605Smrg 906848b8605Smrg OUT_CS_REG(R300_TX_FILTER0_0 + (i * 4), texstate->filter0); 907848b8605Smrg OUT_CS_REG(R300_TX_FILTER1_0 + (i * 4), texstate->filter1); 908848b8605Smrg OUT_CS_REG(R300_TX_BORDER_COLOR_0 + (i * 4), 909848b8605Smrg texstate->border_color); 910848b8605Smrg 911848b8605Smrg OUT_CS_REG(R300_TX_FORMAT0_0 + (i * 4), texstate->format.format0); 912848b8605Smrg OUT_CS_REG(R300_TX_FORMAT1_0 + (i * 4), texstate->format.format1); 913848b8605Smrg OUT_CS_REG(R300_TX_FORMAT2_0 + (i * 4), texstate->format.format2); 914848b8605Smrg 915848b8605Smrg OUT_CS_REG(R300_TX_OFFSET_0 + (i * 4), texstate->format.tile_config); 916848b8605Smrg OUT_CS_RELOC(tex); 917848b8605Smrg 918848b8605Smrg if (has_us_format) { 919848b8605Smrg OUT_CS_REG(R500_US_FORMAT0_0 + (i * 4), 920848b8605Smrg texstate->format.us_format0); 921848b8605Smrg } 922848b8605Smrg } 923848b8605Smrg } 924848b8605Smrg END_CS; 925848b8605Smrg} 926848b8605Smrg 927848b8605Smrgvoid r300_emit_vertex_arrays(struct r300_context* r300, int offset, 928848b8605Smrg boolean indexed, int instance_id) 929848b8605Smrg{ 930848b8605Smrg struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; 931848b8605Smrg struct pipe_vertex_element *velem = r300->velems->velem; 932848b8605Smrg struct r300_resource *buf; 933848b8605Smrg int i; 934848b8605Smrg unsigned vertex_array_count = r300->velems->count; 935848b8605Smrg unsigned packet_size = (vertex_array_count * 3 + 1) / 2; 936848b8605Smrg struct pipe_vertex_buffer *vb1, *vb2; 937848b8605Smrg unsigned *hw_format_size = r300->velems->format_size; 938848b8605Smrg unsigned size1, size2, offset1, offset2, stride1, stride2; 939848b8605Smrg CS_LOCALS(r300); 940848b8605Smrg 941848b8605Smrg BEGIN_CS(2 + packet_size + vertex_array_count * 2); 942848b8605Smrg OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size); 943848b8605Smrg OUT_CS(vertex_array_count | (!indexed ? R300_VC_FORCE_PREFETCH : 0)); 944848b8605Smrg 945848b8605Smrg if (instance_id == -1) { 946848b8605Smrg /* Non-instanced arrays. This ignores instance_divisor and instance_id. */ 947848b8605Smrg for (i = 0; i < vertex_array_count - 1; i += 2) { 948848b8605Smrg vb1 = &vbuf[velem[i].vertex_buffer_index]; 949848b8605Smrg vb2 = &vbuf[velem[i+1].vertex_buffer_index]; 950848b8605Smrg size1 = hw_format_size[i]; 951848b8605Smrg size2 = hw_format_size[i+1]; 952848b8605Smrg 953848b8605Smrg OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride) | 954848b8605Smrg R300_VBPNTR_SIZE1(size2) | R300_VBPNTR_STRIDE1(vb2->stride)); 955848b8605Smrg OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride); 956848b8605Smrg OUT_CS(vb2->buffer_offset + velem[i+1].src_offset + offset * vb2->stride); 957848b8605Smrg } 958848b8605Smrg 959848b8605Smrg if (vertex_array_count & 1) { 960848b8605Smrg vb1 = &vbuf[velem[i].vertex_buffer_index]; 961848b8605Smrg size1 = hw_format_size[i]; 962848b8605Smrg 963848b8605Smrg OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride)); 964848b8605Smrg OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride); 965848b8605Smrg } 966848b8605Smrg 967848b8605Smrg for (i = 0; i < vertex_array_count; i++) { 968b8e80941Smrg buf = r300_resource(vbuf[velem[i].vertex_buffer_index].buffer.resource); 969848b8605Smrg OUT_CS_RELOC(buf); 970848b8605Smrg } 971848b8605Smrg } else { 972848b8605Smrg /* Instanced arrays. */ 973848b8605Smrg for (i = 0; i < vertex_array_count - 1; i += 2) { 974848b8605Smrg vb1 = &vbuf[velem[i].vertex_buffer_index]; 975848b8605Smrg vb2 = &vbuf[velem[i+1].vertex_buffer_index]; 976848b8605Smrg size1 = hw_format_size[i]; 977848b8605Smrg size2 = hw_format_size[i+1]; 978848b8605Smrg 979848b8605Smrg if (velem[i].instance_divisor) { 980848b8605Smrg stride1 = 0; 981848b8605Smrg offset1 = vb1->buffer_offset + velem[i].src_offset + 982848b8605Smrg (instance_id / velem[i].instance_divisor) * vb1->stride; 983848b8605Smrg } else { 984848b8605Smrg stride1 = vb1->stride; 985848b8605Smrg offset1 = vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride; 986848b8605Smrg } 987848b8605Smrg if (velem[i+1].instance_divisor) { 988848b8605Smrg stride2 = 0; 989848b8605Smrg offset2 = vb2->buffer_offset + velem[i+1].src_offset + 990848b8605Smrg (instance_id / velem[i+1].instance_divisor) * vb2->stride; 991848b8605Smrg } else { 992848b8605Smrg stride2 = vb2->stride; 993848b8605Smrg offset2 = vb2->buffer_offset + velem[i+1].src_offset + offset * vb2->stride; 994848b8605Smrg } 995848b8605Smrg 996848b8605Smrg OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(stride1) | 997848b8605Smrg R300_VBPNTR_SIZE1(size2) | R300_VBPNTR_STRIDE1(stride2)); 998848b8605Smrg OUT_CS(offset1); 999848b8605Smrg OUT_CS(offset2); 1000848b8605Smrg } 1001848b8605Smrg 1002848b8605Smrg if (vertex_array_count & 1) { 1003848b8605Smrg vb1 = &vbuf[velem[i].vertex_buffer_index]; 1004848b8605Smrg size1 = hw_format_size[i]; 1005848b8605Smrg 1006848b8605Smrg if (velem[i].instance_divisor) { 1007848b8605Smrg stride1 = 0; 1008848b8605Smrg offset1 = vb1->buffer_offset + velem[i].src_offset + 1009848b8605Smrg (instance_id / velem[i].instance_divisor) * vb1->stride; 1010848b8605Smrg } else { 1011848b8605Smrg stride1 = vb1->stride; 1012848b8605Smrg offset1 = vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride; 1013848b8605Smrg } 1014848b8605Smrg 1015848b8605Smrg OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(stride1)); 1016848b8605Smrg OUT_CS(offset1); 1017848b8605Smrg } 1018848b8605Smrg 1019848b8605Smrg for (i = 0; i < vertex_array_count; i++) { 1020b8e80941Smrg buf = r300_resource(vbuf[velem[i].vertex_buffer_index].buffer.resource); 1021848b8605Smrg OUT_CS_RELOC(buf); 1022848b8605Smrg } 1023848b8605Smrg } 1024848b8605Smrg END_CS; 1025848b8605Smrg} 1026848b8605Smrg 1027848b8605Smrgvoid r300_emit_vertex_arrays_swtcl(struct r300_context *r300, boolean indexed) 1028848b8605Smrg{ 1029848b8605Smrg CS_LOCALS(r300); 1030848b8605Smrg 1031848b8605Smrg DBG(r300, DBG_SWTCL, "r300: Preparing vertex buffer %p for render, " 1032848b8605Smrg "vertex size %d\n", r300->vbo, 1033848b8605Smrg r300->vertex_info.size); 1034848b8605Smrg /* Set the pointer to our vertex buffer. The emitted values are this: 1035848b8605Smrg * PACKET3 [3D_LOAD_VBPNTR] 1036848b8605Smrg * COUNT [1] 1037848b8605Smrg * FORMAT [size | stride << 8] 1038848b8605Smrg * OFFSET [offset into BO] 1039848b8605Smrg * VBPNTR [relocated BO] 1040848b8605Smrg */ 1041848b8605Smrg BEGIN_CS(7); 1042848b8605Smrg OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, 3); 1043848b8605Smrg OUT_CS(1 | (!indexed ? R300_VC_FORCE_PREFETCH : 0)); 1044848b8605Smrg OUT_CS(r300->vertex_info.size | 1045848b8605Smrg (r300->vertex_info.size << 8)); 1046848b8605Smrg OUT_CS(r300->draw_vbo_offset); 1047848b8605Smrg OUT_CS(0); 1048848b8605Smrg 1049b8e80941Smrg assert(r300->vbo); 1050848b8605Smrg OUT_CS(0xc0001000); /* PKT3_NOP */ 1051b8e80941Smrg OUT_CS(r300->rws->cs_lookup_buffer(r300->cs, r300->vbo) * 4); 1052848b8605Smrg END_CS; 1053848b8605Smrg} 1054848b8605Smrg 1055848b8605Smrgvoid r300_emit_vertex_stream_state(struct r300_context* r300, 1056848b8605Smrg unsigned size, void* state) 1057848b8605Smrg{ 1058848b8605Smrg struct r300_vertex_stream_state *streams = 1059848b8605Smrg (struct r300_vertex_stream_state*)state; 1060848b8605Smrg unsigned i; 1061848b8605Smrg CS_LOCALS(r300); 1062848b8605Smrg 1063848b8605Smrg if (DBG_ON(r300, DBG_PSC)) { 1064848b8605Smrg fprintf(stderr, "r300: PSC emit:\n"); 1065848b8605Smrg 1066848b8605Smrg for (i = 0; i < streams->count; i++) { 1067848b8605Smrg fprintf(stderr, " : prog_stream_cntl%d: 0x%08x\n", i, 1068848b8605Smrg streams->vap_prog_stream_cntl[i]); 1069848b8605Smrg } 1070848b8605Smrg 1071848b8605Smrg for (i = 0; i < streams->count; i++) { 1072848b8605Smrg fprintf(stderr, " : prog_stream_cntl_ext%d: 0x%08x\n", i, 1073848b8605Smrg streams->vap_prog_stream_cntl_ext[i]); 1074848b8605Smrg } 1075848b8605Smrg } 1076848b8605Smrg 1077848b8605Smrg BEGIN_CS(size); 1078848b8605Smrg OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_0, streams->count); 1079848b8605Smrg OUT_CS_TABLE(streams->vap_prog_stream_cntl, streams->count); 1080848b8605Smrg OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_EXT_0, streams->count); 1081848b8605Smrg OUT_CS_TABLE(streams->vap_prog_stream_cntl_ext, streams->count); 1082848b8605Smrg END_CS; 1083848b8605Smrg} 1084848b8605Smrg 1085848b8605Smrgvoid r300_emit_pvs_flush(struct r300_context* r300, unsigned size, void* state) 1086848b8605Smrg{ 1087848b8605Smrg CS_LOCALS(r300); 1088848b8605Smrg 1089848b8605Smrg BEGIN_CS(size); 1090848b8605Smrg OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0); 1091848b8605Smrg END_CS; 1092848b8605Smrg} 1093848b8605Smrg 1094848b8605Smrgvoid r300_emit_vap_invariant_state(struct r300_context *r300, 1095848b8605Smrg unsigned size, void *state) 1096848b8605Smrg{ 1097848b8605Smrg CS_LOCALS(r300); 1098848b8605Smrg WRITE_CS_TABLE(state, size); 1099848b8605Smrg} 1100848b8605Smrg 1101848b8605Smrgvoid r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state) 1102848b8605Smrg{ 1103848b8605Smrg struct r300_vertex_shader* vs = (struct r300_vertex_shader*)state; 1104848b8605Smrg struct r300_vertex_program_code* code = &vs->code; 1105848b8605Smrg struct r300_screen* r300screen = r300->screen; 1106848b8605Smrg unsigned instruction_count = code->length / 4; 1107848b8605Smrg 1108848b8605Smrg unsigned vtx_mem_size = r300screen->caps.is_r500 ? 128 : 72; 1109848b8605Smrg unsigned input_count = MAX2(util_bitcount(code->InputsRead), 1); 1110848b8605Smrg unsigned output_count = MAX2(util_bitcount(code->OutputsWritten), 1); 1111848b8605Smrg unsigned temp_count = MAX2(code->num_temporaries, 1); 1112848b8605Smrg 1113848b8605Smrg unsigned pvs_num_slots = MIN3(vtx_mem_size / input_count, 1114848b8605Smrg vtx_mem_size / output_count, 10); 1115848b8605Smrg unsigned pvs_num_controllers = MIN2(vtx_mem_size / temp_count, 5); 1116848b8605Smrg 1117848b8605Smrg CS_LOCALS(r300); 1118848b8605Smrg 1119848b8605Smrg BEGIN_CS(size); 1120848b8605Smrg 1121848b8605Smrg /* R300_VAP_PVS_CODE_CNTL_0 1122848b8605Smrg * R300_VAP_PVS_CONST_CNTL 1123848b8605Smrg * R300_VAP_PVS_CODE_CNTL_1 1124848b8605Smrg * See the r5xx docs for instructions on how to use these. */ 1125848b8605Smrg OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_0, R300_PVS_FIRST_INST(0) | 1126848b8605Smrg R300_PVS_XYZW_VALID_INST(instruction_count - 1) | 1127848b8605Smrg R300_PVS_LAST_INST(instruction_count - 1)); 1128848b8605Smrg OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_1, instruction_count - 1); 1129848b8605Smrg 1130848b8605Smrg OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0); 1131848b8605Smrg OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, code->length); 1132848b8605Smrg OUT_CS_TABLE(code->body.d, code->length); 1133848b8605Smrg 1134848b8605Smrg OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(pvs_num_slots) | 1135848b8605Smrg R300_PVS_NUM_CNTLRS(pvs_num_controllers) | 1136848b8605Smrg R300_PVS_NUM_FPUS(r300screen->caps.num_vert_fpus) | 1137848b8605Smrg R300_PVS_VF_MAX_VTX_NUM(12) | 1138b8e80941Smrg (r300->clip_halfz ? R300_DX_CLIP_SPACE_DEF : 0) | 1139848b8605Smrg (r300screen->caps.is_r500 ? R500_TCL_STATE_OPTIMIZATION : 0)); 1140848b8605Smrg 1141848b8605Smrg /* Emit flow control instructions. Even if there are no fc instructions, 1142848b8605Smrg * we still need to write the registers to make sure they are cleared. */ 1143848b8605Smrg OUT_CS_REG(R300_VAP_PVS_FLOW_CNTL_OPC, code->fc_ops); 1144848b8605Smrg if (r300screen->caps.is_r500) { 1145848b8605Smrg OUT_CS_REG_SEQ(R500_VAP_PVS_FLOW_CNTL_ADDRS_LW_0, R300_VS_MAX_FC_OPS * 2); 1146848b8605Smrg OUT_CS_TABLE(code->fc_op_addrs.r500, R300_VS_MAX_FC_OPS * 2); 1147848b8605Smrg } else { 1148848b8605Smrg OUT_CS_REG_SEQ(R300_VAP_PVS_FLOW_CNTL_ADDRS_0, R300_VS_MAX_FC_OPS); 1149848b8605Smrg OUT_CS_TABLE(code->fc_op_addrs.r300, R300_VS_MAX_FC_OPS); 1150848b8605Smrg } 1151848b8605Smrg OUT_CS_REG_SEQ(R300_VAP_PVS_FLOW_CNTL_LOOP_INDEX_0, R300_VS_MAX_FC_OPS); 1152848b8605Smrg OUT_CS_TABLE(code->fc_loop_index, R300_VS_MAX_FC_OPS); 1153848b8605Smrg 1154848b8605Smrg END_CS; 1155848b8605Smrg} 1156848b8605Smrg 1157848b8605Smrgvoid r300_emit_vs_constants(struct r300_context* r300, 1158848b8605Smrg unsigned size, void *state) 1159848b8605Smrg{ 1160848b8605Smrg unsigned count = 1161848b8605Smrg ((struct r300_vertex_shader*)r300->vs_state.state)->externals_count; 1162848b8605Smrg struct r300_constant_buffer *buf = (struct r300_constant_buffer*)state; 1163848b8605Smrg struct r300_vertex_shader *vs = (struct r300_vertex_shader*)r300->vs_state.state; 1164848b8605Smrg unsigned i; 1165848b8605Smrg int imm_first = vs->externals_count; 1166848b8605Smrg int imm_end = vs->code.constants.Count; 1167848b8605Smrg int imm_count = vs->immediates_count; 1168848b8605Smrg CS_LOCALS(r300); 1169848b8605Smrg 1170848b8605Smrg BEGIN_CS(size); 1171848b8605Smrg OUT_CS_REG(R300_VAP_PVS_CONST_CNTL, 1172848b8605Smrg R300_PVS_CONST_BASE_OFFSET(buf->buffer_base) | 1173848b8605Smrg R300_PVS_MAX_CONST_ADDR(MAX2(imm_end - 1, 0))); 1174848b8605Smrg if (vs->externals_count) { 1175848b8605Smrg OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 1176848b8605Smrg (r300->screen->caps.is_r500 ? 1177848b8605Smrg R500_PVS_CONST_START : R300_PVS_CONST_START) + buf->buffer_base); 1178848b8605Smrg OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, count * 4); 1179848b8605Smrg if (buf->remap_table){ 1180848b8605Smrg for (i = 0; i < count; i++) { 1181848b8605Smrg uint32_t *data = &buf->ptr[buf->remap_table[i]*4]; 1182848b8605Smrg OUT_CS_TABLE(data, 4); 1183848b8605Smrg } 1184848b8605Smrg } else { 1185848b8605Smrg OUT_CS_TABLE(buf->ptr, count * 4); 1186848b8605Smrg } 1187848b8605Smrg } 1188848b8605Smrg 1189848b8605Smrg /* Emit immediates. */ 1190848b8605Smrg if (imm_count) { 1191848b8605Smrg OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 1192848b8605Smrg (r300->screen->caps.is_r500 ? 1193848b8605Smrg R500_PVS_CONST_START : R300_PVS_CONST_START) + 1194848b8605Smrg buf->buffer_base + imm_first); 1195848b8605Smrg OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, imm_count * 4); 1196848b8605Smrg for (i = imm_first; i < imm_end; i++) { 1197848b8605Smrg const float *data = vs->code.constants.Constants[i].u.Immediate; 1198848b8605Smrg OUT_CS_TABLE(data, 4); 1199848b8605Smrg } 1200848b8605Smrg } 1201848b8605Smrg END_CS; 1202848b8605Smrg} 1203848b8605Smrg 1204848b8605Smrgvoid r300_emit_viewport_state(struct r300_context* r300, 1205848b8605Smrg unsigned size, void* state) 1206848b8605Smrg{ 1207848b8605Smrg struct r300_viewport_state* viewport = (struct r300_viewport_state*)state; 1208848b8605Smrg CS_LOCALS(r300); 1209848b8605Smrg 1210848b8605Smrg BEGIN_CS(size); 1211848b8605Smrg OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6); 1212848b8605Smrg OUT_CS_TABLE(&viewport->xscale, 6); 1213848b8605Smrg OUT_CS_REG(R300_VAP_VTE_CNTL, viewport->vte_control); 1214848b8605Smrg END_CS; 1215848b8605Smrg} 1216848b8605Smrg 1217848b8605Smrgvoid r300_emit_hiz_clear(struct r300_context *r300, unsigned size, void *state) 1218848b8605Smrg{ 1219848b8605Smrg struct pipe_framebuffer_state *fb = 1220848b8605Smrg (struct pipe_framebuffer_state*)r300->fb_state.state; 1221848b8605Smrg struct r300_resource* tex; 1222848b8605Smrg CS_LOCALS(r300); 1223848b8605Smrg 1224848b8605Smrg tex = r300_resource(fb->zsbuf->texture); 1225848b8605Smrg 1226848b8605Smrg BEGIN_CS(size); 1227848b8605Smrg OUT_CS_PKT3(R300_PACKET3_3D_CLEAR_HIZ, 2); 1228848b8605Smrg OUT_CS(0); 1229848b8605Smrg OUT_CS(tex->tex.hiz_dwords[fb->zsbuf->u.tex.level]); 1230848b8605Smrg OUT_CS(r300->hiz_clear_value); 1231848b8605Smrg END_CS; 1232848b8605Smrg 1233848b8605Smrg /* Mark the current zbuffer's hiz ram as in use. */ 1234848b8605Smrg r300->hiz_in_use = TRUE; 1235848b8605Smrg r300->hiz_func = HIZ_FUNC_NONE; 1236848b8605Smrg r300_mark_atom_dirty(r300, &r300->hyperz_state); 1237848b8605Smrg} 1238848b8605Smrg 1239848b8605Smrgvoid r300_emit_zmask_clear(struct r300_context *r300, unsigned size, void *state) 1240848b8605Smrg{ 1241848b8605Smrg struct pipe_framebuffer_state *fb = 1242848b8605Smrg (struct pipe_framebuffer_state*)r300->fb_state.state; 1243848b8605Smrg struct r300_resource *tex; 1244848b8605Smrg CS_LOCALS(r300); 1245848b8605Smrg 1246848b8605Smrg tex = r300_resource(fb->zsbuf->texture); 1247848b8605Smrg 1248848b8605Smrg BEGIN_CS(size); 1249848b8605Smrg OUT_CS_PKT3(R300_PACKET3_3D_CLEAR_ZMASK, 2); 1250848b8605Smrg OUT_CS(0); 1251848b8605Smrg OUT_CS(tex->tex.zmask_dwords[fb->zsbuf->u.tex.level]); 1252848b8605Smrg OUT_CS(0); 1253848b8605Smrg END_CS; 1254848b8605Smrg 1255848b8605Smrg /* Mark the current zbuffer's zmask as in use. */ 1256848b8605Smrg r300->zmask_in_use = TRUE; 1257848b8605Smrg r300_mark_atom_dirty(r300, &r300->hyperz_state); 1258848b8605Smrg} 1259848b8605Smrg 1260848b8605Smrgvoid r300_emit_cmask_clear(struct r300_context *r300, unsigned size, void *state) 1261848b8605Smrg{ 1262848b8605Smrg struct pipe_framebuffer_state *fb = 1263848b8605Smrg (struct pipe_framebuffer_state*)r300->fb_state.state; 1264848b8605Smrg struct r300_resource *tex; 1265848b8605Smrg CS_LOCALS(r300); 1266848b8605Smrg 1267848b8605Smrg tex = r300_resource(fb->cbufs[0]->texture); 1268848b8605Smrg 1269848b8605Smrg BEGIN_CS(size); 1270848b8605Smrg OUT_CS_PKT3(R300_PACKET3_3D_CLEAR_CMASK, 2); 1271848b8605Smrg OUT_CS(0); 1272848b8605Smrg OUT_CS(tex->tex.cmask_dwords); 1273848b8605Smrg OUT_CS(0); 1274848b8605Smrg END_CS; 1275848b8605Smrg 1276848b8605Smrg /* Mark the current zbuffer's zmask as in use. */ 1277848b8605Smrg r300->cmask_in_use = TRUE; 1278848b8605Smrg r300_mark_fb_state_dirty(r300, R300_CHANGED_CMASK_ENABLE); 1279848b8605Smrg} 1280848b8605Smrg 1281848b8605Smrgvoid r300_emit_ztop_state(struct r300_context* r300, 1282848b8605Smrg unsigned size, void* state) 1283848b8605Smrg{ 1284848b8605Smrg struct r300_ztop_state* ztop = (struct r300_ztop_state*)state; 1285848b8605Smrg CS_LOCALS(r300); 1286848b8605Smrg 1287848b8605Smrg BEGIN_CS(size); 1288848b8605Smrg OUT_CS_REG(R300_ZB_ZTOP, ztop->z_buffer_top); 1289848b8605Smrg END_CS; 1290848b8605Smrg} 1291848b8605Smrg 1292848b8605Smrgvoid r300_emit_texture_cache_inval(struct r300_context* r300, unsigned size, void* state) 1293848b8605Smrg{ 1294848b8605Smrg CS_LOCALS(r300); 1295848b8605Smrg 1296848b8605Smrg BEGIN_CS(size); 1297848b8605Smrg OUT_CS_REG(R300_TX_INVALTAGS, 0); 1298848b8605Smrg END_CS; 1299848b8605Smrg} 1300848b8605Smrg 1301848b8605Smrgboolean r300_emit_buffer_validate(struct r300_context *r300, 1302848b8605Smrg boolean do_validate_vertex_buffers, 1303848b8605Smrg struct pipe_resource *index_buffer) 1304848b8605Smrg{ 1305848b8605Smrg struct pipe_framebuffer_state *fb = 1306848b8605Smrg (struct pipe_framebuffer_state*)r300->fb_state.state; 1307848b8605Smrg struct r300_aa_state *aa = (struct r300_aa_state*)r300->aa_state.state; 1308848b8605Smrg struct r300_textures_state *texstate = 1309848b8605Smrg (struct r300_textures_state*)r300->textures_state.state; 1310848b8605Smrg struct r300_resource *tex; 1311848b8605Smrg unsigned i; 1312848b8605Smrg boolean flushed = FALSE; 1313848b8605Smrg 1314848b8605Smrgvalidate: 1315848b8605Smrg if (r300->fb_state.dirty) { 1316848b8605Smrg /* Color buffers... */ 1317848b8605Smrg for (i = 0; i < fb->nr_cbufs; i++) { 1318848b8605Smrg if (!fb->cbufs[i]) 1319848b8605Smrg continue; 1320848b8605Smrg tex = r300_resource(fb->cbufs[i]->texture); 1321848b8605Smrg assert(tex && tex->buf && "cbuf is marked, but NULL!"); 1322b8e80941Smrg r300->rws->cs_add_buffer(r300->cs, tex->buf, 1323b8e80941Smrg RADEON_USAGE_READWRITE | RADEON_USAGE_SYNCHRONIZED, 1324848b8605Smrg r300_surface(fb->cbufs[i])->domain, 1325848b8605Smrg tex->b.b.nr_samples > 1 ? 1326848b8605Smrg RADEON_PRIO_COLOR_BUFFER_MSAA : 1327848b8605Smrg RADEON_PRIO_COLOR_BUFFER); 1328848b8605Smrg } 1329848b8605Smrg /* ...depth buffer... */ 1330848b8605Smrg if (fb->zsbuf) { 1331848b8605Smrg tex = r300_resource(fb->zsbuf->texture); 1332848b8605Smrg assert(tex && tex->buf && "zsbuf is marked, but NULL!"); 1333b8e80941Smrg r300->rws->cs_add_buffer(r300->cs, tex->buf, 1334b8e80941Smrg RADEON_USAGE_READWRITE | RADEON_USAGE_SYNCHRONIZED, 1335848b8605Smrg r300_surface(fb->zsbuf)->domain, 1336848b8605Smrg tex->b.b.nr_samples > 1 ? 1337848b8605Smrg RADEON_PRIO_DEPTH_BUFFER_MSAA : 1338848b8605Smrg RADEON_PRIO_DEPTH_BUFFER); 1339848b8605Smrg } 1340848b8605Smrg } 1341848b8605Smrg /* The AA resolve buffer. */ 1342848b8605Smrg if (r300->aa_state.dirty) { 1343848b8605Smrg if (aa->dest) { 1344b8e80941Smrg r300->rws->cs_add_buffer(r300->cs, aa->dest->buf, 1345b8e80941Smrg RADEON_USAGE_WRITE | RADEON_USAGE_SYNCHRONIZED, 1346848b8605Smrg aa->dest->domain, 1347848b8605Smrg RADEON_PRIO_COLOR_BUFFER); 1348848b8605Smrg } 1349848b8605Smrg } 1350848b8605Smrg if (r300->textures_state.dirty) { 1351848b8605Smrg /* ...textures... */ 1352848b8605Smrg for (i = 0; i < texstate->count; i++) { 1353848b8605Smrg if (!(texstate->tx_enable & (1 << i))) { 1354848b8605Smrg continue; 1355848b8605Smrg } 1356848b8605Smrg 1357848b8605Smrg tex = r300_resource(texstate->sampler_views[i]->base.texture); 1358b8e80941Smrg r300->rws->cs_add_buffer(r300->cs, tex->buf, 1359b8e80941Smrg RADEON_USAGE_READ | RADEON_USAGE_SYNCHRONIZED, 1360b8e80941Smrg tex->domain, RADEON_PRIO_SAMPLER_TEXTURE); 1361848b8605Smrg } 1362848b8605Smrg } 1363848b8605Smrg /* ...occlusion query buffer... */ 1364848b8605Smrg if (r300->query_current) 1365b8e80941Smrg r300->rws->cs_add_buffer(r300->cs, r300->query_current->buf, 1366b8e80941Smrg RADEON_USAGE_WRITE | RADEON_USAGE_SYNCHRONIZED, 1367b8e80941Smrg RADEON_DOMAIN_GTT, 1368b8e80941Smrg RADEON_PRIO_QUERY); 1369848b8605Smrg /* ...vertex buffer for SWTCL path... */ 1370b8e80941Smrg if (r300->vbo) 1371b8e80941Smrg r300->rws->cs_add_buffer(r300->cs, r300->vbo, 1372b8e80941Smrg RADEON_USAGE_READ | RADEON_USAGE_SYNCHRONIZED, 1373b8e80941Smrg RADEON_DOMAIN_GTT, 1374b8e80941Smrg RADEON_PRIO_VERTEX_BUFFER); 1375848b8605Smrg /* ...vertex buffers for HWTCL path... */ 1376848b8605Smrg if (do_validate_vertex_buffers && r300->vertex_arrays_dirty) { 1377848b8605Smrg struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; 1378848b8605Smrg struct pipe_vertex_buffer *last = r300->vertex_buffer + 1379848b8605Smrg r300->nr_vertex_buffers; 1380848b8605Smrg struct pipe_resource *buf; 1381848b8605Smrg 1382848b8605Smrg for (; vbuf != last; vbuf++) { 1383b8e80941Smrg buf = vbuf->buffer.resource; 1384848b8605Smrg if (!buf) 1385848b8605Smrg continue; 1386848b8605Smrg 1387b8e80941Smrg r300->rws->cs_add_buffer(r300->cs, r300_resource(buf)->buf, 1388b8e80941Smrg RADEON_USAGE_READ | RADEON_USAGE_SYNCHRONIZED, 1389848b8605Smrg r300_resource(buf)->domain, 1390b8e80941Smrg RADEON_PRIO_SAMPLER_BUFFER); 1391848b8605Smrg } 1392848b8605Smrg } 1393848b8605Smrg /* ...and index buffer for HWTCL path. */ 1394848b8605Smrg if (index_buffer) 1395b8e80941Smrg r300->rws->cs_add_buffer(r300->cs, r300_resource(index_buffer)->buf, 1396b8e80941Smrg RADEON_USAGE_READ | RADEON_USAGE_SYNCHRONIZED, 1397848b8605Smrg r300_resource(index_buffer)->domain, 1398b8e80941Smrg RADEON_PRIO_INDEX_BUFFER); 1399848b8605Smrg 1400848b8605Smrg /* Now do the validation (flush is called inside cs_validate on failure). */ 1401848b8605Smrg if (!r300->rws->cs_validate(r300->cs)) { 1402848b8605Smrg /* Ooops, an infinite loop, give up. */ 1403848b8605Smrg if (flushed) 1404848b8605Smrg return FALSE; 1405848b8605Smrg 1406848b8605Smrg flushed = TRUE; 1407848b8605Smrg goto validate; 1408848b8605Smrg } 1409848b8605Smrg 1410848b8605Smrg return TRUE; 1411848b8605Smrg} 1412848b8605Smrg 1413848b8605Smrgunsigned r300_get_num_dirty_dwords(struct r300_context *r300) 1414848b8605Smrg{ 1415848b8605Smrg struct r300_atom* atom; 1416848b8605Smrg unsigned dwords = 0; 1417848b8605Smrg 1418848b8605Smrg foreach_dirty_atom(r300, atom) { 1419848b8605Smrg if (atom->dirty) { 1420848b8605Smrg dwords += atom->size; 1421848b8605Smrg } 1422848b8605Smrg } 1423848b8605Smrg 1424848b8605Smrg /* let's reserve some more, just in case */ 1425848b8605Smrg dwords += 32; 1426848b8605Smrg 1427848b8605Smrg return dwords; 1428848b8605Smrg} 1429848b8605Smrg 1430848b8605Smrgunsigned r300_get_num_cs_end_dwords(struct r300_context *r300) 1431848b8605Smrg{ 1432848b8605Smrg unsigned dwords = 0; 1433848b8605Smrg 1434848b8605Smrg /* Emitted in flush. */ 1435848b8605Smrg dwords += 26; /* emit_query_end */ 1436848b8605Smrg dwords += r300->hyperz_state.size + 2; /* emit_hyperz_end + zcache flush */ 1437848b8605Smrg if (r300->screen->caps.is_r500) 1438848b8605Smrg dwords += 2; /* emit_index_bias */ 1439b8e80941Smrg dwords += 3; /* MSPOS */ 1440848b8605Smrg 1441848b8605Smrg return dwords; 1442848b8605Smrg} 1443848b8605Smrg 1444848b8605Smrg/* Emit all dirty state. */ 1445848b8605Smrgvoid r300_emit_dirty_state(struct r300_context* r300) 1446848b8605Smrg{ 1447848b8605Smrg struct r300_atom *atom; 1448848b8605Smrg 1449848b8605Smrg foreach_dirty_atom(r300, atom) { 1450848b8605Smrg if (atom->dirty) { 1451848b8605Smrg atom->emit(r300, atom->size, atom->state); 1452848b8605Smrg atom->dirty = FALSE; 1453848b8605Smrg } 1454848b8605Smrg } 1455848b8605Smrg 1456848b8605Smrg r300->first_dirty = NULL; 1457848b8605Smrg r300->last_dirty = NULL; 1458848b8605Smrg r300->dirty_hw++; 1459848b8605Smrg} 1460