r600g: fix up segfault with variation between views and count.
[mesa.git] / src / gallium / drivers / r600 / r600_state.c
1 /*
2 * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
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 * Authors:
24 * Jerome Glisse
25 */
26 #include <stdio.h>
27 #include <util/u_inlines.h>
28 #include <util/u_format.h>
29 #include <util/u_memory.h>
30 #include "r600_screen.h"
31 #include "r600_texture.h"
32 #include "r600_context.h"
33 #include "r600d.h"
34
35
36 static void r600_delete_state(struct pipe_context *ctx, void *state)
37 {
38 struct radeon_state *rstate = state;
39
40 radeon_state_decref(rstate);
41 }
42
43 static void *r600_create_blend_state(struct pipe_context *ctx,
44 const struct pipe_blend_state *state)
45 {
46 struct r600_screen *rscreen = r600_screen(ctx->screen);
47 struct radeon_state *rstate;
48
49 rstate = radeon_state(rscreen->rw, R600_BLEND_TYPE, R600_BLEND);
50 if (rstate == NULL)
51 return NULL;
52 rstate->states[R600_BLEND__CB_BLEND_RED] = 0x00000000;
53 rstate->states[R600_BLEND__CB_BLEND_GREEN] = 0x00000000;
54 rstate->states[R600_BLEND__CB_BLEND_BLUE] = 0x00000000;
55 rstate->states[R600_BLEND__CB_BLEND_ALPHA] = 0x00000000;
56 rstate->states[R600_BLEND__CB_BLEND0_CONTROL] = 0x00010001;
57 rstate->states[R600_BLEND__CB_BLEND1_CONTROL] = 0x00000000;
58 rstate->states[R600_BLEND__CB_BLEND2_CONTROL] = 0x00000000;
59 rstate->states[R600_BLEND__CB_BLEND3_CONTROL] = 0x00000000;
60 rstate->states[R600_BLEND__CB_BLEND4_CONTROL] = 0x00000000;
61 rstate->states[R600_BLEND__CB_BLEND5_CONTROL] = 0x00000000;
62 rstate->states[R600_BLEND__CB_BLEND6_CONTROL] = 0x00000000;
63 rstate->states[R600_BLEND__CB_BLEND7_CONTROL] = 0x00000000;
64 rstate->states[R600_BLEND__CB_BLEND_CONTROL] = 0x00000000;
65 if (radeon_state_pm4(rstate)) {
66 radeon_state_decref(rstate);
67 return NULL;
68 }
69 return rstate;
70 }
71
72 static void r600_bind_blend_state(struct pipe_context *ctx, void *state)
73 {
74 struct r600_context *rctx = r600_context(ctx);
75 radeon_draw_set(rctx->draw, state);
76 }
77
78 static void r600_set_blend_color(struct pipe_context *ctx,
79 const struct pipe_blend_color *color)
80 {
81 }
82
83 static void r600_set_clip_state(struct pipe_context *ctx,
84 const struct pipe_clip_state *state)
85 {
86 }
87
88 static void r600_set_framebuffer_state(struct pipe_context *ctx,
89 const struct pipe_framebuffer_state *state)
90 {
91 struct r600_screen *rscreen = r600_screen(ctx->screen);
92 struct r600_context *rctx = r600_context(ctx);
93 struct r600_texture *rtex;
94 struct r600_buffer *rbuffer;
95 struct radeon_state *rstate;
96 unsigned level = state->cbufs[0]->level;
97 unsigned pitch, slice;
98
99 rstate = radeon_state(rscreen->rw, R600_CB0_TYPE, R600_CB0);
100 if (rstate == NULL)
101 return;
102 rtex = (struct r600_texture*)state->cbufs[0]->texture;
103 rbuffer = (struct r600_buffer*)rtex->buffer;
104 rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
105 rstate->bo[1] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
106 rstate->bo[2] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
107 rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
108 rstate->placement[2] = RADEON_GEM_DOMAIN_GTT;
109 rstate->placement[4] = RADEON_GEM_DOMAIN_GTT;
110 rstate->nbo = 3;
111 pitch = rtex->pitch[level] / 8 - 1;
112 slice = rtex->pitch[level] * state->cbufs[0]->height / 64 - 1;
113 rstate->states[R600_CB0__CB_COLOR0_BASE] = 0x00000000;
114 rstate->states[R600_CB0__CB_COLOR0_INFO] = 0x08110068;
115 rstate->states[R600_CB0__CB_COLOR0_SIZE] = S_028060_PITCH_TILE_MAX(pitch) |
116 S_028060_SLICE_TILE_MAX(slice);
117 rstate->states[R600_CB0__CB_COLOR0_VIEW] = 0x00000000;
118 rstate->states[R600_CB0__CB_COLOR0_FRAG] = 0x00000000;
119 rstate->states[R600_CB0__CB_COLOR0_TILE] = 0x00000000;
120 rstate->states[R600_CB0__CB_COLOR0_MASK] = 0x00000000;
121 if (radeon_state_pm4(rstate)) {
122 radeon_state_decref(rstate);
123 return;
124 }
125 radeon_draw_set_new(rctx->draw, rstate);
126 rctx->db = radeon_state_decref(rctx->db);
127 if(state->zsbuf) {
128 rtex = (struct r600_texture*)state->zsbuf->texture;
129 rbuffer = (struct r600_buffer*)rtex->buffer;
130 rctx->db = radeon_state(rscreen->rw, R600_DB_TYPE, R600_DB);
131 if(rctx->db == NULL)
132 return;
133 rctx->db->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
134 rctx->db->nbo = 1;
135 rctx->db->placement[0] = RADEON_GEM_DOMAIN_VRAM;
136 level = state->zsbuf->level;
137 pitch = rtex->pitch[level] / 8 - 1;
138 slice = rtex->pitch[level] * state->zsbuf->height / 64 - 1;
139
140 rctx->db->states[R600_DB__DB_DEPTH_BASE] = 0x00000000;
141 rctx->db->states[R600_DB__DB_DEPTH_INFO] = 0x00010006;
142 rctx->db->states[R600_DB__DB_DEPTH_VIEW] = 0x00000000;
143 rctx->db->states[R600_DB__DB_PREFETCH_LIMIT] = (state->zsbuf->height / 8) -1;
144 rctx->db->states[R600_DB__DB_DEPTH_SIZE] = S_028000_PITCH_TILE_MAX(pitch) |
145 S_028000_SLICE_TILE_MAX(slice);
146 } else
147 rctx->db = NULL;
148 rctx->fb_state = *state;
149 }
150
151 static void *r600_create_fs_state(struct pipe_context *ctx,
152 const struct pipe_shader_state *shader)
153 {
154 return r600_pipe_shader_create(ctx, shader->tokens);
155 }
156
157 static void r600_bind_fs_state(struct pipe_context *ctx, void *state)
158 {
159 struct r600_context *rctx = r600_context(ctx);
160
161 rctx->ps_shader = state;
162 }
163
164 static void *r600_create_vs_state(struct pipe_context *ctx,
165 const struct pipe_shader_state *shader)
166 {
167 return r600_pipe_shader_create(ctx, shader->tokens);
168 }
169
170 static void r600_bind_vs_state(struct pipe_context *ctx, void *state)
171 {
172 struct r600_context *rctx = r600_context(ctx);
173
174 rctx->vs_shader = state;
175 }
176
177 static void r600_set_polygon_stipple(struct pipe_context *ctx,
178 const struct pipe_poly_stipple *state)
179 {
180 }
181
182 static void *r600_create_rs_state(struct pipe_context *ctx,
183 const struct pipe_rasterizer_state *state)
184 {
185 struct r600_screen *rscreen = r600_screen(ctx->screen);
186 struct r600_context *rctx = r600_context(ctx);
187 struct radeon_state *rstate;
188
189 rctx->flat_shade = state->flatshade;
190 rctx->flat_shade = 0;
191 R600_ERR("flat shade with texture broke tex coord interp\n");
192 rstate = radeon_state(rscreen->rw, R600_RASTERIZER_TYPE, R600_RASTERIZER);
193 if (rstate == NULL)
194 return NULL;
195 rstate->states[R600_RASTERIZER__SPI_INTERP_CONTROL_0] = 0x00000001;
196 rstate->states[R600_RASTERIZER__PA_CL_CLIP_CNTL] = 0x00000000;
197 rstate->states[R600_RASTERIZER__PA_SU_SC_MODE_CNTL] = 0x00080000;
198 rstate->states[R600_RASTERIZER__PA_CL_VS_OUT_CNTL] = 0x00000000;
199 rstate->states[R600_RASTERIZER__PA_CL_NANINF_CNTL] = 0x00000000;
200 rstate->states[R600_RASTERIZER__PA_SU_POINT_SIZE] = 0x00080008;
201 rstate->states[R600_RASTERIZER__PA_SU_POINT_MINMAX] = 0x00000000;
202 rstate->states[R600_RASTERIZER__PA_SU_LINE_CNTL] = 0x00000008;
203 rstate->states[R600_RASTERIZER__PA_SC_LINE_STIPPLE] = 0x00000005;
204 rstate->states[R600_RASTERIZER__PA_SC_MPASS_PS_CNTL] = 0x00000000;
205 rstate->states[R600_RASTERIZER__PA_SC_LINE_CNTL] = 0x00000400;
206 rstate->states[R600_RASTERIZER__PA_CL_GB_VERT_CLIP_ADJ] = 0x3F800000;
207 rstate->states[R600_RASTERIZER__PA_CL_GB_VERT_DISC_ADJ] = 0x3F800000;
208 rstate->states[R600_RASTERIZER__PA_CL_GB_HORZ_CLIP_ADJ] = 0x3F800000;
209 rstate->states[R600_RASTERIZER__PA_CL_GB_HORZ_DISC_ADJ] = 0x3F800000;
210 rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_DB_FMT_CNTL] = 0x00000000;
211 rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_CLAMP] = 0x00000000;
212 rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_FRONT_SCALE] = 0x00000000;
213 rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_FRONT_OFFSET] = 0x00000000;
214 rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_BACK_SCALE] = 0x00000000;
215 rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_BACK_OFFSET] = 0x00000000;
216 if (radeon_state_pm4(rstate)) {
217 radeon_state_decref(rstate);
218 return NULL;
219 }
220 return rstate;
221 }
222
223 static void r600_bind_rs_state(struct pipe_context *ctx, void *state)
224 {
225 struct r600_context *rctx = r600_context(ctx);
226 radeon_draw_set(rctx->draw, state);
227 }
228
229 static inline unsigned r600_tex_wrap(unsigned wrap)
230 {
231 switch (wrap) {
232 default:
233 case PIPE_TEX_WRAP_REPEAT:
234 return V_03C000_SQ_TEX_WRAP;
235 case PIPE_TEX_WRAP_CLAMP:
236 return V_03C000_SQ_TEX_CLAMP_LAST_TEXEL;
237 case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
238 return V_03C000_SQ_TEX_CLAMP_HALF_BORDER;
239 case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
240 return V_03C000_SQ_TEX_CLAMP_BORDER;
241 case PIPE_TEX_WRAP_MIRROR_REPEAT:
242 return V_03C000_SQ_TEX_MIRROR;
243 case PIPE_TEX_WRAP_MIRROR_CLAMP:
244 return V_03C000_SQ_TEX_MIRROR_ONCE_LAST_TEXEL;
245 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
246 return V_03C000_SQ_TEX_MIRROR_ONCE_HALF_BORDER;
247 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
248 return V_03C000_SQ_TEX_MIRROR_ONCE_BORDER;
249 }
250 }
251
252 static inline unsigned r600_tex_filter(unsigned filter)
253 {
254 switch (filter) {
255 default:
256 case PIPE_TEX_FILTER_NEAREST:
257 return V_03C000_SQ_TEX_XY_FILTER_POINT;
258 case PIPE_TEX_FILTER_LINEAR:
259 return V_03C000_SQ_TEX_XY_FILTER_BILINEAR;
260 }
261 }
262
263 static inline unsigned r600_tex_mipfilter(unsigned filter)
264 {
265 switch (filter) {
266 case PIPE_TEX_MIPFILTER_NEAREST:
267 return V_03C000_SQ_TEX_Z_FILTER_POINT;
268 case PIPE_TEX_MIPFILTER_LINEAR:
269 return V_03C000_SQ_TEX_Z_FILTER_LINEAR;
270 default:
271 case PIPE_TEX_MIPFILTER_NONE:
272 return V_03C000_SQ_TEX_Z_FILTER_NONE;
273 }
274 }
275
276 static inline unsigned r600_tex_compare(unsigned compare)
277 {
278 switch (compare) {
279 default:
280 case PIPE_FUNC_NEVER:
281 return V_03C000_SQ_TEX_DEPTH_COMPARE_NEVER;
282 case PIPE_FUNC_LESS:
283 return V_03C000_SQ_TEX_DEPTH_COMPARE_LESS;
284 case PIPE_FUNC_EQUAL:
285 return V_03C000_SQ_TEX_DEPTH_COMPARE_EQUAL;
286 case PIPE_FUNC_LEQUAL:
287 return V_03C000_SQ_TEX_DEPTH_COMPARE_LESSEQUAL;
288 case PIPE_FUNC_GREATER:
289 return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATER;
290 case PIPE_FUNC_NOTEQUAL:
291 return V_03C000_SQ_TEX_DEPTH_COMPARE_NOTEQUAL;
292 case PIPE_FUNC_GEQUAL:
293 return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATEREQUAL;
294 case PIPE_FUNC_ALWAYS:
295 return V_03C000_SQ_TEX_DEPTH_COMPARE_ALWAYS;
296 }
297 }
298
299 static void *r600_create_sampler_state(struct pipe_context *ctx,
300 const struct pipe_sampler_state *state)
301 {
302 struct r600_screen *rscreen = r600_screen(ctx->screen);
303 struct radeon_state *rstate;
304
305 rstate = radeon_state(rscreen->rw, R600_PS_SAMPLER_TYPE, R600_PS_SAMPLER);
306 if (rstate == NULL)
307 return NULL;
308 rstate->states[R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD0_0] =
309 S_03C000_CLAMP_X(r600_tex_wrap(state->wrap_s)) |
310 S_03C000_CLAMP_Y(r600_tex_wrap(state->wrap_t)) |
311 S_03C000_CLAMP_Z(r600_tex_wrap(state->wrap_r)) |
312 S_03C000_XY_MAG_FILTER(r600_tex_filter(state->mag_img_filter)) |
313 S_03C000_XY_MIN_FILTER(r600_tex_filter(state->min_img_filter)) |
314 S_03C000_MIP_FILTER(r600_tex_mipfilter(state->min_mip_filter)) |
315 S_03C000_DEPTH_COMPARE_FUNCTION(r600_tex_compare(state->compare_func));
316 /* FIXME LOD it depends on texture base level ... */
317 rstate->states[R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD1_0] =
318 S_03C004_MIN_LOD(0) |
319 S_03C004_MAX_LOD(0) |
320 S_03C004_LOD_BIAS(0);
321 rstate->states[R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD2_0] = S_03C008_TYPE(1);
322 if (radeon_state_pm4(rstate)) {
323 radeon_state_decref(rstate);
324 return NULL;
325 }
326 return rstate;
327 }
328
329 static void r600_bind_sampler_states(struct pipe_context *ctx,
330 unsigned count, void **states)
331 {
332 struct r600_context *rctx = r600_context(ctx);
333 unsigned i;
334
335 /* FIXME split VS/PS/GS sampler */
336 for (i = 0; i < count; i++) {
337 rctx->ps_sampler[i] = radeon_state_decref(rctx->ps_sampler[i]);
338 }
339 rctx->nps_sampler = count;
340 for (i = 0; i < count; i++) {
341 rctx->ps_sampler[i] = radeon_state_incref(states[i]);
342 rctx->ps_sampler[i]->id = R600_PS_SAMPLER + i;
343 }
344 }
345
346 static inline unsigned r600_tex_swizzle(unsigned swizzle)
347 {
348 switch (swizzle) {
349 case PIPE_SWIZZLE_RED:
350 return V_038010_SQ_SEL_X;
351 case PIPE_SWIZZLE_GREEN:
352 return V_038010_SQ_SEL_Y;
353 case PIPE_SWIZZLE_BLUE:
354 return V_038010_SQ_SEL_Z;
355 case PIPE_SWIZZLE_ALPHA:
356 return V_038010_SQ_SEL_W;
357 case PIPE_SWIZZLE_ZERO:
358 return V_038010_SQ_SEL_0;
359 default:
360 case PIPE_SWIZZLE_ONE:
361 return V_038010_SQ_SEL_1;
362 }
363 }
364
365 static inline unsigned r600_format_type(unsigned format_type)
366 {
367 switch (format_type) {
368 default:
369 case UTIL_FORMAT_TYPE_UNSIGNED:
370 return V_038010_SQ_FORMAT_COMP_UNSIGNED;
371 case UTIL_FORMAT_TYPE_SIGNED:
372 return V_038010_SQ_FORMAT_COMP_SIGNED;
373 case UTIL_FORMAT_TYPE_FIXED:
374 return V_038010_SQ_FORMAT_COMP_UNSIGNED_BIASED;
375 }
376 }
377
378 static inline unsigned r600_tex_dim(unsigned dim)
379 {
380 switch (dim) {
381 default:
382 case PIPE_TEXTURE_1D:
383 return V_038000_SQ_TEX_DIM_1D;
384 case PIPE_TEXTURE_2D:
385 return V_038000_SQ_TEX_DIM_2D;
386 case PIPE_TEXTURE_3D:
387 return V_038000_SQ_TEX_DIM_3D;
388 case PIPE_TEXTURE_CUBE:
389 return V_038000_SQ_TEX_DIM_CUBEMAP;
390 }
391 }
392
393 static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *ctx,
394 struct pipe_resource *texture,
395 const struct pipe_sampler_view *view)
396 {
397 struct r600_screen *rscreen = r600_screen(ctx->screen);
398 struct r600_texture_resource *rtexture;
399 const struct util_format_description *desc;
400 struct r600_texture *tmp;
401 struct r600_buffer *rbuffer;
402 unsigned format;
403
404 if (r600_conv_pipe_format(texture->format, &format))
405 return NULL;
406 rtexture = CALLOC_STRUCT(r600_texture_resource);
407 if (rtexture == NULL)
408 return NULL;
409 desc = util_format_description(texture->format);
410 assert(desc == NULL);
411 rtexture->state = radeon_state(rscreen->rw, R600_PS_RESOURCE_TYPE, R600_PS_RESOURCE);
412 if (rtexture->state == NULL) {
413 FREE(rtexture);
414 return NULL;
415 }
416 rtexture->view = *view;
417 rtexture->view.reference.count = 1;
418 rtexture->view.texture = NULL;
419 pipe_resource_reference(&rtexture->view.texture, texture);
420 rtexture->view.context = ctx;
421
422 tmp = (struct r600_texture*)texture;
423 rbuffer = (struct r600_buffer*)tmp->buffer;
424 rtexture->state->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
425 rtexture->state->bo[1] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
426 rtexture->state->nbo = 2;
427 rtexture->state->placement[0] = RADEON_GEM_DOMAIN_GTT;
428 rtexture->state->placement[1] = RADEON_GEM_DOMAIN_GTT;
429 rtexture->state->placement[2] = RADEON_GEM_DOMAIN_GTT;
430 rtexture->state->placement[3] = RADEON_GEM_DOMAIN_GTT;
431
432 /* FIXME properly handle first level != 0 */
433 rtexture->state->states[R600_PS_RESOURCE__RESOURCE0_WORD0] =
434 S_038000_DIM(r600_tex_dim(texture->target)) |
435 S_038000_PITCH((tmp->pitch[0] / 8) - 1) |
436 S_038000_TEX_WIDTH(texture->width0 - 1);
437 rtexture->state->states[R600_PS_RESOURCE__RESOURCE0_WORD1] =
438 S_038004_TEX_HEIGHT(texture->height0 - 1) |
439 S_038004_TEX_DEPTH(texture->depth0 - 1) |
440 S_038004_DATA_FORMAT(format);
441 rtexture->state->states[R600_PS_RESOURCE__RESOURCE0_WORD2] = 0;
442 rtexture->state->states[R600_PS_RESOURCE__RESOURCE0_WORD3] = tmp->offset[1] >> 8;
443 rtexture->state->states[R600_PS_RESOURCE__RESOURCE0_WORD4] =
444 S_038010_FORMAT_COMP_X(r600_format_type(UTIL_FORMAT_TYPE_UNSIGNED)) |
445 S_038010_FORMAT_COMP_Y(r600_format_type(UTIL_FORMAT_TYPE_UNSIGNED)) |
446 S_038010_FORMAT_COMP_Z(r600_format_type(UTIL_FORMAT_TYPE_UNSIGNED)) |
447 S_038010_FORMAT_COMP_W(r600_format_type(UTIL_FORMAT_TYPE_UNSIGNED)) |
448 S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_NORM) |
449 S_038010_SRF_MODE_ALL(V_038010_SFR_MODE_NO_ZERO) |
450 S_038010_REQUEST_SIZE(1) |
451 S_038010_DST_SEL_X(r600_tex_swizzle(view->swizzle_r)) |
452 S_038010_DST_SEL_Y(r600_tex_swizzle(view->swizzle_g)) |
453 S_038010_DST_SEL_Z(r600_tex_swizzle(view->swizzle_b)) |
454 S_038010_DST_SEL_W(r600_tex_swizzle(view->swizzle_a)) |
455 S_038010_BASE_LEVEL(view->first_level);
456 rtexture->state->states[R600_PS_RESOURCE__RESOURCE0_WORD5] =
457 S_038014_LAST_LEVEL(view->last_level) |
458 S_038014_BASE_ARRAY(0) |
459 S_038014_LAST_ARRAY(0);
460 rtexture->state->states[R600_PS_RESOURCE__RESOURCE0_WORD6] =
461 S_038018_TYPE(V_038010_SQ_TEX_VTX_VALID_TEXTURE);
462 return &rtexture->view;
463 }
464
465 static void r600_sampler_view_destroy(struct pipe_context *ctx,
466 struct pipe_sampler_view *view)
467 {
468 struct r600_texture_resource *texture;
469
470 if (view == NULL)
471 return;
472 texture = LIST_ENTRY(struct r600_texture_resource, view, view);
473 radeon_state_decref(texture->state);
474 FREE(texture);
475 }
476
477 static void r600_set_fragment_sampler_views(struct pipe_context *ctx,
478 unsigned count,
479 struct pipe_sampler_view **views)
480 {
481 struct r600_texture_resource *rtexture;
482 struct r600_context *rctx = r600_context(ctx);
483 struct pipe_sampler_view *tmp;
484 unsigned i, real_num_views = 0;
485
486 if (views == NULL)
487 return;
488
489 for (i = 0; i < count; i++) {
490 if (views[i])
491 real_num_views++;
492 }
493
494 for (i = 0; i < rctx->nps_view; i++) {
495 tmp = &rctx->ps_view[i]->view;
496 pipe_sampler_view_reference(&tmp, NULL);
497 rctx->ps_view[i] = NULL;
498 }
499 rctx->nps_view = real_num_views;
500 for (i = 0; i < count; i++) {
501
502 if (!views[i])
503 continue;
504 rtexture = LIST_ENTRY(struct r600_texture_resource, views[i], view);
505 rctx->ps_view[i] = rtexture;
506 tmp = NULL;
507 pipe_sampler_view_reference(&tmp, views[i]);
508 rtexture->state->id = R600_PS_RESOURCE + i;
509 }
510 }
511
512 static void r600_set_vertex_sampler_views(struct pipe_context *ctx,
513 unsigned count,
514 struct pipe_sampler_view **views)
515 {
516 struct r600_texture_resource *rtexture;
517 struct r600_context *rctx = r600_context(ctx);
518 struct pipe_sampler_view *tmp;
519 unsigned i, real_num_views = 0;
520
521 if (views == NULL)
522 return;
523
524 for (i = 0; i < count; i++) {
525 if (views[i])
526 real_num_views++;
527 }
528 for (i = 0; i < rctx->nvs_view; i++) {
529 tmp = &rctx->vs_view[i]->view;
530 pipe_sampler_view_reference(&tmp, NULL);
531 rctx->vs_view[i] = NULL;
532 }
533 rctx->nvs_view = real_num_views;
534 for (i = 0; i < count; i++) {
535 if (!views[i])
536 continue;
537 rtexture = LIST_ENTRY(struct r600_texture_resource, views[i], view);
538 rctx->vs_view[i] = rtexture;
539 tmp = NULL;
540 pipe_sampler_view_reference(&tmp, views[i]);
541 rtexture->state->id = R600_VS_RESOURCE + i;
542 }
543 }
544
545 static void r600_set_scissor_state(struct pipe_context *ctx,
546 const struct pipe_scissor_state *state)
547 {
548 struct r600_screen *rscreen = r600_screen(ctx->screen);
549 struct r600_context *rctx = r600_context(ctx);
550 struct radeon_state *rstate;
551 u32 tl, br;
552
553 tl = S_028240_TL_X(state->minx) | S_028240_TL_Y(state->miny) | S_028240_WINDOW_OFFSET_DISABLE(1);
554 br = S_028244_BR_X(state->maxx) | S_028244_BR_Y(state->maxy);
555 rstate = radeon_state(rscreen->rw, R600_SCISSOR_TYPE, R600_SCISSOR);
556 if (rstate == NULL)
557 return;
558 rstate->states[R600_SCISSOR__PA_SC_SCREEN_SCISSOR_TL] = tl;
559 rstate->states[R600_SCISSOR__PA_SC_SCREEN_SCISSOR_BR] = br;
560 rstate->states[R600_SCISSOR__PA_SC_WINDOW_OFFSET] = 0x00000000;
561 rstate->states[R600_SCISSOR__PA_SC_WINDOW_SCISSOR_TL] = tl;
562 rstate->states[R600_SCISSOR__PA_SC_WINDOW_SCISSOR_BR] = br;
563 rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_RULE] = 0x0000FFFF;
564 rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_0_TL] = tl;
565 rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_0_BR] = br;
566 rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_1_TL] = tl;
567 rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_1_BR] = br;
568 rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_2_TL] = tl;
569 rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_2_BR] = br;
570 rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_3_TL] = tl;
571 rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_3_BR] = br;
572 rstate->states[R600_SCISSOR__PA_SC_EDGERULE] = 0xAAAAAAAA;
573 rstate->states[R600_SCISSOR__PA_SC_GENERIC_SCISSOR_TL] = tl;
574 rstate->states[R600_SCISSOR__PA_SC_GENERIC_SCISSOR_BR] = br;
575 rstate->states[R600_SCISSOR__PA_SC_VPORT_SCISSOR_0_TL] = tl;
576 rstate->states[R600_SCISSOR__PA_SC_VPORT_SCISSOR_0_BR] = br;
577 if (radeon_state_pm4(rstate)) {
578 radeon_state_decref(rstate);
579 return;
580 }
581 radeon_draw_set_new(rctx->draw, rstate);
582 }
583
584 static void r600_set_viewport_state(struct pipe_context *ctx,
585 const struct pipe_viewport_state *state)
586 {
587 struct r600_screen *rscreen = r600_screen(ctx->screen);
588 struct r600_context *rctx = r600_context(ctx);
589 struct radeon_state *rstate;
590
591 rstate = radeon_state(rscreen->rw, R600_VIEWPORT_TYPE, R600_VIEWPORT);
592 if (rstate == NULL)
593 return;
594 rstate->states[R600_VIEWPORT__PA_SC_VPORT_ZMIN_0] = 0x00000000;
595 rstate->states[R600_VIEWPORT__PA_SC_VPORT_ZMAX_0] = 0x3F800000;
596 rstate->states[R600_VIEWPORT__PA_CL_VPORT_XSCALE_0] = fui(state->scale[0]);
597 rstate->states[R600_VIEWPORT__PA_CL_VPORT_YSCALE_0] = fui(state->scale[1]);
598 rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZSCALE_0] = fui(state->scale[2]);
599 rstate->states[R600_VIEWPORT__PA_CL_VPORT_XOFFSET_0] = fui(state->translate[0]);
600 rstate->states[R600_VIEWPORT__PA_CL_VPORT_YOFFSET_0] = fui(state->translate[1]);
601 rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZOFFSET_0] = fui(state->translate[2]);
602 rstate->states[R600_VIEWPORT__PA_CL_VTE_CNTL] = 0x0000043F;
603 if (radeon_state_pm4(rstate)) {
604 radeon_state_decref(rstate);
605 return;
606 }
607 radeon_draw_set_new(rctx->draw, rstate);
608 rctx->viewport = *state;
609 }
610
611 static void r600_set_vertex_buffers(struct pipe_context *ctx,
612 unsigned count,
613 const struct pipe_vertex_buffer *buffers)
614 {
615 struct r600_context *rctx = r600_context(ctx);
616
617 memcpy(rctx->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count);
618 rctx->nvertex_buffer = count;
619 }
620
621
622 static void *r600_create_vertex_elements_state(struct pipe_context *ctx,
623 unsigned count,
624 const struct pipe_vertex_element *elements)
625 {
626 struct r600_vertex_elements_state *v = CALLOC_STRUCT(r600_vertex_elements_state);
627
628 assert(count < 32);
629 v->count = count;
630 memcpy(v->elements, elements, count * sizeof(struct pipe_vertex_element));
631 return v;
632 }
633
634 static void r600_bind_vertex_elements_state(struct pipe_context *ctx, void *state)
635 {
636 struct r600_context *rctx = r600_context(ctx);
637 struct r600_vertex_elements_state *v = (struct r600_vertex_elements_state*)state;
638
639 rctx->vertex_elements = v;
640 }
641
642 static void r600_delete_vertex_elements_state(struct pipe_context *ctx, void *state)
643 {
644 FREE(state);
645 }
646
647 static void *r600_create_dsa_state(struct pipe_context *ctx,
648 const struct pipe_depth_stencil_alpha_state *state)
649 {
650 struct r600_screen *rscreen = r600_screen(ctx->screen);
651 struct radeon_state *rstate;
652 unsigned db_depth_control;
653
654 rstate = radeon_state(rscreen->rw, R600_DSA_TYPE, R600_DSA);
655 if (rstate == NULL)
656 return NULL;
657 db_depth_control = 0x00700700 | S_028800_Z_ENABLE(state->depth.enabled) | S_028800_Z_WRITE_ENABLE(state->depth.writemask) | S_028800_ZFUNC(state->depth.func);
658
659 rstate->states[R600_DSA__DB_STENCIL_CLEAR] = 0x00000000;
660 rstate->states[R600_DSA__DB_DEPTH_CLEAR] = 0x3F800000;
661 rstate->states[R600_DSA__SX_ALPHA_TEST_CONTROL] = 0x00000000;
662 rstate->states[R600_DSA__DB_STENCILREFMASK] = 0xFFFFFF00;
663 rstate->states[R600_DSA__DB_STENCILREFMASK_BF] = 0xFFFFFF00;
664 rstate->states[R600_DSA__SX_ALPHA_REF] = 0x00000000;
665 rstate->states[R600_DSA__SPI_FOG_FUNC_SCALE] = 0x00000000;
666 rstate->states[R600_DSA__SPI_FOG_FUNC_BIAS] = 0x00000000;
667 rstate->states[R600_DSA__SPI_FOG_CNTL] = 0x00000000;
668 rstate->states[R600_DSA__DB_DEPTH_CONTROL] = db_depth_control;
669 rstate->states[R600_DSA__DB_SHADER_CONTROL] = 0x00000210;
670 rstate->states[R600_DSA__DB_RENDER_CONTROL] = 0x00000060;
671 rstate->states[R600_DSA__DB_RENDER_OVERRIDE] = 0x0000002A;
672 rstate->states[R600_DSA__DB_SRESULTS_COMPARE_STATE1] = 0x00000000;
673 rstate->states[R600_DSA__DB_PRELOAD_CONTROL] = 0x00000000;
674 rstate->states[R600_DSA__DB_ALPHA_TO_MASK] = 0x0000AA00;
675 if (radeon_state_pm4(rstate)) {
676 radeon_state_decref(rstate);
677 return NULL;
678 }
679 return rstate;
680 }
681
682 static void r600_bind_dsa_state(struct pipe_context *ctx, void *state)
683 {
684 struct r600_context *rctx = r600_context(ctx);
685 radeon_draw_set(rctx->draw, state);
686 }
687
688 static void r600_set_constant_buffer(struct pipe_context *ctx,
689 uint shader, uint index,
690 struct pipe_resource *buffer)
691 {
692 struct r600_screen *rscreen = r600_screen(ctx->screen);
693 struct r600_context *rctx = r600_context(ctx);
694 unsigned nconstant = 0, i, type, id;
695 struct radeon_state *rstate;
696 struct pipe_transfer *transfer;
697 u32 *ptr;
698
699 switch (shader) {
700 case PIPE_SHADER_VERTEX:
701 id = R600_VS_CONSTANT;
702 type = R600_VS_CONSTANT_TYPE;
703 break;
704 case PIPE_SHADER_FRAGMENT:
705 id = R600_PS_CONSTANT;
706 type = R600_PS_CONSTANT_TYPE;
707 break;
708 default:
709 fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, shader);
710 return;
711 }
712 if (buffer && buffer->width0 > 0) {
713 nconstant = buffer->width0 / 16;
714 ptr = pipe_buffer_map(ctx, buffer, PIPE_TRANSFER_READ, &transfer);
715 if (ptr == NULL)
716 return;
717 for (i = 0; i < nconstant; i++) {
718 rstate = radeon_state(rscreen->rw, type, id + i);
719 if (rstate == NULL)
720 return;
721 rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT0_0] = ptr[i * 4 + 0];
722 rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT1_0] = ptr[i * 4 + 1];
723 rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT2_0] = ptr[i * 4 + 2];
724 rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT3_0] = ptr[i * 4 + 3];
725 if (radeon_state_pm4(rstate))
726 return;
727 if (radeon_draw_set_new(rctx->draw, rstate))
728 return;
729 }
730 pipe_buffer_unmap(ctx, buffer, transfer);
731 }
732 }
733
734 static void r600_set_stencil_ref(struct pipe_context *ctx,
735 const struct pipe_stencil_ref *sr)
736 {
737 struct r600_context *rctx = r600_context(ctx);
738 rctx->stencil_ref = *sr;
739 }
740
741 static void r600_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
742 {
743 }
744
745 void r600_init_state_functions(struct r600_context *rctx)
746 {
747 rctx->context.set_sample_mask = r600_set_sample_mask;
748 rctx->context.create_blend_state = r600_create_blend_state;
749 rctx->context.bind_blend_state = r600_bind_blend_state;
750 rctx->context.delete_blend_state = r600_delete_state;
751 rctx->context.set_blend_color = r600_set_blend_color;
752 rctx->context.set_clip_state = r600_set_clip_state;
753 rctx->context.set_constant_buffer = r600_set_constant_buffer;
754 rctx->context.create_depth_stencil_alpha_state = r600_create_dsa_state;
755 rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state;
756 rctx->context.delete_depth_stencil_alpha_state = r600_delete_state;
757 rctx->context.set_framebuffer_state = r600_set_framebuffer_state;
758 rctx->context.create_fs_state = r600_create_fs_state;
759 rctx->context.bind_fs_state = r600_bind_fs_state;
760 rctx->context.delete_fs_state = r600_delete_state;
761 rctx->context.set_polygon_stipple = r600_set_polygon_stipple;
762 rctx->context.create_rasterizer_state = r600_create_rs_state;
763 rctx->context.bind_rasterizer_state = r600_bind_rs_state;
764 rctx->context.delete_rasterizer_state = r600_delete_state;
765 rctx->context.create_sampler_state = r600_create_sampler_state;
766 rctx->context.bind_fragment_sampler_states = r600_bind_sampler_states;
767 rctx->context.bind_vertex_sampler_states = r600_bind_sampler_states;
768 rctx->context.delete_sampler_state = r600_delete_state;
769 rctx->context.create_sampler_view = r600_create_sampler_view;
770 rctx->context.sampler_view_destroy = r600_sampler_view_destroy;
771 rctx->context.set_fragment_sampler_views = r600_set_fragment_sampler_views;
772 rctx->context.set_vertex_sampler_views = r600_set_vertex_sampler_views;
773 rctx->context.set_scissor_state = r600_set_scissor_state;
774 rctx->context.set_viewport_state = r600_set_viewport_state;
775 rctx->context.set_vertex_buffers = r600_set_vertex_buffers;
776 rctx->context.create_vertex_elements_state = r600_create_vertex_elements_state;
777 rctx->context.bind_vertex_elements_state = r600_bind_vertex_elements_state;
778 rctx->context.delete_vertex_elements_state = r600_delete_vertex_elements_state;
779 rctx->context.create_vs_state = r600_create_vs_state;
780 rctx->context.bind_vs_state = r600_bind_vs_state;
781 rctx->context.delete_vs_state = r600_delete_state;
782 rctx->context.set_stencil_ref = r600_set_stencil_ref;
783 }