Rev 4358 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4358 | Serge | 1 | /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ |
2 | |||
3 | /* |
||
4 | * Copyright (C) 2012 Rob Clark |
||
5 | * |
||
6 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
7 | * copy of this software and associated documentation files (the "Software"), |
||
8 | * to deal in the Software without restriction, including without limitation |
||
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||
10 | * and/or sell copies of the Software, and to permit persons to whom the |
||
11 | * Software is furnished to do so, subject to the following conditions: |
||
12 | * |
||
13 | * The above copyright notice and this permission notice (including the next |
||
14 | * paragraph) shall be included in all copies or substantial portions of the |
||
15 | * Software. |
||
16 | * |
||
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||
20 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||
23 | * SOFTWARE. |
||
24 | * |
||
25 | * Authors: |
||
26 | * Rob Clark |
||
27 | */ |
||
28 | |||
29 | #include "pipe/p_state.h" |
||
30 | #include "util/u_string.h" |
||
31 | #include "util/u_memory.h" |
||
32 | #include "util/u_helpers.h" |
||
33 | |||
34 | #include "freedreno_state.h" |
||
35 | #include "freedreno_context.h" |
||
36 | #include "freedreno_resource.h" |
||
37 | #include "freedreno_texture.h" |
||
38 | #include "freedreno_gmem.h" |
||
39 | #include "freedreno_util.h" |
||
40 | |||
41 | /* All the generic state handling.. In case of CSO's that are specific |
||
42 | * to the GPU version, when the bind and the delete are common they can |
||
43 | * go in here. |
||
44 | */ |
||
45 | |||
46 | static void |
||
47 | fd_set_blend_color(struct pipe_context *pctx, |
||
48 | const struct pipe_blend_color *blend_color) |
||
49 | { |
||
50 | struct fd_context *ctx = fd_context(pctx); |
||
51 | ctx->blend_color = *blend_color; |
||
52 | ctx->dirty |= FD_DIRTY_BLEND_COLOR; |
||
53 | } |
||
54 | |||
55 | static void |
||
56 | fd_set_stencil_ref(struct pipe_context *pctx, |
||
57 | const struct pipe_stencil_ref *stencil_ref) |
||
58 | { |
||
59 | struct fd_context *ctx = fd_context(pctx); |
||
60 | ctx->stencil_ref =* stencil_ref; |
||
61 | ctx->dirty |= FD_DIRTY_STENCIL_REF; |
||
62 | } |
||
63 | |||
64 | static void |
||
65 | fd_set_clip_state(struct pipe_context *pctx, |
||
66 | const struct pipe_clip_state *clip) |
||
67 | { |
||
68 | DBG("TODO: "); |
||
69 | } |
||
70 | |||
71 | static void |
||
72 | fd_set_sample_mask(struct pipe_context *pctx, unsigned sample_mask) |
||
73 | { |
||
74 | struct fd_context *ctx = fd_context(pctx); |
||
75 | ctx->sample_mask = (uint16_t)sample_mask; |
||
76 | ctx->dirty |= FD_DIRTY_SAMPLE_MASK; |
||
77 | } |
||
78 | |||
79 | /* notes from calim on #dri-devel: |
||
80 | * index==0 will be non-UBO (ie. glUniformXYZ()) all packed together padded |
||
81 | * out to vec4's |
||
82 | * I should be able to consider that I own the user_ptr until the next |
||
83 | * set_constant_buffer() call, at which point I don't really care about the |
||
84 | * previous values. |
||
85 | * index>0 will be UBO's.. well, I'll worry about that later |
||
86 | */ |
||
87 | static void |
||
88 | fd_set_constant_buffer(struct pipe_context *pctx, uint shader, uint index, |
||
89 | struct pipe_constant_buffer *cb) |
||
90 | { |
||
91 | struct fd_context *ctx = fd_context(pctx); |
||
92 | struct fd_constbuf_stateobj *so = &ctx->constbuf[shader]; |
||
93 | |||
94 | /* Note that the state tracker can unbind constant buffers by |
||
95 | * passing NULL here. |
||
96 | */ |
||
97 | if (unlikely(!cb)) { |
||
98 | so->enabled_mask &= ~(1 << index); |
||
99 | so->dirty_mask &= ~(1 << index); |
||
100 | pipe_resource_reference(&so->cb[index].buffer, NULL); |
||
101 | return; |
||
102 | } |
||
103 | |||
104 | pipe_resource_reference(&so->cb[index].buffer, cb->buffer); |
||
105 | so->cb[index].buffer_offset = cb->buffer_offset; |
||
106 | so->cb[index].buffer_size = cb->buffer_size; |
||
107 | so->cb[index].user_buffer = cb->user_buffer; |
||
108 | |||
109 | so->enabled_mask |= 1 << index; |
||
110 | so->dirty_mask |= 1 << index; |
||
111 | ctx->dirty |= FD_DIRTY_CONSTBUF; |
||
112 | } |
||
113 | |||
114 | static void |
||
115 | fd_set_framebuffer_state(struct pipe_context *pctx, |
||
116 | const struct pipe_framebuffer_state *framebuffer) |
||
117 | { |
||
118 | struct fd_context *ctx = fd_context(pctx); |
||
119 | struct pipe_framebuffer_state *cso = &ctx->framebuffer; |
||
120 | unsigned i; |
||
121 | |||
122 | DBG("%d: cbufs[0]=%p, zsbuf=%p", ctx->needs_flush, |
||
4401 | Serge | 123 | framebuffer->cbufs[0], framebuffer->zsbuf); |
4358 | Serge | 124 | |
125 | fd_context_render(pctx); |
||
126 | |||
127 | for (i = 0; i < framebuffer->nr_cbufs; i++) |
||
128 | pipe_surface_reference(&cso->cbufs[i], framebuffer->cbufs[i]); |
||
129 | for (; i < ctx->framebuffer.nr_cbufs; i++) |
||
130 | pipe_surface_reference(&cso->cbufs[i], NULL); |
||
131 | |||
132 | cso->nr_cbufs = framebuffer->nr_cbufs; |
||
133 | cso->width = framebuffer->width; |
||
134 | cso->height = framebuffer->height; |
||
135 | |||
136 | pipe_surface_reference(&cso->zsbuf, framebuffer->zsbuf); |
||
137 | |||
138 | ctx->dirty |= FD_DIRTY_FRAMEBUFFER; |
||
139 | |||
140 | ctx->disabled_scissor.minx = 0; |
||
141 | ctx->disabled_scissor.miny = 0; |
||
142 | ctx->disabled_scissor.maxx = cso->width; |
||
143 | ctx->disabled_scissor.maxy = cso->height; |
||
144 | |||
145 | ctx->dirty |= FD_DIRTY_SCISSOR; |
||
146 | } |
||
147 | |||
148 | static void |
||
149 | fd_set_polygon_stipple(struct pipe_context *pctx, |
||
150 | const struct pipe_poly_stipple *stipple) |
||
151 | { |
||
152 | struct fd_context *ctx = fd_context(pctx); |
||
153 | ctx->stipple = *stipple; |
||
154 | ctx->dirty |= FD_DIRTY_STIPPLE; |
||
155 | } |
||
156 | |||
157 | static void |
||
158 | fd_set_scissor_states(struct pipe_context *pctx, |
||
159 | unsigned start_slot, |
||
160 | unsigned num_scissors, |
||
161 | const struct pipe_scissor_state *scissor) |
||
162 | { |
||
163 | struct fd_context *ctx = fd_context(pctx); |
||
164 | |||
165 | ctx->scissor = *scissor; |
||
166 | ctx->dirty |= FD_DIRTY_SCISSOR; |
||
167 | } |
||
168 | |||
169 | static void |
||
170 | fd_set_viewport_states(struct pipe_context *pctx, |
||
171 | unsigned start_slot, |
||
172 | unsigned num_viewports, |
||
173 | const struct pipe_viewport_state *viewport) |
||
174 | { |
||
175 | struct fd_context *ctx = fd_context(pctx); |
||
176 | ctx->viewport = *viewport; |
||
177 | ctx->dirty |= FD_DIRTY_VIEWPORT; |
||
178 | } |
||
179 | |||
180 | static void |
||
181 | fd_set_vertex_buffers(struct pipe_context *pctx, |
||
182 | unsigned start_slot, unsigned count, |
||
183 | const struct pipe_vertex_buffer *vb) |
||
184 | { |
||
185 | struct fd_context *ctx = fd_context(pctx); |
||
186 | struct fd_vertexbuf_stateobj *so = &ctx->vertexbuf; |
||
187 | int i; |
||
188 | |||
189 | /* on a2xx, pitch is encoded in the vtx fetch instruction, so |
||
190 | * we need to mark VTXSTATE as dirty as well to trigger patching |
||
191 | * and re-emitting the vtx shader: |
||
192 | */ |
||
193 | for (i = 0; i < count; i++) { |
||
194 | bool new_enabled = vb && (vb[i].buffer || vb[i].user_buffer); |
||
195 | bool old_enabled = so->vb[i].buffer || so->vb[i].user_buffer; |
||
196 | uint32_t new_stride = vb ? vb[i].stride : 0; |
||
197 | uint32_t old_stride = so->vb[i].stride; |
||
198 | if ((new_enabled != old_enabled) || (new_stride != old_stride)) { |
||
199 | ctx->dirty |= FD_DIRTY_VTXSTATE; |
||
200 | break; |
||
201 | } |
||
202 | } |
||
203 | |||
204 | util_set_vertex_buffers_mask(so->vb, &so->enabled_mask, vb, start_slot, count); |
||
205 | so->count = util_last_bit(so->enabled_mask); |
||
206 | |||
207 | ctx->dirty |= FD_DIRTY_VTXBUF; |
||
208 | } |
||
209 | |||
210 | static void |
||
211 | fd_set_index_buffer(struct pipe_context *pctx, |
||
212 | const struct pipe_index_buffer *ib) |
||
213 | { |
||
214 | struct fd_context *ctx = fd_context(pctx); |
||
215 | |||
216 | if (ib) { |
||
217 | pipe_resource_reference(&ctx->indexbuf.buffer, ib->buffer); |
||
218 | ctx->indexbuf.index_size = ib->index_size; |
||
219 | ctx->indexbuf.offset = ib->offset; |
||
220 | ctx->indexbuf.user_buffer = ib->user_buffer; |
||
221 | } else { |
||
222 | pipe_resource_reference(&ctx->indexbuf.buffer, NULL); |
||
223 | } |
||
224 | |||
225 | ctx->dirty |= FD_DIRTY_INDEXBUF; |
||
226 | } |
||
227 | |||
228 | static void |
||
229 | fd_blend_state_bind(struct pipe_context *pctx, void *hwcso) |
||
230 | { |
||
231 | struct fd_context *ctx = fd_context(pctx); |
||
232 | ctx->blend = hwcso; |
||
233 | ctx->dirty |= FD_DIRTY_BLEND; |
||
234 | } |
||
235 | |||
236 | static void |
||
237 | fd_blend_state_delete(struct pipe_context *pctx, void *hwcso) |
||
238 | { |
||
239 | FREE(hwcso); |
||
240 | } |
||
241 | |||
242 | static void |
||
243 | fd_rasterizer_state_bind(struct pipe_context *pctx, void *hwcso) |
||
244 | { |
||
245 | struct fd_context *ctx = fd_context(pctx); |
||
246 | ctx->rasterizer = hwcso; |
||
247 | ctx->dirty |= FD_DIRTY_RASTERIZER; |
||
248 | } |
||
249 | |||
250 | static void |
||
251 | fd_rasterizer_state_delete(struct pipe_context *pctx, void *hwcso) |
||
252 | { |
||
253 | FREE(hwcso); |
||
254 | } |
||
255 | |||
256 | static void |
||
257 | fd_zsa_state_bind(struct pipe_context *pctx, void *hwcso) |
||
258 | { |
||
259 | struct fd_context *ctx = fd_context(pctx); |
||
260 | ctx->zsa = hwcso; |
||
261 | ctx->dirty |= FD_DIRTY_ZSA; |
||
262 | } |
||
263 | |||
264 | static void |
||
265 | fd_zsa_state_delete(struct pipe_context *pctx, void *hwcso) |
||
266 | { |
||
267 | FREE(hwcso); |
||
268 | } |
||
269 | |||
270 | static void * |
||
271 | fd_vertex_state_create(struct pipe_context *pctx, unsigned num_elements, |
||
272 | const struct pipe_vertex_element *elements) |
||
273 | { |
||
274 | struct fd_vertex_stateobj *so = CALLOC_STRUCT(fd_vertex_stateobj); |
||
275 | |||
276 | if (!so) |
||
277 | return NULL; |
||
278 | |||
279 | memcpy(so->pipe, elements, sizeof(*elements) * num_elements); |
||
280 | so->num_elements = num_elements; |
||
281 | |||
282 | return so; |
||
283 | } |
||
284 | |||
285 | static void |
||
286 | fd_vertex_state_delete(struct pipe_context *pctx, void *hwcso) |
||
287 | { |
||
288 | FREE(hwcso); |
||
289 | } |
||
290 | |||
291 | static void |
||
292 | fd_vertex_state_bind(struct pipe_context *pctx, void *hwcso) |
||
293 | { |
||
294 | struct fd_context *ctx = fd_context(pctx); |
||
295 | ctx->vtx = hwcso; |
||
296 | ctx->dirty |= FD_DIRTY_VTXSTATE; |
||
297 | } |
||
298 | |||
299 | void |
||
300 | fd_state_init(struct pipe_context *pctx) |
||
301 | { |
||
302 | pctx->set_blend_color = fd_set_blend_color; |
||
303 | pctx->set_stencil_ref = fd_set_stencil_ref; |
||
304 | pctx->set_clip_state = fd_set_clip_state; |
||
305 | pctx->set_sample_mask = fd_set_sample_mask; |
||
306 | pctx->set_constant_buffer = fd_set_constant_buffer; |
||
307 | pctx->set_framebuffer_state = fd_set_framebuffer_state; |
||
308 | pctx->set_polygon_stipple = fd_set_polygon_stipple; |
||
309 | pctx->set_scissor_states = fd_set_scissor_states; |
||
310 | pctx->set_viewport_states = fd_set_viewport_states; |
||
311 | |||
312 | pctx->set_vertex_buffers = fd_set_vertex_buffers; |
||
313 | pctx->set_index_buffer = fd_set_index_buffer; |
||
314 | |||
315 | pctx->bind_blend_state = fd_blend_state_bind; |
||
316 | pctx->delete_blend_state = fd_blend_state_delete; |
||
317 | |||
318 | pctx->bind_rasterizer_state = fd_rasterizer_state_bind; |
||
319 | pctx->delete_rasterizer_state = fd_rasterizer_state_delete; |
||
320 | |||
321 | pctx->bind_depth_stencil_alpha_state = fd_zsa_state_bind; |
||
322 | pctx->delete_depth_stencil_alpha_state = fd_zsa_state_delete; |
||
323 | |||
324 | pctx->create_vertex_elements_state = fd_vertex_state_create; |
||
325 | pctx->delete_vertex_elements_state = fd_vertex_state_delete; |
||
326 | pctx->bind_vertex_elements_state = fd_vertex_state_bind; |
||
327 | }>>>><>><>><>><> |