lima: track write submits of context (v3)
[mesa.git] / src / gallium / drivers / lima / lima_state.c
1 /*
2 * Copyright (c) 2011-2013 Luc Verhaegen <libv@skynet.be>
3 * Copyright (c) 2017-2019 Lima Project
4 *
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 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 */
25
26 #include "util/u_memory.h"
27 #include "util/u_inlines.h"
28 #include "util/u_helpers.h"
29 #include "util/u_debug.h"
30 #include "util/u_framebuffer.h"
31
32 #include "pipe/p_state.h"
33
34 #include "lima_screen.h"
35 #include "lima_context.h"
36 #include "lima_resource.h"
37
38 static void
39 lima_set_framebuffer_state(struct pipe_context *pctx,
40 const struct pipe_framebuffer_state *framebuffer)
41 {
42 struct lima_context *ctx = lima_context(pctx);
43
44 /* submit need framebuffer info, flush before change it */
45 lima_flush(ctx);
46
47 struct lima_context_framebuffer *fb = &ctx->framebuffer;
48
49 util_copy_framebuffer_state(&fb->base, framebuffer);
50
51 int width = align(framebuffer->width, 16) >> 4;
52 int height = align(framebuffer->height, 16) >> 4;
53 if (fb->tiled_w != width || fb->tiled_h != height) {
54 struct lima_screen *screen = lima_screen(ctx->base.screen);
55
56 fb->tiled_w = width;
57 fb->tiled_h = height;
58
59 fb->shift_h = 0;
60 fb->shift_w = 0;
61
62 int limit = screen->plb_max_blk;
63 while ((width * height) > limit) {
64 if (width >= height) {
65 width = (width + 1) >> 1;
66 fb->shift_w++;
67 } else {
68 height = (height + 1) >> 1;
69 fb->shift_h++;
70 }
71 }
72
73 fb->block_w = width;
74 fb->block_h = height;
75
76 fb->shift_min = MIN3(fb->shift_w, fb->shift_h, 2);
77
78 debug_printf("fb dim change tiled=%d/%d block=%d/%d shift=%d/%d/%d\n",
79 fb->tiled_w, fb->tiled_h, fb->block_w, fb->block_h,
80 fb->shift_w, fb->shift_h, fb->shift_min);
81 }
82
83 ctx->submit = NULL;
84 ctx->dirty |= LIMA_CONTEXT_DIRTY_FRAMEBUFFER;
85 }
86
87 static void
88 lima_set_polygon_stipple(struct pipe_context *pctx,
89 const struct pipe_poly_stipple *stipple)
90 {
91
92 }
93
94 static void *
95 lima_create_depth_stencil_alpha_state(struct pipe_context *pctx,
96 const struct pipe_depth_stencil_alpha_state *cso)
97 {
98 struct lima_depth_stencil_alpha_state *so;
99
100 so = CALLOC_STRUCT(lima_depth_stencil_alpha_state);
101 if (!so)
102 return NULL;
103
104 so->base = *cso;
105
106 return so;
107 }
108
109 static void
110 lima_bind_depth_stencil_alpha_state(struct pipe_context *pctx, void *hwcso)
111 {
112 struct lima_context *ctx = lima_context(pctx);
113
114 ctx->zsa = hwcso;
115 ctx->dirty |= LIMA_CONTEXT_DIRTY_ZSA;
116 }
117
118 static void
119 lima_delete_depth_stencil_alpha_state(struct pipe_context *pctx, void *hwcso)
120 {
121 FREE(hwcso);
122 }
123
124 static void *
125 lima_create_rasterizer_state(struct pipe_context *pctx,
126 const struct pipe_rasterizer_state *cso)
127 {
128 struct lima_rasterizer_state *so;
129
130 so = CALLOC_STRUCT(lima_rasterizer_state);
131 if (!so)
132 return NULL;
133
134 so->base = *cso;
135
136 return so;
137 }
138
139 static void
140 lima_bind_rasterizer_state(struct pipe_context *pctx, void *hwcso)
141 {
142 struct lima_context *ctx = lima_context(pctx);
143
144 ctx->rasterizer = hwcso;
145 ctx->dirty |= LIMA_CONTEXT_DIRTY_RASTERIZER;
146 }
147
148 static void
149 lima_delete_rasterizer_state(struct pipe_context *pctx, void *hwcso)
150 {
151 FREE(hwcso);
152 }
153
154 static void *
155 lima_create_blend_state(struct pipe_context *pctx,
156 const struct pipe_blend_state *cso)
157 {
158 struct lima_blend_state *so;
159
160 so = CALLOC_STRUCT(lima_blend_state);
161 if (!so)
162 return NULL;
163
164 so->base = *cso;
165
166 return so;
167 }
168
169 static void
170 lima_bind_blend_state(struct pipe_context *pctx, void *hwcso)
171 {
172 struct lima_context *ctx = lima_context(pctx);
173
174 ctx->blend = hwcso;
175 ctx->dirty |= LIMA_CONTEXT_DIRTY_BLEND;
176 }
177
178 static void
179 lima_delete_blend_state(struct pipe_context *pctx, void *hwcso)
180 {
181 FREE(hwcso);
182 }
183
184 static void *
185 lima_create_vertex_elements_state(struct pipe_context *pctx, unsigned num_elements,
186 const struct pipe_vertex_element *elements)
187 {
188 struct lima_vertex_element_state *so;
189
190 so = CALLOC_STRUCT(lima_vertex_element_state);
191 if (!so)
192 return NULL;
193
194 memcpy(so->pipe, elements, sizeof(*elements) * num_elements);
195 so->num_elements = num_elements;
196
197 return so;
198 }
199
200 static void
201 lima_bind_vertex_elements_state(struct pipe_context *pctx, void *hwcso)
202 {
203 struct lima_context *ctx = lima_context(pctx);
204
205 ctx->vertex_elements = hwcso;
206 ctx->dirty |= LIMA_CONTEXT_DIRTY_VERTEX_ELEM;
207 }
208
209 static void
210 lima_delete_vertex_elements_state(struct pipe_context *pctx, void *hwcso)
211 {
212 FREE(hwcso);
213 }
214
215 static void
216 lima_set_vertex_buffers(struct pipe_context *pctx,
217 unsigned start_slot, unsigned count,
218 const struct pipe_vertex_buffer *vb)
219 {
220 struct lima_context *ctx = lima_context(pctx);
221 struct lima_context_vertex_buffer *so = &ctx->vertex_buffers;
222
223 util_set_vertex_buffers_mask(so->vb, &so->enabled_mask,
224 vb, start_slot, count);
225 so->count = util_last_bit(so->enabled_mask);
226
227 ctx->dirty |= LIMA_CONTEXT_DIRTY_VERTEX_BUFF;
228 }
229
230 static void
231 lima_set_viewport_states(struct pipe_context *pctx,
232 unsigned start_slot,
233 unsigned num_viewports,
234 const struct pipe_viewport_state *viewport)
235 {
236 struct lima_context *ctx = lima_context(pctx);
237
238 /* reverse calculate the parameter of glViewport */
239 ctx->viewport.left = viewport->translate[0] - fabsf(viewport->scale[0]);
240 ctx->viewport.right = viewport->translate[0] + fabsf(viewport->scale[0]);
241 ctx->viewport.bottom = viewport->translate[1] - fabsf(viewport->scale[1]);
242 ctx->viewport.top = viewport->translate[1] + fabsf(viewport->scale[1]);
243
244 /* reverse calculate the parameter of glDepthRange */
245 float near, far;
246 near = viewport->translate[2] - viewport->scale[2];
247 far = viewport->translate[2] + viewport->scale[2];
248
249 ctx->viewport.near = MIN2(near, far);
250 ctx->viewport.far = MAX2(near, far);
251
252 ctx->viewport.transform = *viewport;
253 ctx->dirty |= LIMA_CONTEXT_DIRTY_VIEWPORT;
254 }
255
256 static void
257 lima_set_scissor_states(struct pipe_context *pctx,
258 unsigned start_slot,
259 unsigned num_scissors,
260 const struct pipe_scissor_state *scissor)
261 {
262 struct lima_context *ctx = lima_context(pctx);
263
264 ctx->scissor = *scissor;
265 ctx->dirty |= LIMA_CONTEXT_DIRTY_SCISSOR;
266 }
267
268 static void
269 lima_set_blend_color(struct pipe_context *pctx,
270 const struct pipe_blend_color *blend_color)
271 {
272 struct lima_context *ctx = lima_context(pctx);
273
274 ctx->blend_color = *blend_color;
275 ctx->dirty |= LIMA_CONTEXT_DIRTY_BLEND_COLOR;
276 }
277
278 static void
279 lima_set_stencil_ref(struct pipe_context *pctx,
280 const struct pipe_stencil_ref *stencil_ref)
281 {
282 struct lima_context *ctx = lima_context(pctx);
283
284 ctx->stencil_ref = *stencil_ref;
285 ctx->dirty |= LIMA_CONTEXT_DIRTY_STENCIL_REF;
286 }
287
288 static void
289 lima_set_constant_buffer(struct pipe_context *pctx,
290 enum pipe_shader_type shader, uint index,
291 const struct pipe_constant_buffer *cb)
292 {
293 struct lima_context *ctx = lima_context(pctx);
294 struct lima_context_constant_buffer *so = ctx->const_buffer + shader;
295
296 assert(index == 0);
297
298 if (unlikely(!cb)) {
299 so->buffer = NULL;
300 so->size = 0;
301 } else {
302 assert(!cb->buffer);
303
304 so->buffer = cb->user_buffer + cb->buffer_offset;
305 so->size = cb->buffer_size;
306 }
307
308 so->dirty = true;
309 ctx->dirty |= LIMA_CONTEXT_DIRTY_CONST_BUFF;
310
311 }
312
313 static void *
314 lima_create_sampler_state(struct pipe_context *pctx,
315 const struct pipe_sampler_state *cso)
316 {
317 struct lima_sampler_state *so = CALLOC_STRUCT(lima_sampler_state);
318 if (!so)
319 return NULL;
320
321 memcpy(so, cso, sizeof(*cso));
322
323 return so;
324 }
325
326 static void
327 lima_sampler_state_delete(struct pipe_context *pctx, void *sstate)
328 {
329 free(sstate);
330 }
331
332 static void
333 lima_sampler_states_bind(struct pipe_context *pctx,
334 enum pipe_shader_type shader, unsigned start,
335 unsigned nr, void **hwcso)
336 {
337 struct lima_context *ctx = lima_context(pctx);
338 struct lima_texture_stateobj *lima_tex = &ctx->tex_stateobj;
339 unsigned i;
340 unsigned new_nr = 0;
341
342 assert(start == 0);
343
344 for (i = 0; i < nr; i++) {
345 if (hwcso[i])
346 new_nr = i + 1;
347 lima_tex->samplers[i] = hwcso[i];
348 }
349
350 for (; i < lima_tex->num_samplers; i++) {
351 lima_tex->samplers[i] = NULL;
352 }
353
354 lima_tex->num_samplers = new_nr;
355 ctx->dirty |= LIMA_CONTEXT_DIRTY_TEXTURES;
356 }
357
358 static struct pipe_sampler_view *
359 lima_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc,
360 const struct pipe_sampler_view *cso)
361 {
362 struct lima_sampler_view *so = CALLOC_STRUCT(lima_sampler_view);
363
364 if (!so)
365 return NULL;
366
367 so->base = *cso;
368
369 pipe_reference(NULL, &prsc->reference);
370 so->base.texture = prsc;
371 so->base.reference.count = 1;
372 so->base.context = pctx;
373
374 return &so->base;
375 }
376
377 static void
378 lima_sampler_view_destroy(struct pipe_context *pctx,
379 struct pipe_sampler_view *pview)
380 {
381 struct lima_sampler_view *view = lima_sampler_view(pview);
382
383 pipe_resource_reference(&pview->texture, NULL);
384
385 free(view);
386 }
387
388 static void
389 lima_set_sampler_views(struct pipe_context *pctx,
390 enum pipe_shader_type shader,
391 unsigned start, unsigned nr,
392 struct pipe_sampler_view **views)
393 {
394 struct lima_context *ctx = lima_context(pctx);
395 struct lima_texture_stateobj *lima_tex = &ctx->tex_stateobj;
396 int i;
397 unsigned new_nr = 0;
398
399 assert(start == 0);
400
401 for (i = 0; i < nr; i++) {
402 if (views[i])
403 new_nr = i + 1;
404 pipe_sampler_view_reference(&lima_tex->textures[i], views[i]);
405 }
406
407 for (; i < lima_tex->num_textures; i++) {
408 pipe_sampler_view_reference(&lima_tex->textures[i], NULL);
409 }
410
411 lima_tex->num_textures = new_nr;
412 ctx->dirty |= LIMA_CONTEXT_DIRTY_TEXTURES;
413 }
414
415 static void
416 lima_set_sample_mask(struct pipe_context *pctx,
417 unsigned sample_mask)
418 {
419 }
420
421 void
422 lima_state_init(struct lima_context *ctx)
423 {
424 ctx->base.set_framebuffer_state = lima_set_framebuffer_state;
425 ctx->base.set_polygon_stipple = lima_set_polygon_stipple;
426 ctx->base.set_viewport_states = lima_set_viewport_states;
427 ctx->base.set_scissor_states = lima_set_scissor_states;
428 ctx->base.set_blend_color = lima_set_blend_color;
429 ctx->base.set_stencil_ref = lima_set_stencil_ref;
430
431 ctx->base.set_vertex_buffers = lima_set_vertex_buffers;
432 ctx->base.set_constant_buffer = lima_set_constant_buffer;
433
434 ctx->base.create_depth_stencil_alpha_state = lima_create_depth_stencil_alpha_state;
435 ctx->base.bind_depth_stencil_alpha_state = lima_bind_depth_stencil_alpha_state;
436 ctx->base.delete_depth_stencil_alpha_state = lima_delete_depth_stencil_alpha_state;
437
438 ctx->base.create_rasterizer_state = lima_create_rasterizer_state;
439 ctx->base.bind_rasterizer_state = lima_bind_rasterizer_state;
440 ctx->base.delete_rasterizer_state = lima_delete_rasterizer_state;
441
442 ctx->base.create_blend_state = lima_create_blend_state;
443 ctx->base.bind_blend_state = lima_bind_blend_state;
444 ctx->base.delete_blend_state = lima_delete_blend_state;
445
446 ctx->base.create_vertex_elements_state = lima_create_vertex_elements_state;
447 ctx->base.bind_vertex_elements_state = lima_bind_vertex_elements_state;
448 ctx->base.delete_vertex_elements_state = lima_delete_vertex_elements_state;
449
450 ctx->base.create_sampler_state = lima_create_sampler_state;
451 ctx->base.delete_sampler_state = lima_sampler_state_delete;
452 ctx->base.bind_sampler_states = lima_sampler_states_bind;
453
454 ctx->base.create_sampler_view = lima_create_sampler_view;
455 ctx->base.sampler_view_destroy = lima_sampler_view_destroy;
456 ctx->base.set_sampler_views = lima_set_sampler_views;
457
458 ctx->base.set_sample_mask = lima_set_sample_mask;
459 }
460
461 void
462 lima_state_fini(struct lima_context *ctx)
463 {
464 struct lima_context_vertex_buffer *so = &ctx->vertex_buffers;
465
466 util_set_vertex_buffers_mask(so->vb, &so->enabled_mask, NULL,
467 0, ARRAY_SIZE(so->vb));
468
469 pipe_surface_reference(&ctx->framebuffer.base.cbufs[0], NULL);
470 pipe_surface_reference(&ctx->framebuffer.base.zsbuf, NULL);
471 }