Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright 2012 Red Hat Inc.
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice shall be included in
  12.  * all copies or substantial portions of the Software.
  13.  *
  14.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20.  * OTHER DEALINGS IN THE SOFTWARE.
  21.  *
  22.  * Authors: Ben Skeggs
  23.  *
  24.  */
  25.  
  26. #include "pipe/p_defines.h"
  27. #include "util/u_pack_color.h"
  28.  
  29. #include "nouveau/nouveau_gldefs.h"
  30. #include "nouveau/nv_object.xml.h"
  31. #include "nv30-40_3d.xml.h"
  32. #include "nv30_context.h"
  33. #include "nv30_format.h"
  34.  
  35. static INLINE uint32_t
  36. pack_rgba(enum pipe_format format, const float *rgba)
  37. {
  38.    union util_color uc;
  39.    util_pack_color(rgba, format, &uc);
  40.    return uc.ui;
  41. }
  42.  
  43. static INLINE uint32_t
  44. pack_zeta(enum pipe_format format, double depth, unsigned stencil)
  45. {
  46.    uint32_t zuint = (uint32_t)(depth * 4294967295.0);
  47.    if (format != PIPE_FORMAT_Z16_UNORM)
  48.       return (zuint & 0xffffff00) | (stencil & 0xff);
  49.    return zuint >> 16;
  50. }
  51.  
  52. static void
  53. nv30_clear(struct pipe_context *pipe, unsigned buffers,
  54.            const union pipe_color_union *color, double depth, unsigned stencil)
  55. {
  56.    struct nv30_context *nv30 = nv30_context(pipe);
  57.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  58.    struct pipe_framebuffer_state *fb = &nv30->framebuffer;
  59.    uint32_t colr = 0, zeta = 0, mode = 0;
  60.  
  61.    if (!nv30_state_validate(nv30, TRUE))
  62.       return;
  63.  
  64.    if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
  65.       colr  = pack_rgba(fb->cbufs[0]->format, color->f);
  66.       mode |= NV30_3D_CLEAR_BUFFERS_COLOR_R |
  67.               NV30_3D_CLEAR_BUFFERS_COLOR_G |
  68.               NV30_3D_CLEAR_BUFFERS_COLOR_B |
  69.               NV30_3D_CLEAR_BUFFERS_COLOR_A;
  70.    }
  71.  
  72.    if (fb->zsbuf) {
  73.       zeta = pack_zeta(fb->zsbuf->format, depth, stencil);
  74.       if (buffers & PIPE_CLEAR_DEPTH)
  75.          mode |= NV30_3D_CLEAR_BUFFERS_DEPTH;
  76.       if (buffers & PIPE_CLEAR_STENCIL)
  77.          mode |= NV30_3D_CLEAR_BUFFERS_STENCIL;
  78.    }
  79.  
  80.    /*XXX: wtf? fixes clears sometimes not clearing on nv3x... */
  81.    if (nv30->screen->eng3d->oclass < NV40_3D_CLASS) {
  82.       BEGIN_NV04(push, NV30_3D(CLEAR_DEPTH_VALUE), 3);
  83.       PUSH_DATA (push, zeta);
  84.       PUSH_DATA (push, colr);
  85.       PUSH_DATA (push, mode);
  86.    }
  87.  
  88.    BEGIN_NV04(push, NV30_3D(CLEAR_DEPTH_VALUE), 3);
  89.    PUSH_DATA (push, zeta);
  90.    PUSH_DATA (push, colr);
  91.    PUSH_DATA (push, mode);
  92.  
  93.    nv30_state_release(nv30);
  94. }
  95.  
  96. static void
  97. nv30_clear_render_target(struct pipe_context *pipe, struct pipe_surface *ps,
  98.                          const union pipe_color_union *color,
  99.                          unsigned x, unsigned y, unsigned w, unsigned h)
  100. {
  101.    struct nv30_context *nv30 = nv30_context(pipe);
  102.    struct nv30_surface *sf = nv30_surface(ps);
  103.    struct nv30_miptree *mt = nv30_miptree(ps->texture);
  104.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  105.    struct nouveau_object *eng3d = nv30->screen->eng3d;
  106.    struct nouveau_pushbuf_refn refn;
  107.    uint32_t rt_format;
  108.  
  109.    rt_format = nv30_format(pipe->screen, ps->format)->hw;
  110.    if (util_format_get_blocksize(ps->format) == 4)
  111.       rt_format |= NV30_3D_RT_FORMAT_ZETA_Z24S8;
  112.    else
  113.       rt_format |= NV30_3D_RT_FORMAT_ZETA_Z16;
  114.  
  115.    if (nv30_miptree(ps->texture)->swizzled) {
  116.       rt_format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED;
  117.       rt_format |= util_logbase2(sf->width) << 16;
  118.       rt_format |= util_logbase2(sf->height) << 24;
  119.    } else {
  120.       rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
  121.    }
  122.  
  123.    refn.bo = mt->base.bo;
  124.    refn.flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR;
  125.    if (nouveau_pushbuf_space(push, 16, 1, 0) ||
  126.        nouveau_pushbuf_refn (push, &refn, 1))
  127.       return;
  128.  
  129.    BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
  130.    PUSH_DATA (push, NV30_3D_RT_ENABLE_COLOR0);
  131.    BEGIN_NV04(push, NV30_3D(RT_HORIZ), 3);
  132.    PUSH_DATA (push, sf->width << 16);
  133.    PUSH_DATA (push, sf->height << 16);
  134.    PUSH_DATA (push, rt_format);
  135.    BEGIN_NV04(push, NV30_3D(COLOR0_PITCH), 2);
  136.    if (eng3d->oclass < NV40_3D_CLASS)
  137.       PUSH_DATA (push, (sf->pitch << 16) | sf->pitch);
  138.    else
  139.       PUSH_DATA (push, sf->pitch);
  140.    PUSH_RELOC(push, mt->base.bo, sf->offset, NOUVEAU_BO_LOW, 0, 0);
  141.    BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2);
  142.    PUSH_DATA (push, (w << 16) | x);
  143.    PUSH_DATA (push, (h << 16) | y);
  144.  
  145.    BEGIN_NV04(push, NV30_3D(CLEAR_COLOR_VALUE), 2);
  146.    PUSH_DATA (push, pack_rgba(ps->format, color->f));
  147.    PUSH_DATA (push, NV30_3D_CLEAR_BUFFERS_COLOR_R |
  148.                     NV30_3D_CLEAR_BUFFERS_COLOR_G |
  149.                     NV30_3D_CLEAR_BUFFERS_COLOR_B |
  150.                     NV30_3D_CLEAR_BUFFERS_COLOR_A);
  151.  
  152.    nv30->dirty |= NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR;
  153. }
  154.  
  155. static void
  156. nv30_clear_depth_stencil(struct pipe_context *pipe, struct pipe_surface *ps,
  157.                          unsigned buffers, double depth, unsigned stencil,
  158.                          unsigned x, unsigned y, unsigned w, unsigned h)
  159. {
  160.    struct nv30_context *nv30 = nv30_context(pipe);
  161.    struct nv30_surface *sf = nv30_surface(ps);
  162.    struct nv30_miptree *mt = nv30_miptree(ps->texture);
  163.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  164.    struct nouveau_object *eng3d = nv30->screen->eng3d;
  165.    struct nouveau_pushbuf_refn refn;
  166.    uint32_t rt_format, mode = 0;
  167.  
  168.    rt_format = nv30_format(pipe->screen, ps->format)->hw;
  169.    if (util_format_get_blocksize(ps->format) == 4)
  170.       rt_format |= NV30_3D_RT_FORMAT_COLOR_A8R8G8B8;
  171.    else
  172.       rt_format |= NV30_3D_RT_FORMAT_COLOR_R5G6B5;
  173.  
  174.    if (nv30_miptree(ps->texture)->swizzled) {
  175.       rt_format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED;
  176.       rt_format |= util_logbase2(sf->width) << 16;
  177.       rt_format |= util_logbase2(sf->height) << 24;
  178.    } else {
  179.       rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
  180.    }
  181.  
  182.    if (buffers & PIPE_CLEAR_DEPTH)
  183.       mode |= NV30_3D_CLEAR_BUFFERS_DEPTH;
  184.    if (buffers & PIPE_CLEAR_STENCIL)
  185.       mode |= NV30_3D_CLEAR_BUFFERS_STENCIL;
  186.  
  187.    refn.bo = mt->base.bo;
  188.    refn.flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR;
  189.    if (nouveau_pushbuf_space(push, 32, 1, 0) ||
  190.        nouveau_pushbuf_refn (push, &refn, 1))
  191.       return;
  192.  
  193.    BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
  194.    PUSH_DATA (push, 0);
  195.    BEGIN_NV04(push, NV30_3D(RT_HORIZ), 3);
  196.    PUSH_DATA (push, sf->width << 16);
  197.    PUSH_DATA (push, sf->height << 16);
  198.    PUSH_DATA (push, rt_format);
  199.    if (eng3d->oclass < NV40_3D_CLASS) {
  200.       BEGIN_NV04(push, NV30_3D(COLOR0_PITCH), 1);
  201.       PUSH_DATA (push, (sf->pitch << 16) | sf->pitch);
  202.    } else {
  203.       BEGIN_NV04(push, NV40_3D(ZETA_PITCH), 1);
  204.       PUSH_DATA (push, sf->pitch);
  205.    }
  206.    BEGIN_NV04(push, NV30_3D(ZETA_OFFSET), 1);
  207.    PUSH_RELOC(push, mt->base.bo, sf->offset, NOUVEAU_BO_LOW, 0, 0);
  208.    BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2);
  209.    PUSH_DATA (push, (w << 16) | x);
  210.    PUSH_DATA (push, (h << 16) | y);
  211.  
  212.    BEGIN_NV04(push, NV30_3D(CLEAR_DEPTH_VALUE), 1);
  213.    PUSH_DATA (push, pack_zeta(ps->format, depth, stencil));
  214.    BEGIN_NV04(push, NV30_3D(CLEAR_BUFFERS), 1);
  215.    PUSH_DATA (push, mode);
  216.  
  217.    nv30->dirty |= NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR;
  218. }
  219.  
  220. void
  221. nv30_clear_init(struct pipe_context *pipe)
  222. {
  223.    pipe->clear = nv30_clear;
  224.    pipe->clear_render_target = nv30_clear_render_target;
  225.    pipe->clear_depth_stencil = nv30_clear_depth_stencil;
  226. }
  227.