Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright (C) 2009 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 "nv_object.xml.h"
  32. #include "nv10_3d.xml.h"
  33. #include "nv10_driver.h"
  34.  
  35. static inline unsigned
  36. get_rt_format(gl_format format)
  37. {
  38.         switch (format) {
  39.         case MESA_FORMAT_XRGB8888:
  40.                 return NV10_3D_RT_FORMAT_COLOR_X8R8G8B8;
  41.         case MESA_FORMAT_ARGB8888:
  42.                 return NV10_3D_RT_FORMAT_COLOR_A8R8G8B8;
  43.         case MESA_FORMAT_RGB565:
  44.                 return NV10_3D_RT_FORMAT_COLOR_R5G6B5;
  45.         case MESA_FORMAT_Z16:
  46.                 return NV10_3D_RT_FORMAT_DEPTH_Z16;
  47.         case MESA_FORMAT_Z24_S8:
  48.                 return NV10_3D_RT_FORMAT_DEPTH_Z24S8;
  49.         default:
  50.                 assert(0);
  51.         }
  52. }
  53.  
  54. static void
  55. setup_hierz_buffer(struct gl_context *ctx)
  56. {
  57.         struct nouveau_pushbuf *push = context_push(ctx);
  58.         struct gl_framebuffer *fb = ctx->DrawBuffer;
  59.         struct nouveau_framebuffer *nfb = to_nouveau_framebuffer(fb);
  60.         unsigned pitch = align(fb->Width, 128),
  61.                 height = align(fb->Height, 2),
  62.                 size = pitch * height;
  63.  
  64.         if (!nfb->hierz.bo || nfb->hierz.bo->size != size) {
  65.                 union nouveau_bo_config config = {
  66.                         .nv04.surf_flags = NV04_BO_ZETA,
  67.                         .nv04.surf_pitch = 0
  68.                 };
  69.  
  70.                 nouveau_bo_ref(NULL, &nfb->hierz.bo);
  71.                 nouveau_bo_new(context_dev(ctx), NOUVEAU_BO_VRAM, 0, size,
  72.                                &config, &nfb->hierz.bo);
  73.         }
  74.  
  75.         PUSH_SPACE(push, 11);
  76.         BEGIN_NV04(push, NV17_3D(HIERZ_OFFSET), 1);
  77.         PUSH_MTHDl(push, NV17_3D(HIERZ_OFFSET), BUFCTX_FB,
  78.                          nfb->hierz.bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
  79.         BEGIN_NV04(push, NV17_3D(HIERZ_WINDOW_X), 4);
  80.         PUSH_DATAf(push, - 1792);
  81.         PUSH_DATAf(push, - 2304 + fb->Height);
  82.         PUSH_DATAf(push, fb->_DepthMaxF / 2);
  83.         PUSH_DATAf(push, 0);
  84.  
  85.         BEGIN_NV04(push, NV17_3D(HIERZ_PITCH), 1);
  86.         PUSH_DATA (push, pitch);
  87.  
  88.         BEGIN_NV04(push, NV17_3D(HIERZ_ENABLE), 1);
  89.         PUSH_DATA (push, 1);
  90. }
  91.  
  92. void
  93. nv10_emit_framebuffer(struct gl_context *ctx, int emit)
  94. {
  95.         struct nouveau_pushbuf *push = context_push(ctx);
  96.         struct gl_framebuffer *fb = ctx->DrawBuffer;
  97.         struct nouveau_surface *s;
  98.         unsigned rt_format = NV10_3D_RT_FORMAT_TYPE_LINEAR;
  99.         unsigned rt_pitch = 0, zeta_pitch = 0;
  100.         unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR;
  101.  
  102.         if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT)
  103.                 return;
  104.  
  105.         PUSH_RESET(push, BUFCTX_FB);
  106.  
  107.         /* At least nv11 seems to get sad if we don't do this before
  108.          * swapping RTs.*/
  109.         if (context_chipset(ctx) < 0x17) {
  110.                 int i;
  111.  
  112.                 for (i = 0; i < 6; i++) {
  113.                         BEGIN_NV04(push, NV04_GRAPH(3D, NOP), 1);
  114.                         PUSH_DATA (push, 0);
  115.                 }
  116.         }
  117.  
  118.         /* Render target */
  119.         if (fb->_ColorDrawBuffers[0]) {
  120.                 s = &to_nouveau_renderbuffer(
  121.                         fb->_ColorDrawBuffers[0])->surface;
  122.  
  123.                 rt_format |= get_rt_format(s->format);
  124.                 zeta_pitch = rt_pitch = s->pitch;
  125.  
  126.                 BEGIN_NV04(push, NV10_3D(COLOR_OFFSET), 1);
  127.                 PUSH_MTHDl(push, NV10_3D(COLOR_OFFSET), BUFCTX_FB,
  128.                                  s->bo, 0, bo_flags);
  129.         }
  130.  
  131.         /* depth/stencil */
  132.         if (fb->Attachment[BUFFER_DEPTH].Renderbuffer) {
  133.                 s = &to_nouveau_renderbuffer(
  134.                         fb->Attachment[BUFFER_DEPTH].Renderbuffer)->surface;
  135.  
  136.                 rt_format |= get_rt_format(s->format);
  137.                 zeta_pitch = s->pitch;
  138.  
  139.                 BEGIN_NV04(push, NV10_3D(ZETA_OFFSET), 1);
  140.                 PUSH_MTHDl(push, NV10_3D(ZETA_OFFSET), BUFCTX_FB,
  141.                                  s->bo, 0, bo_flags);
  142.  
  143.                 if (context_chipset(ctx) >= 0x17) {
  144.                         setup_hierz_buffer(ctx);
  145.                         context_dirty(ctx, ZCLEAR);
  146.                 }
  147.         }
  148.  
  149.         BEGIN_NV04(push, NV10_3D(RT_FORMAT), 2);
  150.         PUSH_DATA (push, rt_format);
  151.         PUSH_DATA (push, zeta_pitch << 16 | rt_pitch);
  152.  
  153.         context_dirty(ctx, VIEWPORT);
  154.         context_dirty(ctx, SCISSOR);
  155. }
  156.  
  157. void
  158. nv10_emit_render_mode(struct gl_context *ctx, int emit)
  159. {
  160. }
  161.  
  162. void
  163. nv10_emit_scissor(struct gl_context *ctx, int emit)
  164. {
  165.         struct nouveau_pushbuf *push = context_push(ctx);
  166.         int x, y, w, h;
  167.  
  168.         get_scissors(ctx->DrawBuffer, &x, &y, &w, &h);
  169.  
  170.         BEGIN_NV04(push, NV10_3D(RT_HORIZ), 2);
  171.         PUSH_DATA (push, w << 16 | x);
  172.         PUSH_DATA (push, h << 16 | y);
  173. }
  174.  
  175. void
  176. nv10_emit_viewport(struct gl_context *ctx, int emit)
  177. {
  178.         struct nouveau_pushbuf *push = context_push(ctx);
  179.         struct gl_viewport_attrib *vp = &ctx->Viewport;
  180.         struct gl_framebuffer *fb = ctx->DrawBuffer;
  181.         float a[4] = {};
  182.  
  183.         get_viewport_translate(ctx, a);
  184.         a[0] -= 2048;
  185.         a[1] -= 2048;
  186.         if (nv10_use_viewport_zclear(ctx))
  187.                 a[2] = nv10_transform_depth(ctx, (vp->Far + vp->Near) / 2);
  188.  
  189.         BEGIN_NV04(push, NV10_3D(VIEWPORT_TRANSLATE_X), 4);
  190.         PUSH_DATAp(push, a, 4);
  191.  
  192.         BEGIN_NV04(push, NV10_3D(VIEWPORT_CLIP_HORIZ(0)), 1);
  193.         PUSH_DATA (push, (fb->Width - 1) << 16 | 0x08000800);
  194.         BEGIN_NV04(push, NV10_3D(VIEWPORT_CLIP_VERT(0)), 1);
  195.         PUSH_DATA (push, (fb->Height - 1) << 16 | 0x08000800);
  196.  
  197.         context_dirty(ctx, PROJECTION);
  198. }
  199.  
  200. void
  201. nv10_emit_zclear(struct gl_context *ctx, int emit)
  202. {
  203.         struct nouveau_context *nctx = to_nouveau_context(ctx);
  204.         struct nouveau_pushbuf *push = context_push(ctx);
  205.         struct nouveau_framebuffer *nfb =
  206.                 to_nouveau_framebuffer(ctx->DrawBuffer);
  207.  
  208.         if (nfb->hierz.bo) {
  209.                 BEGIN_NV04(push, NV17_3D(ZCLEAR_ENABLE), 2);
  210.                 PUSH_DATAb(push, !nctx->hierz.clear_blocked);
  211.                 PUSH_DATA (push, nfb->hierz.clear_value |
  212.                          (nctx->hierz.clear_seq & 0xff));
  213.         } else {
  214.                 BEGIN_NV04(push, NV10_3D(DEPTH_RANGE_NEAR), 2);
  215.                 PUSH_DATAf(push, nv10_transform_depth(ctx, 0));
  216.                 PUSH_DATAf(push, nv10_transform_depth(ctx, 1));
  217.                 context_dirty(ctx, VIEWPORT);
  218.         }
  219. }
  220.