示例#1
0
void
GLDriver::decafClearDepthStencil(const pm4::DecafClearDepthStencil &data)
{
   auto db_depth_clear = getRegister<latte::DB_DEPTH_CLEAR>(latte::Register::DB_DEPTH_CLEAR);
   auto db_stencil_clear = getRegister<latte::DB_STENCIL_CLEAR>(latte::Register::DB_STENCIL_CLEAR);
   auto dbFormat = data.db_depth_info.FORMAT();
   auto hasStencil = (dbFormat == latte::DEPTH_8_24
                   || dbFormat == latte::DEPTH_8_24_FLOAT
                   || dbFormat == latte::DEPTH_X24_8_32_FLOAT);

   // Find our depthbuffer to clear
   auto db_depth_base = bit_cast<latte::DB_DEPTH_BASE>(data.bufferAddr);
   auto buffer = getDepthBuffer(db_depth_base, data.db_depth_size, data.db_depth_info);

   // Bind depth buffer
   if (hasStencil) {
      gl::glNamedFramebufferTexture(mDepthClearFrameBuffer, gl::GL_DEPTH_STENCIL_ATTACHMENT, buffer->object, 0);
   } else {
      gl::glNamedFramebufferTexture(mDepthClearFrameBuffer, gl::GL_STENCIL_ATTACHMENT, 0, 0);
      gl::glNamedFramebufferTexture(mDepthClearFrameBuffer, gl::GL_DEPTH_ATTACHMENT, buffer->object, 0);
   }

   // Check depth frame buffer is complete
   auto status = gl::glCheckNamedFramebufferStatus(mDepthClearFrameBuffer, gl::GL_DRAW_FRAMEBUFFER);

   if (status != gl::GL_FRAMEBUFFER_COMPLETE) {
      gLog->warn("Skipping clear with invalid depth buffer, status {}.", status);
      return;
   }

   // Clear depth buffer
   gl::glDisable(gl::GL_SCISSOR_TEST);

   if (hasStencil) {
      gl::glClearNamedFramebufferfi(mDepthClearFrameBuffer, gl::GL_DEPTH_STENCIL, 0, db_depth_clear.DEPTH_CLEAR, db_stencil_clear.CLEAR());
   } else {
      gl::glClearNamedFramebufferfv(mDepthClearFrameBuffer, gl::GL_DEPTH, 0, &db_depth_clear.DEPTH_CLEAR);
   }

   gl::glEnable(gl::GL_SCISSOR_TEST);
}
示例#2
0
bool GLDriver::checkActiveDepthBuffer()
{
   auto db_depth_base = getRegister<latte::DB_DEPTH_BASE>(latte::Register::DB_DEPTH_BASE);
   auto &active = mActiveDepthBuffer;

   if (!db_depth_base.BASE_256B) {
      if (active) {
         // Unbind depth buffer
         gl::glFramebufferTexture(gl::GL_FRAMEBUFFER, gl::GL_DEPTH_ATTACHMENT, 0, 0);
         active = nullptr;
      }

      return true;
   }

   // Bind depth buffer
   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);
   active = getDepthBuffer(db_depth_base, db_depth_size, db_depth_info);
   gl::glFramebufferTexture(gl::GL_FRAMEBUFFER, gl::GL_DEPTH_ATTACHMENT, active->object, 0);
   return true;
}
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;
}