• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
lima_set_framebuffer_state(struct pipe_context * pctx,const struct pipe_framebuffer_state * framebuffer)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    /* make sure there are always single job in this context */
45    if (lima_debug & LIMA_DEBUG_SINGLE_JOB)
46       lima_flush(ctx);
47 
48    struct lima_context_framebuffer *fb = &ctx->framebuffer;
49 
50    util_copy_framebuffer_state(&fb->base, framebuffer);
51 
52    ctx->job = NULL;
53    ctx->dirty |= LIMA_CONTEXT_DIRTY_FRAMEBUFFER;
54 }
55 
56 static void
lima_set_polygon_stipple(struct pipe_context * pctx,const struct pipe_poly_stipple * stipple)57 lima_set_polygon_stipple(struct pipe_context *pctx,
58                          const struct pipe_poly_stipple *stipple)
59 {
60 
61 }
62 
63 static void *
lima_create_depth_stencil_alpha_state(struct pipe_context * pctx,const struct pipe_depth_stencil_alpha_state * cso)64 lima_create_depth_stencil_alpha_state(struct pipe_context *pctx,
65                                       const struct pipe_depth_stencil_alpha_state *cso)
66 {
67    struct lima_depth_stencil_alpha_state *so;
68 
69    so = CALLOC_STRUCT(lima_depth_stencil_alpha_state);
70    if (!so)
71       return NULL;
72 
73    so->base = *cso;
74 
75    return so;
76 }
77 
78 static void
lima_bind_depth_stencil_alpha_state(struct pipe_context * pctx,void * hwcso)79 lima_bind_depth_stencil_alpha_state(struct pipe_context *pctx, void *hwcso)
80 {
81    struct lima_context *ctx = lima_context(pctx);
82 
83    ctx->zsa = hwcso;
84    ctx->dirty |= LIMA_CONTEXT_DIRTY_ZSA;
85 }
86 
87 static void
lima_delete_depth_stencil_alpha_state(struct pipe_context * pctx,void * hwcso)88 lima_delete_depth_stencil_alpha_state(struct pipe_context *pctx, void *hwcso)
89 {
90    FREE(hwcso);
91 }
92 
93 static void *
lima_create_rasterizer_state(struct pipe_context * pctx,const struct pipe_rasterizer_state * cso)94 lima_create_rasterizer_state(struct pipe_context *pctx,
95                              const struct pipe_rasterizer_state *cso)
96 {
97    struct lima_rasterizer_state *so;
98 
99    so = CALLOC_STRUCT(lima_rasterizer_state);
100    if (!so)
101       return NULL;
102 
103    so->base = *cso;
104 
105    return so;
106 }
107 
108 static void
lima_bind_rasterizer_state(struct pipe_context * pctx,void * hwcso)109 lima_bind_rasterizer_state(struct pipe_context *pctx, void *hwcso)
110 {
111    struct lima_context *ctx = lima_context(pctx);
112 
113    ctx->rasterizer = hwcso;
114    ctx->dirty |= LIMA_CONTEXT_DIRTY_RASTERIZER;
115 }
116 
117 static void
lima_delete_rasterizer_state(struct pipe_context * pctx,void * hwcso)118 lima_delete_rasterizer_state(struct pipe_context *pctx, void *hwcso)
119 {
120    FREE(hwcso);
121 }
122 
123 static void *
lima_create_blend_state(struct pipe_context * pctx,const struct pipe_blend_state * cso)124 lima_create_blend_state(struct pipe_context *pctx,
125                         const struct pipe_blend_state *cso)
126 {
127    struct lima_blend_state *so;
128 
129    so = CALLOC_STRUCT(lima_blend_state);
130    if (!so)
131       return NULL;
132 
133    so->base = *cso;
134 
135    return so;
136 }
137 
138 static void
lima_bind_blend_state(struct pipe_context * pctx,void * hwcso)139 lima_bind_blend_state(struct pipe_context *pctx, void *hwcso)
140 {
141    struct lima_context *ctx = lima_context(pctx);
142 
143    ctx->blend = hwcso;
144    ctx->dirty |= LIMA_CONTEXT_DIRTY_BLEND;
145 }
146 
147 static void
lima_delete_blend_state(struct pipe_context * pctx,void * hwcso)148 lima_delete_blend_state(struct pipe_context *pctx, void *hwcso)
149 {
150    FREE(hwcso);
151 }
152 
153 static void *
lima_create_vertex_elements_state(struct pipe_context * pctx,unsigned num_elements,const struct pipe_vertex_element * elements)154 lima_create_vertex_elements_state(struct pipe_context *pctx, unsigned num_elements,
155                                   const struct pipe_vertex_element *elements)
156 {
157    struct lima_vertex_element_state *so;
158 
159    so = CALLOC_STRUCT(lima_vertex_element_state);
160    if (!so)
161       return NULL;
162 
163    memcpy(so->pipe, elements, sizeof(*elements) * num_elements);
164    so->num_elements = num_elements;
165 
166    return so;
167 }
168 
169 static void
lima_bind_vertex_elements_state(struct pipe_context * pctx,void * hwcso)170 lima_bind_vertex_elements_state(struct pipe_context *pctx, void *hwcso)
171 {
172    struct lima_context *ctx = lima_context(pctx);
173 
174    ctx->vertex_elements = hwcso;
175    ctx->dirty |= LIMA_CONTEXT_DIRTY_VERTEX_ELEM;
176 }
177 
178 static void
lima_delete_vertex_elements_state(struct pipe_context * pctx,void * hwcso)179 lima_delete_vertex_elements_state(struct pipe_context *pctx, void *hwcso)
180 {
181    FREE(hwcso);
182 }
183 
184 static void
lima_set_vertex_buffers(struct pipe_context * pctx,unsigned start_slot,unsigned count,const struct pipe_vertex_buffer * vb)185 lima_set_vertex_buffers(struct pipe_context *pctx,
186                         unsigned start_slot, unsigned count,
187                         const struct pipe_vertex_buffer *vb)
188 {
189    struct lima_context *ctx = lima_context(pctx);
190    struct lima_context_vertex_buffer *so = &ctx->vertex_buffers;
191 
192    util_set_vertex_buffers_mask(so->vb, &so->enabled_mask,
193                                 vb, start_slot, count);
194    so->count = util_last_bit(so->enabled_mask);
195 
196    ctx->dirty |= LIMA_CONTEXT_DIRTY_VERTEX_BUFF;
197 }
198 
199 static void
lima_set_viewport_states(struct pipe_context * pctx,unsigned start_slot,unsigned num_viewports,const struct pipe_viewport_state * viewport)200 lima_set_viewport_states(struct pipe_context *pctx,
201                          unsigned start_slot,
202                          unsigned num_viewports,
203                          const struct pipe_viewport_state *viewport)
204 {
205    struct lima_context *ctx = lima_context(pctx);
206 
207    /* reverse calculate the parameter of glViewport */
208    ctx->viewport.left = viewport->translate[0] - fabsf(viewport->scale[0]);
209    ctx->viewport.right = viewport->translate[0] + fabsf(viewport->scale[0]);
210    ctx->viewport.bottom = viewport->translate[1] - fabsf(viewport->scale[1]);
211    ctx->viewport.top = viewport->translate[1] + fabsf(viewport->scale[1]);
212 
213    /* reverse calculate the parameter of glDepthRange */
214    float near, far;
215    near = viewport->translate[2] - viewport->scale[2];
216    far = viewport->translate[2] + viewport->scale[2];
217 
218    ctx->viewport.near = MIN2(near, far);
219    ctx->viewport.far = MAX2(near, far);
220 
221    ctx->viewport.transform = *viewport;
222    ctx->dirty |= LIMA_CONTEXT_DIRTY_VIEWPORT;
223 }
224 
225 static void
lima_set_scissor_states(struct pipe_context * pctx,unsigned start_slot,unsigned num_scissors,const struct pipe_scissor_state * scissor)226 lima_set_scissor_states(struct pipe_context *pctx,
227                         unsigned start_slot,
228                         unsigned num_scissors,
229                         const struct pipe_scissor_state *scissor)
230 {
231    struct lima_context *ctx = lima_context(pctx);
232 
233    ctx->scissor = *scissor;
234    ctx->dirty |= LIMA_CONTEXT_DIRTY_SCISSOR;
235 }
236 
237 static void
lima_set_blend_color(struct pipe_context * pctx,const struct pipe_blend_color * blend_color)238 lima_set_blend_color(struct pipe_context *pctx,
239                      const struct pipe_blend_color *blend_color)
240 {
241    struct lima_context *ctx = lima_context(pctx);
242 
243    ctx->blend_color = *blend_color;
244    ctx->dirty |= LIMA_CONTEXT_DIRTY_BLEND_COLOR;
245 }
246 
247 static void
lima_set_stencil_ref(struct pipe_context * pctx,const struct pipe_stencil_ref * stencil_ref)248 lima_set_stencil_ref(struct pipe_context *pctx,
249                      const struct pipe_stencil_ref *stencil_ref)
250 {
251    struct lima_context *ctx = lima_context(pctx);
252 
253    ctx->stencil_ref = *stencil_ref;
254    ctx->dirty |= LIMA_CONTEXT_DIRTY_STENCIL_REF;
255 }
256 
257 static void
lima_set_constant_buffer(struct pipe_context * pctx,enum pipe_shader_type shader,uint index,const struct pipe_constant_buffer * cb)258 lima_set_constant_buffer(struct pipe_context *pctx,
259                          enum pipe_shader_type shader, uint index,
260                          const struct pipe_constant_buffer *cb)
261 {
262    struct lima_context *ctx = lima_context(pctx);
263    struct lima_context_constant_buffer *so = ctx->const_buffer + shader;
264 
265    assert(index == 0);
266 
267    if (unlikely(!cb)) {
268       so->buffer = NULL;
269       so->size = 0;
270    } else {
271       assert(!cb->buffer);
272 
273       so->buffer = cb->user_buffer + cb->buffer_offset;
274       so->size = cb->buffer_size;
275    }
276 
277    so->dirty = true;
278    ctx->dirty |= LIMA_CONTEXT_DIRTY_CONST_BUFF;
279 
280 }
281 
282 static void *
lima_create_sampler_state(struct pipe_context * pctx,const struct pipe_sampler_state * cso)283 lima_create_sampler_state(struct pipe_context *pctx,
284                          const struct pipe_sampler_state *cso)
285 {
286    struct lima_sampler_state *so = CALLOC_STRUCT(lima_sampler_state);
287    if (!so)
288       return NULL;
289 
290    memcpy(so, cso, sizeof(*cso));
291 
292    return so;
293 }
294 
295 static void
lima_sampler_state_delete(struct pipe_context * pctx,void * sstate)296 lima_sampler_state_delete(struct pipe_context *pctx, void *sstate)
297 {
298    free(sstate);
299 }
300 
301 static void
lima_sampler_states_bind(struct pipe_context * pctx,enum pipe_shader_type shader,unsigned start,unsigned nr,void ** hwcso)302 lima_sampler_states_bind(struct pipe_context *pctx,
303                         enum pipe_shader_type shader, unsigned start,
304                         unsigned nr, void **hwcso)
305 {
306    struct lima_context *ctx = lima_context(pctx);
307    struct lima_texture_stateobj *lima_tex = &ctx->tex_stateobj;
308    unsigned i;
309    unsigned new_nr = 0;
310 
311    assert(start == 0);
312 
313    for (i = 0; i < nr; i++) {
314       if (hwcso[i])
315          new_nr = i + 1;
316       lima_tex->samplers[i] = hwcso[i];
317    }
318 
319    for (; i < lima_tex->num_samplers; i++) {
320       lima_tex->samplers[i] = NULL;
321    }
322 
323    lima_tex->num_samplers = new_nr;
324    ctx->dirty |= LIMA_CONTEXT_DIRTY_TEXTURES;
325 }
326 
327 static struct pipe_sampler_view *
lima_create_sampler_view(struct pipe_context * pctx,struct pipe_resource * prsc,const struct pipe_sampler_view * cso)328 lima_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc,
329                         const struct pipe_sampler_view *cso)
330 {
331    struct lima_sampler_view *so = CALLOC_STRUCT(lima_sampler_view);
332 
333    if (!so)
334       return NULL;
335 
336    so->base = *cso;
337 
338    pipe_reference(NULL, &prsc->reference);
339    so->base.texture = prsc;
340    so->base.reference.count = 1;
341    so->base.context = pctx;
342 
343    return &so->base;
344 }
345 
346 static void
lima_sampler_view_destroy(struct pipe_context * pctx,struct pipe_sampler_view * pview)347 lima_sampler_view_destroy(struct pipe_context *pctx,
348                          struct pipe_sampler_view *pview)
349 {
350    struct lima_sampler_view *view = lima_sampler_view(pview);
351 
352    pipe_resource_reference(&pview->texture, NULL);
353 
354    free(view);
355 }
356 
357 static void
lima_set_sampler_views(struct pipe_context * pctx,enum pipe_shader_type shader,unsigned start,unsigned nr,struct pipe_sampler_view ** views)358 lima_set_sampler_views(struct pipe_context *pctx,
359                       enum pipe_shader_type shader,
360                       unsigned start, unsigned nr,
361                       struct pipe_sampler_view **views)
362 {
363    struct lima_context *ctx = lima_context(pctx);
364    struct lima_texture_stateobj *lima_tex = &ctx->tex_stateobj;
365    int i;
366    unsigned new_nr = 0;
367 
368    assert(start == 0);
369 
370    for (i = 0; i < nr; i++) {
371       if (views[i])
372          new_nr = i + 1;
373       pipe_sampler_view_reference(&lima_tex->textures[i], views[i]);
374    }
375 
376    for (; i < lima_tex->num_textures; i++) {
377       pipe_sampler_view_reference(&lima_tex->textures[i], NULL);
378    }
379 
380    lima_tex->num_textures = new_nr;
381    ctx->dirty |= LIMA_CONTEXT_DIRTY_TEXTURES;
382 }
383 
384 static void
lima_set_sample_mask(struct pipe_context * pctx,unsigned sample_mask)385 lima_set_sample_mask(struct pipe_context *pctx,
386                      unsigned sample_mask)
387 {
388 }
389 
390 void
lima_state_init(struct lima_context * ctx)391 lima_state_init(struct lima_context *ctx)
392 {
393    ctx->base.set_framebuffer_state = lima_set_framebuffer_state;
394    ctx->base.set_polygon_stipple = lima_set_polygon_stipple;
395    ctx->base.set_viewport_states = lima_set_viewport_states;
396    ctx->base.set_scissor_states = lima_set_scissor_states;
397    ctx->base.set_blend_color = lima_set_blend_color;
398    ctx->base.set_stencil_ref = lima_set_stencil_ref;
399 
400    ctx->base.set_vertex_buffers = lima_set_vertex_buffers;
401    ctx->base.set_constant_buffer = lima_set_constant_buffer;
402 
403    ctx->base.create_depth_stencil_alpha_state = lima_create_depth_stencil_alpha_state;
404    ctx->base.bind_depth_stencil_alpha_state = lima_bind_depth_stencil_alpha_state;
405    ctx->base.delete_depth_stencil_alpha_state = lima_delete_depth_stencil_alpha_state;
406 
407    ctx->base.create_rasterizer_state = lima_create_rasterizer_state;
408    ctx->base.bind_rasterizer_state = lima_bind_rasterizer_state;
409    ctx->base.delete_rasterizer_state = lima_delete_rasterizer_state;
410 
411    ctx->base.create_blend_state = lima_create_blend_state;
412    ctx->base.bind_blend_state = lima_bind_blend_state;
413    ctx->base.delete_blend_state = lima_delete_blend_state;
414 
415    ctx->base.create_vertex_elements_state = lima_create_vertex_elements_state;
416    ctx->base.bind_vertex_elements_state = lima_bind_vertex_elements_state;
417    ctx->base.delete_vertex_elements_state = lima_delete_vertex_elements_state;
418 
419    ctx->base.create_sampler_state = lima_create_sampler_state;
420    ctx->base.delete_sampler_state = lima_sampler_state_delete;
421    ctx->base.bind_sampler_states = lima_sampler_states_bind;
422 
423    ctx->base.create_sampler_view = lima_create_sampler_view;
424    ctx->base.sampler_view_destroy = lima_sampler_view_destroy;
425    ctx->base.set_sampler_views = lima_set_sampler_views;
426 
427    ctx->base.set_sample_mask = lima_set_sample_mask;
428 }
429 
430 void
lima_state_fini(struct lima_context * ctx)431 lima_state_fini(struct lima_context *ctx)
432 {
433    struct lima_context_vertex_buffer *so = &ctx->vertex_buffers;
434 
435    util_set_vertex_buffers_mask(so->vb, &so->enabled_mask, NULL,
436                                 0, ARRAY_SIZE(so->vb));
437 
438    pipe_surface_reference(&ctx->framebuffer.base.cbufs[0], NULL);
439    pipe_surface_reference(&ctx->framebuffer.base.zsbuf, NULL);
440 }
441