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 */
251 ctx
->viewport
.near
= viewport
->translate
[2] - viewport
->scale
[2];
252 ctx
->viewport
.far
= viewport
->translate
[2] + viewport
->scale
[2];
254 ctx
->viewport
.transform
= *viewport
;
255 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_VIEWPORT
;
259 lima_set_scissor_states(struct pipe_context
*pctx
,
261 unsigned num_scissors
,
262 const struct pipe_scissor_state
*scissor
)
264 struct lima_context
*ctx
= lima_context(pctx
);
266 ctx
->scissor
= *scissor
;
267 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_SCISSOR
;
271 lima_set_blend_color(struct pipe_context
*pctx
,
272 const struct pipe_blend_color
*blend_color
)
274 struct lima_context
*ctx
= lima_context(pctx
);
276 ctx
->blend_color
= *blend_color
;
277 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_BLEND_COLOR
;
281 lima_set_stencil_ref(struct pipe_context
*pctx
,
282 const struct pipe_stencil_ref
*stencil_ref
)
284 struct lima_context
*ctx
= lima_context(pctx
);
286 ctx
->stencil_ref
= *stencil_ref
;
287 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_STENCIL_REF
;
291 lima_set_constant_buffer(struct pipe_context
*pctx
,
292 enum pipe_shader_type shader
, uint index
,
293 const struct pipe_constant_buffer
*cb
)
295 struct lima_context
*ctx
= lima_context(pctx
);
296 struct lima_context_constant_buffer
*so
= ctx
->const_buffer
+ shader
;
306 so
->buffer
= cb
->user_buffer
+ cb
->buffer_offset
;
307 so
->size
= cb
->buffer_size
;
311 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_CONST_BUFF
;
316 lima_create_sampler_state(struct pipe_context
*pctx
,
317 const struct pipe_sampler_state
*cso
)
319 struct lima_sampler_state
*so
= CALLOC_STRUCT(lima_sampler_state
);
323 memcpy(so
, cso
, sizeof(*cso
));
329 lima_sampler_state_delete(struct pipe_context
*pctx
, void *sstate
)
335 lima_sampler_states_bind(struct pipe_context
*pctx
,
336 enum pipe_shader_type shader
, unsigned start
,
337 unsigned nr
, void **hwcso
)
339 struct lima_context
*ctx
= lima_context(pctx
);
340 struct lima_texture_stateobj
*lima_tex
= &ctx
->tex_stateobj
;
346 for (i
= 0; i
< nr
; i
++) {
349 lima_tex
->samplers
[i
] = hwcso
[i
];
352 for (; i
< lima_tex
->num_samplers
; i
++) {
353 lima_tex
->samplers
[i
] = NULL
;
356 lima_tex
->num_samplers
= new_nr
;
357 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_TEXTURES
;
360 static struct pipe_sampler_view
*
361 lima_create_sampler_view(struct pipe_context
*pctx
, struct pipe_resource
*prsc
,
362 const struct pipe_sampler_view
*cso
)
364 struct lima_sampler_view
*so
= CALLOC_STRUCT(lima_sampler_view
);
371 pipe_reference(NULL
, &prsc
->reference
);
372 so
->base
.texture
= prsc
;
373 so
->base
.reference
.count
= 1;
374 so
->base
.context
= pctx
;
380 lima_sampler_view_destroy(struct pipe_context
*pctx
,
381 struct pipe_sampler_view
*pview
)
383 struct lima_sampler_view
*view
= lima_sampler_view(pview
);
385 pipe_resource_reference(&pview
->texture
, NULL
);
391 lima_set_sampler_views(struct pipe_context
*pctx
,
392 enum pipe_shader_type shader
,
393 unsigned start
, unsigned nr
,
394 struct pipe_sampler_view
**views
)
396 struct lima_context
*ctx
= lima_context(pctx
);
397 struct lima_texture_stateobj
*lima_tex
= &ctx
->tex_stateobj
;
403 for (i
= 0; i
< nr
; i
++) {
406 pipe_sampler_view_reference(&lima_tex
->textures
[i
], views
[i
]);
409 for (; i
< lima_tex
->num_textures
; i
++) {
410 pipe_sampler_view_reference(&lima_tex
->textures
[i
], NULL
);
413 lima_tex
->num_textures
= new_nr
;
414 ctx
->dirty
|= LIMA_CONTEXT_DIRTY_TEXTURES
;
418 lima_set_sample_mask(struct pipe_context
*pctx
,
419 unsigned sample_mask
)
424 lima_state_init(struct lima_context
*ctx
)
426 ctx
->base
.set_framebuffer_state
= lima_set_framebuffer_state
;
427 ctx
->base
.set_polygon_stipple
= lima_set_polygon_stipple
;
428 ctx
->base
.set_viewport_states
= lima_set_viewport_states
;
429 ctx
->base
.set_scissor_states
= lima_set_scissor_states
;
430 ctx
->base
.set_blend_color
= lima_set_blend_color
;
431 ctx
->base
.set_stencil_ref
= lima_set_stencil_ref
;
433 ctx
->base
.set_vertex_buffers
= lima_set_vertex_buffers
;
434 ctx
->base
.set_constant_buffer
= lima_set_constant_buffer
;
436 ctx
->base
.create_depth_stencil_alpha_state
= lima_create_depth_stencil_alpha_state
;
437 ctx
->base
.bind_depth_stencil_alpha_state
= lima_bind_depth_stencil_alpha_state
;
438 ctx
->base
.delete_depth_stencil_alpha_state
= lima_delete_depth_stencil_alpha_state
;
440 ctx
->base
.create_rasterizer_state
= lima_create_rasterizer_state
;
441 ctx
->base
.bind_rasterizer_state
= lima_bind_rasterizer_state
;
442 ctx
->base
.delete_rasterizer_state
= lima_delete_rasterizer_state
;
444 ctx
->base
.create_blend_state
= lima_create_blend_state
;
445 ctx
->base
.bind_blend_state
= lima_bind_blend_state
;
446 ctx
->base
.delete_blend_state
= lima_delete_blend_state
;
448 ctx
->base
.create_vertex_elements_state
= lima_create_vertex_elements_state
;
449 ctx
->base
.bind_vertex_elements_state
= lima_bind_vertex_elements_state
;
450 ctx
->base
.delete_vertex_elements_state
= lima_delete_vertex_elements_state
;
452 ctx
->base
.create_sampler_state
= lima_create_sampler_state
;
453 ctx
->base
.delete_sampler_state
= lima_sampler_state_delete
;
454 ctx
->base
.bind_sampler_states
= lima_sampler_states_bind
;
456 ctx
->base
.create_sampler_view
= lima_create_sampler_view
;
457 ctx
->base
.sampler_view_destroy
= lima_sampler_view_destroy
;
458 ctx
->base
.set_sampler_views
= lima_set_sampler_views
;
460 ctx
->base
.set_sample_mask
= lima_set_sample_mask
;
464 lima_state_fini(struct lima_context
*ctx
)
466 struct lima_context_vertex_buffer
*so
= &ctx
->vertex_buffers
;
468 util_set_vertex_buffers_mask(so
->vb
, &so
->enabled_mask
, NULL
,
469 0, ARRAY_SIZE(so
->vb
));
471 pipe_surface_reference(&ctx
->framebuffer
.base
.cbufs
[0], NULL
);
472 pipe_surface_reference(&ctx
->framebuffer
.base
.zsbuf
, NULL
);