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 "util/u_format.h"
  27. #include "util/u_math.h"
  28. #include "util/u_half.h"
  29.  
  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 void
  36. nv30_validate_fb(struct nv30_context *nv30)
  37. {
  38.    struct pipe_screen *pscreen = &nv30->screen->base.base;
  39.    struct pipe_framebuffer_state *fb = &nv30->framebuffer;
  40.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  41.    struct nouveau_object *eng3d = nv30->screen->eng3d;
  42.    uint32_t rt_format;
  43.    int h = fb->height;
  44.    int w = fb->width;
  45.    int x = 0;
  46.    int y = 0;
  47.  
  48.    nv30->state.rt_enable = (NV30_3D_RT_ENABLE_COLOR0 << fb->nr_cbufs) - 1;
  49.    if (nv30->state.rt_enable > 1)
  50.       nv30->state.rt_enable |= NV30_3D_RT_ENABLE_MRT;
  51.  
  52.    rt_format = 0;
  53.    if (fb->nr_cbufs > 0) {
  54.       struct nv30_miptree *mt = nv30_miptree(fb->cbufs[0]->texture);
  55.       rt_format |= nv30_format(pscreen, fb->cbufs[0]->format)->hw;
  56.       rt_format |= mt->ms_mode;
  57.       if (mt->swizzled)
  58.          rt_format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED;
  59.       else
  60.          rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
  61.    } else {
  62.       if (fb->zsbuf && util_format_get_blocksize(fb->zsbuf->format) > 2)
  63.          rt_format |= NV30_3D_RT_FORMAT_COLOR_A8R8G8B8;
  64.       else
  65.          rt_format |= NV30_3D_RT_FORMAT_COLOR_R5G6B5;
  66.    }
  67.  
  68.    if (fb->zsbuf) {
  69.       rt_format |= nv30_format(pscreen, fb->zsbuf->format)->hw;
  70.       if (nv30_miptree(fb->zsbuf->texture)->swizzled)
  71.          rt_format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED;
  72.       else
  73.          rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
  74.    } else {
  75.       if (fb->nr_cbufs && util_format_get_blocksize(fb->cbufs[0]->format) > 2)
  76.          rt_format |= NV30_3D_RT_FORMAT_ZETA_Z24S8;
  77.       else
  78.          rt_format |= NV30_3D_RT_FORMAT_ZETA_Z16;
  79.    }
  80.  
  81.    /* hardware rounds down render target offset to 64 bytes, but surfaces
  82.     * with a size of 2x2 pixel (16bpp) or 1x1 pixel (32bpp) have an
  83.     * unaligned start aaddress.  For these two important square formats
  84.     * we can hack around this limitation by adjusting the viewport origin
  85.     */
  86.    if (nv30->state.rt_enable) {
  87.       int off = nv30_surface(fb->cbufs[0])->offset & 63;
  88.       if (off) {
  89.          x += off / (util_format_get_blocksize(fb->cbufs[0]->format) * 2);
  90.          w  = 16;
  91.          h  = 2;
  92.       }
  93.    }
  94.  
  95.    if (rt_format & NV30_3D_RT_FORMAT_TYPE_SWIZZLED) {
  96.       rt_format |= util_logbase2(w) << 16;
  97.       rt_format |= util_logbase2(h) << 24;
  98.    }
  99.  
  100.    if (!PUSH_SPACE(push, 64))
  101.       return;
  102.    PUSH_RESET(push, BUFCTX_FB);
  103.  
  104.    BEGIN_NV04(push, SUBC_3D(0x1da4), 1);
  105.    PUSH_DATA (push, 0);
  106.    BEGIN_NV04(push, NV30_3D(RT_HORIZ), 3);
  107.    PUSH_DATA (push, w << 16);
  108.    PUSH_DATA (push, h << 16);
  109.    PUSH_DATA (push, rt_format);
  110.    BEGIN_NV04(push, NV30_3D(VIEWPORT_HORIZ), 2);
  111.    PUSH_DATA (push, w << 16);
  112.    PUSH_DATA (push, h << 16);
  113.    BEGIN_NV04(push, NV30_3D(VIEWPORT_TX_ORIGIN), 4);
  114.    PUSH_DATA (push, (y << 16) | x);
  115.    PUSH_DATA (push, 0);
  116.    PUSH_DATA (push, ((w - 1) << 16) | 0);
  117.    PUSH_DATA (push, ((h - 1) << 16) | 0);
  118.  
  119.    if ((nv30->state.rt_enable & NV30_3D_RT_ENABLE_COLOR0) || fb->zsbuf) {
  120.       struct nv30_surface *rsf = nv30_surface(fb->cbufs[0]);
  121.       struct nv30_surface *zsf = nv30_surface(fb->zsbuf);
  122.       struct nouveau_bo *rbo, *zbo;
  123.  
  124.       if (!rsf)      rsf = zsf;
  125.       else if (!zsf) zsf = rsf;
  126.       rbo = nv30_miptree(rsf->base.texture)->base.bo;
  127.       zbo = nv30_miptree(zsf->base.texture)->base.bo;
  128.  
  129.       if (eng3d->oclass >= NV40_3D_CLASS) {
  130.          BEGIN_NV04(push, NV40_3D(ZETA_PITCH), 1);
  131.          PUSH_DATA (push, zsf->pitch);
  132.          BEGIN_NV04(push, NV40_3D(COLOR0_PITCH), 3);
  133.          PUSH_DATA (push, rsf->pitch);
  134.       } else {
  135.          BEGIN_NV04(push, NV30_3D(COLOR0_PITCH), 3);
  136.          PUSH_DATA (push, (zsf->pitch << 16) | rsf->pitch);
  137.       }
  138.       PUSH_MTHDl(push, NV30_3D(COLOR0_OFFSET), BUFCTX_FB, rbo, rsf->offset & ~63,
  139.                        NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
  140.       PUSH_MTHDl(push, NV30_3D(ZETA_OFFSET), BUFCTX_FB, zbo, zsf->offset & ~63,
  141.                        NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
  142.    }
  143.  
  144.    if (nv30->state.rt_enable & NV30_3D_RT_ENABLE_COLOR1) {
  145.       struct nv30_surface *sf = nv30_surface(fb->cbufs[1]);
  146.       struct nouveau_bo *bo = nv30_miptree(sf->base.texture)->base.bo;
  147.  
  148.       BEGIN_NV04(push, NV30_3D(COLOR1_OFFSET), 2);
  149.       PUSH_MTHDl(push, NV30_3D(COLOR1_OFFSET), BUFCTX_FB, bo, sf->offset,
  150.                        NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
  151.       PUSH_DATA (push, sf->pitch);
  152.    }
  153.  
  154.    if (nv30->state.rt_enable & NV40_3D_RT_ENABLE_COLOR2) {
  155.       struct nv30_surface *sf = nv30_surface(fb->cbufs[2]);
  156.       struct nouveau_bo *bo = nv30_miptree(sf->base.texture)->base.bo;
  157.  
  158.       BEGIN_NV04(push, NV40_3D(COLOR2_OFFSET), 1);
  159.       PUSH_MTHDl(push, NV40_3D(COLOR2_OFFSET), BUFCTX_FB, bo, sf->offset,
  160.                        NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
  161.       BEGIN_NV04(push, NV40_3D(COLOR2_PITCH), 1);
  162.       PUSH_DATA (push, sf->pitch);
  163.    }
  164.  
  165.    if (nv30->state.rt_enable & NV40_3D_RT_ENABLE_COLOR3) {
  166.       struct nv30_surface *sf = nv30_surface(fb->cbufs[3]);
  167.       struct nouveau_bo *bo = nv30_miptree(sf->base.texture)->base.bo;
  168.  
  169.       BEGIN_NV04(push, NV40_3D(COLOR3_OFFSET), 1);
  170.       PUSH_MTHDl(push, NV40_3D(COLOR3_OFFSET), BUFCTX_FB, bo, sf->offset,
  171.                        NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
  172.       BEGIN_NV04(push, NV40_3D(COLOR3_PITCH), 1);
  173.       PUSH_DATA (push, sf->pitch);
  174.    }
  175. }
  176.  
  177. static void
  178. nv30_validate_blend_colour(struct nv30_context *nv30)
  179. {
  180.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  181.    float *rgba = nv30->blend_colour.color;
  182.  
  183.    if (nv30->framebuffer.nr_cbufs) {
  184.       switch (nv30->framebuffer.cbufs[0]->format) {
  185.       case PIPE_FORMAT_R16G16B16A16_FLOAT:
  186.       case PIPE_FORMAT_R32G32B32A32_FLOAT:
  187.          BEGIN_NV04(push, NV30_3D(BLEND_COLOR), 1);
  188.          PUSH_DATA (push, (util_float_to_half(rgba[0]) <<  0) |
  189.                           (util_float_to_half(rgba[1]) << 16));
  190.          BEGIN_NV04(push, SUBC_3D(0x037c), 1);
  191.          PUSH_DATA (push, (util_float_to_half(rgba[2]) <<  0) |
  192.                           (util_float_to_half(rgba[3]) << 16));
  193.          break;
  194.       default:
  195.          break;
  196.       }
  197.    }
  198.  
  199.    BEGIN_NV04(push, NV30_3D(BLEND_COLOR), 1);
  200.    PUSH_DATA (push, (float_to_ubyte(rgba[3]) << 24) |
  201.                     (float_to_ubyte(rgba[0]) << 16) |
  202.                     (float_to_ubyte(rgba[1]) <<  8) |
  203.                     (float_to_ubyte(rgba[2]) <<  0));
  204. }
  205.  
  206. static void
  207. nv30_validate_stencil_ref(struct nv30_context *nv30)
  208. {
  209.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  210.  
  211.    BEGIN_NV04(push, NV30_3D(STENCIL_FUNC_REF(0)), 1);
  212.    PUSH_DATA (push, nv30->stencil_ref.ref_value[0]);
  213.    BEGIN_NV04(push, NV30_3D(STENCIL_FUNC_REF(1)), 1);
  214.    PUSH_DATA (push, nv30->stencil_ref.ref_value[1]);
  215. }
  216.  
  217. static void
  218. nv30_validate_stipple(struct nv30_context *nv30)
  219. {
  220.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  221.  
  222.    BEGIN_NV04(push, NV30_3D(POLYGON_STIPPLE_PATTERN(0)), 32);
  223.    PUSH_DATAp(push, nv30->stipple.stipple, 32);
  224. }
  225.  
  226. static void
  227. nv30_validate_scissor(struct nv30_context *nv30)
  228. {
  229.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  230.    struct pipe_scissor_state *s = &nv30->scissor;
  231.  
  232.    if (!(nv30->dirty & NV30_NEW_SCISSOR) &&
  233.        nv30->rast->pipe.scissor != nv30->state.scissor_off)
  234.       return;
  235.    nv30->state.scissor_off = !nv30->rast->pipe.scissor;
  236.  
  237.    BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2);
  238.    if (nv30->rast->pipe.scissor) {
  239.       PUSH_DATA (push, ((s->maxx - s->minx) << 16) | s->minx);
  240.       PUSH_DATA (push, ((s->maxy - s->miny) << 16) | s->miny);
  241.    } else {
  242.       PUSH_DATA (push, 0x10000000);
  243.       PUSH_DATA (push, 0x10000000);
  244.    }
  245. }
  246.  
  247. static void
  248. nv30_validate_viewport(struct nv30_context *nv30)
  249. {
  250.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  251.    struct pipe_viewport_state *vp = &nv30->viewport;
  252.  
  253.    BEGIN_NV04(push, NV30_3D(VIEWPORT_TRANSLATE_X), 8);
  254.    PUSH_DATAf(push, vp->translate[0]);
  255.    PUSH_DATAf(push, vp->translate[1]);
  256.    PUSH_DATAf(push, vp->translate[2]);
  257.    PUSH_DATAf(push, vp->translate[3]);
  258.    PUSH_DATAf(push, vp->scale[0]);
  259.    PUSH_DATAf(push, vp->scale[1]);
  260.    PUSH_DATAf(push, vp->scale[2]);
  261.    PUSH_DATAf(push, vp->scale[3]);
  262.    BEGIN_NV04(push, NV30_3D(DEPTH_RANGE_NEAR), 2);
  263.    PUSH_DATAf(push, vp->translate[2] - fabsf(vp->scale[2]));
  264.    PUSH_DATAf(push, vp->translate[2] + fabsf(vp->scale[2]));
  265. }
  266.  
  267. static void
  268. nv30_validate_clip(struct nv30_context *nv30)
  269. {
  270.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  271.    unsigned i;
  272.    uint32_t clpd_enable = 0;
  273.  
  274.    for (i = 0; i < 6; i++) {
  275.       if (nv30->rast->pipe.clip_plane_enable & (1 << i)) {
  276.          if (nv30->dirty & NV30_NEW_CLIP) {
  277.             BEGIN_NV04(push, NV30_3D(VP_UPLOAD_CONST_ID), 5);
  278.             PUSH_DATA (push, i);
  279.             PUSH_DATAp(push, nv30->clip.ucp[i], 4);
  280.          }
  281.  
  282.          clpd_enable |= 1 << (1 + 4*i);
  283.       }
  284.    }
  285.  
  286.    BEGIN_NV04(push, NV30_3D(VP_CLIP_PLANES_ENABLE), 1);
  287.    PUSH_DATA (push, clpd_enable);
  288. }
  289.  
  290. static void
  291. nv30_validate_blend(struct nv30_context *nv30)
  292. {
  293.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  294.  
  295.    PUSH_SPACE(push, nv30->blend->size);
  296.    PUSH_DATAp(push, nv30->blend->data, nv30->blend->size);
  297. }
  298.  
  299. static void
  300. nv30_validate_zsa(struct nv30_context *nv30)
  301. {
  302.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  303.  
  304.    PUSH_SPACE(push, nv30->zsa->size);
  305.    PUSH_DATAp(push, nv30->zsa->data, nv30->zsa->size);
  306. }
  307.  
  308. static void
  309. nv30_validate_rasterizer(struct nv30_context *nv30)
  310. {
  311.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  312.  
  313.    PUSH_SPACE(push, nv30->rast->size);
  314.    PUSH_DATAp(push, nv30->rast->data, nv30->rast->size);
  315. }
  316.  
  317. static void
  318. nv30_validate_multisample(struct nv30_context *nv30)
  319. {
  320.    struct pipe_rasterizer_state *rasterizer = &nv30->rast->pipe;
  321.    struct pipe_blend_state *blend = &nv30->blend->pipe;
  322.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  323.    uint32_t ctrl = nv30->sample_mask << 16;
  324.  
  325.    if (blend->alpha_to_one)
  326.       ctrl |= 0x00000100;
  327.    if (blend->alpha_to_coverage)
  328.       ctrl |= 0x00000010;
  329.    if (rasterizer->multisample)
  330.       ctrl |= 0x00000001;
  331.  
  332.    BEGIN_NV04(push, NV30_3D(MULTISAMPLE_CONTROL), 1);
  333.    PUSH_DATA (push, ctrl);
  334. }
  335.  
  336. static void
  337. nv30_validate_fragment(struct nv30_context *nv30)
  338. {
  339.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  340.    struct nv30_fragprog *fp = nv30->fragprog.program;
  341.  
  342.    BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
  343.    PUSH_DATA (push, nv30->state.rt_enable & ~fp->rt_enable);
  344.    BEGIN_NV04(push, NV30_3D(COORD_CONVENTIONS), 1);
  345.    PUSH_DATA (push, fp->coord_conventions | nv30->framebuffer.height);
  346. }
  347.  
  348. static void
  349. nv30_validate_point_coord(struct nv30_context *nv30)
  350. {
  351.    struct pipe_rasterizer_state *rasterizer = &nv30->rast->pipe;
  352.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  353.    struct nv30_fragprog *fp = nv30->fragprog.program;
  354.    uint32_t hw = 0x00000000;
  355.  
  356.    if (rasterizer) {
  357.       hw |= (nv30->rast->pipe.sprite_coord_enable & 0xff) << 8;
  358.       if (fp)
  359.          hw |= fp->point_sprite_control;
  360.  
  361.       if (rasterizer->sprite_coord_mode == PIPE_SPRITE_COORD_LOWER_LEFT) {
  362.          if (hw)
  363.             nv30->draw_flags |= NV30_NEW_RASTERIZER;
  364.       } else
  365.       if (rasterizer->point_quad_rasterization) {
  366.          hw |= NV30_3D_POINT_SPRITE_ENABLE;
  367.       }
  368.    }
  369.  
  370.    BEGIN_NV04(push, NV30_3D(POINT_SPRITE), 1);
  371.    PUSH_DATA (push, hw);
  372. }
  373.  
  374. struct state_validate {
  375.    void (*func)(struct nv30_context *);
  376.    uint32_t mask;
  377. };
  378.  
  379. static struct state_validate hwtnl_validate_list[] = {
  380.     { nv30_validate_fb,            NV30_NEW_FRAMEBUFFER },
  381.     { nv30_validate_blend,         NV30_NEW_BLEND },
  382.     { nv30_validate_zsa,           NV30_NEW_ZSA },
  383.     { nv30_validate_rasterizer,    NV30_NEW_RASTERIZER },
  384.     { nv30_validate_multisample,   NV30_NEW_SAMPLE_MASK | NV30_NEW_BLEND |
  385.                                    NV30_NEW_RASTERIZER },
  386.     { nv30_validate_blend_colour,  NV30_NEW_BLEND_COLOUR |
  387.                                    NV30_NEW_FRAMEBUFFER },
  388.     { nv30_validate_stencil_ref,   NV30_NEW_STENCIL_REF },
  389.     { nv30_validate_stipple,       NV30_NEW_STIPPLE },
  390.     { nv30_validate_scissor,       NV30_NEW_SCISSOR | NV30_NEW_RASTERIZER },
  391.     { nv30_validate_viewport,      NV30_NEW_VIEWPORT },
  392.     { nv30_validate_clip,          NV30_NEW_CLIP },
  393.     { nv30_fragprog_validate,      NV30_NEW_FRAGPROG | NV30_NEW_FRAGCONST },
  394.     { nv30_vertprog_validate,      NV30_NEW_VERTPROG | NV30_NEW_VERTCONST |
  395.                                    NV30_NEW_FRAGPROG | NV30_NEW_RASTERIZER },
  396.     { nv30_validate_fragment,      NV30_NEW_FRAMEBUFFER | NV30_NEW_FRAGPROG },
  397.     { nv30_validate_point_coord,   NV30_NEW_RASTERIZER | NV30_NEW_FRAGPROG },
  398.     { nv30_fragtex_validate,       NV30_NEW_FRAGTEX },
  399.     { nv40_verttex_validate,       NV30_NEW_VERTTEX },
  400.     { nv30_vbo_validate,           NV30_NEW_VERTEX | NV30_NEW_ARRAYS },
  401.     {}
  402. };
  403.  
  404. #define NV30_SWTNL_MASK (NV30_NEW_VIEWPORT |  \
  405.                          NV30_NEW_CLIP |      \
  406.                          NV30_NEW_VERTPROG |  \
  407.                          NV30_NEW_VERTCONST | \
  408.                          NV30_NEW_VERTTEX |   \
  409.                          NV30_NEW_VERTEX |    \
  410.                          NV30_NEW_ARRAYS)
  411.  
  412. static struct state_validate swtnl_validate_list[] = {
  413.     { nv30_validate_fb,            NV30_NEW_FRAMEBUFFER },
  414.     { nv30_validate_blend,         NV30_NEW_BLEND },
  415.     { nv30_validate_zsa,           NV30_NEW_ZSA },
  416.     { nv30_validate_rasterizer,    NV30_NEW_RASTERIZER },
  417.     { nv30_validate_multisample,   NV30_NEW_SAMPLE_MASK | NV30_NEW_BLEND |
  418.                                    NV30_NEW_RASTERIZER },
  419.     { nv30_validate_blend_colour,  NV30_NEW_BLEND_COLOUR |
  420.                                    NV30_NEW_FRAMEBUFFER },
  421.     { nv30_validate_stencil_ref,   NV30_NEW_STENCIL_REF },
  422.     { nv30_validate_stipple,       NV30_NEW_STIPPLE },
  423.     { nv30_validate_scissor,       NV30_NEW_SCISSOR | NV30_NEW_RASTERIZER },
  424.     { nv30_fragprog_validate,      NV30_NEW_FRAGPROG | NV30_NEW_FRAGCONST },
  425.     { nv30_validate_fragment,      NV30_NEW_FRAMEBUFFER | NV30_NEW_FRAGPROG },
  426.     { nv30_fragtex_validate,       NV30_NEW_FRAGTEX },
  427.     {}
  428. };
  429.  
  430. static void
  431. nv30_state_context_switch(struct nv30_context *nv30)
  432. {
  433.    struct nv30_context *prev = nv30->screen->cur_ctx;
  434.  
  435.    if (prev)
  436.       nv30->state = prev->state;
  437.    nv30->dirty = NV30_NEW_ALL;
  438.  
  439.    if (!nv30->vertex)
  440.       nv30->dirty &= ~(NV30_NEW_VERTEX | NV30_NEW_ARRAYS);
  441.  
  442.    if (!nv30->vertprog.program)
  443.       nv30->dirty &= ~NV30_NEW_VERTPROG;
  444.    if (!nv30->fragprog.program)
  445.       nv30->dirty &= ~NV30_NEW_FRAGPROG;
  446.  
  447.    if (!nv30->blend)
  448.       nv30->dirty &= ~NV30_NEW_BLEND;
  449.    if (!nv30->rast)
  450.       nv30->dirty &= ~NV30_NEW_RASTERIZER;
  451.    if (!nv30->zsa)
  452.       nv30->dirty &= ~NV30_NEW_ZSA;
  453.  
  454.    nv30->screen->cur_ctx = nv30;
  455.    nv30->base.pushbuf->user_priv = &nv30->bufctx;
  456. }
  457.  
  458. boolean
  459. nv30_state_validate(struct nv30_context *nv30, boolean hwtnl)
  460. {
  461.    struct nouveau_screen *screen = &nv30->screen->base;
  462.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  463.    struct nouveau_bufctx *bctx = nv30->bufctx;
  464.    struct nouveau_bufref *bref;
  465.    struct state_validate *validate;
  466.  
  467.    if (nv30->screen->cur_ctx != nv30)
  468.       nv30_state_context_switch(nv30);
  469.  
  470.    if (hwtnl) {
  471.       nv30->draw_dirty |= nv30->dirty;
  472.       if (nv30->draw_flags) {
  473.          nv30->draw_flags &= ~nv30->dirty;
  474.          if (!nv30->draw_flags)
  475.             nv30->dirty |= NV30_SWTNL_MASK;
  476.       }
  477.    }
  478.  
  479.    if (!nv30->draw_flags)
  480.       validate = hwtnl_validate_list;
  481.    else
  482.       validate = swtnl_validate_list;
  483.  
  484.    if (nv30->dirty) {
  485.       while (validate->func) {
  486.          if (nv30->dirty & validate->mask)
  487.             validate->func(nv30);
  488.          validate++;
  489.       }
  490.  
  491.       nv30->dirty = 0;
  492.    }
  493.  
  494.    nouveau_pushbuf_bufctx(push, bctx);
  495.    if (nouveau_pushbuf_validate(push)) {
  496.       nouveau_pushbuf_bufctx(push, NULL);
  497.       return FALSE;
  498.    }
  499.  
  500.    /*XXX*/
  501.    BEGIN_NV04(push, NV30_3D(VTX_CACHE_INVALIDATE_1710), 1);
  502.    PUSH_DATA (push, 0);
  503.    if (nv30->screen->eng3d->oclass >= NV40_3D_CLASS) {
  504.       BEGIN_NV04(push, NV40_3D(TEX_CACHE_CTL), 1);
  505.       PUSH_DATA (push, 2);
  506.       BEGIN_NV04(push, NV40_3D(TEX_CACHE_CTL), 1);
  507.       PUSH_DATA (push, 1);
  508.       BEGIN_NV04(push, NV30_3D(R1718), 1);
  509.       PUSH_DATA (push, 0);
  510.       BEGIN_NV04(push, NV30_3D(R1718), 1);
  511.       PUSH_DATA (push, 0);
  512.       BEGIN_NV04(push, NV30_3D(R1718), 1);
  513.       PUSH_DATA (push, 0);
  514.    }
  515.  
  516.    LIST_FOR_EACH_ENTRY(bref, &bctx->current, thead) {
  517.       struct nv04_resource *res = bref->priv;
  518.       if (res && res->mm) {
  519.          nouveau_fence_ref(screen->fence.current, &res->fence);
  520.  
  521.          if (bref->flags & NOUVEAU_BO_RD)
  522.             res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
  523.  
  524.          if (bref->flags & NOUVEAU_BO_WR) {
  525.             nouveau_fence_ref(screen->fence.current, &res->fence_wr);
  526.             res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
  527.          }
  528.       }
  529.    }
  530.  
  531.    return TRUE;
  532. }
  533.  
  534. void
  535. nv30_state_release(struct nv30_context *nv30)
  536. {
  537.    nouveau_pushbuf_bufctx(nv30->base.pushbuf, NULL);
  538. }
  539.