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