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"
30 #include "util/u_framebuffer.h"
32 #include "pipe/p_state.h"
34 #include "lima_screen.h"
35 #include "lima_context.h"
36 #include "lima_resource.h"
39 lima_set_framebuffer_state(struct pipe_context
*pctx
,
40 const struct pipe_framebuffer_state
*framebuffer
)
42 struct lima_context
*ctx
= lima_context(pctx
);
44 /* submit need framebuffer info, flush before change it */
47 struct lima_context_framebuffer
*fb
= &ctx
->framebuffer
;
49 util_copy_framebuffer_state(&fb
->base
, framebuffer
);
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
);
62 int limit
= screen
->plb_max_blk
;
63 while ((width
* height
) > limit
) {
64 if (width
>= height
) {
65 width
= (width
+ 1) >> 1;
68 height
= (height
+ 1) >> 1;
76 fb
->shift_min
= MIN3(fb
->shift_w
, fb
->shift_h
, 2);
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
);
84 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_FRAMEBUFFER
;
88 lima_set_polygon_stipple(struct pipe_context
*pctx
,
89 const struct pipe_poly_stipple
*stipple
)
95 lima_create_depth_stencil_alpha_state(struct pipe_context
*pctx
,
96 const struct pipe_depth_stencil_alpha_state
*cso
)
98 struct lima_depth_stencil_alpha_state
*so
;
100 so
= CALLOC_STRUCT(lima_depth_stencil_alpha_state
);
110 lima_bind_depth_stencil_alpha_state(struct pipe_context
*pctx
, void *hwcso
)
112 struct lima_context
*ctx
= lima_context(pctx
);
115 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_ZSA
;
119 lima_delete_depth_stencil_alpha_state(struct pipe_context
*pctx
, void *hwcso
)
125 lima_create_rasterizer_state(struct pipe_context
*pctx
,
126 const struct pipe_rasterizer_state
*cso
)
128 struct lima_rasterizer_state
*so
;
130 so
= CALLOC_STRUCT(lima_rasterizer_state
);
140 lima_bind_rasterizer_state(struct pipe_context
*pctx
, void *hwcso
)
142 struct lima_context
*ctx
= lima_context(pctx
);
144 ctx
->rasterizer
= hwcso
;
145 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_RASTERIZER
;
149 lima_delete_rasterizer_state(struct pipe_context
*pctx
, void *hwcso
)
155 lima_create_blend_state(struct pipe_context
*pctx
,
156 const struct pipe_blend_state
*cso
)
158 struct lima_blend_state
*so
;
160 so
= CALLOC_STRUCT(lima_blend_state
);
170 lima_bind_blend_state(struct pipe_context
*pctx
, void *hwcso
)
172 struct lima_context
*ctx
= lima_context(pctx
);
175 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_BLEND
;
179 lima_delete_blend_state(struct pipe_context
*pctx
, void *hwcso
)
185 lima_create_vertex_elements_state(struct pipe_context
*pctx
, unsigned num_elements
,
186 const struct pipe_vertex_element
*elements
)
188 struct lima_vertex_element_state
*so
;
190 so
= CALLOC_STRUCT(lima_vertex_element_state
);
194 memcpy(so
->pipe
, elements
, sizeof(*elements
) * num_elements
);
195 so
->num_elements
= num_elements
;
201 lima_bind_vertex_elements_state(struct pipe_context
*pctx
, void *hwcso
)
203 struct lima_context
*ctx
= lima_context(pctx
);
205 ctx
->vertex_elements
= hwcso
;
206 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_VERTEX_ELEM
;
210 lima_delete_vertex_elements_state(struct pipe_context
*pctx
, void *hwcso
)
216 lima_set_vertex_buffers(struct pipe_context
*pctx
,
217 unsigned start_slot
, unsigned count
,
218 const struct pipe_vertex_buffer
*vb
)
220 struct lima_context
*ctx
= lima_context(pctx
);
221 struct lima_context_vertex_buffer
*so
= &ctx
->vertex_buffers
;
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
);
227 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_VERTEX_BUFF
;
231 lima_set_viewport_states(struct pipe_context
*pctx
,
233 unsigned num_viewports
,
234 const struct pipe_viewport_state
*viewport
)
236 struct lima_context
*ctx
= lima_context(pctx
);
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]);
244 /* reverse calculate the parameter of glDepthRange */
246 near
= viewport
->translate
[2] - viewport
->scale
[2];
247 far
= viewport
->translate
[2] + viewport
->scale
[2];
249 ctx
->viewport
.near
= MIN2(near
, far
);
250 ctx
->viewport
.far
= MAX2(near
, far
);
252 ctx
->viewport
.transform
= *viewport
;
253 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_VIEWPORT
;
257 lima_set_scissor_states(struct pipe_context
*pctx
,
259 unsigned num_scissors
,
260 const struct pipe_scissor_state
*scissor
)
262 struct lima_context
*ctx
= lima_context(pctx
);
264 ctx
->scissor
= *scissor
;
265 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_SCISSOR
;
269 lima_set_blend_color(struct pipe_context
*pctx
,
270 const struct pipe_blend_color
*blend_color
)
272 struct lima_context
*ctx
= lima_context(pctx
);
274 ctx
->blend_color
= *blend_color
;
275 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_BLEND_COLOR
;
279 lima_set_stencil_ref(struct pipe_context
*pctx
,
280 const struct pipe_stencil_ref
*stencil_ref
)
282 struct lima_context
*ctx
= lima_context(pctx
);
284 ctx
->stencil_ref
= *stencil_ref
;
285 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_STENCIL_REF
;
289 lima_set_constant_buffer(struct pipe_context
*pctx
,
290 enum pipe_shader_type shader
, uint index
,
291 const struct pipe_constant_buffer
*cb
)
293 struct lima_context
*ctx
= lima_context(pctx
);
294 struct lima_context_constant_buffer
*so
= ctx
->const_buffer
+ shader
;
304 so
->buffer
= cb
->user_buffer
+ cb
->buffer_offset
;
305 so
->size
= cb
->buffer_size
;
309 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_CONST_BUFF
;
314 lima_create_sampler_state(struct pipe_context
*pctx
,
315 const struct pipe_sampler_state
*cso
)
317 struct lima_sampler_state
*so
= CALLOC_STRUCT(lima_sampler_state
);
321 memcpy(so
, cso
, sizeof(*cso
));
327 lima_sampler_state_delete(struct pipe_context
*pctx
, void *sstate
)
333 lima_sampler_states_bind(struct pipe_context
*pctx
,
334 enum pipe_shader_type shader
, unsigned start
,
335 unsigned nr
, void **hwcso
)
337 struct lima_context
*ctx
= lima_context(pctx
);
338 struct lima_texture_stateobj
*lima_tex
= &ctx
->tex_stateobj
;
344 for (i
= 0; i
< nr
; i
++) {
347 lima_tex
->samplers
[i
] = hwcso
[i
];
350 for (; i
< lima_tex
->num_samplers
; i
++) {
351 lima_tex
->samplers
[i
] = NULL
;
354 lima_tex
->num_samplers
= new_nr
;
355 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_TEXTURES
;
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
)
362 struct lima_sampler_view
*so
= CALLOC_STRUCT(lima_sampler_view
);
369 pipe_reference(NULL
, &prsc
->reference
);
370 so
->base
.texture
= prsc
;
371 so
->base
.reference
.count
= 1;
372 so
->base
.context
= pctx
;
378 lima_sampler_view_destroy(struct pipe_context
*pctx
,
379 struct pipe_sampler_view
*pview
)
381 struct lima_sampler_view
*view
= lima_sampler_view(pview
);
383 pipe_resource_reference(&pview
->texture
, NULL
);
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
)
394 struct lima_context
*ctx
= lima_context(pctx
);
395 struct lima_texture_stateobj
*lima_tex
= &ctx
->tex_stateobj
;
401 for (i
= 0; i
< nr
; i
++) {
404 pipe_sampler_view_reference(&lima_tex
->textures
[i
], views
[i
]);
407 for (; i
< lima_tex
->num_textures
; i
++) {
408 pipe_sampler_view_reference(&lima_tex
->textures
[i
], NULL
);
411 lima_tex
->num_textures
= new_nr
;
412 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_TEXTURES
;
416 lima_set_sample_mask(struct pipe_context
*pctx
,
417 unsigned sample_mask
)
422 lima_state_init(struct lima_context
*ctx
)
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
;
431 ctx
->base
.set_vertex_buffers
= lima_set_vertex_buffers
;
432 ctx
->base
.set_constant_buffer
= lima_set_constant_buffer
;
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
;
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
;
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
;
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
;
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
;
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
;
458 ctx
->base
.set_sample_mask
= lima_set_sample_mask
;
462 lima_state_fini(struct lima_context
*ctx
)
464 struct lima_context_vertex_buffer
*so
= &ctx
->vertex_buffers
;
466 util_set_vertex_buffers_mask(so
->vb
, &so
->enabled_mask
, NULL
,
467 0, ARRAY_SIZE(so
->vb
));
469 pipe_surface_reference(&ctx
->framebuffer
.base
.cbufs
[0], NULL
);
470 pipe_surface_reference(&ctx
->framebuffer
.base
.zsbuf
, NULL
);