Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright (C) 2009-2010 Francisco Jerez.
  3.  * All Rights Reserved.
  4.  *
  5.  * Permission is hereby granted, free of charge, to any person obtaining
  6.  * a copy of this software and associated documentation files (the
  7.  * "Software"), to deal in the Software without restriction, including
  8.  * without limitation the rights to use, copy, modify, merge, publish,
  9.  * distribute, sublicense, and/or sell copies of the Software, and to
  10.  * permit persons to whom the Software is furnished to do so, subject to
  11.  * the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice (including the
  14.  * next paragraph) shall be included in all copies or substantial
  15.  * portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18.  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  20.  * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
  21.  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  22.  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  23.  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24.  *
  25.  */
  26.  
  27. #include "nouveau_driver.h"
  28. #include "nouveau_context.h"
  29. #include "nouveau_fbo.h"
  30. #include "nouveau_util.h"
  31. #include "nv04_3d.xml.h"
  32. #include "nv04_driver.h"
  33.  
  34. static GLboolean
  35. texunit_needs_combiners(struct gl_texture_unit *u)
  36. {
  37.         struct gl_texture_object *t = u->_Current;
  38.         struct gl_texture_image *ti = t->Image[0][t->BaseLevel];
  39.  
  40.         return ti->TexFormat == MESA_FORMAT_A8 ||
  41.                 ti->TexFormat == MESA_FORMAT_L8 ||
  42.                 u->EnvMode == GL_COMBINE ||
  43.                 u->EnvMode == GL_COMBINE4_NV ||
  44.                 u->EnvMode == GL_BLEND ||
  45.                 u->EnvMode == GL_ADD;
  46. }
  47.  
  48. struct nouveau_object *
  49. nv04_context_engine(struct gl_context *ctx)
  50. {
  51.         struct nv04_context *nctx = to_nv04_context(ctx);
  52.         struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw;
  53.         struct nouveau_pushbuf *push = context_push(ctx);
  54.         struct nouveau_object *fahrenheit;
  55.  
  56.         if ((ctx->Texture.Unit[0]._ReallyEnabled &&
  57.              texunit_needs_combiners(&ctx->Texture.Unit[0])) ||
  58.             ctx->Texture.Unit[1]._ReallyEnabled ||
  59.             ctx->Stencil.Enabled ||
  60.             !(ctx->Color.ColorMask[0][RCOMP] &&
  61.               ctx->Color.ColorMask[0][GCOMP] &&
  62.               ctx->Color.ColorMask[0][BCOMP] &&
  63.               ctx->Color.ColorMask[0][ACOMP]))
  64.                 fahrenheit = hw->eng3dm;
  65.         else
  66.                 fahrenheit = hw->eng3d;
  67.  
  68.         if (fahrenheit != nctx->eng3d) {
  69.                 BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1);
  70.                 PUSH_DATA (push, fahrenheit->handle);
  71.                 nctx->eng3d = fahrenheit;
  72.         }
  73.  
  74.         return fahrenheit;
  75. }
  76.  
  77. static void
  78. nv04_hwctx_init(struct gl_context *ctx)
  79. {
  80.         struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw;
  81.         struct nouveau_pushbuf *push = context_push(ctx);
  82.         struct nv04_fifo *fifo = hw->chan->data;
  83.  
  84.         BEGIN_NV04(push, NV01_SUBC(SURF, OBJECT), 1);
  85.         PUSH_DATA (push, hw->surf3d->handle);
  86.         BEGIN_NV04(push, NV04_SF3D(DMA_NOTIFY), 3);
  87.         PUSH_DATA (push, hw->ntfy->handle);
  88.         PUSH_DATA (push, fifo->vram);
  89.         PUSH_DATA (push, fifo->vram);
  90.  
  91.         BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1);
  92.         PUSH_DATA (push, hw->eng3d->handle);
  93.         BEGIN_NV04(push, NV04_TTRI(DMA_NOTIFY), 4);
  94.         PUSH_DATA (push, hw->ntfy->handle);
  95.         PUSH_DATA (push, fifo->vram);
  96.         PUSH_DATA (push, fifo->gart);
  97.         PUSH_DATA (push, hw->surf3d->handle);
  98.  
  99.         BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1);
  100.         PUSH_DATA (push, hw->eng3dm->handle);
  101.         BEGIN_NV04(push, NV04_MTRI(DMA_NOTIFY), 4);
  102.         PUSH_DATA (push, hw->ntfy->handle);
  103.         PUSH_DATA (push, fifo->vram);
  104.         PUSH_DATA (push, fifo->gart);
  105.         PUSH_DATA (push, hw->surf3d->handle);
  106.  
  107.         PUSH_KICK (push);
  108. }
  109.  
  110. static void
  111. init_dummy_texture(struct gl_context *ctx)
  112. {
  113.         struct nouveau_surface *s = &to_nv04_context(ctx)->dummy_texture;
  114.  
  115.         nouveau_surface_alloc(ctx, s, SWIZZLED,
  116.                               NOUVEAU_BO_MAP | NOUVEAU_BO_VRAM,
  117.                               MESA_FORMAT_ARGB8888, 1, 1);
  118.  
  119.         nouveau_bo_map(s->bo, NOUVEAU_BO_WR, context_client(ctx));
  120.         *(uint32_t *)s->bo->map = 0xffffffff;
  121. }
  122.  
  123. static void
  124. nv04_context_destroy(struct gl_context *ctx)
  125. {
  126.         struct nouveau_context *nctx = to_nouveau_context(ctx);
  127.  
  128.         nv04_surface_takedown(ctx);
  129.         nv04_render_destroy(ctx);
  130.         nouveau_surface_ref(NULL, &to_nv04_context(ctx)->dummy_texture);
  131.  
  132.         nouveau_object_del(&nctx->hw.eng3d);
  133.         nouveau_object_del(&nctx->hw.eng3dm);
  134.         nouveau_object_del(&nctx->hw.surf3d);
  135.  
  136.         nouveau_context_deinit(ctx);
  137.         free(ctx);
  138. }
  139.  
  140. static struct gl_context *
  141. nv04_context_create(struct nouveau_screen *screen, const struct gl_config *visual,
  142.                     struct gl_context *share_ctx)
  143. {
  144.         struct nv04_context *nctx;
  145.         struct nouveau_hw_state *hw;
  146.         struct gl_context *ctx;
  147.         int ret;
  148.  
  149.         nctx = CALLOC_STRUCT(nv04_context);
  150.         if (!nctx)
  151.                 return NULL;
  152.  
  153.         ctx = &nctx->base.base;
  154.         hw = &nctx->base.hw;
  155.  
  156.         if (!nouveau_context_init(ctx, screen, visual, share_ctx))
  157.                 goto fail;
  158.  
  159.         /* GL constants. */
  160.         ctx->Const.MaxTextureLevels = 11;
  161.         ctx->Const.MaxTextureCoordUnits = NV04_TEXTURE_UNITS;
  162.         ctx->Const.FragmentProgram.MaxTextureImageUnits = NV04_TEXTURE_UNITS;
  163.         ctx->Const.MaxTextureUnits = NV04_TEXTURE_UNITS;
  164.         ctx->Const.MaxTextureMaxAnisotropy = 2;
  165.         ctx->Const.MaxTextureLodBias = 15;
  166.  
  167.         /* 2D engine. */
  168.         ret = nv04_surface_init(ctx);
  169.         if (!ret)
  170.                 goto fail;
  171.  
  172.         /* 3D engine. */
  173.         ret = nouveau_object_new(context_chan(ctx), 0xbeef0001,
  174.                                  NV04_TEXTURED_TRIANGLE_CLASS, NULL, 0,
  175.                                  &hw->eng3d);
  176.         if (ret)
  177.                 goto fail;
  178.  
  179.         ret = nouveau_object_new(context_chan(ctx), 0xbeef0002,
  180.                                  NV04_MULTITEX_TRIANGLE_CLASS, NULL, 0,
  181.                                  &hw->eng3dm);
  182.         if (ret)
  183.                 goto fail;
  184.  
  185.         ret = nouveau_object_new(context_chan(ctx), 0xbeef0003,
  186.                                  NV04_SURFACE_3D_CLASS, NULL, 0,
  187.                                  &hw->surf3d);
  188.         if (ret)
  189.                 goto fail;
  190.  
  191.         init_dummy_texture(ctx);
  192.         nv04_hwctx_init(ctx);
  193.         nv04_render_init(ctx);
  194.  
  195.         return ctx;
  196.  
  197. fail:
  198.         nv04_context_destroy(ctx);
  199.         return NULL;
  200. }
  201.  
  202. const struct nouveau_driver nv04_driver = {
  203.         .context_create = nv04_context_create,
  204.         .context_destroy = nv04_context_destroy,
  205.         .surface_copy = nv04_surface_copy,
  206.         .surface_fill = nv04_surface_fill,
  207.         .emit = (nouveau_state_func[]) {
  208.                 nv04_defer_control,
  209.                 nouveau_emit_nothing,
  210.                 nv04_defer_blend,
  211.                 nv04_defer_blend,
  212.                 nouveau_emit_nothing,
  213.                 nouveau_emit_nothing,
  214.                 nouveau_emit_nothing,
  215.                 nouveau_emit_nothing,
  216.                 nouveau_emit_nothing,
  217.                 nouveau_emit_nothing,
  218.                 nv04_defer_control,
  219.                 nouveau_emit_nothing,
  220.                 nv04_defer_control,
  221.                 nouveau_emit_nothing,
  222.                 nv04_defer_control,
  223.                 nv04_defer_control,
  224.                 nouveau_emit_nothing,
  225.                 nv04_emit_framebuffer,
  226.                 nv04_defer_blend,
  227.                 nouveau_emit_nothing,
  228.                 nouveau_emit_nothing,
  229.                 nouveau_emit_nothing,
  230.                 nouveau_emit_nothing,
  231.                 nouveau_emit_nothing,
  232.                 nouveau_emit_nothing,
  233.                 nouveau_emit_nothing,
  234.                 nouveau_emit_nothing,
  235.                 nouveau_emit_nothing,
  236.                 nouveau_emit_nothing,
  237.                 nouveau_emit_nothing,
  238.                 nouveau_emit_nothing,
  239.                 nouveau_emit_nothing,
  240.                 nouveau_emit_nothing,
  241.                 nouveau_emit_nothing,
  242.                 nouveau_emit_nothing,
  243.                 nouveau_emit_nothing,
  244.                 nouveau_emit_nothing,
  245.                 nouveau_emit_nothing,
  246.                 nouveau_emit_nothing,
  247.                 nouveau_emit_nothing,
  248.                 nouveau_emit_nothing,
  249.                 nouveau_emit_nothing,
  250.                 nouveau_emit_nothing,
  251.                 nouveau_emit_nothing,
  252.                 nouveau_emit_nothing,
  253.                 nouveau_emit_nothing,
  254.                 nouveau_emit_nothing,
  255.                 nouveau_emit_nothing,
  256.                 nv04_emit_scissor,
  257.                 nv04_defer_blend,
  258.                 nv04_defer_control,
  259.                 nv04_defer_control,
  260.                 nv04_defer_control,
  261.                 nv04_emit_tex_env,
  262.                 nv04_emit_tex_env,
  263.                 nouveau_emit_nothing,
  264.                 nouveau_emit_nothing,
  265.                 nouveau_emit_nothing,
  266.                 nouveau_emit_nothing,
  267.                 nouveau_emit_nothing,
  268.                 nouveau_emit_nothing,
  269.                 nouveau_emit_nothing,
  270.                 nouveau_emit_nothing,
  271.                 nouveau_emit_nothing,
  272.                 nouveau_emit_nothing,
  273.                 nv04_emit_tex_obj,
  274.                 nv04_emit_tex_obj,
  275.                 nouveau_emit_nothing,
  276.                 nouveau_emit_nothing,
  277.                 nouveau_emit_nothing,
  278.                 nv04_emit_blend,
  279.                 nv04_emit_control,
  280.         },
  281.         .num_emit = NUM_NV04_STATE,
  282. };
  283.