2 * Copyright 2010 Red Hat Inc.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
24 * Authors: Dave Airlie <airlied@redhat.com>
25 * Jerome Glisse <jglisse@redhat.com>
27 #include <util/u_memory.h>
28 #include <util/u_format.h>
29 #include <pipebuffer/pb_buffer.h>
30 #include "r600_pipe.h"
32 /* common state between evergreen and r600 */
33 void r600_bind_blend_state(struct pipe_context
*ctx
, void *state
)
35 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
36 struct r600_pipe_blend
*blend
= (struct r600_pipe_blend
*)state
;
37 struct r600_pipe_state
*rstate
;
41 rstate
= &blend
->rstate
;
42 rctx
->states
[rstate
->id
] = rstate
;
43 rctx
->cb_target_mask
= blend
->cb_target_mask
;
44 r600_context_pipe_state_set(&rctx
->ctx
, rstate
);
47 void r600_bind_rs_state(struct pipe_context
*ctx
, void *state
)
49 struct r600_pipe_rasterizer
*rs
= (struct r600_pipe_rasterizer
*)state
;
50 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
55 rctx
->flatshade
= rs
->flatshade
;
56 rctx
->sprite_coord_enable
= rs
->sprite_coord_enable
;
57 rctx
->rasterizer
= rs
;
59 rctx
->states
[rs
->rstate
.id
] = &rs
->rstate
;
60 r600_context_pipe_state_set(&rctx
->ctx
, &rs
->rstate
);
62 if (rctx
->family
>= CHIP_CEDAR
) {
63 evergreen_polygon_offset_update(rctx
);
65 r600_polygon_offset_update(rctx
);
69 void r600_delete_rs_state(struct pipe_context
*ctx
, void *state
)
71 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
72 struct r600_pipe_rasterizer
*rs
= (struct r600_pipe_rasterizer
*)state
;
74 if (rctx
->rasterizer
== rs
) {
75 rctx
->rasterizer
= NULL
;
77 if (rctx
->states
[rs
->rstate
.id
] == &rs
->rstate
) {
78 rctx
->states
[rs
->rstate
.id
] = NULL
;
83 void r600_sampler_view_destroy(struct pipe_context
*ctx
,
84 struct pipe_sampler_view
*state
)
86 struct r600_pipe_sampler_view
*resource
= (struct r600_pipe_sampler_view
*)state
;
88 pipe_resource_reference(&state
->texture
, NULL
);
92 void r600_bind_state(struct pipe_context
*ctx
, void *state
)
94 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
95 struct r600_pipe_state
*rstate
= (struct r600_pipe_state
*)state
;
99 rctx
->states
[rstate
->id
] = rstate
;
100 r600_context_pipe_state_set(&rctx
->ctx
, rstate
);
103 void r600_delete_state(struct pipe_context
*ctx
, void *state
)
105 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
106 struct r600_pipe_state
*rstate
= (struct r600_pipe_state
*)state
;
108 if (rctx
->states
[rstate
->id
] == rstate
) {
109 rctx
->states
[rstate
->id
] = NULL
;
111 for (int i
= 0; i
< rstate
->nregs
; i
++) {
112 r600_bo_reference(rctx
->radeon
, &rstate
->regs
[i
].bo
, NULL
);
117 void r600_bind_vertex_elements(struct pipe_context
*ctx
, void *state
)
119 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
120 struct r600_vertex_element
*v
= (struct r600_vertex_element
*)state
;
122 rctx
->vertex_elements
= v
;
124 rctx
->states
[v
->rstate
.id
] = &v
->rstate
;
125 r600_context_pipe_state_set(&rctx
->ctx
, &v
->rstate
);
126 if (rctx
->family
>= CHIP_CEDAR
) {
127 evergreen_vertex_buffer_update(rctx
);
129 r600_vertex_buffer_update(rctx
);
134 // rctx->vs_rebuild = TRUE;
138 void r600_delete_vertex_element(struct pipe_context
*ctx
, void *state
)
140 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
141 struct r600_vertex_element
*v
= (struct r600_vertex_element
*)state
;
143 if (rctx
->states
[v
->rstate
.id
] == &v
->rstate
) {
144 rctx
->states
[v
->rstate
.id
] = NULL
;
146 if (rctx
->vertex_elements
== state
)
147 rctx
->vertex_elements
= NULL
;
149 r600_bo_reference(rctx
->radeon
, &v
->fetch_shader
, NULL
);
154 void r600_set_index_buffer(struct pipe_context
*ctx
,
155 const struct pipe_index_buffer
*ib
)
157 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
160 pipe_resource_reference(&rctx
->index_buffer
.buffer
, ib
->buffer
);
161 memcpy(&rctx
->index_buffer
, ib
, sizeof(rctx
->index_buffer
));
163 pipe_resource_reference(&rctx
->index_buffer
.buffer
, NULL
);
164 memset(&rctx
->index_buffer
, 0, sizeof(rctx
->index_buffer
));
167 /* TODO make this more like a state */
170 void r600_set_vertex_buffers(struct pipe_context
*ctx
, unsigned count
,
171 const struct pipe_vertex_buffer
*buffers
)
173 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
174 struct pipe_vertex_buffer
*vbo
;
175 unsigned max_index
= (unsigned)-1;
177 for (int i
= 0; i
< rctx
->nvertex_buffer
; i
++) {
178 pipe_resource_reference(&rctx
->vertex_buffer
[i
].buffer
, NULL
);
180 memcpy(rctx
->vertex_buffer
, buffers
, sizeof(struct pipe_vertex_buffer
) * count
);
182 for (int i
= 0; i
< count
; i
++) {
183 vbo
= (struct pipe_vertex_buffer
*)&buffers
[i
];
185 rctx
->vertex_buffer
[i
].buffer
= NULL
;
186 if (r600_buffer_is_user_buffer(buffers
[i
].buffer
))
187 rctx
->any_user_vbs
= TRUE
;
188 pipe_resource_reference(&rctx
->vertex_buffer
[i
].buffer
, buffers
[i
].buffer
);
190 if (vbo
->max_index
== ~0) {
194 vbo
->max_index
= (vbo
->buffer
->width0
- vbo
->buffer_offset
) / vbo
->stride
;
196 max_index
= MIN2(vbo
->max_index
, max_index
);
198 rctx
->nvertex_buffer
= count
;
199 rctx
->vb_max_index
= max_index
;
200 if (rctx
->family
>= CHIP_CEDAR
) {
201 evergreen_vertex_buffer_update(rctx
);
203 r600_vertex_buffer_update(rctx
);
208 #define FORMAT_REPLACE(what, withwhat) \
209 case PIPE_FORMAT_##what: *format = PIPE_FORMAT_##withwhat; break
211 void *r600_create_vertex_elements(struct pipe_context
*ctx
,
213 const struct pipe_vertex_element
*elements
)
215 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
216 struct r600_vertex_element
*v
= CALLOC_STRUCT(r600_vertex_element
);
217 enum pipe_format
*format
;
225 memcpy(v
->elements
, elements
, count
* sizeof(struct pipe_vertex_element
));
227 for (i
= 0; i
< count
; i
++) {
228 v
->hw_format
[i
] = v
->elements
[i
].src_format
;
229 format
= &v
->hw_format
[i
];
232 FORMAT_REPLACE(R64_FLOAT
, R32_FLOAT
);
233 FORMAT_REPLACE(R64G64_FLOAT
, R32G32_FLOAT
);
234 FORMAT_REPLACE(R64G64B64_FLOAT
, R32G32B32_FLOAT
);
235 FORMAT_REPLACE(R64G64B64A64_FLOAT
, R32G32B32A32_FLOAT
);
238 v
->incompatible_layout
=
239 v
->incompatible_layout
||
240 v
->elements
[i
].src_format
!= v
->hw_format
[i
];
242 v
->hw_format_size
[i
] = align(util_format_get_blocksize(v
->hw_format
[i
]), 4);
245 if (r600_vertex_elements_build_fetch_shader(rctx
, v
)) {
253 void *r600_create_shader_state(struct pipe_context
*ctx
,
254 const struct pipe_shader_state
*state
)
256 struct r600_pipe_shader
*shader
= CALLOC_STRUCT(r600_pipe_shader
);
259 r
= r600_pipe_shader_create(ctx
, shader
, state
->tokens
);
266 void r600_bind_ps_shader(struct pipe_context
*ctx
, void *state
)
268 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
270 /* TODO delete old shader */
271 rctx
->ps_shader
= (struct r600_pipe_shader
*)state
;
274 void r600_bind_vs_shader(struct pipe_context
*ctx
, void *state
)
276 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
278 /* TODO delete old shader */
279 rctx
->vs_shader
= (struct r600_pipe_shader
*)state
;
282 void r600_delete_ps_shader(struct pipe_context
*ctx
, void *state
)
284 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
285 struct r600_pipe_shader
*shader
= (struct r600_pipe_shader
*)state
;
287 if (rctx
->ps_shader
== shader
) {
288 rctx
->ps_shader
= NULL
;
291 r600_pipe_shader_destroy(ctx
, shader
);
295 void r600_delete_vs_shader(struct pipe_context
*ctx
, void *state
)
297 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
298 struct r600_pipe_shader
*shader
= (struct r600_pipe_shader
*)state
;
300 if (rctx
->vs_shader
== shader
) {
301 rctx
->vs_shader
= NULL
;
304 r600_pipe_shader_destroy(ctx
, shader
);