Subversion Repositories Kolibri OS

Rev

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 "nv_object.xml.h"
  31. #include "nv30/nv30-40_3d.xml.h"
  32. #include "nv30/nv30_context.h"
  33. #include "nv30/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, 0.0f);
  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, 1.0f);
  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->dirty & NV30_NEW_CLIP) {
  276.          BEGIN_NV04(push, NV30_3D(VP_UPLOAD_CONST_ID), 5);
  277.          PUSH_DATA (push, i);
  278.          PUSH_DATAp(push, nv30->clip.ucp[i], 4);
  279.       }
  280.       if (nv30->rast->pipe.clip_plane_enable & (1 << i))
  281.          clpd_enable |= 2 << (4*i);
  282.    }
  283.  
  284.    BEGIN_NV04(push, NV30_3D(VP_CLIP_PLANES_ENABLE), 1);
  285.    PUSH_DATA (push, clpd_enable);
  286. }
  287.  
  288. static void
  289. nv30_validate_blend(struct nv30_context *nv30)
  290. {
  291.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  292.  
  293.    PUSH_SPACE(push, nv30->blend->size);
  294.    PUSH_DATAp(push, nv30->blend->data, nv30->blend->size);
  295. }
  296.  
  297. static void
  298. nv30_validate_zsa(struct nv30_context *nv30)
  299. {
  300.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  301.  
  302.    PUSH_SPACE(push, nv30->zsa->size);
  303.    PUSH_DATAp(push, nv30->zsa->data, nv30->zsa->size);
  304. }
  305.  
  306. static void
  307. nv30_validate_rasterizer(struct nv30_context *nv30)
  308. {
  309.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  310.  
  311.    PUSH_SPACE(push, nv30->rast->size);
  312.    PUSH_DATAp(push, nv30->rast->data, nv30->rast->size);
  313. }
  314.  
  315. static void
  316. nv30_validate_multisample(struct nv30_context *nv30)
  317. {
  318.    struct pipe_rasterizer_state *rasterizer = &nv30->rast->pipe;
  319.    struct pipe_blend_state *blend = &nv30->blend->pipe;
  320.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  321.    uint32_t ctrl = nv30->sample_mask << 16;
  322.  
  323.    if (blend->alpha_to_one)
  324.       ctrl |= 0x00000100;
  325.    if (blend->alpha_to_coverage)
  326.       ctrl |= 0x00000010;
  327.    if (rasterizer->multisample)
  328.       ctrl |= 0x00000001;
  329.  
  330.    BEGIN_NV04(push, NV30_3D(MULTISAMPLE_CONTROL), 1);
  331.    PUSH_DATA (push, ctrl);
  332. }
  333.  
  334. static void
  335. nv30_validate_fragment(struct nv30_context *nv30)
  336. {
  337.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  338.    struct nv30_fragprog *fp = nv30->fragprog.program;
  339.  
  340.    BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
  341.    PUSH_DATA (push, nv30->state.rt_enable & ~fp->rt_enable);
  342.    BEGIN_NV04(push, NV30_3D(COORD_CONVENTIONS), 1);
  343.    PUSH_DATA (push, fp->coord_conventions | nv30->framebuffer.height);
  344. }
  345.  
  346. static void
  347. nv30_validate_point_coord(struct nv30_context *nv30)
  348. {
  349.    struct pipe_rasterizer_state *rasterizer = &nv30->rast->pipe;
  350.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  351.    struct nv30_fragprog *fp = nv30->fragprog.program;
  352.    uint32_t hw = 0x00000000;
  353.  
  354.    if (rasterizer) {
  355.       hw |= (nv30->rast->pipe.sprite_coord_enable & 0xff) << 8;
  356.       if (fp)
  357.          hw |= fp->point_sprite_control;
  358.  
  359.       if (rasterizer->sprite_coord_mode == PIPE_SPRITE_COORD_LOWER_LEFT) {
  360.          if (hw)
  361.             nv30->draw_flags |= NV30_NEW_RASTERIZER;
  362.       } else
  363.       if (rasterizer->point_quad_rasterization) {
  364.          hw |= NV30_3D_POINT_SPRITE_ENABLE;
  365.       }
  366.    }
  367.  
  368.    BEGIN_NV04(push, NV30_3D(POINT_SPRITE), 1);
  369.    PUSH_DATA (push, hw);
  370. }
  371.  
  372. struct state_validate {
  373.    void (*func)(struct nv30_context *);
  374.    uint32_t mask;
  375. };
  376.  
  377. static struct state_validate hwtnl_validate_list[] = {
  378.     { nv30_validate_fb,            NV30_NEW_FRAMEBUFFER },
  379.     { nv30_validate_blend,         NV30_NEW_BLEND },
  380.     { nv30_validate_zsa,           NV30_NEW_ZSA },
  381.     { nv30_validate_rasterizer,    NV30_NEW_RASTERIZER },
  382.     { nv30_validate_multisample,   NV30_NEW_SAMPLE_MASK | NV30_NEW_BLEND |
  383.                                    NV30_NEW_RASTERIZER },
  384.     { nv30_validate_blend_colour,  NV30_NEW_BLEND_COLOUR |
  385.                                    NV30_NEW_FRAMEBUFFER },
  386.     { nv30_validate_stencil_ref,   NV30_NEW_STENCIL_REF },
  387.     { nv30_validate_stipple,       NV30_NEW_STIPPLE },
  388.     { nv30_validate_scissor,       NV30_NEW_SCISSOR | NV30_NEW_RASTERIZER },
  389.     { nv30_validate_viewport,      NV30_NEW_VIEWPORT },
  390.     { nv30_validate_clip,          NV30_NEW_CLIP | NV30_NEW_RASTERIZER },
  391.     { nv30_fragprog_validate,      NV30_NEW_FRAGPROG | NV30_NEW_FRAGCONST },
  392.     { nv30_vertprog_validate,      NV30_NEW_VERTPROG | NV30_NEW_VERTCONST |
  393.                                    NV30_NEW_FRAGPROG | NV30_NEW_RASTERIZER },
  394.     { nv30_validate_fragment,      NV30_NEW_FRAMEBUFFER | NV30_NEW_FRAGPROG },
  395.     { nv30_validate_point_coord,   NV30_NEW_RASTERIZER | NV30_NEW_FRAGPROG },
  396.     { nv30_fragtex_validate,       NV30_NEW_FRAGTEX },
  397.     { nv40_verttex_validate,       NV30_NEW_VERTTEX },
  398.     { nv30_vbo_validate,           NV30_NEW_VERTEX | NV30_NEW_ARRAYS },
  399.     {}
  400. };
  401.  
  402. #define NV30_SWTNL_MASK (NV30_NEW_VIEWPORT |  \
  403.                          NV30_NEW_CLIP |      \
  404.                          NV30_NEW_VERTPROG |  \
  405.                          NV30_NEW_VERTCONST | \
  406.                          NV30_NEW_VERTTEX |   \
  407.                          NV30_NEW_VERTEX |    \
  408.                          NV30_NEW_ARRAYS)
  409.  
  410. static struct state_validate swtnl_validate_list[] = {
  411.     { nv30_validate_fb,            NV30_NEW_FRAMEBUFFER },
  412.     { nv30_validate_blend,         NV30_NEW_BLEND },
  413.     { nv30_validate_zsa,           NV30_NEW_ZSA },
  414.     { nv30_validate_rasterizer,    NV30_NEW_RASTERIZER },
  415.     { nv30_validate_multisample,   NV30_NEW_SAMPLE_MASK | NV30_NEW_BLEND |
  416.                                    NV30_NEW_RASTERIZER },
  417.     { nv30_validate_blend_colour,  NV30_NEW_BLEND_COLOUR |
  418.                                    NV30_NEW_FRAMEBUFFER },
  419.     { nv30_validate_stencil_ref,   NV30_NEW_STENCIL_REF },
  420.     { nv30_validate_stipple,       NV30_NEW_STIPPLE },
  421.     { nv30_validate_scissor,       NV30_NEW_SCISSOR | NV30_NEW_RASTERIZER },
  422.     { nv30_fragprog_validate,      NV30_NEW_FRAGPROG | NV30_NEW_FRAGCONST },
  423.     { nv30_validate_fragment,      NV30_NEW_FRAMEBUFFER | NV30_NEW_FRAGPROG },
  424.     { nv30_fragtex_validate,       NV30_NEW_FRAGTEX },
  425.     {}
  426. };
  427.  
  428. static void
  429. nv30_state_context_switch(struct nv30_context *nv30)
  430. {
  431.    struct nv30_context *prev = nv30->screen->cur_ctx;
  432.  
  433.    if (prev)
  434.       nv30->state = prev->state;
  435.    nv30->dirty = NV30_NEW_ALL;
  436.  
  437.    if (!nv30->vertex)
  438.       nv30->dirty &= ~(NV30_NEW_VERTEX | NV30_NEW_ARRAYS);
  439.  
  440.    if (!nv30->vertprog.program)
  441.       nv30->dirty &= ~NV30_NEW_VERTPROG;
  442.    if (!nv30->fragprog.program)
  443.       nv30->dirty &= ~NV30_NEW_FRAGPROG;
  444.  
  445.    if (!nv30->blend)
  446.       nv30->dirty &= ~NV30_NEW_BLEND;
  447.    if (!nv30->rast)
  448.       nv30->dirty &= ~NV30_NEW_RASTERIZER;
  449.    if (!nv30->zsa)
  450.       nv30->dirty &= ~NV30_NEW_ZSA;
  451.  
  452.    nv30->screen->cur_ctx = nv30;
  453.    nv30->base.pushbuf->user_priv = &nv30->bufctx;
  454. }
  455.  
  456. boolean
  457. nv30_state_validate(struct nv30_context *nv30, boolean hwtnl)
  458. {
  459.    struct nouveau_screen *screen = &nv30->screen->base;
  460.    struct nouveau_pushbuf *push = nv30->base.pushbuf;
  461.    struct nouveau_bufctx *bctx = nv30->bufctx;
  462.    struct nouveau_bufref *bref;
  463.    struct state_validate *validate;
  464.  
  465.    if (nv30->screen->cur_ctx != nv30)
  466.       nv30_state_context_switch(nv30);
  467.  
  468.    if (hwtnl) {
  469.       nv30->draw_dirty |= nv30->dirty;
  470.       if (nv30->draw_flags) {
  471.          nv30->draw_flags &= ~nv30->dirty;
  472.          if (!nv30->draw_flags)
  473.             nv30->dirty |= NV30_SWTNL_MASK;
  474.       }
  475.    }
  476.  
  477.    if (!nv30->draw_flags)
  478.       validate = hwtnl_validate_list;
  479.    else
  480.       validate = swtnl_validate_list;
  481.  
  482.    if (nv30->dirty) {
  483.       while (validate->func) {
  484.          if (nv30->dirty & validate->mask)
  485.             validate->func(nv30);
  486.          validate++;
  487.       }
  488.  
  489.       nv30->dirty = 0;
  490.    }
  491.  
  492.    nouveau_pushbuf_bufctx(push, bctx);
  493.    if (nouveau_pushbuf_validate(push)) {
  494.       nouveau_pushbuf_bufctx(push, NULL);
  495.       return FALSE;
  496.    }
  497.  
  498.    /*XXX*/
  499.    BEGIN_NV04(push, NV30_3D(VTX_CACHE_INVALIDATE_1710), 1);
  500.    PUSH_DATA (push, 0);
  501.    if (nv30->screen->eng3d->oclass >= NV40_3D_CLASS) {
  502.       BEGIN_NV04(push, NV40_3D(TEX_CACHE_CTL), 1);
  503.       PUSH_DATA (push, 2);
  504.       BEGIN_NV04(push, NV40_3D(TEX_CACHE_CTL), 1);
  505.       PUSH_DATA (push, 1);
  506.       BEGIN_NV04(push, NV30_3D(R1718), 1);
  507.       PUSH_DATA (push, 0);
  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.    }
  513.  
  514.    LIST_FOR_EACH_ENTRY(bref, &bctx->current, thead) {
  515.       struct nv04_resource *res = bref->priv;
  516.       if (res && res->mm) {
  517.          nouveau_fence_ref(screen->fence.current, &res->fence);
  518.  
  519.          if (bref->flags & NOUVEAU_BO_RD)
  520.             res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
  521.  
  522.          if (bref->flags & NOUVEAU_BO_WR) {
  523.             nouveau_fence_ref(screen->fence.current, &res->fence_wr);
  524.             res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
  525.          }
  526.       }
  527.    }
  528.  
  529.    return TRUE;
  530. }
  531.  
  532. void
  533. nv30_state_release(struct nv30_context *nv30)
  534. {
  535.    nouveau_pushbuf_bufctx(nv30->base.pushbuf, NULL);
  536. }
  537.