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->vs_rebuild = TRUE;
128 void r600_delete_vertex_element(struct pipe_context
*ctx
, void *state
)
130 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
134 if (rctx
->vertex_elements
== state
)
135 rctx
->vertex_elements
= NULL
;
139 void r600_set_index_buffer(struct pipe_context
*ctx
,
140 const struct pipe_index_buffer
*ib
)
142 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
145 pipe_resource_reference(&rctx
->index_buffer
.buffer
, ib
->buffer
);
146 memcpy(&rctx
->index_buffer
, ib
, sizeof(rctx
->index_buffer
));
148 pipe_resource_reference(&rctx
->index_buffer
.buffer
, NULL
);
149 memset(&rctx
->index_buffer
, 0, sizeof(rctx
->index_buffer
));
152 /* TODO make this more like a state */
155 void r600_set_vertex_buffers(struct pipe_context
*ctx
, unsigned count
,
156 const struct pipe_vertex_buffer
*buffers
)
158 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
159 struct pipe_vertex_buffer
*vbo
;
160 unsigned max_index
= (unsigned)-1;
162 for (int i
= 0; i
< rctx
->nvertex_buffer
; i
++) {
163 pipe_resource_reference(&rctx
->vertex_buffer
[i
].buffer
, NULL
);
165 memcpy(rctx
->vertex_buffer
, buffers
, sizeof(struct pipe_vertex_buffer
) * count
);
167 for (int i
= 0; i
< count
; i
++) {
168 vbo
= (struct pipe_vertex_buffer
*)&buffers
[i
];
170 rctx
->vertex_buffer
[i
].buffer
= NULL
;
171 if (r600_buffer_is_user_buffer(buffers
[i
].buffer
))
172 rctx
->any_user_vbs
= TRUE
;
173 pipe_resource_reference(&rctx
->vertex_buffer
[i
].buffer
, buffers
[i
].buffer
);
175 if (vbo
->max_index
== ~0) {
179 vbo
->max_index
= (vbo
->buffer
->width0
- vbo
->buffer_offset
) / vbo
->stride
;
181 max_index
= MIN2(vbo
->max_index
, max_index
);
183 rctx
->nvertex_buffer
= count
;
184 rctx
->vb_max_index
= max_index
;
188 #define FORMAT_REPLACE(what, withwhat) \
189 case PIPE_FORMAT_##what: *format = PIPE_FORMAT_##withwhat; break
191 void *r600_create_vertex_elements(struct pipe_context
*ctx
,
193 const struct pipe_vertex_element
*elements
)
195 struct r600_vertex_element
*v
= CALLOC_STRUCT(r600_vertex_element
);
197 enum pipe_format
*format
;
204 memcpy(v
->elements
, elements
, count
* sizeof(struct pipe_vertex_element
));
206 for (i
= 0; i
< count
; i
++) {
207 v
->hw_format
[i
] = v
->elements
[i
].src_format
;
208 format
= &v
->hw_format
[i
];
211 FORMAT_REPLACE(R64_FLOAT
, R32_FLOAT
);
212 FORMAT_REPLACE(R64G64_FLOAT
, R32G32_FLOAT
);
213 FORMAT_REPLACE(R64G64B64_FLOAT
, R32G32B32_FLOAT
);
214 FORMAT_REPLACE(R64G64B64A64_FLOAT
, R32G32B32A32_FLOAT
);
217 v
->incompatible_layout
=
218 v
->incompatible_layout
||
219 v
->elements
[i
].src_format
!= v
->hw_format
[i
] ||
220 v
->elements
[i
].src_offset
% 4 != 0;
222 v
->hw_format_size
[i
] = align(util_format_get_blocksize(v
->hw_format
[i
]), 4);
228 void *r600_create_shader_state(struct pipe_context
*ctx
,
229 const struct pipe_shader_state
*state
)
231 struct r600_pipe_shader
*shader
= CALLOC_STRUCT(r600_pipe_shader
);
234 r
= r600_pipe_shader_create(ctx
, shader
, state
->tokens
);
241 void r600_bind_ps_shader(struct pipe_context
*ctx
, void *state
)
243 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
245 /* TODO delete old shader */
246 rctx
->ps_shader
= (struct r600_pipe_shader
*)state
;
249 void r600_bind_vs_shader(struct pipe_context
*ctx
, void *state
)
251 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
253 /* TODO delete old shader */
254 rctx
->vs_shader
= (struct r600_pipe_shader
*)state
;
257 void r600_delete_ps_shader(struct pipe_context
*ctx
, void *state
)
259 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
260 struct r600_pipe_shader
*shader
= (struct r600_pipe_shader
*)state
;
262 if (rctx
->ps_shader
== shader
) {
263 rctx
->ps_shader
= NULL
;
266 r600_pipe_shader_destroy(ctx
, shader
);
270 void r600_delete_vs_shader(struct pipe_context
*ctx
, void *state
)
272 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
273 struct r600_pipe_shader
*shader
= (struct r600_pipe_shader
*)state
;
275 if (rctx
->vs_shader
== shader
) {
276 rctx
->vs_shader
= NULL
;
279 r600_pipe_shader_destroy(ctx
, shader
);