Exemplo n.º 1
0
void
GalliumContext::ResizeViewport(int32 width, int32 height)
{
	CALLED();
	for (context_id i = 0; i < CONTEXT_MAX; i++) {
		if (fContext[i] && fContext[i]->st) {
			struct st_context *stContext = (struct st_context*)fContext[i]->st;
			_mesa_set_viewport(stContext->ctx, 0, 0, 0, width, height);
        		st_manager_validate_framebuffers(stContext);
		}
	}
}
Exemplo n.º 2
0
void st_validate_state( struct st_context *st )
{
    struct st_state_flags *state = &st->dirty;
    GLuint i;

    /* The bitmap cache is immune to pixel unpack changes.
     * Note that GLUT makes several calls to glPixelStore for each
     * bitmap char it draws so this is an important check.
     */
    if (state->mesa & ~_NEW_PACKUNPACK)
        st_flush_bitmap_cache(st);

    check_program_state( st );

    st_manager_validate_framebuffers(st);

    if (state->st == 0)
        return;

    /*printf("%s %x/%x\n", __FUNCTION__, state->mesa, state->st);*/

    if (1) {
        /* Debug version which enforces various sanity checks on the
         * state flags which are generated and checked to help ensure
         * state atoms are ordered correctly in the list.
         */
        struct st_state_flags examined, prev;
        memset(&examined, 0, sizeof(examined));
        prev = *state;

        for (i = 0; i < Elements(atoms); i++) {
            const struct st_tracked_state *atom = atoms[i];
            struct st_state_flags generated;

            /*printf("atom %s %x/%x\n", atom->name, atom->dirty.mesa, atom->dirty.st);*/

            if (!(atom->dirty.mesa || atom->dirty.st) ||
                    !atom->update) {
                printf("malformed atom %s\n", atom->name);
                assert(0);
            }

            if (check_state(state, &atom->dirty)) {
                atoms[i]->update( st );
                /*printf("after: %x\n", atom->dirty.mesa);*/
            }

            accumulate_state(&examined, &atom->dirty);

            /* generated = (prev ^ state)
             * if (examined & generated)
             *     fail;
             */
            xor_states(&generated, &prev, state);
            assert(!check_state(&examined, &generated));
            prev = *state;
        }
        /*printf("\n");*/

    }
    else {
        for (i = 0; i < Elements(atoms); i++) {
            if (check_state(state, &atoms[i]->dirty))
                atoms[i]->update( st );
        }
    }

    memset(state, 0, sizeof(*state));
}
Exemplo n.º 3
0
static void
st_BlitFramebuffer(struct gl_context *ctx,
                   struct gl_framebuffer *readFB,
                   struct gl_framebuffer *drawFB,
                   GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
                   GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
                   GLbitfield mask, GLenum filter)
{
   const GLbitfield depthStencil = (GL_DEPTH_BUFFER_BIT |
                                    GL_STENCIL_BUFFER_BIT);
   struct st_context *st = st_context(ctx);
   const uint pFilter = ((filter == GL_NEAREST)
                         ? PIPE_TEX_FILTER_NEAREST
                         : PIPE_TEX_FILTER_LINEAR);
   struct {
      GLint srcX0, srcY0, srcX1, srcY1;
      GLint dstX0, dstY0, dstX1, dstY1;
   } clip;
   struct pipe_blit_info blit;

   st_manager_validate_framebuffers(st);

   /* Make sure bitmap rendering has landed in the framebuffers */
   st_flush_bitmap_cache(st);
   st_invalidate_readpix_cache(st);

   clip.srcX0 = srcX0;
   clip.srcY0 = srcY0;
   clip.srcX1 = srcX1;
   clip.srcY1 = srcY1;
   clip.dstX0 = dstX0;
   clip.dstY0 = dstY0;
   clip.dstX1 = dstX1;
   clip.dstY1 = dstY1;

   /* NOTE: If the src and dst dimensions don't match, we cannot simply adjust
    * the integer coordinates to account for clipping (or scissors) because that
    * would make us cut off fractional parts, affecting the result of the blit.
    *
    * XXX: This should depend on mask !
    */
   if (!_mesa_clip_blit(ctx, readFB, drawFB,
                        &clip.srcX0, &clip.srcY0, &clip.srcX1, &clip.srcY1,
                        &clip.dstX0, &clip.dstY0, &clip.dstX1, &clip.dstY1)) {
      return; /* nothing to draw/blit */
   }
   memset(&blit, 0, sizeof(struct pipe_blit_info));
   blit.scissor_enable =
      (dstX0 != clip.dstX0) ||
      (dstY0 != clip.dstY0) ||
      (dstX1 != clip.dstX1) ||
      (dstY1 != clip.dstY1);

   if (st_fb_orientation(drawFB) == Y_0_TOP) {
      /* invert Y for dest */
      dstY0 = drawFB->Height - dstY0;
      dstY1 = drawFB->Height - dstY1;
      /* invert Y for clip */
      clip.dstY0 = drawFB->Height - clip.dstY0;
      clip.dstY1 = drawFB->Height - clip.dstY1;
   }
   if (blit.scissor_enable) {
      blit.scissor.minx = MIN2(clip.dstX0, clip.dstX1);
      blit.scissor.miny = MIN2(clip.dstY0, clip.dstY1);
      blit.scissor.maxx = MAX2(clip.dstX0, clip.dstX1);
      blit.scissor.maxy = MAX2(clip.dstY0, clip.dstY1);
#if 0
      debug_printf("scissor = (%i,%i)-(%i,%i)\n",
                   blit.scissor.minx,blit.scissor.miny,
                   blit.scissor.maxx,blit.scissor.maxy);
#endif
   }

   if (st_fb_orientation(readFB) == Y_0_TOP) {
      /* invert Y for src */
      srcY0 = readFB->Height - srcY0;
      srcY1 = readFB->Height - srcY1;
   }

   if (srcY0 > srcY1 && dstY0 > dstY1) {
      /* Both src and dst are upside down.  Swap Y to make it
       * right-side up to increase odds of using a fast path.
       * Recall that all Gallium raster coords have Y=0=top.
       */
      GLint tmp;
      tmp = srcY0;
      srcY0 = srcY1;
      srcY1 = tmp;
      tmp = dstY0;
      dstY0 = dstY1;
      dstY1 = tmp;
   }

   blit.src.box.depth = 1;
   blit.dst.box.depth = 1;

   /* Destination dimensions have to be positive: */
   if (dstX0 < dstX1) {
      blit.dst.box.x = dstX0;
      blit.src.box.x = srcX0;
      blit.dst.box.width = dstX1 - dstX0;
      blit.src.box.width = srcX1 - srcX0;
   } else {
      blit.dst.box.x = dstX1;
      blit.src.box.x = srcX1;
      blit.dst.box.width = dstX0 - dstX1;
      blit.src.box.width = srcX0 - srcX1;
   }
   if (dstY0 < dstY1) {
      blit.dst.box.y = dstY0;
      blit.src.box.y = srcY0;
      blit.dst.box.height = dstY1 - dstY0;
      blit.src.box.height = srcY1 - srcY0;
   } else {
      blit.dst.box.y = dstY1;
      blit.src.box.y = srcY1;
      blit.dst.box.height = dstY0 - dstY1;
      blit.src.box.height = srcY0 - srcY1;
   }

   if (drawFB != ctx->WinSysDrawBuffer)
      st_window_rectangles_to_blit(ctx, &blit);

   blit.filter = pFilter;
   blit.render_condition_enable = TRUE;
   blit.alpha_blend = FALSE;

   if (mask & GL_COLOR_BUFFER_BIT) {
      struct gl_renderbuffer_attachment *srcAtt =
         &readFB->Attachment[readFB->_ColorReadBufferIndex];

      blit.mask = PIPE_MASK_RGBA;

      if (srcAtt->Type == GL_TEXTURE) {
         struct st_texture_object *srcObj = st_texture_object(srcAtt->Texture);
         GLuint i;

         if (!srcObj || !srcObj->pt) {
            return;
         }

         for (i = 0; i < drawFB->_NumColorDrawBuffers; i++) {
            struct st_renderbuffer *dstRb =
               st_renderbuffer(drawFB->_ColorDrawBuffers[i]);

            if (dstRb) {
               struct pipe_surface *dstSurf = dstRb->surface;

               if (dstSurf) {
                  blit.dst.resource = dstSurf->texture;
                  blit.dst.level = dstSurf->u.tex.level;
                  blit.dst.box.z = dstSurf->u.tex.first_layer;
                  blit.dst.format = dstSurf->format;

                  blit.src.resource = srcObj->pt;
                  blit.src.level = srcAtt->TextureLevel;
                  blit.src.box.z = srcAtt->Zoffset + srcAtt->CubeMapFace;
                  blit.src.format = srcObj->pt->format;

                  st_adjust_blit_for_srgb(&blit, ctx->Color.sRGBEnabled);

                  st->pipe->blit(st->pipe, &blit);
                  dstRb->defined = true; /* front buffer tracking */
               }
            }
         }
      }
      else {
         struct st_renderbuffer *srcRb =
            st_renderbuffer(readFB->_ColorReadBuffer);
         struct pipe_surface *srcSurf;
         GLuint i;

         if (!srcRb || !srcRb->surface) {
            return;
         }

         srcSurf = srcRb->surface;

         for (i = 0; i < drawFB->_NumColorDrawBuffers; i++) {
            struct st_renderbuffer *dstRb =
               st_renderbuffer(drawFB->_ColorDrawBuffers[i]);

            if (dstRb) {
               struct pipe_surface *dstSurf = dstRb->surface;

               if (dstSurf) {
                  blit.dst.resource = dstSurf->texture;
                  blit.dst.level = dstSurf->u.tex.level;
                  blit.dst.box.z = dstSurf->u.tex.first_layer;
                  blit.dst.format = dstSurf->format;

                  blit.src.resource = srcSurf->texture;
                  blit.src.level = srcSurf->u.tex.level;
                  blit.src.box.z = srcSurf->u.tex.first_layer;
                  blit.src.format = srcSurf->format;

                  st_adjust_blit_for_srgb(&blit, ctx->Color.sRGBEnabled);

                  st->pipe->blit(st->pipe, &blit);
                  dstRb->defined = true; /* front buffer tracking */
               }
            }
         }
      }
   }

   if (mask & depthStencil) {
      /* depth and/or stencil blit */

      /* get src/dst depth surfaces */
      struct st_renderbuffer *srcDepthRb =
         st_renderbuffer(readFB->Attachment[BUFFER_DEPTH].Renderbuffer);
      struct st_renderbuffer *dstDepthRb = 
         st_renderbuffer(drawFB->Attachment[BUFFER_DEPTH].Renderbuffer);
      struct pipe_surface *dstDepthSurf =
         dstDepthRb ? dstDepthRb->surface : NULL;

      struct st_renderbuffer *srcStencilRb =
         st_renderbuffer(readFB->Attachment[BUFFER_STENCIL].Renderbuffer);
      struct st_renderbuffer *dstStencilRb =
         st_renderbuffer(drawFB->Attachment[BUFFER_STENCIL].Renderbuffer);
      struct pipe_surface *dstStencilSurf =
         dstStencilRb ? dstStencilRb->surface : NULL;

      if (_mesa_has_depthstencil_combined(readFB) &&
          _mesa_has_depthstencil_combined(drawFB)) {
         blit.mask = 0;
         if (mask & GL_DEPTH_BUFFER_BIT)
            blit.mask |= PIPE_MASK_Z;
         if (mask & GL_STENCIL_BUFFER_BIT)
            blit.mask |= PIPE_MASK_S;

         blit.dst.resource = dstDepthSurf->texture;
         blit.dst.level = dstDepthSurf->u.tex.level;
         blit.dst.box.z = dstDepthSurf->u.tex.first_layer;
         blit.dst.format = dstDepthSurf->format;

         blit.src.resource = srcDepthRb->texture;
         blit.src.level = srcDepthRb->surface->u.tex.level;
         blit.src.box.z = srcDepthRb->surface->u.tex.first_layer;
         blit.src.format = srcDepthRb->surface->format;

         st->pipe->blit(st->pipe, &blit);
      }
      else {
         /* blitting depth and stencil separately */

         if (mask & GL_DEPTH_BUFFER_BIT) {
            blit.mask = PIPE_MASK_Z;

            blit.dst.resource = dstDepthSurf->texture;
            blit.dst.level = dstDepthSurf->u.tex.level;
            blit.dst.box.z = dstDepthSurf->u.tex.first_layer;
            blit.dst.format = dstDepthSurf->format;

            blit.src.resource = srcDepthRb->texture;
            blit.src.level = srcDepthRb->surface->u.tex.level;
            blit.src.box.z = srcDepthRb->surface->u.tex.first_layer;
            blit.src.format = srcDepthRb->surface->format;

            st->pipe->blit(st->pipe, &blit);
         }

         if (mask & GL_STENCIL_BUFFER_BIT) {
            blit.mask = PIPE_MASK_S;

            blit.dst.resource = dstStencilSurf->texture;
            blit.dst.level = dstStencilSurf->u.tex.level;
            blit.dst.box.z = dstStencilSurf->u.tex.first_layer;
            blit.dst.format = dstStencilSurf->format;

            blit.src.resource = srcStencilRb->texture;
            blit.src.level = srcStencilRb->surface->u.tex.level;
            blit.src.box.z = srcStencilRb->surface->u.tex.first_layer;
            blit.src.format = srcStencilRb->surface->format;

            st->pipe->blit(st->pipe, &blit);
         }
      }
   }
}
Exemplo n.º 4
0
void st_validate_state( struct st_context *st, enum st_pipeline pipeline )
{
   const struct st_tracked_state **atoms;
   struct st_state_flags *state;
   GLuint num_atoms;
   GLuint i;

   /* Get pipeline state. */
   switch (pipeline) {
    case ST_PIPELINE_RENDER:
      atoms     = render_atoms;
      num_atoms = ARRAY_SIZE(render_atoms);
      state     = &st->dirty;
      break;
   case ST_PIPELINE_COMPUTE:
      atoms     = compute_atoms;
      num_atoms = ARRAY_SIZE(compute_atoms);
      state     = &st->dirty_cp;
      break;
   default:
      unreachable("Invalid pipeline specified");
   }

   /* Get Mesa driver state. */
   st->dirty.st |= st->ctx->NewDriverState;
   st->dirty_cp.st |= st->ctx->NewDriverState;
   st->ctx->NewDriverState = 0;

   if (pipeline == ST_PIPELINE_RENDER) {
      check_attrib_edgeflag(st);

      check_program_state(st);

      st_manager_validate_framebuffers(st);
   }

   if (state->st == 0 && state->mesa == 0)
      return;

   /*printf("%s %x/%x\n", __func__, state->mesa, state->st);*/

#ifdef DEBUG
   if (1) {
#else
   if (0) {
#endif
      /* Debug version which enforces various sanity checks on the
       * state flags which are generated and checked to help ensure
       * state atoms are ordered correctly in the list.
       */
      struct st_state_flags examined, prev;      
      memset(&examined, 0, sizeof(examined));
      prev = *state;

      for (i = 0; i < num_atoms; i++) {
	 const struct st_tracked_state *atom = atoms[i];
	 struct st_state_flags generated;
	 
	 /*printf("atom %s %x/%x\n", atom->name, atom->dirty.mesa, atom->dirty.st);*/

	 if (!(atom->dirty.mesa || atom->dirty.st) ||
	     !atom->update) {
	    printf("malformed atom %s\n", atom->name);
	    assert(0);
	 }

	 if (check_state(state, &atom->dirty)) {
	    atoms[i]->update( st );
	    /*printf("after: %x\n", atom->dirty.mesa);*/
	 }

	 accumulate_state(&examined, &atom->dirty);

	 /* generated = (prev ^ state)
	  * if (examined & generated)
	  *     fail;
	  */
	 xor_states(&generated, &prev, state);
	 assert(!check_state(&examined, &generated));
	 prev = *state;
      }
      /*printf("\n");*/

   }
   else {
      for (i = 0; i < num_atoms; i++) {
	 if (check_state(state, &atoms[i]->dirty))
	    atoms[i]->update( st );
      }
   }

   memset(state, 0, sizeof(*state));
}
Exemplo n.º 5
0
void st_validate_state( struct st_context *st, enum st_pipeline pipeline )
{
   struct gl_context *ctx = st->ctx;
   uint64_t dirty, pipeline_mask;
   uint32_t dirty_lo, dirty_hi;

   /* Get Mesa driver state.
    *
    * Inactive states are shader states not used by shaders at the moment.
    */
   st->dirty |= ctx->NewDriverState & st->active_states & ST_ALL_STATES_MASK;
   ctx->NewDriverState = 0;

   /* Get pipeline state. */
   switch (pipeline) {
   case ST_PIPELINE_RENDER:
      if (st->ctx->API == API_OPENGL_COMPAT)
         check_attrib_edgeflag(st);

      check_program_state(st);
      st_manager_validate_framebuffers(st);

      pipeline_mask = ST_PIPELINE_RENDER_STATE_MASK;
      break;

   case ST_PIPELINE_COMPUTE: {
      struct st_compute_program *old_cp = st->cp;
      struct gl_compute_program *new_cp = ctx->ComputeProgram._Current;

      if (new_cp != &old_cp->Base) {
         if (old_cp)
            st->dirty |= old_cp->affected_states;
         assert(new_cp);
         st->dirty |= st_compute_program(new_cp)->affected_states;
      }

      st->compute_shader_may_be_dirty = false;
      pipeline_mask = ST_PIPELINE_COMPUTE_STATE_MASK;
      break;
   }

   default:
      unreachable("Invalid pipeline specified");
   }

   dirty = st->dirty & pipeline_mask;
   if (!dirty)
      return;

   dirty_lo = dirty;
   dirty_hi = dirty >> 32;

   /* Update states.
    *
    * Don't use u_bit_scan64, it may be slower on 32-bit.
    */
   while (dirty_lo)
      atoms[u_bit_scan(&dirty_lo)]->update(st);
   while (dirty_hi)
      atoms[32 + u_bit_scan(&dirty_hi)]->update(st);

   /* Clear the render or compute state bits. */
   st->dirty &= ~pipeline_mask;
}
Exemplo n.º 6
0
void st_validate_state( struct st_context *st )
{
   struct st_state_flags *state = &st->dirty;
   GLuint i;

   /* Get Mesa driver state. */
   st->dirty.st |= st->ctx->NewDriverState;
   st->ctx->NewDriverState = 0;

   check_attrib_edgeflag(st);

   if (state->mesa)
      st_flush_bitmap_cache(st);

   check_program_state( st );

   st_manager_validate_framebuffers(st);

   if (state->st == 0)
      return;

   /*printf("%s %x/%x\n", __FUNCTION__, state->mesa, state->st);*/

#ifdef DEBUG
   if (1) {
#else
   if (0) {
#endif
      /* Debug version which enforces various sanity checks on the
       * state flags which are generated and checked to help ensure
       * state atoms are ordered correctly in the list.
       */
      struct st_state_flags examined, prev;      
      memset(&examined, 0, sizeof(examined));
      prev = *state;

      for (i = 0; i < ARRAY_SIZE(atoms); i++) {	 
	 const struct st_tracked_state *atom = atoms[i];
	 struct st_state_flags generated;
	 
	 /*printf("atom %s %x/%x\n", atom->name, atom->dirty.mesa, atom->dirty.st);*/

	 if (!(atom->dirty.mesa || atom->dirty.st) ||
	     !atom->update) {
	    printf("malformed atom %s\n", atom->name);
	    assert(0);
	 }

	 if (check_state(state, &atom->dirty)) {
	    atoms[i]->update( st );
	    /*printf("after: %x\n", atom->dirty.mesa);*/
	 }

	 accumulate_state(&examined, &atom->dirty);

	 /* generated = (prev ^ state)
	  * if (examined & generated)
	  *     fail;
	  */
	 xor_states(&generated, &prev, state);
	 assert(!check_state(&examined, &generated));
	 prev = *state;
      }
      /*printf("\n");*/

   }
   else {
      for (i = 0; i < ARRAY_SIZE(atoms); i++) {	 
	 if (check_state(state, &atoms[i]->dirty))
	    atoms[i]->update( st );
      }
   }

   memset(state, 0, sizeof(*state));
}
Exemplo n.º 7
0
void st_validate_state( struct st_context *st, enum st_pipeline pipeline )
{
   struct gl_context *ctx = st->ctx;
   uint64_t dirty, pipeline_mask;
   uint32_t dirty_lo, dirty_hi;

   /* Get Mesa driver state.
    *
    * Inactive states are shader states not used by shaders at the moment.
    */
   st->dirty |= ctx->NewDriverState & st->active_states & ST_ALL_STATES_MASK;
   ctx->NewDriverState = 0;

   /* Get pipeline state. */
   switch (pipeline) {
   case ST_PIPELINE_RENDER:
      if (st->ctx->API == API_OPENGL_COMPAT)
         check_attrib_edgeflag(st);

      if (st->gfx_shaders_may_be_dirty) {
         check_program_state(st);
         st->gfx_shaders_may_be_dirty = false;
      }

      st_manager_validate_framebuffers(st);

      pipeline_mask = ST_PIPELINE_RENDER_STATE_MASK;
      break;

   case ST_PIPELINE_CLEAR:
      st_manager_validate_framebuffers(st);
      pipeline_mask = ST_PIPELINE_CLEAR_STATE_MASK;
      break;

   case ST_PIPELINE_META:
      if (st->gfx_shaders_may_be_dirty) {
         check_program_state(st);
         st->gfx_shaders_may_be_dirty = false;
      }

      st_manager_validate_framebuffers(st);
      pipeline_mask = ST_PIPELINE_META_STATE_MASK;
      break;

   case ST_PIPELINE_UPDATE_FRAMEBUFFER:
      st_manager_validate_framebuffers(st);
      pipeline_mask = ST_PIPELINE_UPDATE_FB_STATE_MASK;
      break;

   case ST_PIPELINE_COMPUTE: {
      struct st_compute_program *old_cp = st->cp;
      struct gl_program *new_cp = ctx->ComputeProgram._Current;

      if (new_cp != &old_cp->Base) {
         if (old_cp)
            st->dirty |= old_cp->affected_states;
         assert(new_cp);
         st->dirty |= st_compute_program(new_cp)->affected_states;
      }

      st->compute_shader_may_be_dirty = false;

      /*
       * We add the ST_NEW_FB_STATE bit here as well, because glBindFramebuffer
       * acts as a barrier that breaks feedback loops between the framebuffer
       * and textures bound to the framebuffer, even when those textures are
       * accessed by compute shaders; so we must inform the driver of new
       * framebuffer state.
       */
      pipeline_mask = ST_PIPELINE_COMPUTE_STATE_MASK | ST_NEW_FB_STATE;
      break;
   }

   default:
      unreachable("Invalid pipeline specified");
   }

   dirty = st->dirty & pipeline_mask;
   if (!dirty)
      return;

   dirty_lo = dirty;
   dirty_hi = dirty >> 32;

   /* Update states.
    *
    * Don't use u_bit_scan64, it may be slower on 32-bit.
    */
   while (dirty_lo)
      update_functions[u_bit_scan(&dirty_lo)](st);
   while (dirty_hi)
      update_functions[32 + u_bit_scan(&dirty_hi)](st);

   /* Clear the render or compute state bits. */
   st->dirty &= ~pipeline_mask;
}