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
);
63 void r600_delete_rs_state(struct pipe_context
*ctx
, void *state
)
65 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
66 struct r600_pipe_rasterizer
*rs
= (struct r600_pipe_rasterizer
*)state
;
68 if (rctx
->rasterizer
== rs
) {
69 rctx
->rasterizer
= NULL
;
71 if (rctx
->states
[rs
->rstate
.id
] == &rs
->rstate
) {
72 rctx
->states
[rs
->rstate
.id
] = NULL
;
77 void r600_sampler_view_destroy(struct pipe_context
*ctx
,
78 struct pipe_sampler_view
*state
)
80 struct r600_pipe_sampler_view
*resource
= (struct r600_pipe_sampler_view
*)state
;
82 pipe_resource_reference(&state
->texture
, NULL
);
86 void r600_bind_state(struct pipe_context
*ctx
, void *state
)
88 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
89 struct r600_pipe_state
*rstate
= (struct r600_pipe_state
*)state
;
93 rctx
->states
[rstate
->id
] = rstate
;
94 r600_context_pipe_state_set(&rctx
->ctx
, rstate
);
97 void r600_delete_state(struct pipe_context
*ctx
, void *state
)
99 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
100 struct r600_pipe_state
*rstate
= (struct r600_pipe_state
*)state
;
102 if (rctx
->states
[rstate
->id
] == rstate
) {
103 rctx
->states
[rstate
->id
] = NULL
;
105 for (int i
= 0; i
< rstate
->nregs
; i
++) {
106 r600_bo_reference(rctx
->radeon
, &rstate
->regs
[i
].bo
, NULL
);
111 void r600_bind_vertex_elements(struct pipe_context
*ctx
, void *state
)
113 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
114 struct r600_vertex_element
*v
= (struct r600_vertex_element
*)state
;
116 rctx
->vertex_elements
= v
;
118 // rctx->vs_rebuild = TRUE;
122 void r600_delete_vertex_element(struct pipe_context
*ctx
, void *state
)
124 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
128 if (rctx
->vertex_elements
== state
)
129 rctx
->vertex_elements
= NULL
;
133 void r600_set_index_buffer(struct pipe_context
*ctx
,
134 const struct pipe_index_buffer
*ib
)
136 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
139 pipe_resource_reference(&rctx
->index_buffer
.buffer
, ib
->buffer
);
140 memcpy(&rctx
->index_buffer
, ib
, sizeof(rctx
->index_buffer
));
142 pipe_resource_reference(&rctx
->index_buffer
.buffer
, NULL
);
143 memset(&rctx
->index_buffer
, 0, sizeof(rctx
->index_buffer
));
146 /* TODO make this more like a state */
149 void r600_set_vertex_buffers(struct pipe_context
*ctx
, unsigned count
,
150 const struct pipe_vertex_buffer
*buffers
)
152 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
153 struct pipe_vertex_buffer
*vbo
;
154 unsigned max_index
= (unsigned)-1;
156 for (int i
= 0; i
< rctx
->nvertex_buffer
; i
++) {
157 pipe_resource_reference(&rctx
->vertex_buffer
[i
].buffer
, NULL
);
159 memcpy(rctx
->vertex_buffer
, buffers
, sizeof(struct pipe_vertex_buffer
) * count
);
161 for (int i
= 0; i
< count
; i
++) {
162 vbo
= (struct pipe_vertex_buffer
*)&buffers
[i
];
164 rctx
->vertex_buffer
[i
].buffer
= NULL
;
165 if (r600_buffer_is_user_buffer(buffers
[i
].buffer
))
166 rctx
->any_user_vbs
= TRUE
;
167 pipe_resource_reference(&rctx
->vertex_buffer
[i
].buffer
, buffers
[i
].buffer
);
169 if (vbo
->max_index
== ~0) {
173 vbo
->max_index
= (vbo
->buffer
->width0
- vbo
->buffer_offset
) / vbo
->stride
;
175 max_index
= MIN2(vbo
->max_index
, max_index
);
177 rctx
->nvertex_buffer
= count
;
178 rctx
->vb_max_index
= max_index
;
182 #define FORMAT_REPLACE(what, withwhat) \
183 case PIPE_FORMAT_##what: *format = PIPE_FORMAT_##withwhat; break
185 void *r600_create_vertex_elements(struct pipe_context
*ctx
,
187 const struct pipe_vertex_element
*elements
)
189 struct r600_vertex_element
*v
= CALLOC_STRUCT(r600_vertex_element
);
191 enum pipe_format
*format
;
198 memcpy(v
->elements
, elements
, count
* sizeof(struct pipe_vertex_element
));
200 for (i
= 0; i
< count
; i
++) {
201 v
->hw_format
[i
] = v
->elements
[i
].src_format
;
202 format
= &v
->hw_format
[i
];
205 FORMAT_REPLACE(R64_FLOAT
, R32_FLOAT
);
206 FORMAT_REPLACE(R64G64_FLOAT
, R32G32_FLOAT
);
207 FORMAT_REPLACE(R64G64B64_FLOAT
, R32G32B32_FLOAT
);
208 FORMAT_REPLACE(R64G64B64A64_FLOAT
, R32G32B32A32_FLOAT
);
211 v
->incompatible_layout
=
212 v
->incompatible_layout
||
213 v
->elements
[i
].src_format
!= v
->hw_format
[i
] ||
214 v
->elements
[i
].src_offset
% 4 != 0;
216 v
->hw_format_size
[i
] = align(util_format_get_blocksize(v
->hw_format
[i
]), 4);
222 void *r600_create_shader_state(struct pipe_context
*ctx
,
223 const struct pipe_shader_state
*state
)
225 struct r600_pipe_shader
*shader
= CALLOC_STRUCT(r600_pipe_shader
);
228 r
= r600_pipe_shader_create(ctx
, shader
, state
->tokens
);
235 void r600_bind_ps_shader(struct pipe_context
*ctx
, void *state
)
237 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
239 /* TODO delete old shader */
240 rctx
->ps_shader
= (struct r600_pipe_shader
*)state
;
243 void r600_bind_vs_shader(struct pipe_context
*ctx
, void *state
)
245 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
247 /* TODO delete old shader */
248 rctx
->vs_shader
= (struct r600_pipe_shader
*)state
;
251 void r600_delete_ps_shader(struct pipe_context
*ctx
, void *state
)
253 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
254 struct r600_pipe_shader
*shader
= (struct r600_pipe_shader
*)state
;
256 if (rctx
->ps_shader
== shader
) {
257 rctx
->ps_shader
= NULL
;
260 r600_pipe_shader_destroy(ctx
, shader
);
264 void r600_delete_vs_shader(struct pipe_context
*ctx
, void *state
)
266 struct r600_pipe_context
*rctx
= (struct r600_pipe_context
*)ctx
;
267 struct r600_pipe_shader
*shader
= (struct r600_pipe_shader
*)state
;
269 if (rctx
->vs_shader
== shader
) {
270 rctx
->vs_shader
= NULL
;
273 r600_pipe_shader_destroy(ctx
, shader
);