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