Ejemplo n.º 1
0
RenderPassDesc
Driver::getRenderPassDesc()
{
   auto desc = RenderPassDesc {};

   auto cb_target_mask = getRegister<latte::CB_TARGET_MASK>(latte::Register::CB_TARGET_MASK);

   for (auto i = 0u; i < latte::MaxRenderTargets; ++i) {
      auto targetMask = (cb_target_mask.value >> (i * 4)) & 0xF;

      auto cb_color_base = getRegister<latte::CB_COLORN_BASE>(latte::Register::CB_COLOR0_BASE + i * 4);
      auto cb_color_info = getRegister<latte::CB_COLORN_INFO>(latte::Register::CB_COLOR0_INFO + i * 4);

      if (!!targetMask && cb_color_base.BASE_256B() != 0) {
         desc.colorTargets[i] = RenderPassDesc::ColorTarget {
            true,
            cb_color_info.FORMAT(),
            cb_color_info.NUMBER_TYPE(),
            1
         };
      } else {
         desc.colorTargets[i] = RenderPassDesc::ColorTarget {
            false,
            latte::CB_FORMAT::COLOR_INVALID,
            latte::CB_NUMBER_TYPE::UNORM,
            0
         };
      }
   }

   auto db_depth_control = getRegister<latte::DB_DEPTH_CONTROL>(latte::Register::DB_DEPTH_CONTROL);
   auto zEnable = db_depth_control.Z_ENABLE();
   auto stencilEnable = db_depth_control.STENCIL_ENABLE();
   auto depthEnabled = zEnable || stencilEnable;

   auto db_depth_base = getRegister<latte::DB_DEPTH_BASE>(latte::Register::DB_DEPTH_BASE);
   auto db_depth_info = getRegister<latte::DB_DEPTH_INFO>(latte::Register::DB_DEPTH_INFO);

   if (depthEnabled && db_depth_base.BASE_256B() != 0) {
      desc.depthTarget = RenderPassDesc::DepthStencilTarget {
         true,
         db_depth_info.FORMAT()
      };
   } else {
      desc.depthTarget = {
         false,
         latte::DB_FORMAT::DEPTH_INVALID
      };
   }

   return desc;
}
Ejemplo n.º 2
0
static void *
nv30_zsa_state_create(struct pipe_context *pipe,
                      const struct pipe_depth_stencil_alpha_state *cso)
{
   struct nouveau_object *eng3d = nv30_context(pipe)->screen->eng3d;
   struct nv30_zsa_stateobj *so;

   so = CALLOC_STRUCT(nv30_zsa_stateobj);
   if (!so)
      return NULL;
   so->pipe = *cso;

   SB_MTHD30(so, DEPTH_FUNC, 3);
   SB_DATA  (so, nvgl_comparison_op(cso->depth.func));
   SB_DATA  (so, cso->depth.writemask);
   SB_DATA  (so, cso->depth.enabled);

   if (eng3d->oclass == NV35_3D_CLASS || eng3d->oclass >= NV40_3D_CLASS) {
      SB_MTHD35(so, DEPTH_BOUNDS_TEST_ENABLE, 3);
      SB_DATA  (so, cso->depth.bounds_test);
      SB_DATA  (so, fui(cso->depth.bounds_min));
      SB_DATA  (so, fui(cso->depth.bounds_max));
   }

   if (cso->stencil[0].enabled) {
      SB_MTHD30(so, STENCIL_ENABLE(0), 3);
      SB_DATA  (so, 1);
      SB_DATA  (so, cso->stencil[0].writemask);
      SB_DATA  (so, nvgl_comparison_op(cso->stencil[0].func));
      SB_MTHD30(so, STENCIL_FUNC_MASK(0), 4);
      SB_DATA  (so, cso->stencil[0].valuemask);
      SB_DATA  (so, nvgl_stencil_op(cso->stencil[0].fail_op));
      SB_DATA  (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
      SB_DATA  (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
   } else {
      SB_MTHD30(so, STENCIL_ENABLE(0), 2);
      SB_DATA  (so, 0);
      SB_DATA  (so, 0x000000ff);
   }

   if (cso->stencil[1].enabled) {
      SB_MTHD30(so, STENCIL_ENABLE(1), 3);
      SB_DATA  (so, 1);
      SB_DATA  (so, cso->stencil[1].writemask);
      SB_DATA  (so, nvgl_comparison_op(cso->stencil[1].func));
      SB_MTHD30(so, STENCIL_FUNC_MASK(1), 4);
      SB_DATA  (so, cso->stencil[1].valuemask);
      SB_DATA  (so, nvgl_stencil_op(cso->stencil[1].fail_op));
      SB_DATA  (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
      SB_DATA  (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
   } else {
      SB_MTHD30(so, STENCIL_ENABLE(1), 1);
      SB_DATA  (so, 0);
   }

   SB_MTHD30(so, ALPHA_FUNC_ENABLE, 3);
   SB_DATA  (so, cso->alpha.enabled ? 1 : 0);
   SB_DATA  (so, nvgl_comparison_op(cso->alpha.func));
   SB_DATA  (so, float_to_ubyte(cso->alpha.ref_value));

   return so;
}
Ejemplo n.º 3
0
static void
nv30_transfer_rect_blit(XFER_ARGS)
{
   struct nv04_resource *fp = nv30_transfer_rect_fragprog(nv30);
   struct nouveau_heap *vp = nv30_transfer_rect_vertprog(nv30);
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   struct nouveau_pushbuf_refn refs[] = {
      { fp->bo, fp->domain | NOUVEAU_BO_RD },
      { src->bo, src->domain | NOUVEAU_BO_RD },
      { dst->bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR },
   };
   u32 texfmt, texswz;
   u32 format, stride;

   if (nouveau_pushbuf_space(push, 512, 8, 0) ||
       nouveau_pushbuf_refn (push, refs, sizeof(refs) / sizeof(refs[0])))
      return;

   /* various switches depending on cpp of the transfer */
   switch (dst->cpp) {
   case 4:
      format = NV30_3D_RT_FORMAT_COLOR_A8R8G8B8 |
               NV30_3D_RT_FORMAT_ZETA_Z24S8;
      texfmt = NV40_3D_TEX_FORMAT_FORMAT_A8R8G8B8;
      texswz = 0x0000aae4;
      break;
   case 2:
      format = NV30_3D_RT_FORMAT_COLOR_R5G6B5 |
               NV30_3D_RT_FORMAT_ZETA_Z16;
      texfmt = NV40_3D_TEX_FORMAT_FORMAT_R5G6B5;
      texswz = 0x0000a9e4;
      break;
   case 1:
      format = NV30_3D_RT_FORMAT_COLOR_B8 |
               NV30_3D_RT_FORMAT_ZETA_Z16;
      texfmt = NV40_3D_TEX_FORMAT_FORMAT_L8;
      texswz = 0x0000aaff;
      break;
   default:
      assert(0);
      return;
   }

   /* render target */
   if (!dst->pitch) {
      format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED;
      format |= util_logbase2(dst->w) << 16;
      format |= util_logbase2(dst->h) << 24;
      stride  = 64;
   } else {
      format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
      stride  = dst->pitch;
   }

   BEGIN_NV04(push, NV30_3D(VIEWPORT_HORIZ), 2);
   PUSH_DATA (push, dst->w << 16);
   PUSH_DATA (push, dst->h << 16);
   BEGIN_NV04(push, NV30_3D(RT_HORIZ), 5);
   PUSH_DATA (push, dst->w << 16);
   PUSH_DATA (push, dst->h << 16);
   PUSH_DATA (push, format);
   PUSH_DATA (push, stride);
   PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0);
   BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
   PUSH_DATA (push, NV30_3D_RT_ENABLE_COLOR0);

   nv30->dirty |= NV30_NEW_FRAMEBUFFER;

   /* viewport state */
   BEGIN_NV04(push, NV30_3D(VIEWPORT_TRANSLATE_X), 8);
   PUSH_DATAf(push, 0.0);
   PUSH_DATAf(push, 0.0);
   PUSH_DATAf(push, 0.0);
   PUSH_DATAf(push, 0.0);
   PUSH_DATAf(push, 1.0);
   PUSH_DATAf(push, 1.0);
   PUSH_DATAf(push, 1.0);
   PUSH_DATAf(push, 1.0);
   BEGIN_NV04(push, NV30_3D(DEPTH_RANGE_NEAR), 2);
   PUSH_DATAf(push, 0.0);
   PUSH_DATAf(push, 1.0);

   nv30->dirty |= NV30_NEW_VIEWPORT;

   /* blend state */
   BEGIN_NV04(push, NV30_3D(COLOR_LOGIC_OP_ENABLE), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV30_3D(DITHER_ENABLE), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV30_3D(BLEND_FUNC_ENABLE), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV30_3D(COLOR_MASK), 1);
   PUSH_DATA (push, 0x01010101);

   nv30->dirty |= NV30_NEW_BLEND;

   /* depth-stencil-alpha state */
   BEGIN_NV04(push, NV30_3D(DEPTH_WRITE_ENABLE), 2);
   PUSH_DATA (push, 0);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV30_3D(STENCIL_ENABLE(0)), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV30_3D(STENCIL_ENABLE(1)), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV30_3D(ALPHA_FUNC_ENABLE), 1);
   PUSH_DATA (push, 0);

   nv30->dirty |= NV30_NEW_ZSA;

   /* rasterizer state */
   BEGIN_NV04(push, NV30_3D(SHADE_MODEL), 1);
   PUSH_DATA (push, NV30_3D_SHADE_MODEL_FLAT);
   BEGIN_NV04(push, NV30_3D(CULL_FACE_ENABLE), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV30_3D(POLYGON_MODE_FRONT), 2);
   PUSH_DATA (push, NV30_3D_POLYGON_MODE_FRONT_FILL);
   PUSH_DATA (push, NV30_3D_POLYGON_MODE_BACK_FILL);
   BEGIN_NV04(push, NV30_3D(POLYGON_OFFSET_FILL_ENABLE), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV30_3D(POLYGON_STIPPLE_ENABLE), 1);
   PUSH_DATA (push, 0);

   nv30->state.scissor_off = 0;
   nv30->dirty |= NV30_NEW_RASTERIZER;

   /* vertex program */
   BEGIN_NV04(push, NV30_3D(VP_START_FROM_ID), 1);
   PUSH_DATA (push, vp->start);
   BEGIN_NV04(push, NV40_3D(VP_ATTRIB_EN), 2);
   PUSH_DATA (push, 0x00000101); /* attrib: 0, 8 */
   PUSH_DATA (push, 0x00004000); /* result: hpos, tex0 */
   BEGIN_NV04(push, NV30_3D(ENGINE), 1);
   PUSH_DATA (push, 0x00000103);
   BEGIN_NV04(push, NV30_3D(VP_CLIP_PLANES_ENABLE), 1);
   PUSH_DATA (push, 0x00000000);

   nv30->dirty |= NV30_NEW_VERTPROG;
   nv30->dirty |= NV30_NEW_CLIP;

   /* fragment program */
   BEGIN_NV04(push, NV30_3D(FP_ACTIVE_PROGRAM), 1);
   PUSH_RELOC(push, fp->bo, fp->offset, fp->domain |
                    NOUVEAU_BO_LOW | NOUVEAU_BO_OR,
                    NV30_3D_FP_ACTIVE_PROGRAM_DMA0,
                    NV30_3D_FP_ACTIVE_PROGRAM_DMA1);
   BEGIN_NV04(push, NV30_3D(FP_CONTROL), 1);
   PUSH_DATA (push, 0x02000000);

   nv30->state.fragprog = NULL;
   nv30->dirty |= NV30_NEW_FRAGPROG;

   /* texture */
   texfmt |= 1 << NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT;
   texfmt |= NV30_3D_TEX_FORMAT_NO_BORDER;
   texfmt |= NV40_3D_TEX_FORMAT_RECT;
   texfmt |= 0x00008000;
   if (src->d < 2)
      texfmt |= NV30_3D_TEX_FORMAT_DIMS_2D;
   else
      texfmt |= NV30_3D_TEX_FORMAT_DIMS_3D;
   if (src->pitch)
      texfmt |= NV40_3D_TEX_FORMAT_LINEAR;

   BEGIN_NV04(push, NV30_3D(TEX_OFFSET(0)), 8);
   PUSH_RELOC(push, src->bo, src->offset, NOUVEAU_BO_LOW, 0, 0);
   PUSH_RELOC(push, src->bo, texfmt, NOUVEAU_BO_OR,
                    NV30_3D_TEX_FORMAT_DMA0, NV30_3D_TEX_FORMAT_DMA1);
   PUSH_DATA (push, NV30_3D_TEX_WRAP_S_CLAMP_TO_EDGE |
                    NV30_3D_TEX_WRAP_T_CLAMP_TO_EDGE |
                    NV30_3D_TEX_WRAP_R_CLAMP_TO_EDGE);
   PUSH_DATA (push, NV40_3D_TEX_ENABLE_ENABLE);
   PUSH_DATA (push, texswz);
   switch (filter) {
   case BILINEAR:
      PUSH_DATA (push, NV30_3D_TEX_FILTER_MIN_LINEAR |
                       NV30_3D_TEX_FILTER_MAG_LINEAR | 0x00002000);
      break;
   default:
      PUSH_DATA (push, NV30_3D_TEX_FILTER_MIN_NEAREST |
                       NV30_3D_TEX_FILTER_MAG_NEAREST | 0x00002000);
      break;
   }
   PUSH_DATA (push, (src->w << 16) | src->h);
   PUSH_DATA (push, 0x00000000);
   BEGIN_NV04(push, NV40_3D(TEX_SIZE1(0)), 1);
   PUSH_DATA (push, 0x00100000 | src->pitch);
   BEGIN_NV04(push, SUBC_3D(0x0b40), 1);
   PUSH_DATA (push, src->d < 2 ? 0x00000001 : 0x00000000);
   BEGIN_NV04(push, NV40_3D(TEX_CACHE_CTL), 1);
   PUSH_DATA (push, 1);

   nv30->fragprog.dirty_samplers |= 1;
   nv30->dirty |= NV30_NEW_FRAGTEX;

   /* blit! */
   BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2);
   PUSH_DATA (push, (dst->x1 - dst->x0) << 16 | dst->x0);
   PUSH_DATA (push, (dst->y1 - dst->y0) << 16 | dst->y0);
   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
   PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_QUADS);
   BEGIN_NV04(push, NV30_3D(VTX_ATTR_3F(8)), 3);
   PUSH_DATAf(push, src->x0);
   PUSH_DATAf(push, src->y0);
   PUSH_DATAf(push, src->z);
   BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1);
   PUSH_DATA (push, (dst->y0 << 16) | dst->x0);
   BEGIN_NV04(push, NV30_3D(VTX_ATTR_3F(8)), 3);
   PUSH_DATAf(push, src->x1);
   PUSH_DATAf(push, src->y0);
   PUSH_DATAf(push, src->z);
   BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1);
   PUSH_DATA (push, (dst->y0 << 16) | dst->x1);
   BEGIN_NV04(push, NV30_3D(VTX_ATTR_3F(8)), 3);
   PUSH_DATAf(push, src->x1);
   PUSH_DATAf(push, src->y1);
   PUSH_DATAf(push, src->z);
   BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1);
   PUSH_DATA (push, (dst->y1 << 16) | dst->x1);
   BEGIN_NV04(push, NV30_3D(VTX_ATTR_3F(8)), 3);
   PUSH_DATAf(push, src->x0);
   PUSH_DATAf(push, src->y1);
   PUSH_DATAf(push, src->z);
   BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1);
   PUSH_DATA (push, (dst->y1 << 16) | dst->x0);
   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
   PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
}
Ejemplo n.º 4
0
bool GLDriver::checkActiveDepthBuffer()
{
   auto db_depth_base = getRegister<latte::DB_DEPTH_BASE>(latte::Register::DB_DEPTH_BASE);
   auto db_depth_size = getRegister<latte::DB_DEPTH_SIZE>(latte::Register::DB_DEPTH_SIZE);
   auto db_depth_info = getRegister<latte::DB_DEPTH_INFO>(latte::Register::DB_DEPTH_INFO);
   auto db_depth_control = getRegister<latte::DB_DEPTH_CONTROL>(latte::Register::DB_DEPTH_CONTROL);
   auto format = db_depth_info.FORMAT();
   auto z_enable = db_depth_control.Z_ENABLE();
   auto stencil_enable = db_depth_control.STENCIL_ENABLE();

   // We unbind the depth buffer whenever depth testing is disabled so a
   //  size mismatch with color buffers doesn't clip render operations, but
   //  we have to look up the surface regardless of whether depth testing
   //  is enabled; if it's a combined depth/stencil format and stencil
   //  testing is enabled, we still have to bind the buffer to the stencil
   //  attachment.
   SurfaceBuffer *surface;

   if (db_depth_base.BASE_256B()) {
      surface = getDepthBuffer(db_depth_base, db_depth_size, db_depth_info, false);
   } else {
      surface = nullptr;
   }

   auto surfaceObject = surface ? surface->active->object : 0;

   if (format != latte::DB_FORMAT::DEPTH_8_24
    && format != latte::DB_FORMAT::DEPTH_8_24_FLOAT
    && format != latte::DB_FORMAT::DEPTH_X8_24
    && format != latte::DB_FORMAT::DEPTH_X8_24_FLOAT
    && format != latte::DB_FORMAT::DEPTH_X24_8_32_FLOAT) {
      // You cannot bind a stencil buffer if the framebuffer does not support it.
      stencil_enable = false;
   }

   if (surfaceObject != mDepthBufferCache.object
    || z_enable != mDepthBufferCache.depthBound
    || stencil_enable != mDepthBufferCache.stencilBound) {
      if (z_enable && stencil_enable) {
         gl::glFramebufferTexture(gl::GL_FRAMEBUFFER, gl::GL_DEPTH_STENCIL_ATTACHMENT, surfaceObject, 0);
      } else if (!z_enable && !stencil_enable) {
         if (mDepthBufferCache.depthBound || mDepthBufferCache.stencilBound) {
            gl::glFramebufferTexture(gl::GL_FRAMEBUFFER, gl::GL_DEPTH_STENCIL_ATTACHMENT, 0, 0);
         }
      } else if (z_enable) {
         decaf_check(!stencil_enable);

         if (mDepthBufferCache.stencilBound) {
            gl::glFramebufferTexture(gl::GL_FRAMEBUFFER, gl::GL_STENCIL_ATTACHMENT, 0, 0);
         }

         gl::glFramebufferTexture(gl::GL_FRAMEBUFFER, gl::GL_DEPTH_ATTACHMENT, surfaceObject, 0);
      } else {
         decaf_check(!z_enable && stencil_enable);

         if (mDepthBufferCache.depthBound) {
            gl::glFramebufferTexture(gl::GL_FRAMEBUFFER, gl::GL_DEPTH_ATTACHMENT, 0, 0);
         }

         gl::glFramebufferTexture(gl::GL_FRAMEBUFFER, gl::GL_STENCIL_ATTACHMENT, surfaceObject, 0);
      }

      mFramebufferChanged = true;

      mDepthBufferCache.object = surfaceObject;
      mDepthBufferCache.depthBound = z_enable;
      mDepthBufferCache.stencilBound = stencil_enable;
   }

   return true;
}