r300: Add DSA state.
[platform/upstream/mesa.git] / src / gallium / drivers / r300 / r300_state.c
1 /*
2  * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * on the rights to use, copy, modify, merge, publish, distribute, sub
8  * license, and/or sell copies of the Software, and to permit persons to whom
9  * the Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21  * USE OR OTHER DEALINGS IN THE SOFTWARE. */
22
23 #include "r300_context.h"
24 #include "r300_state.h"
25
26 static uint32_t translate_blend_function(int blend_func) {
27     switch (blend_func) {
28         case PIPE_BLEND_ADD:
29             return R300_COMB_FCN_ADD_CLAMP;
30         case PIPE_BLEND_SUBTRACT:
31             return R300_COMB_FCN_SUB_CLAMP;
32         case PIPE_BLEND_REVERSE_SUBTRACT:
33             return R300_COMB_FCN_RSUB_CLAMP;
34         case PIPE_BLEND_MIN:
35             return R300_COMB_FCN_MIN;
36         case PIPE_BLEND_MAX:
37             return R300_COMB_FCN_MAX;
38         default:
39             /* XXX should be unreachable, handle this */
40             break;
41     }
42     return 0;
43 }
44
45 /* XXX we can also offer the D3D versions of some of these... */
46 static uint32_t translate_blend_factor(int blend_fact) {
47     switch (blend_fact) {
48         case PIPE_BLENDFACTOR_ONE:
49             return R300_BLEND_GL_ONE;
50         case PIPE_BLENDFACTOR_SRC_COLOR:
51             return R300_BLEND_GL_SRC_COLOR;
52         case PIPE_BLENDFACTOR_SRC_ALPHA:
53             return R300_BLEND_GL_SRC_ALPHA;
54         case PIPE_BLENDFACTOR_DST_ALPHA:
55             return R300_BLEND_GL_DST_ALPHA;
56         case PIPE_BLENDFACTOR_DST_COLOR:
57             return R300_BLEND_GL_DST_COLOR;
58         case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
59             return R300_BLEND_GL_SRC_ALPHA_SATURATE;
60         case PIPE_BLENDFACTOR_CONST_COLOR:
61             return R300_BLEND_GL_CONST_COLOR;
62         case PIPE_BLENDFACTOR_CONST_ALPHA:
63             return R300_BLEND_GL_CONST_ALPHA;
64         /* XXX WTF are these?
65         case PIPE_BLENDFACTOR_SRC1_COLOR:
66         case PIPE_BLENDFACTOR_SRC1_ALPHA: */
67         case PIPE_BLENDFACTOR_ZERO:
68             return R300_BLEND_GL_ZERO;
69         case PIPE_BLENDFACTOR_INV_SRC_COLOR:
70             return R300_BLEND_GL_ONE_MINUS_SRC_COLOR;
71         case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
72             return R300_BLEND_GL_ONE_MINUS_SRC_ALPHA;
73         case PIPE_BLENDFACTOR_INV_DST_ALPHA:
74             return R300_BLEND_GL_ONE_MINUS_DST_ALPHA;
75         case PIPE_BLENDFACTOR_INV_DST_COLOR:
76             return R300_BLEND_GL_ONE_MINUS_DST_COLOR;
77         case PIPE_BLENDFACTOR_INV_CONST_COLOR:
78             return R300_BLEND_GL_ONE_MINUS_CONST_COLOR;
79         case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
80             return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA;
81         /* XXX see above
82         case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
83         case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: */
84         default:
85             /* XXX the mythical 0x16 blend factor! */
86             break;
87     }
88     return 0;
89 }
90
91 /* Create a new blend state based on the CSO blend state.
92  *
93  * This encompasses alpha blending, logic/raster ops, and blend dithering. */
94 static void* r300_create_blend_state(struct pipe_context* pipe,
95                                      struct pipe_blend_state* state)
96 {
97     struct r300_blend_state* blend = CALLOC_STRUCT(r300_blend_state);
98
99     if (state->blend_enable) {
100         /* XXX for now, always do separate alpha...
101          * is it faster to do it with one reg? */
102         blend->blend_control = R300_ALPHA_BLEND_ENABLE |
103                 R300_SEPARATE_ALPHA_ENABLE |
104                 R300_READ_ENABLE |
105                 translate_blend_function(state->rgb_func) |
106                 (translate_blend_factor(state->rgb_src_factor) <<
107                     R300_SRC_BLEND_SHIFT) |
108                 (translate_blend_factor(state->rgb_dst_factor) <<
109                     R300_DST_BLEND_SHIFT);
110         blend->alpha_blend_control =
111                 translate_blend_function(state->alpha_func) |
112                 (translate_blend_factor(state->alpha_src_factor) <<
113                     R300_SRC_BLEND_SHIFT) |
114                 (translate_blend_factor(state->alpha_dst_factor) <<
115                     R300_DST_BLEND_SHIFT);
116     }
117
118     /* PIPE_LOGICOP_* don't need to be translated, fortunately. */
119     /* XXX are logicops still allowed if blending's disabled?
120      * Does Gallium take care of it for us? */
121     if (state->logicop_enable) {
122         blend->rop = R300_RB3D_ROPCNTL_ROP_ENABLE |
123                 (state->logicop_func) << R300_RB3D_ROPCNTL_ROP_SHIFT;
124     }
125
126     if (state->dither) {
127         blend->dither = R300_RB3D_DITHER_CTL_DITHER_MODE_LUT |
128                 R300_RB3D_DITHER_CTL_ALPHA_DITHER_MODE_LUT;
129     }
130
131     return (void*)blend;
132 }
133
134 /* Bind blend state. */
135 static void r300_bind_blend_state(struct pipe_context* pipe,
136                                   void* state)
137 {
138     struct r300_context* r300 = r300_context(pipe);
139
140     r300->blend_state = (struct r300_blend_state*)state;
141     r300->dirty_state |= R300_NEW_BLEND;
142 }
143
144 /* Free blend state. */
145 static void r300_delete_blend_state(struct pipe_context* pipe,
146                                     void* state)
147 {
148     FREE(state);
149 }
150
151 static uint32_t translate_depth_stencil_function(int zs_func) {
152     switch (zs_func) {
153         case PIPE_FUNC_NEVER:
154             return R300_ZS_NEVER;
155         case PIPE_FUNC_LESS:
156             return R300_ZS_LESS;
157         case PIPE_FUNC_EQUAL:
158             return R300_ZS_EQUAL;
159         case PIPE_FUNC_LEQUAL:
160             return R300_ZS_LEQUAL;
161         case PIPE_FUNC_GREATER:
162             return R300_ZS_GREATER;
163         case PIPE_FUNC_NOTEQUAL:
164             return R300_ZS_NOTEQUAL;
165         case PIPE_FUNC_GEQUAL:
166             return R300_ZS_GEQUAL;
167         case PIPE_FUNC_ALWAYS:
168             return R300_ZS_ALWAYS;
169         default:
170             /* XXX shouldn't be reachable */
171             break;
172     }
173     return 0;
174 }
175
176 static uint32_t translate_stencil_op(int s_op) {
177     switch (s_op) {
178         case PIPE_STENCIL_OP_KEEP:
179             return R300_ZS_KEEP;
180         case PIPE_STENCIL_OP_ZERO:
181             return R300_ZS_ZERO;
182         case PIPE_STENCIL_OP_REPLACE:
183             return R300_ZS_REPLACE;
184         case PIPE_STENCIL_OP_INCR:
185             return R300_ZS_INCR;
186         case PIPE_STENCIL_OP_DECR:
187             return R300_ZS_DECR;
188         case PIPE_STENCIL_OP_INCR_WRAP:
189             return R300_ZS_INCR_WRAP;
190         case PIPE_STENCIL_OP_DECR_WRAP:
191             return R300_ZS_DECR_WRAP;
192         case PIPE_STENCIL_OP_INVERT:
193             return R300_ZS_INVERT;
194         default:
195             /* XXX shouldn't be reachable */
196             break;
197     }
198     return 0;
199 }
200
201 static uint32_t translate_alpha_function(int alpha_func) {
202     switch (alpha_func) {
203         case PIPE_FUNC_NEVER:
204             return R300_FG_ALPHA_FUNC_NEVER;
205         case PIPE_FUNC_LESS:
206             return R300_FG_ALPHA_FUNC_LESS;
207         case PIPE_FUNC_EQUAL:
208             return R300_FG_ALPHA_FUNC_EQUAL;
209         case PIPE_FUNC_LEQUAL:
210             return R300_FG_ALPHA_FUNC_LE;
211         case PIPE_FUNC_GREATER:
212             return R300_FG_ALPHA_FUNC_GREATER;
213         case PIPE_FUNC_NOTEQUAL:
214             return R300_FG_ALPHA_FUNC_NOTEQUAL;
215         case PIPE_FUNC_GEQUAL:
216             return R300_FG_ALPHA_FUNC_GE;
217         case PIPE_FUNC_ALWAYS:
218             return R300_FG_ALPHA_FUNC_ALWAYS;
219         default:
220             /* XXX shouldn't be reachable */
221             break;
222     }
223     return 0;
224 }
225
226 /* Create a new depth, stencil, and alpha state based on the CSO dsa state.
227  *
228  * This contains the depth buffer, stencil buffer, alpha test, and such.
229  * On the Radeon, depth and stencil buffer setup are intertwined, which is
230  * the reason for some of the strange-looking assignments across registers. */
231 static void* r300_create_dsa_state(struct pipe_context* pipe,
232                                      struct pipe_depth_stencil_alpha_state* state)
233 {
234     struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state);
235
236     /* Depth test setup. */
237     if (state->depth.enabled) {
238         dsa->z_buffer_control |= R300_Z_ENABLE;
239
240         if (state->depth.writemask) {
241             dsa->z_buffer_control |= R300_Z_WRITE_ENABLE;
242         }
243
244         dsa->z_stencil_control |=
245                 (translate_depth_stencil_function(state->depth.func) <<
246                     R300_Z_FUNC_SHIFT);
247     }
248
249     /* Stencil buffer setup. */
250     if (state->stencil[0].enabled) {
251         dsa->z_buffer_control |= R300_STENCIL_ENABLE;
252         dsa->z_stencil_control |=
253                 (translate_depth_stencil_function(state->stencil[0].func) <<
254                     R300_S_FRONT_FUNC_SHIFT) |
255                 (translate_stencil_op(state->stencil[0].fail_op) <<
256                     R300_S_FRONT_SFAIL_OP_SHIFT) |
257                 (translate_stencil_op(state->stencil[0].zpass_op) <<
258                     R300_S_FRONT_ZPASS_OP_SHIFT) |
259                 (translate_stencil_op(state->stencil[0].zfail_op) <<
260                     R300_S_FRONT_ZFAIL_OP_SHIFT);
261
262         dsa->stencil_ref_mask = (state->stencil[0].ref_value) |
263                 (state->stencil[0].value_mask << R300_STENCILMASK_SHIFT) |
264                 (state->stencil[0].write_mask << R300_STENCILWRITEMASK_SHIFT);
265
266         if (state->stencil[1].enabled) {
267             dsa->z_buffer_control |= R300_STENCIL_FRONT_BACK;
268             dsa->z_stencil_control |=
269                     (translate_depth_stencil_function(state->stencil[1].func) <<
270                         R300_S_BACK_FUNC_SHIFT) |
271                     (translate_stencil_op(state->stencil[1].fail_op) <<
272                         R300_S_BACK_SFAIL_OP_SHIFT) |
273                     (translate_stencil_op(state->stencil[1].zpass_op) <<
274                         R300_S_BACK_ZPASS_OP_SHIFT) |
275                     (translate_stencil_op(state->stencil[1].zfail_op) <<
276                         R300_S_BACK_ZFAIL_OP_SHIFT);
277
278             dsa->stencil_ref_bf = (state->stencil[1].ref_value) |
279                     (state->stencil[1].value_mask << R300_STENCILMASK_SHIFT) |
280                     (state->stencil[1].write_mask << R300_STENCILWRITEMASK_SHIFT);
281         }
282     }
283
284     /* Alpha test setup. */
285     if (state->alpha.enabled) {
286         dsa->alpha_function = translate_alpha_function(state->alpha.func) |
287                 R300_FG_ALPHA_FUNC_ENABLE;
288         dsa->alpha_reference = CLAMP(state->alpha.ref * 1023.0f, 0, 1023);
289     } else {
290         dsa->z_buffer_top = R300_ZTOP_ENABLE;
291     }
292
293     return (void*)dsa;
294 }
295
296 /* Bind DSA state. */
297 static void r300_bind_dsa_state(struct pipe_context* pipe,
298                                   void* state)
299 {
300     struct r300_context* r300 = r300_context(pipe);
301
302     r300->dsa_state = (struct r300_dsa_state*)state;
303     r300->dirty_state |= R300_NEW_DSA;
304 }
305
306 /* Free DSA state. */
307 static void r300_delete_dsa_state(struct pipe_context* pipe,
308                                     void* state)
309 {
310     FREE(state);
311 }
312
313 /* Create a new scissor state based on the CSO scissor state.
314  *
315  * This is only for the fragment scissors. */
316 static void* r300_create_scissor_state(struct pipe_context* pipe,
317                                     struct pipe_scissor_state* state)
318 {
319     uint32_t left, top, right, bottom;
320     struct r300_scissor_state* scissor = CALLOC_STRUCT(r300_scissor_state);
321
322     /* So, a bit of info. The scissors are offset by R300_SCISSORS_OFFSET in
323      * both directions for all values, and can only be 13 bits wide. Why?
324      * We may never know. */
325     left = (state->minx + R300_SCISSORS_OFFSET) & 0x1fff;
326     top = (state->miny + R300_SCISSORS_OFFSET) & 0x1fff;
327     right = (state->maxx + R300_SCISSORS_OFFSET) & 0x1fff;
328     bottom = (state->maxy + R300_SCISSORS_OFFSET) & 0x1fff;
329
330     scissor->scissor_top_left = (left << R300_SCISSORS_X_SHIFT) |
331             (top << R300_SCISSORS_Y_SHIFT);
332     scissor->scissor_bottom_right = (right << R300_SCISSORS_X_SHIFT) |
333             (bottom << R300_SCISSORS_Y_SHIFT);
334
335     return (void*)scissor;
336 }
337
338 /* Bind scissor state.*/
339 static void r300_bind_scissor_state(struct pipe_context* pipe,
340                                  void* state)
341 {
342     struct r300_context* r300 = r300_context(pipe);
343
344     r300->scissor_state = (struct r300_scissor_state*)state;
345     r300->dirty_state |= R300_NEW_SCISSOR;
346 }
347
348 /* Delete scissor state. */
349 static void r300_delete_scissor_state(struct pipe_context* pipe,
350                                    void* state)
351 {
352     FREE(state);
353 }
354
355 static void* r300_create_vs_state(struct pipe_context* pipe,
356                                   struct pipe_shader_state* state)
357 {
358     struct r300_context* context = r300_context(pipe);
359     /* XXX handing this off to Draw for now */
360     return draw_create_vertex_shader(context->draw, state);
361 }
362
363 static void r300_bind_vs_state(struct pipe_context* pipe, void* state) {
364     struct r300_context* context = r300_context(pipe);
365     /* XXX handing this off to Draw for now */
366     draw_bind_vertex_shader(context->draw, (struct draw_vertex_shader*)state);
367 }
368
369 static void r300_delete_vs_state(struct pipe_context* pipe, void* state)
370 {
371     struct r300_context* context = r300_context(pipe);
372     /* XXX handing this off to Draw for now */
373     draw_delete_vertex_shader(context->draw, (struct draw_vertex_shader*)state);
374 }