Subversion Repositories Kolibri OS

Rev

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

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