2 * Copyright (c) 2011-2013 Luc Verhaegen <libv@skynet.be>
3 * Copyright (c) 2017-2019 Lima Project
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:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
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.
26 #include "util/u_memory.h"
27 #include "util/u_inlines.h"
28 #include "util/u_helpers.h"
29 #include "util/u_debug.h"
31 #include "pipe/p_state.h"
33 #include "lima_screen.h"
34 #include "lima_context.h"
35 #include "lima_resource.h"
38 lima_set_framebuffer_state(struct pipe_context
*pctx
,
39 const struct pipe_framebuffer_state
*framebuffer
)
41 struct lima_context
*ctx
= lima_context(pctx
);
43 /* submit need framebuffer info, flush before change it */
46 struct lima_context_framebuffer
*fb
= &ctx
->framebuffer
;
48 fb
->base
.samples
= framebuffer
->samples
;
50 fb
->base
.nr_cbufs
= framebuffer
->nr_cbufs
;
51 pipe_surface_reference(&fb
->base
.cbufs
[0], framebuffer
->cbufs
[0]);
52 pipe_surface_reference(&fb
->base
.zsbuf
, framebuffer
->zsbuf
);
54 /* need align here? */
55 fb
->base
.width
= framebuffer
->width
;
56 fb
->base
.height
= framebuffer
->height
;
58 int width
= align(framebuffer
->width
, 16) >> 4;
59 int height
= align(framebuffer
->height
, 16) >> 4;
60 if (fb
->tiled_w
!= width
|| fb
->tiled_h
!= height
) {
61 struct lima_screen
*screen
= lima_screen(ctx
->base
.screen
);
69 int limit
= screen
->plb_max_blk
;
70 while ((width
* height
) > limit
) {
71 if (width
>= height
) {
72 width
= (width
+ 1) >> 1;
75 height
= (height
+ 1) >> 1;
83 fb
->shift_min
= MIN3(fb
->shift_w
, fb
->shift_h
, 2);
85 debug_printf("fb dim change tiled=%d/%d block=%d/%d shift=%d/%d/%d\n",
86 fb
->tiled_w
, fb
->tiled_h
, fb
->block_w
, fb
->block_h
,
87 fb
->shift_w
, fb
->shift_h
, fb
->shift_min
);
90 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_FRAMEBUFFER
;
94 lima_set_polygon_stipple(struct pipe_context
*pctx
,
95 const struct pipe_poly_stipple
*stipple
)
101 lima_create_depth_stencil_alpha_state(struct pipe_context
*pctx
,
102 const struct pipe_depth_stencil_alpha_state
*cso
)
104 struct lima_depth_stencil_alpha_state
*so
;
106 so
= CALLOC_STRUCT(lima_depth_stencil_alpha_state
);
116 lima_bind_depth_stencil_alpha_state(struct pipe_context
*pctx
, void *hwcso
)
118 struct lima_context
*ctx
= lima_context(pctx
);
121 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_ZSA
;
125 lima_delete_depth_stencil_alpha_state(struct pipe_context
*pctx
, void *hwcso
)
131 lima_create_rasterizer_state(struct pipe_context
*pctx
,
132 const struct pipe_rasterizer_state
*cso
)
134 struct lima_rasterizer_state
*so
;
136 so
= CALLOC_STRUCT(lima_rasterizer_state
);
146 lima_bind_rasterizer_state(struct pipe_context
*pctx
, void *hwcso
)
148 struct lima_context
*ctx
= lima_context(pctx
);
150 ctx
->rasterizer
= hwcso
;
151 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_RASTERIZER
;
155 lima_delete_rasterizer_state(struct pipe_context
*pctx
, void *hwcso
)
161 lima_create_blend_state(struct pipe_context
*pctx
,
162 const struct pipe_blend_state
*cso
)
164 struct lima_blend_state
*so
;
166 so
= CALLOC_STRUCT(lima_blend_state
);
176 lima_bind_blend_state(struct pipe_context
*pctx
, void *hwcso
)
178 struct lima_context
*ctx
= lima_context(pctx
);
181 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_BLEND
;
185 lima_delete_blend_state(struct pipe_context
*pctx
, void *hwcso
)
191 lima_create_vertex_elements_state(struct pipe_context
*pctx
, unsigned num_elements
,
192 const struct pipe_vertex_element
*elements
)
194 struct lima_vertex_element_state
*so
;
196 so
= CALLOC_STRUCT(lima_vertex_element_state
);
200 memcpy(so
->pipe
, elements
, sizeof(*elements
) * num_elements
);
201 so
->num_elements
= num_elements
;
207 lima_bind_vertex_elements_state(struct pipe_context
*pctx
, void *hwcso
)
209 struct lima_context
*ctx
= lima_context(pctx
);
211 ctx
->vertex_elements
= hwcso
;
212 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_VERTEX_ELEM
;
216 lima_delete_vertex_elements_state(struct pipe_context
*pctx
, void *hwcso
)
222 lima_set_vertex_buffers(struct pipe_context
*pctx
,
223 unsigned start_slot
, unsigned count
,
224 const struct pipe_vertex_buffer
*vb
)
226 struct lima_context
*ctx
= lima_context(pctx
);
227 struct lima_context_vertex_buffer
*so
= &ctx
->vertex_buffers
;
229 util_set_vertex_buffers_mask(so
->vb
+ start_slot
, &so
->enabled_mask
,
230 vb
, start_slot
, count
);
231 so
->count
= util_last_bit(so
->enabled_mask
);
233 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_VERTEX_BUFF
;
237 lima_set_viewport_states(struct pipe_context
*pctx
,
239 unsigned num_viewports
,
240 const struct pipe_viewport_state
*viewport
)
242 struct lima_context
*ctx
= lima_context(pctx
);
244 /* reverse calculate the parameter of glViewport */
245 ctx
->viewport
.left
= viewport
->translate
[0] - fabsf(viewport
->scale
[0]);
246 ctx
->viewport
.right
= viewport
->translate
[0] + fabsf(viewport
->scale
[0]);
247 ctx
->viewport
.bottom
= viewport
->translate
[1] - fabsf(viewport
->scale
[1]);
248 ctx
->viewport
.top
= viewport
->translate
[1] + fabsf(viewport
->scale
[1]);
250 /* reverse calculate the parameter of glDepthRange */
252 near
= viewport
->translate
[2] - viewport
->scale
[2];
253 far
= viewport
->translate
[2] + viewport
->scale
[2];
255 ctx
->viewport
.near
= MIN2(near
, far
);
256 ctx
->viewport
.far
= MAX2(near
, far
);
258 ctx
->viewport
.transform
= *viewport
;
259 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_VIEWPORT
;
263 lima_set_scissor_states(struct pipe_context
*pctx
,
265 unsigned num_scissors
,
266 const struct pipe_scissor_state
*scissor
)
268 struct lima_context
*ctx
= lima_context(pctx
);
270 ctx
->scissor
= *scissor
;
271 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_SCISSOR
;
275 lima_set_blend_color(struct pipe_context
*pctx
,
276 const struct pipe_blend_color
*blend_color
)
278 struct lima_context
*ctx
= lima_context(pctx
);
280 ctx
->blend_color
= *blend_color
;
281 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_BLEND_COLOR
;
285 lima_set_stencil_ref(struct pipe_context
*pctx
,
286 const struct pipe_stencil_ref
*stencil_ref
)
288 struct lima_context
*ctx
= lima_context(pctx
);
290 ctx
->stencil_ref
= *stencil_ref
;
291 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_STENCIL_REF
;
295 lima_set_constant_buffer(struct pipe_context
*pctx
,
296 enum pipe_shader_type shader
, uint index
,
297 const struct pipe_constant_buffer
*cb
)
299 struct lima_context
*ctx
= lima_context(pctx
);
300 struct lima_context_constant_buffer
*so
= ctx
->const_buffer
+ shader
;
310 so
->buffer
= cb
->user_buffer
+ cb
->buffer_offset
;
311 so
->size
= cb
->buffer_size
;
315 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_CONST_BUFF
;
320 lima_create_sampler_state(struct pipe_context
*pctx
,
321 const struct pipe_sampler_state
*cso
)
323 struct lima_sampler_state
*so
= CALLOC_STRUCT(lima_sampler_state
);
327 memcpy(so
, cso
, sizeof(*cso
));
333 lima_sampler_state_delete(struct pipe_context
*pctx
, void *sstate
)
339 lima_sampler_states_bind(struct pipe_context
*pctx
,
340 enum pipe_shader_type shader
, unsigned start
,
341 unsigned nr
, void **hwcso
)
343 struct lima_context
*ctx
= lima_context(pctx
);
344 struct lima_texture_stateobj
*lima_tex
= &ctx
->tex_stateobj
;
350 for (i
= 0; i
< nr
; i
++) {
353 lima_tex
->samplers
[i
] = hwcso
[i
];
356 for (; i
< lima_tex
->num_samplers
; i
++) {
357 lima_tex
->samplers
[i
] = NULL
;
360 lima_tex
->num_samplers
= new_nr
;
361 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_TEXTURES
;
364 static struct pipe_sampler_view
*
365 lima_create_sampler_view(struct pipe_context
*pctx
, struct pipe_resource
*prsc
,
366 const struct pipe_sampler_view
*cso
)
368 struct lima_sampler_view
*so
= CALLOC_STRUCT(lima_sampler_view
);
375 pipe_reference(NULL
, &prsc
->reference
);
376 so
->base
.texture
= prsc
;
377 so
->base
.reference
.count
= 1;
378 so
->base
.context
= pctx
;
384 lima_sampler_view_destroy(struct pipe_context
*pctx
,
385 struct pipe_sampler_view
*pview
)
387 struct lima_sampler_view
*view
= lima_sampler_view(pview
);
389 pipe_resource_reference(&pview
->texture
, NULL
);
395 lima_set_sampler_views(struct pipe_context
*pctx
,
396 enum pipe_shader_type shader
,
397 unsigned start
, unsigned nr
,
398 struct pipe_sampler_view
**views
)
400 struct lima_context
*ctx
= lima_context(pctx
);
401 struct lima_texture_stateobj
*lima_tex
= &ctx
->tex_stateobj
;
407 for (i
= 0; i
< nr
; i
++) {
410 pipe_sampler_view_reference(&lima_tex
->textures
[i
], views
[i
]);
413 for (; i
< lima_tex
->num_textures
; i
++) {
414 pipe_sampler_view_reference(&lima_tex
->textures
[i
], NULL
);
417 lima_tex
->num_textures
= new_nr
;
418 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_TEXTURES
;
422 lima_set_sample_mask(struct pipe_context
*pctx
,
423 unsigned sample_mask
)
428 lima_state_init(struct lima_context
*ctx
)
430 ctx
->base
.set_framebuffer_state
= lima_set_framebuffer_state
;
431 ctx
->base
.set_polygon_stipple
= lima_set_polygon_stipple
;
432 ctx
->base
.set_viewport_states
= lima_set_viewport_states
;
433 ctx
->base
.set_scissor_states
= lima_set_scissor_states
;
434 ctx
->base
.set_blend_color
= lima_set_blend_color
;
435 ctx
->base
.set_stencil_ref
= lima_set_stencil_ref
;
437 ctx
->base
.set_vertex_buffers
= lima_set_vertex_buffers
;
438 ctx
->base
.set_constant_buffer
= lima_set_constant_buffer
;
440 ctx
->base
.create_depth_stencil_alpha_state
= lima_create_depth_stencil_alpha_state
;
441 ctx
->base
.bind_depth_stencil_alpha_state
= lima_bind_depth_stencil_alpha_state
;
442 ctx
->base
.delete_depth_stencil_alpha_state
= lima_delete_depth_stencil_alpha_state
;
444 ctx
->base
.create_rasterizer_state
= lima_create_rasterizer_state
;
445 ctx
->base
.bind_rasterizer_state
= lima_bind_rasterizer_state
;
446 ctx
->base
.delete_rasterizer_state
= lima_delete_rasterizer_state
;
448 ctx
->base
.create_blend_state
= lima_create_blend_state
;
449 ctx
->base
.bind_blend_state
= lima_bind_blend_state
;
450 ctx
->base
.delete_blend_state
= lima_delete_blend_state
;
452 ctx
->base
.create_vertex_elements_state
= lima_create_vertex_elements_state
;
453 ctx
->base
.bind_vertex_elements_state
= lima_bind_vertex_elements_state
;
454 ctx
->base
.delete_vertex_elements_state
= lima_delete_vertex_elements_state
;
456 ctx
->base
.create_sampler_state
= lima_create_sampler_state
;
457 ctx
->base
.delete_sampler_state
= lima_sampler_state_delete
;
458 ctx
->base
.bind_sampler_states
= lima_sampler_states_bind
;
460 ctx
->base
.create_sampler_view
= lima_create_sampler_view
;
461 ctx
->base
.sampler_view_destroy
= lima_sampler_view_destroy
;
462 ctx
->base
.set_sampler_views
= lima_set_sampler_views
;
464 ctx
->base
.set_sample_mask
= lima_set_sample_mask
;
468 lima_state_fini(struct lima_context
*ctx
)
470 struct lima_context_vertex_buffer
*so
= &ctx
->vertex_buffers
;
472 util_set_vertex_buffers_mask(so
->vb
, &so
->enabled_mask
, NULL
,
473 0, ARRAY_SIZE(so
->vb
));
475 pipe_surface_reference(&ctx
->framebuffer
.base
.cbufs
[0], NULL
);
476 pipe_surface_reference(&ctx
->framebuffer
.base
.zsbuf
, NULL
);