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