Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2003 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 "i915_surface.h"
  29. #include "i915_resource.h"
  30. #include "i915_state.h"
  31. #include "i915_blit.h"
  32. #include "i915_reg.h"
  33. #include "i915_screen.h"
  34. #include "pipe/p_defines.h"
  35. #include "util/u_inlines.h"
  36. #include "util/u_math.h"
  37. #include "util/u_format.h"
  38. #include "util/u_memory.h"
  39. #include "util/u_pack_color.h"
  40. #include "util/u_surface.h"
  41.  
  42. static struct pipe_surface *
  43. i915_create_surface_custom(struct pipe_context *ctx,
  44.                            struct pipe_resource *pt,
  45.                            const struct pipe_surface *surf_tmpl,
  46.                            unsigned width0,
  47.                            unsigned height0);
  48. /*
  49.  * surface functions using the render engine
  50.  */
  51.  
  52. static void
  53. i915_util_blitter_save_states(struct i915_context *i915)
  54. {
  55.    util_blitter_save_blend(i915->blitter, (void *)i915->blend);
  56.    util_blitter_save_depth_stencil_alpha(i915->blitter, (void *)i915->depth_stencil);
  57.    util_blitter_save_stencil_ref(i915->blitter, &i915->stencil_ref);
  58.    util_blitter_save_rasterizer(i915->blitter, (void *)i915->rasterizer);
  59.    util_blitter_save_fragment_shader(i915->blitter, i915->fs);
  60.    util_blitter_save_vertex_shader(i915->blitter, i915->vs);
  61.    util_blitter_save_viewport(i915->blitter, &i915->viewport);
  62.    util_blitter_save_scissor(i915->blitter, &i915->scissor);
  63.    util_blitter_save_vertex_elements(i915->blitter, i915->velems);
  64.    util_blitter_save_vertex_buffer_slot(i915->blitter,
  65.                                     i915->vertex_buffers);
  66.  
  67.    util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer);
  68.  
  69.    util_blitter_save_fragment_sampler_states(i915->blitter,
  70.                                              i915->num_samplers,
  71.                                              (void**)i915->fragment_sampler);
  72.    util_blitter_save_fragment_sampler_views(i915->blitter,
  73.                                             i915->num_fragment_sampler_views,
  74.                                             i915->fragment_sampler_views);
  75. }
  76.  
  77. static void
  78. i915_surface_copy_render(struct pipe_context *pipe,
  79.                          struct pipe_resource *dst, unsigned dst_level,
  80.                          unsigned dstx, unsigned dsty, unsigned dstz,
  81.                          struct pipe_resource *src, unsigned src_level,
  82.                          const struct pipe_box *src_box)
  83. {
  84.    struct i915_context *i915 = i915_context(pipe);
  85.    unsigned src_width0 = src->width0;
  86.    unsigned src_height0 = src->height0;
  87.    unsigned dst_width0 = dst->width0;
  88.    unsigned dst_height0 = dst->height0;
  89.    struct pipe_box dstbox;
  90.    struct pipe_sampler_view src_templ, *src_view;
  91.    struct pipe_surface dst_templ, *dst_view;
  92.    const struct util_format_description *desc;
  93.  
  94.    /* Fallback for buffers. */
  95.    if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER)
  96.       goto fallback;
  97.  
  98.    /* Fallback for depth&stencil. XXX: see if we can use a proxy format */
  99.    desc = util_format_description(src->format);
  100.    if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)
  101.       goto fallback;
  102.  
  103.    desc = util_format_description(dst->format);
  104.    if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)
  105.       goto fallback;
  106.  
  107.    util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz);
  108.    util_blitter_default_src_texture(&src_templ, src, src_level);
  109.  
  110.    if (!util_blitter_is_copy_supported(i915->blitter, dst, src))
  111.       goto fallback;
  112.  
  113.    i915_util_blitter_save_states(i915);
  114.  
  115.    dst_view = i915_create_surface_custom(pipe, dst, &dst_templ, dst_width0, dst_height0);
  116.    src_view = i915_create_sampler_view_custom(pipe, src, &src_templ, src_width0, src_height0);
  117.  
  118.    u_box_3d(dstx, dsty, dstz, abs(src_box->width), abs(src_box->height),
  119.             abs(src_box->depth), &dstbox);
  120.  
  121.    util_blitter_blit_generic(i915->blitter, dst_view, &dstbox,
  122.                              src_view, src_box, src_width0, src_height0,
  123.                              PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL);
  124.    return;
  125.  
  126. fallback:
  127.    util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
  128.                              src, src_level, src_box);
  129. }
  130.  
  131. static void
  132. i915_clear_render_target_render(struct pipe_context *pipe,
  133.                                 struct pipe_surface *dst,
  134.                                 const union pipe_color_union *color,
  135.                                 unsigned dstx, unsigned dsty,
  136.                                 unsigned width, unsigned height)
  137. {
  138.    struct i915_context *i915 = i915_context(pipe);
  139.    struct pipe_framebuffer_state fb_state;
  140.  
  141.    util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer);
  142.  
  143.    fb_state.width = dst->width;
  144.    fb_state.height = dst->height;
  145.    fb_state.nr_cbufs = 1;
  146.    fb_state.cbufs[0] = dst;
  147.    fb_state.zsbuf = NULL;
  148.    pipe->set_framebuffer_state(pipe, &fb_state);
  149.  
  150.    if (i915->dirty)
  151.       i915_update_derived(i915);
  152.  
  153.    i915_clear_emit(pipe, PIPE_CLEAR_COLOR, color, 0.0, 0x0,
  154.                    dstx, dsty, width, height);
  155.  
  156.    pipe->set_framebuffer_state(pipe, &i915->blitter->saved_fb_state);
  157.    util_unreference_framebuffer_state(&i915->blitter->saved_fb_state);
  158.    i915->blitter->saved_fb_state.nr_cbufs = ~0;
  159. }
  160.  
  161. static void
  162. i915_clear_depth_stencil_render(struct pipe_context *pipe,
  163.                                 struct pipe_surface *dst,
  164.                                 unsigned clear_flags,
  165.                                 double depth,
  166.                                 unsigned stencil,
  167.                                 unsigned dstx, unsigned dsty,
  168.                                 unsigned width, unsigned height)
  169. {
  170.    struct i915_context *i915 = i915_context(pipe);
  171.    struct pipe_framebuffer_state fb_state;
  172.  
  173.    util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer);
  174.  
  175.    fb_state.width = dst->width;
  176.    fb_state.height = dst->height;
  177.    fb_state.nr_cbufs = 0;
  178.    fb_state.zsbuf = dst;
  179.    pipe->set_framebuffer_state(pipe, &fb_state);
  180.  
  181.    if (i915->dirty)
  182.       i915_update_derived(i915);
  183.  
  184.    i915_clear_emit(pipe, clear_flags & PIPE_CLEAR_DEPTHSTENCIL,
  185.                    NULL, depth, stencil,
  186.                    dstx, dsty, width, height);
  187.  
  188.    pipe->set_framebuffer_state(pipe, &i915->blitter->saved_fb_state);
  189.    util_unreference_framebuffer_state(&i915->blitter->saved_fb_state);
  190.    i915->blitter->saved_fb_state.nr_cbufs = ~0;
  191. }
  192.  
  193. /*
  194.  * surface functions using the blitter
  195.  */
  196.  
  197. /* Assumes all values are within bounds -- no checking at this level -
  198.  * do it higher up if required.
  199.  */
  200. static void
  201. i915_surface_copy_blitter(struct pipe_context *pipe,
  202.                           struct pipe_resource *dst, unsigned dst_level,
  203.                           unsigned dstx, unsigned dsty, unsigned dstz,
  204.                           struct pipe_resource *src, unsigned src_level,
  205.                           const struct pipe_box *src_box)
  206. {
  207.    struct i915_texture *dst_tex = i915_texture(dst);
  208.    struct i915_texture *src_tex = i915_texture(src);
  209.    struct pipe_resource *dpt = &dst_tex->b.b;
  210.    struct pipe_resource *spt = &src_tex->b.b;
  211.    unsigned dst_offset, src_offset;  /* in bytes */
  212.  
  213.    /* Fallback for buffers. */
  214.    if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
  215.       util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
  216.                                 src, src_level, src_box);
  217.       return;
  218.    }
  219.  
  220.    /* XXX cannot copy 3d regions at this time */
  221.    assert(src_box->depth == 1);
  222.    if (dst->target != PIPE_TEXTURE_CUBE &&
  223.        dst->target != PIPE_TEXTURE_3D)
  224.       assert(dstz == 0);
  225.    dst_offset = i915_texture_offset(dst_tex, dst_level, dstz);
  226.  
  227.    if (src->target != PIPE_TEXTURE_CUBE &&
  228.        src->target != PIPE_TEXTURE_3D)
  229.       assert(src_box->z == 0);
  230.    src_offset = i915_texture_offset(src_tex, src_level, src_box->z);
  231.  
  232.    assert( util_format_get_blocksize(dpt->format) == util_format_get_blocksize(spt->format) );
  233.    assert( util_format_get_blockwidth(dpt->format) == util_format_get_blockwidth(spt->format) );
  234.    assert( util_format_get_blockheight(dpt->format) == util_format_get_blockheight(spt->format) );
  235.    assert( util_format_get_blockwidth(dpt->format) == 1 );
  236.    assert( util_format_get_blockheight(dpt->format) == 1 );
  237.  
  238.    i915_copy_blit( i915_context(pipe),
  239.                    util_format_get_blocksize(dpt->format),
  240.                    (unsigned short) src_tex->stride, src_tex->buffer, src_offset,
  241.                    (unsigned short) dst_tex->stride, dst_tex->buffer, dst_offset,
  242.                    (short) src_box->x, (short) src_box->y, (short) dstx, (short) dsty,
  243.                    (short) src_box->width, (short) src_box->height );
  244. }
  245.  
  246. static void
  247. i915_blit(struct pipe_context *pipe, const struct pipe_blit_info *blit_info)
  248. {
  249.    struct i915_context *i915 = i915_context(pipe);
  250.    struct pipe_blit_info info = *blit_info;
  251.  
  252.    if (util_try_blit_via_copy_region(pipe, &info)) {
  253.       return; /* done */
  254.    }
  255.  
  256.    if (info.mask & PIPE_MASK_S) {
  257.       debug_printf("i915: cannot blit stencil, skipping\n");
  258.       info.mask &= ~PIPE_MASK_S;
  259.    }
  260.  
  261.    if (!util_blitter_is_blit_supported(i915->blitter, &info)) {
  262.       debug_printf("i915: blit unsupported %s -> %s\n",
  263.                    util_format_short_name(info.src.resource->format),
  264.                    util_format_short_name(info.dst.resource->format));
  265.       return;
  266.    }
  267.  
  268.    i915_util_blitter_save_states(i915);
  269.  
  270.    util_blitter_blit(i915->blitter, &info);
  271. }
  272.  
  273. static void
  274. i915_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource)
  275. {
  276. }
  277.  
  278. static void
  279. i915_clear_render_target_blitter(struct pipe_context *pipe,
  280.                                  struct pipe_surface *dst,
  281.                                  const union pipe_color_union *color,
  282.                                  unsigned dstx, unsigned dsty,
  283.                                  unsigned width, unsigned height)
  284. {
  285.    struct i915_texture *tex = i915_texture(dst->texture);
  286.    struct pipe_resource *pt = &tex->b.b;
  287.    union util_color uc;
  288.    unsigned offset = i915_texture_offset(tex, dst->u.tex.level, dst->u.tex.first_layer);
  289.  
  290.    assert(util_format_get_blockwidth(pt->format) == 1);
  291.    assert(util_format_get_blockheight(pt->format) == 1);
  292.  
  293.    util_pack_color(color->f, dst->format, &uc);
  294.    i915_fill_blit( i915_context(pipe),
  295.                    util_format_get_blocksize(pt->format),
  296.                    XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB,
  297.                    (unsigned short) tex->stride,
  298.                    tex->buffer, offset,
  299.                    (short) dstx, (short) dsty,
  300.                    (short) width, (short) height,
  301.                    uc.ui[0] );
  302. }
  303.  
  304. static void
  305. i915_clear_depth_stencil_blitter(struct pipe_context *pipe,
  306.                                  struct pipe_surface *dst,
  307.                                  unsigned clear_flags,
  308.                                  double depth,
  309.                                  unsigned stencil,
  310.                                  unsigned dstx, unsigned dsty,
  311.                                  unsigned width, unsigned height)
  312. {
  313.    struct i915_texture *tex = i915_texture(dst->texture);
  314.    struct pipe_resource *pt = &tex->b.b;
  315.    unsigned packedds;
  316.    unsigned mask = 0;
  317.    unsigned offset = i915_texture_offset(tex, dst->u.tex.level, dst->u.tex.first_layer);
  318.  
  319.    assert(util_format_get_blockwidth(pt->format) == 1);
  320.    assert(util_format_get_blockheight(pt->format) == 1);
  321.  
  322.    packedds = util_pack_z_stencil(dst->format, depth, stencil);
  323.  
  324.    if (clear_flags & PIPE_CLEAR_DEPTH)
  325.       mask |= XY_COLOR_BLT_WRITE_RGB;
  326.    /* XXX presumably this does read-modify-write
  327.       (otherwise this won't work anyway). Hence will only want to
  328.       do it if really have stencil and it isn't cleared */
  329.    if ((clear_flags & PIPE_CLEAR_STENCIL) ||
  330.        (dst->format != PIPE_FORMAT_Z24_UNORM_S8_UINT))
  331.       mask |= XY_COLOR_BLT_WRITE_ALPHA;
  332.  
  333.    i915_fill_blit( i915_context(pipe),
  334.                    util_format_get_blocksize(pt->format),
  335.                    mask,
  336.                    (unsigned short) tex->stride,
  337.                    tex->buffer, offset,
  338.                    (short) dstx, (short) dsty,
  339.                    (short) width, (short) height,
  340.                    packedds );
  341. }
  342.  
  343. /*
  344.  * Screen surface functions
  345.  */
  346.  
  347.  
  348. static struct pipe_surface *
  349. i915_create_surface_custom(struct pipe_context *ctx,
  350.                            struct pipe_resource *pt,
  351.                            const struct pipe_surface *surf_tmpl,
  352.                            unsigned width0,
  353.                            unsigned height0)
  354. {
  355.    struct pipe_surface *ps;
  356.  
  357.    assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
  358.    if (pt->target != PIPE_TEXTURE_CUBE &&
  359.        pt->target != PIPE_TEXTURE_3D)
  360.       assert(surf_tmpl->u.tex.first_layer == 0);
  361.  
  362.    ps = CALLOC_STRUCT(pipe_surface);
  363.    if (ps) {
  364.       /* could subclass pipe_surface and store offset as it used to do */
  365.       pipe_reference_init(&ps->reference, 1);
  366.       pipe_resource_reference(&ps->texture, pt);
  367.       ps->format = surf_tmpl->format;
  368.       ps->width = u_minify(width0, surf_tmpl->u.tex.level);
  369.       ps->height = u_minify(height0, surf_tmpl->u.tex.level);
  370.       ps->u.tex.level = surf_tmpl->u.tex.level;
  371.       ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
  372.       ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer;
  373.       ps->context = ctx;
  374.    }
  375.    return ps;
  376. }
  377.  
  378. static struct pipe_surface *
  379. i915_create_surface(struct pipe_context *ctx,
  380.                     struct pipe_resource *pt,
  381.                     const struct pipe_surface *surf_tmpl)
  382. {
  383.    return i915_create_surface_custom(ctx, pt, surf_tmpl,
  384.                                      pt->width0, pt->height0);
  385. }
  386.  
  387. static void
  388. i915_surface_destroy(struct pipe_context *ctx,
  389.                      struct pipe_surface *surf)
  390. {
  391.    pipe_resource_reference(&surf->texture, NULL);
  392.    FREE(surf);
  393. }
  394.  
  395.  
  396. void
  397. i915_init_surface_functions(struct i915_context *i915)
  398. {
  399.    if (i915_screen(i915->base.screen)->debug.use_blitter) {
  400.       i915->base.resource_copy_region = i915_surface_copy_blitter;
  401.       i915->base.clear_render_target = i915_clear_render_target_blitter;
  402.       i915->base.clear_depth_stencil = i915_clear_depth_stencil_blitter;
  403.    } else {
  404.       i915->base.resource_copy_region = i915_surface_copy_render;
  405.       i915->base.clear_render_target = i915_clear_render_target_render;
  406.       i915->base.clear_depth_stencil = i915_clear_depth_stencil_render;
  407.    }
  408.    i915->base.blit = i915_blit;
  409.    i915->base.flush_resource = i915_flush_resource;
  410.    i915->base.create_surface = i915_create_surface;
  411.    i915->base.surface_destroy = i915_surface_destroy;
  412. }
  413.