Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2007 VMware, Inc.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28. #include "util/u_rect.h"
  29. #include "util/u_surface.h"
  30. #include "lp_context.h"
  31. #include "lp_flush.h"
  32. #include "lp_limits.h"
  33. #include "lp_surface.h"
  34. #include "lp_texture.h"
  35. #include "lp_query.h"
  36.  
  37.  
  38. static void
  39. lp_resource_copy(struct pipe_context *pipe,
  40.                  struct pipe_resource *dst, unsigned dst_level,
  41.                  unsigned dstx, unsigned dsty, unsigned dstz,
  42.                  struct pipe_resource *src, unsigned src_level,
  43.                  const struct pipe_box *src_box)
  44. {
  45.    struct llvmpipe_resource *src_tex = llvmpipe_resource(src);
  46.    struct llvmpipe_resource *dst_tex = llvmpipe_resource(dst);
  47.    const enum pipe_format format = src_tex->base.format;
  48.    unsigned width = src_box->width;
  49.    unsigned height = src_box->height;
  50.    unsigned depth = src_box->depth;
  51.  
  52.    llvmpipe_flush_resource(pipe,
  53.                            dst, dst_level,
  54.                            FALSE, /* read_only */
  55.                            TRUE, /* cpu_access */
  56.                            FALSE, /* do_not_block */
  57.                            "blit dest");
  58.  
  59.    llvmpipe_flush_resource(pipe,
  60.                            src, src_level,
  61.                            TRUE, /* read_only */
  62.                            TRUE, /* cpu_access */
  63.                            FALSE, /* do_not_block */
  64.                            "blit src");
  65.  
  66.    /* Fallback for buffers. */
  67.    if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
  68.       util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
  69.                                 src, src_level, src_box);
  70.       return;
  71.    }
  72.  
  73.    /*
  74.    printf("surface copy from %u lvl %u to %u lvl %u: %u,%u,%u to %u,%u,%u %u x %u x %u\n",
  75.           src_tex->id, src_level, dst_tex->id, dst_level,
  76.           src_box->x, src_box->y, src_box->z, dstx, dsty, dstz,
  77.           src_box->width, src_box->height, src_box->depth);
  78.    */
  79.  
  80.    /* make sure display target resources (which cannot have levels/layers) are mapped */
  81.    if (src_tex->dt)
  82.       (void) llvmpipe_resource_map(src, src_level, 0, LP_TEX_USAGE_READ);
  83.    if (dst_tex->dt)
  84.       /*
  85.        * Could set this to WRITE_ALL if complete dst is covered but it gets
  86.        * ignored anyway.
  87.        */
  88.       (void) llvmpipe_resource_map(dst, dst_level, 0, LP_TEX_USAGE_READ_WRITE);
  89.  
  90.  
  91.    /* copy */
  92.    {
  93.       const ubyte *src_linear_ptr
  94.          = llvmpipe_get_texture_image_address(src_tex, src_box->z,
  95.                                               src_level);
  96.       ubyte *dst_linear_ptr
  97.          = llvmpipe_get_texture_image_address(dst_tex, dstz,
  98.                                               dst_level);
  99.  
  100.       if (dst_linear_ptr && src_linear_ptr) {
  101.          util_copy_box(dst_linear_ptr, format,
  102.                        llvmpipe_resource_stride(&dst_tex->base, dst_level),
  103.                        dst_tex->img_stride[dst_level],
  104.                        dstx, dsty, 0,
  105.                        width, height, depth,
  106.                        src_linear_ptr,
  107.                        llvmpipe_resource_stride(&src_tex->base, src_level),
  108.                        src_tex->img_stride[src_level],
  109.                        src_box->x, src_box->y, 0);
  110.       }
  111.    }
  112.  
  113.    if (src_tex->dt)
  114.       llvmpipe_resource_unmap(src, 0, 0);
  115.    if (dst_tex->dt)
  116.       llvmpipe_resource_unmap(dst, 0, 0);
  117.  
  118. }
  119.  
  120.  
  121. static void lp_blit(struct pipe_context *pipe,
  122.                     const struct pipe_blit_info *blit_info)
  123. {
  124.    struct llvmpipe_context *lp = llvmpipe_context(pipe);
  125.    struct pipe_blit_info info = *blit_info;
  126.  
  127.    if (blit_info->render_condition_enable && !llvmpipe_check_render_cond(lp))
  128.       return;
  129.  
  130.    if (info.src.resource->nr_samples > 1 &&
  131.        info.dst.resource->nr_samples <= 1 &&
  132.        !util_format_is_depth_or_stencil(info.src.resource->format) &&
  133.        !util_format_is_pure_integer(info.src.resource->format)) {
  134.       debug_printf("llvmpipe: color resolve unimplemented\n");
  135.       return;
  136.    }
  137.  
  138.    if (util_try_blit_via_copy_region(pipe, &info)) {
  139.       return; /* done */
  140.    }
  141.  
  142.    if (info.mask & PIPE_MASK_S) {
  143.       debug_printf("llvmpipe: cannot blit stencil, skipping\n");
  144.       info.mask &= ~PIPE_MASK_S;
  145.    }
  146.  
  147.    if (!util_blitter_is_blit_supported(lp->blitter, &info)) {
  148.       debug_printf("llvmpipe: blit unsupported %s -> %s\n",
  149.                    util_format_short_name(info.src.resource->format),
  150.                    util_format_short_name(info.dst.resource->format));
  151.       return;
  152.    }
  153.  
  154.    /* XXX turn off occlusion and streamout queries */
  155.  
  156.    util_blitter_save_vertex_buffer_slot(lp->blitter, lp->vertex_buffer);
  157.    util_blitter_save_vertex_elements(lp->blitter, (void*)lp->velems);
  158.    util_blitter_save_vertex_shader(lp->blitter, (void*)lp->vs);
  159.    util_blitter_save_geometry_shader(lp->blitter, (void*)lp->gs);
  160.    util_blitter_save_so_targets(lp->blitter, lp->num_so_targets,
  161.                                 (struct pipe_stream_output_target**)lp->so_targets);
  162.    util_blitter_save_rasterizer(lp->blitter, (void*)lp->rasterizer);
  163.    util_blitter_save_viewport(lp->blitter, &lp->viewports[0]);
  164.    util_blitter_save_scissor(lp->blitter, &lp->scissors[0]);
  165.    util_blitter_save_fragment_shader(lp->blitter, lp->fs);
  166.    util_blitter_save_blend(lp->blitter, (void*)lp->blend);
  167.    util_blitter_save_depth_stencil_alpha(lp->blitter, (void*)lp->depth_stencil);
  168.    util_blitter_save_stencil_ref(lp->blitter, &lp->stencil_ref);
  169.    /*util_blitter_save_sample_mask(sp->blitter, lp->sample_mask);*/
  170.    util_blitter_save_framebuffer(lp->blitter, &lp->framebuffer);
  171.    util_blitter_save_fragment_sampler_states(lp->blitter,
  172.                      lp->num_samplers[PIPE_SHADER_FRAGMENT],
  173.                      (void**)lp->samplers[PIPE_SHADER_FRAGMENT]);
  174.    util_blitter_save_fragment_sampler_views(lp->blitter,
  175.                      lp->num_sampler_views[PIPE_SHADER_FRAGMENT],
  176.                      lp->sampler_views[PIPE_SHADER_FRAGMENT]);
  177.    util_blitter_save_render_condition(lp->blitter, lp->render_cond_query,
  178.                                       lp->render_cond_cond, lp->render_cond_mode);
  179.    util_blitter_blit(lp->blitter, &info);
  180. }
  181.  
  182.  
  183. static void
  184. lp_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource)
  185. {
  186. }
  187.  
  188.  
  189. static struct pipe_surface *
  190. llvmpipe_create_surface(struct pipe_context *pipe,
  191.                         struct pipe_resource *pt,
  192.                         const struct pipe_surface *surf_tmpl)
  193. {
  194.    struct pipe_surface *ps;
  195.  
  196.    if (!(pt->bind & (PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_RENDER_TARGET)))
  197.       debug_printf("Illegal surface creation without bind flag\n");
  198.  
  199.    ps = CALLOC_STRUCT(pipe_surface);
  200.    if (ps) {
  201.       pipe_reference_init(&ps->reference, 1);
  202.       pipe_resource_reference(&ps->texture, pt);
  203.       ps->context = pipe;
  204.       ps->format = surf_tmpl->format;
  205.       if (llvmpipe_resource_is_texture(pt)) {
  206.          assert(surf_tmpl->u.tex.level <= pt->last_level);
  207.          assert(surf_tmpl->u.tex.first_layer <= surf_tmpl->u.tex.last_layer);
  208.          ps->width = u_minify(pt->width0, surf_tmpl->u.tex.level);
  209.          ps->height = u_minify(pt->height0, surf_tmpl->u.tex.level);
  210.          ps->u.tex.level = surf_tmpl->u.tex.level;
  211.          ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
  212.          ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer;
  213.       }
  214.       else {
  215.          /* setting width as number of elements should get us correct renderbuffer width */
  216.          ps->width = surf_tmpl->u.buf.last_element - surf_tmpl->u.buf.first_element + 1;
  217.          ps->height = pt->height0;
  218.          ps->u.buf.first_element = surf_tmpl->u.buf.first_element;
  219.          ps->u.buf.last_element = surf_tmpl->u.buf.last_element;
  220.          assert(ps->u.buf.first_element <= ps->u.buf.last_element);
  221.          assert(util_format_get_blocksize(surf_tmpl->format) *
  222.                 (ps->u.buf.last_element + 1) <= pt->width0);
  223.       }
  224.    }
  225.    return ps;
  226. }
  227.  
  228.  
  229. static void
  230. llvmpipe_surface_destroy(struct pipe_context *pipe,
  231.                          struct pipe_surface *surf)
  232. {
  233.    /* Effectively do the texture_update work here - if texture images
  234.     * needed post-processing to put them into hardware layout, this is
  235.     * where it would happen.  For llvmpipe, nothing to do.
  236.     */
  237.    assert(surf->texture);
  238.    pipe_resource_reference(&surf->texture, NULL);
  239.    FREE(surf);
  240. }
  241.  
  242.  
  243. static void
  244. llvmpipe_clear_render_target(struct pipe_context *pipe,
  245.                              struct pipe_surface *dst,
  246.                              const union pipe_color_union *color,
  247.                              unsigned dstx, unsigned dsty,
  248.                              unsigned width, unsigned height)
  249. {
  250.    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
  251.  
  252.    if (!llvmpipe_check_render_cond(llvmpipe))
  253.       return;
  254.  
  255.    util_clear_render_target(pipe, dst, color,
  256.                             dstx, dsty, width, height);
  257. }
  258.  
  259.  
  260. static void
  261. llvmpipe_clear_depth_stencil(struct pipe_context *pipe,
  262.                              struct pipe_surface *dst,
  263.                              unsigned clear_flags,
  264.                              double depth,
  265.                              unsigned stencil,
  266.                              unsigned dstx, unsigned dsty,
  267.                              unsigned width, unsigned height)
  268. {
  269.    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
  270.  
  271.    if (!llvmpipe_check_render_cond(llvmpipe))
  272.       return;
  273.  
  274.    util_clear_depth_stencil(pipe, dst, clear_flags,
  275.                             depth, stencil,
  276.                             dstx, dsty, width, height);
  277. }
  278.  
  279.  
  280. void
  281. llvmpipe_init_surface_functions(struct llvmpipe_context *lp)
  282. {
  283.    lp->pipe.clear_render_target = llvmpipe_clear_render_target;
  284.    lp->pipe.clear_depth_stencil = llvmpipe_clear_depth_stencil;
  285.    lp->pipe.create_surface = llvmpipe_create_surface;
  286.    lp->pipe.surface_destroy = llvmpipe_surface_destroy;
  287.    /* These two are not actually functions dealing with surfaces */
  288.    lp->pipe.resource_copy_region = lp_resource_copy;
  289.    lp->pipe.blit = lp_blit;
  290.    lp->pipe.flush_resource = lp_flush_resource;
  291. }
  292.