r600g: texture support
[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;
485
486 if (views == NULL)
487 return;
488
489 for (i = 0; i < rctx->nps_view; i++) {
490 tmp = &rctx->ps_view[i]->view;
491 pipe_sampler_view_reference(&tmp, NULL);
492 rctx->ps_view[i] = NULL;
493 }
494 rctx->nps_view = count;
495 for (i = 0; i < count; i++) {
496 rtexture = LIST_ENTRY(struct r600_texture_resource, views[i], view);
497 rctx->ps_view[i] = rtexture;
498 tmp = NULL;
499 pipe_sampler_view_reference(&tmp, views[i]);
500 rtexture->state->id = R600_PS_RESOURCE + i;
501 }
502 }
503
504 static void r600_set_vertex_sampler_views(struct pipe_context *ctx,
505 unsigned count,
506 struct pipe_sampler_view **views)
507 {
508 struct r600_texture_resource *rtexture;
509 struct r600_context *rctx = r600_context(ctx);
510 struct pipe_sampler_view *tmp;
511 unsigned i;
512
513 if (views == NULL)
514 return;
515
516 for (i = 0; i < rctx->nvs_view; i++) {
517 tmp = &rctx->vs_view[i]->view;
518 pipe_sampler_view_reference(&tmp, NULL);
519 rctx->vs_view[i] = NULL;
520 }
521 rctx->nps_view = count;
522 for (i = 0; i < count; i++) {
523 rtexture = LIST_ENTRY(struct r600_texture_resource, views[i], view);
524 rctx->vs_view[i] = rtexture;
525 tmp = NULL;
526 pipe_sampler_view_reference(&tmp, views[i]);
527 rtexture->state->id = R600_VS_RESOURCE + i;
528 }
529 }
530
531 static void r600_set_scissor_state(struct pipe_context *ctx,
532 const struct pipe_scissor_state *state)
533 {
534 struct r600_screen *rscreen = r600_screen(ctx->screen);
535 struct r600_context *rctx = r600_context(ctx);
536 struct radeon_state *rstate;
537 u32 tl, br;
538
539 tl = S_028240_TL_X(state->minx) | S_028240_TL_Y(state->miny) | S_028240_WINDOW_OFFSET_DISABLE(1);
540 br = S_028244_BR_X(state->maxx) | S_028244_BR_Y(state->maxy);
541 rstate = radeon_state(rscreen->rw, R600_SCISSOR_TYPE, R600_SCISSOR);
542 if (rstate == NULL)
543 return;
544 rstate->states[R600_SCISSOR__PA_SC_SCREEN_SCISSOR_TL] = tl;
545 rstate->states[R600_SCISSOR__PA_SC_SCREEN_SCISSOR_BR] = br;
546 rstate->states[R600_SCISSOR__PA_SC_WINDOW_OFFSET] = 0x00000000;
547 rstate->states[R600_SCISSOR__PA_SC_WINDOW_SCISSOR_TL] = tl;
548 rstate->states[R600_SCISSOR__PA_SC_WINDOW_SCISSOR_BR] = br;
549 rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_RULE] = 0x0000FFFF;
550 rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_0_TL] = tl;
551 rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_0_BR] = br;
552 rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_1_TL] = tl;
553 rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_1_BR] = br;
554 rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_2_TL] = tl;
555 rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_2_BR] = br;
556 rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_3_TL] = tl;
557 rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_3_BR] = br;
558 rstate->states[R600_SCISSOR__PA_SC_EDGERULE] = 0xAAAAAAAA;
559 rstate->states[R600_SCISSOR__PA_SC_GENERIC_SCISSOR_TL] = tl;
560 rstate->states[R600_SCISSOR__PA_SC_GENERIC_SCISSOR_BR] = br;
561 rstate->states[R600_SCISSOR__PA_SC_VPORT_SCISSOR_0_TL] = tl;
562 rstate->states[R600_SCISSOR__PA_SC_VPORT_SCISSOR_0_BR] = br;
563 if (radeon_state_pm4(rstate)) {
564 radeon_state_decref(rstate);
565 return;
566 }
567 radeon_draw_set_new(rctx->draw, rstate);
568 }
569
570 static void r600_set_viewport_state(struct pipe_context *ctx,
571 const struct pipe_viewport_state *state)
572 {
573 struct r600_screen *rscreen = r600_screen(ctx->screen);
574 struct r600_context *rctx = r600_context(ctx);
575 struct radeon_state *rstate;
576
577 rstate = radeon_state(rscreen->rw, R600_VIEWPORT_TYPE, R600_VIEWPORT);
578 if (rstate == NULL)
579 return;
580 rstate->states[R600_VIEWPORT__PA_SC_VPORT_ZMIN_0] = 0x00000000;
581 rstate->states[R600_VIEWPORT__PA_SC_VPORT_ZMAX_0] = 0x3F800000;
582 rstate->states[R600_VIEWPORT__PA_CL_VPORT_XSCALE_0] = r600_float_to_u32(state->scale[0]);
583 rstate->states[R600_VIEWPORT__PA_CL_VPORT_YSCALE_0] = r600_float_to_u32(state->scale[1]);
584 rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZSCALE_0] = r600_float_to_u32(state->scale[2]);
585 rstate->states[R600_VIEWPORT__PA_CL_VPORT_XOFFSET_0] = r600_float_to_u32(state->translate[0]);
586 rstate->states[R600_VIEWPORT__PA_CL_VPORT_YOFFSET_0] = r600_float_to_u32(state->translate[1]);
587 rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZOFFSET_0] = r600_float_to_u32(state->translate[2]);
588 rstate->states[R600_VIEWPORT__PA_CL_VTE_CNTL] = 0x0000043F;
589 if (radeon_state_pm4(rstate)) {
590 radeon_state_decref(rstate);
591 return;
592 }
593 radeon_draw_set_new(rctx->draw, rstate);
594 rctx->viewport = *state;
595 }
596
597 static void r600_set_vertex_buffers(struct pipe_context *ctx,
598 unsigned count,
599 const struct pipe_vertex_buffer *buffers)
600 {
601 struct r600_context *rctx = r600_context(ctx);
602
603 memcpy(rctx->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count);
604 rctx->nvertex_buffer = count;
605 }
606
607
608 static void *r600_create_vertex_elements_state(struct pipe_context *ctx,
609 unsigned count,
610 const struct pipe_vertex_element *elements)
611 {
612 struct r600_vertex_elements_state *v = CALLOC_STRUCT(r600_vertex_elements_state);
613
614 assert(count < 32);
615 v->count = count;
616 memcpy(v->elements, elements, count * sizeof(struct pipe_vertex_element));
617 return v;
618 }
619
620 static void r600_bind_vertex_elements_state(struct pipe_context *ctx, void *state)
621 {
622 struct r600_context *rctx = r600_context(ctx);
623 struct r600_vertex_elements_state *v = (struct r600_vertex_elements_state*)state;
624
625 rctx->vertex_elements = v;
626 }
627
628 static void r600_delete_vertex_elements_state(struct pipe_context *ctx, void *state)
629 {
630 FREE(state);
631 }
632
633 static void *r600_create_dsa_state(struct pipe_context *ctx,
634 const struct pipe_depth_stencil_alpha_state *state)
635 {
636 struct r600_screen *rscreen = r600_screen(ctx->screen);
637 struct radeon_state *rstate;
638 unsigned db_depth_control;
639
640 rstate = radeon_state(rscreen->rw, R600_DSA_TYPE, R600_DSA);
641 if (rstate == NULL)
642 return NULL;
643 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);
644
645 rstate->states[R600_DSA__DB_STENCIL_CLEAR] = 0x00000000;
646 rstate->states[R600_DSA__DB_DEPTH_CLEAR] = 0x3F800000;
647 rstate->states[R600_DSA__SX_ALPHA_TEST_CONTROL] = 0x00000000;
648 rstate->states[R600_DSA__DB_STENCILREFMASK] = 0xFFFFFF00;
649 rstate->states[R600_DSA__DB_STENCILREFMASK_BF] = 0xFFFFFF00;
650 rstate->states[R600_DSA__SX_ALPHA_REF] = 0x00000000;
651 rstate->states[R600_DSA__SPI_FOG_FUNC_SCALE] = 0x00000000;
652 rstate->states[R600_DSA__SPI_FOG_FUNC_BIAS] = 0x00000000;
653 rstate->states[R600_DSA__SPI_FOG_CNTL] = 0x00000000;
654 rstate->states[R600_DSA__DB_DEPTH_CONTROL] = db_depth_control;
655 rstate->states[R600_DSA__DB_SHADER_CONTROL] = 0x00000210;
656 rstate->states[R600_DSA__DB_RENDER_CONTROL] = 0x00000060;
657 rstate->states[R600_DSA__DB_RENDER_OVERRIDE] = 0x0000002A;
658 rstate->states[R600_DSA__DB_SRESULTS_COMPARE_STATE1] = 0x00000000;
659 rstate->states[R600_DSA__DB_PRELOAD_CONTROL] = 0x00000000;
660 rstate->states[R600_DSA__DB_ALPHA_TO_MASK] = 0x0000AA00;
661 if (radeon_state_pm4(rstate)) {
662 radeon_state_decref(rstate);
663 return NULL;
664 }
665 return rstate;
666 }
667
668 static void r600_bind_dsa_state(struct pipe_context *ctx, void *state)
669 {
670 struct r600_context *rctx = r600_context(ctx);
671 radeon_draw_set(rctx->draw, state);
672 }
673
674 static void r600_set_constant_buffer(struct pipe_context *ctx,
675 uint shader, uint index,
676 struct pipe_resource *buffer)
677 {
678 struct r600_screen *rscreen = r600_screen(ctx->screen);
679 struct r600_context *rctx = r600_context(ctx);
680 unsigned nconstant = 0, i, type, id;
681 struct radeon_state *rstate;
682 struct pipe_transfer *transfer;
683 u32 *ptr;
684
685 switch (shader) {
686 case PIPE_SHADER_VERTEX:
687 id = R600_VS_CONSTANT;
688 type = R600_VS_CONSTANT_TYPE;
689 break;
690 case PIPE_SHADER_FRAGMENT:
691 id = R600_PS_CONSTANT;
692 type = R600_PS_CONSTANT_TYPE;
693 break;
694 default:
695 fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, shader);
696 return;
697 }
698 if (buffer && buffer->width0 > 0) {
699 nconstant = buffer->width0 / 16;
700 ptr = pipe_buffer_map(ctx, buffer, PIPE_TRANSFER_READ, &transfer);
701 if (ptr == NULL)
702 return;
703 for (i = 0; i < nconstant; i++) {
704 rstate = radeon_state(rscreen->rw, type, id + i);
705 if (rstate == NULL)
706 return;
707 rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT0_0] = ptr[i * 4 + 0];
708 rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT1_0] = ptr[i * 4 + 1];
709 rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT2_0] = ptr[i * 4 + 2];
710 rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT3_0] = ptr[i * 4 + 3];
711 if (radeon_state_pm4(rstate))
712 return;
713 if (radeon_draw_set_new(rctx->draw, rstate))
714 return;
715 }
716 pipe_buffer_unmap(ctx, buffer, transfer);
717 }
718 }
719
720 static void r600_set_stencil_ref(struct pipe_context *ctx,
721 const struct pipe_stencil_ref *sr)
722 {
723 struct r600_context *rctx = r600_context(ctx);
724 rctx->stencil_ref = *sr;
725 }
726
727 static void r600_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
728 {
729 }
730
731 void r600_init_state_functions(struct r600_context *rctx)
732 {
733 rctx->context.set_sample_mask = r600_set_sample_mask;
734 rctx->context.create_blend_state = r600_create_blend_state;
735 rctx->context.bind_blend_state = r600_bind_blend_state;
736 rctx->context.delete_blend_state = r600_delete_state;
737 rctx->context.set_blend_color = r600_set_blend_color;
738 rctx->context.set_clip_state = r600_set_clip_state;
739 rctx->context.set_constant_buffer = r600_set_constant_buffer;
740 rctx->context.create_depth_stencil_alpha_state = r600_create_dsa_state;
741 rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state;
742 rctx->context.delete_depth_stencil_alpha_state = r600_delete_state;
743 rctx->context.set_framebuffer_state = r600_set_framebuffer_state;
744 rctx->context.create_fs_state = r600_create_fs_state;
745 rctx->context.bind_fs_state = r600_bind_fs_state;
746 rctx->context.delete_fs_state = r600_delete_state;
747 rctx->context.set_polygon_stipple = r600_set_polygon_stipple;
748 rctx->context.create_rasterizer_state = r600_create_rs_state;
749 rctx->context.bind_rasterizer_state = r600_bind_rs_state;
750 rctx->context.delete_rasterizer_state = r600_delete_state;
751 rctx->context.create_sampler_state = r600_create_sampler_state;
752 rctx->context.bind_fragment_sampler_states = r600_bind_sampler_states;
753 rctx->context.bind_vertex_sampler_states = r600_bind_sampler_states;
754 rctx->context.delete_sampler_state = r600_delete_state;
755 rctx->context.create_sampler_view = r600_create_sampler_view;
756 rctx->context.sampler_view_destroy = r600_sampler_view_destroy;
757 rctx->context.set_fragment_sampler_views = r600_set_fragment_sampler_views;
758 rctx->context.set_vertex_sampler_views = r600_set_vertex_sampler_views;
759 rctx->context.set_scissor_state = r600_set_scissor_state;
760 rctx->context.set_viewport_state = r600_set_viewport_state;
761 rctx->context.set_vertex_buffers = r600_set_vertex_buffers;
762 rctx->context.create_vertex_elements_state = r600_create_vertex_elements_state;
763 rctx->context.bind_vertex_elements_state = r600_bind_vertex_elements_state;
764 rctx->context.delete_vertex_elements_state = r600_delete_vertex_elements_state;
765 rctx->context.create_vs_state = r600_create_vs_state;
766 rctx->context.bind_vs_state = r600_bind_vs_state;
767 rctx->context.delete_vs_state = r600_delete_state;
768 rctx->context.set_stencil_ref = r600_set_stencil_ref;
769 }