Ejemplo n.º 1
0
static
void brw_update_texture_surface( GLcontext *ctx, 
				 GLuint unit,
				 struct brw_surface_state *surf )
{
   struct intel_context *intel = intel_context(ctx);
   struct brw_context *brw = brw_context(ctx);
   struct gl_texture_object *tObj = brw->attribs.Texture->Unit[unit]._Current;
   struct intel_texture_object *intelObj = intel_texture_object(tObj);
   struct gl_texture_image *firstImage = tObj->Image[0][intelObj->firstLevel];

   memset(surf, 0, sizeof(*surf));

   surf->ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;   
   surf->ss0.surface_type = translate_tex_target(tObj->Target);
   surf->ss0.surface_format = translate_tex_format(firstImage->TexFormat->MesaFormat, tObj->DepthMode);

   /* This is ok for all textures with channel width 8bit or less:
    */
/*    surf->ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */

   /* BRW_NEW_LOCK */
   surf->ss1.base_addr = bmBufferOffset(intel,
					intelObj->mt->region->buffer);

   surf->ss2.mip_count = intelObj->lastLevel - intelObj->firstLevel;
   surf->ss2.width = firstImage->Width - 1;
   surf->ss2.height = firstImage->Height - 1;

   surf->ss3.tile_walk = BRW_TILEWALK_XMAJOR;
   surf->ss3.tiled_surface = intelObj->mt->region->tiled; /* always zero */
   surf->ss3.pitch = (intelObj->mt->pitch * intelObj->mt->cpp) - 1;
   surf->ss3.depth = firstImage->Depth - 1;

   surf->ss4.min_lod = 0;
 
   if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
      surf->ss0.cube_pos_x = 1;
      surf->ss0.cube_pos_y = 1;
      surf->ss0.cube_pos_z = 1;
      surf->ss0.cube_neg_x = 1;
      surf->ss0.cube_neg_y = 1;
      surf->ss0.cube_neg_z = 1;
   }
}
Ejemplo n.º 2
0
void intelEmitFillBlit( struct intel_context *intel,
                        GLuint cpp,
                        GLshort dst_pitch,
                        struct buffer *dst_buffer,
                        GLuint dst_offset,
                        GLboolean dst_tiled,
                        GLshort x, GLshort y,
                        GLshort w, GLshort h,
                        GLuint color )
{
    GLuint BR13, CMD;
    BATCH_LOCALS;

    dst_pitch *= cpp;

    switch(cpp) {
    case 1:
    case 2:
    case 3:
        BR13 = (0xF0 << 16) | (1<<24);
        CMD = XY_COLOR_BLT_CMD;
        break;
    case 4:
        BR13 = (0xF0 << 16) | (1<<24) | (1<<25);
        CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA |
               XY_COLOR_BLT_WRITE_RGB);
        break;
    default:
        return;
    }

    if (dst_tiled) {
        CMD |= XY_DST_TILED;
        dst_pitch /= 4;
    }

    BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
    OUT_BATCH( CMD );
    OUT_BATCH( dst_pitch | BR13 );
    OUT_BATCH( (y << 16) | x );
    OUT_BATCH( ((y+h) << 16) | (x+w) );
    OUT_BATCH( bmBufferOffset(intel, dst_buffer) + dst_offset );
    OUT_BATCH( color );
    ADVANCE_BATCH();
}
Ejemplo n.º 3
0
/***********************************************************************
 * Emit all state:
 */
void brw_validate_state( struct brw_context *brw )
{
   struct brw_state_flags *state = &brw->state.dirty;
   GLuint i;

   state->mesa |= brw->intel.NewGLState;
   brw->intel.NewGLState = 0;

   if (brw->wrap)
      state->brw |= BRW_NEW_CONTEXT;

   if (brw->emit_state_always) {
      state->mesa |= ~0;
      state->brw |= ~0;
   }

   /* texenv program needs to notify us somehow when this happens: 
    * Some confusion about which state flag should represent this change.
    */
   if (brw->fragment_program != brw->attribs.FragmentProgram->_Current) {
      brw->fragment_program = brw->attribs.FragmentProgram->_Current;
      brw->state.dirty.mesa |= _NEW_PROGRAM;
      brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
   }


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

   if (brw->state.dirty.brw & BRW_NEW_CONTEXT)
      brw_clear_batch_cache_flush(brw);


   /* Make an early reference to the state pools, as we don't cope
    * well with them being evicted from here down.
    */
   (void)bmBufferOffset(&brw->intel, brw->pool[BRW_GS_POOL].buffer);
   (void)bmBufferOffset(&brw->intel, brw->pool[BRW_SS_POOL].buffer);
   (void)bmBufferOffset(&brw->intel, brw->intel.batch->buffer);

   if (INTEL_DEBUG) {
      /* 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 brw_state_flags examined, prev;      
      _mesa_memset(&examined, 0, sizeof(examined));
      prev = *state;

      for (i = 0; i < brw->state.nr_atoms; i++) {	 
	 const struct brw_tracked_state *atom = brw->state.atoms[i];
	 struct brw_state_flags generated;

	 assert(atom->dirty.mesa ||
		atom->dirty.brw ||
		atom->dirty.cache);
	 assert(atom->update);

	 if (check_state(state, &atom->dirty)) {
	    brw->state.atoms[i]->update( brw );
	    
/* 	    emit_foo(brw); */
	 }

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

	 /* generated = (prev ^ state)
	  * if (examined & generated)
	  *     fail;
	  */
	 xor_states(&generated, &prev, state);
	 assert(!check_state(&examined, &generated));
	 prev = *state;
      }
   }
   else {
      for (i = 0; i < Elements(atoms); i++) {	 
	 if (check_state(state, &brw->state.atoms[i]->dirty))
	    brw->state.atoms[i]->update( brw );
      }
   }

   memset(state, 0, sizeof(*state));
}
Ejemplo n.º 4
0
static void upload_wm_surfaces(struct brw_context *brw )
{
   GLcontext *ctx = &brw->intel.ctx;
   struct intel_context *intel = &brw->intel;
   GLuint i;

   {
      struct brw_surface_state surf;
      struct intel_region *region = brw->state.draw_region;

      memset(&surf, 0, sizeof(surf));

      if (region->cpp == 4)
	 surf.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
      else 
	 surf.ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;

      surf.ss0.surface_type = BRW_SURFACE_2D;

      /* _NEW_COLOR */
      surf.ss0.color_blend = (!brw->attribs.Color->_LogicOpEnabled &&
			      brw->attribs.Color->BlendEnabled);


      surf.ss0.writedisable_red =   !brw->attribs.Color->ColorMask[0];
      surf.ss0.writedisable_green = !brw->attribs.Color->ColorMask[1];
      surf.ss0.writedisable_blue =  !brw->attribs.Color->ColorMask[2];
      surf.ss0.writedisable_alpha = !brw->attribs.Color->ColorMask[3];

      /* BRW_NEW_LOCK */
      surf.ss1.base_addr = bmBufferOffset(&brw->intel, region->buffer);


      surf.ss2.width = region->pitch - 1; /* XXX: not really! */
      surf.ss2.height = region->height - 1;
      surf.ss3.tile_walk = BRW_TILEWALK_XMAJOR;
      surf.ss3.tiled_surface = region->tiled;
      surf.ss3.pitch = (region->pitch * region->cpp) - 1;

      brw->wm.bind.surf_ss_offset[0] = brw_cache_data( &brw->cache[BRW_SS_SURFACE], &surf );
      brw->wm.nr_surfaces = 1;
   }


   for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
      struct gl_texture_unit *texUnit = &brw->attribs.Texture->Unit[i];

      /* _NEW_TEXTURE, BRW_NEW_TEXDATA 
       */
      if (texUnit->_ReallyEnabled &&
	  intel_finalize_mipmap_tree(intel,texUnit->_Current)) {

	 struct brw_surface_state surf;

	 brw_update_texture_surface(ctx, i, &surf);

	 brw->wm.bind.surf_ss_offset[i+1] = brw_cache_data( &brw->cache[BRW_SS_SURFACE], &surf );
	 brw->wm.nr_surfaces = i+2;
      }
      else if( texUnit->_ReallyEnabled &&
	       texUnit->_Current == intel->frame_buffer_texobj )
      {
	 brw->wm.bind.surf_ss_offset[i+1] = brw->wm.bind.surf_ss_offset[0];
	 brw->wm.nr_surfaces = i+2;
      }    
      else {
	 brw->wm.bind.surf_ss_offset[i+1] = 0;
      }
   }

   brw->wm.bind_ss_offset = brw_cache_data( &brw->cache[BRW_SS_SURF_BIND],
					    &brw->wm.bind );
}
Ejemplo n.º 5
0
void brw_upload_indices( struct brw_context *brw,
			 const struct _mesa_index_buffer *index_buffer )
{
   GLcontext *ctx = &brw->intel.ctx;
   struct intel_context *intel = &brw->intel;
   GLuint ib_size = get_size(index_buffer->type) * index_buffer->count;
   struct gl_buffer_object *bufferobj = index_buffer->obj;
   GLuint offset = (GLuint)index_buffer->ptr;

   /* Turn into a proper VBO:
    */
   if (!bufferobj->Name) {
     
      /* Get new bufferobj, offset:
       */
      get_space(brw, ib_size, &bufferobj, &offset);

      /* Straight upload
       */
      ctx->Driver.BufferSubData( ctx,
				 GL_ELEMENT_ARRAY_BUFFER_ARB,
				 offset, 
				 ib_size,
				 index_buffer->ptr,
				 bufferobj);
   } else {
      /* If the index buffer isn't aligned to its element size, we have to
       * rebase it into a temporary.
       */
       if ((get_size(index_buffer->type) - 1) & offset) {
           struct gl_buffer_object *vbo;
           GLuint voffset;
           GLubyte *map = ctx->Driver.MapBuffer(ctx,
                                                GL_ELEMENT_ARRAY_BUFFER_ARB,
                                                GL_DYNAMIC_DRAW_ARB,
                                                bufferobj);
           map += offset;
           get_space(brw, ib_size, &vbo, &voffset);
           
           ctx->Driver.BufferSubData(ctx,
                                     GL_ELEMENT_ARRAY_BUFFER_ARB,
                                     voffset,
                                     ib_size,
                                     map,
                                     vbo);
           ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, bufferobj);

           bufferobj = vbo;
           offset = voffset;
       }
   }

   /* Emit the indexbuffer packet:
    */
   {
      struct brw_indexbuffer ib;
      struct buffer *buffer = intel_bufferobj_buffer(intel_buffer_object(bufferobj));

      memset(&ib, 0, sizeof(ib));
   
      ib.header.bits.opcode = CMD_INDEX_BUFFER;
      ib.header.bits.length = sizeof(ib)/4 - 2;
      ib.header.bits.index_format = get_index_type(index_buffer->type);
      ib.header.bits.cut_index_enable = 0;
   

      BEGIN_BATCH(4, 0);
      OUT_BATCH( ib.header.dword );
      OUT_BATCH( bmBufferOffset(intel, buffer) + offset );
      OUT_BATCH( bmBufferOffset(intel, buffer) + offset + ib_size );
      OUT_BATCH( 0 );
      ADVANCE_BATCH();
   }
}
Ejemplo n.º 6
0
GLboolean brw_upload_vertices( struct brw_context *brw,
			       GLuint min_index,
			       GLuint max_index )
{
   GLcontext *ctx = &brw->intel.ctx;
   struct intel_context *intel = intel_context(ctx);
   GLuint tmp = brw->vs.prog_data->inputs_read; 
   struct brw_vertex_element_packet vep;
   struct brw_array_state vbp;
   GLuint i;
   const void *ptr = NULL;
   GLuint interleave = 0;

   struct brw_vertex_element *enabled[VERT_ATTRIB_MAX];
   GLuint nr_enabled = 0;

   struct brw_vertex_element *upload[VERT_ATTRIB_MAX];
   GLuint nr_uploads = 0;
   

   memset(&vbp, 0, sizeof(vbp));
   memset(&vep, 0, sizeof(vep));

   /* First build an array of pointers to ve's in vb.inputs_read
    */
   if (0)
      _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
   
   while (tmp) {
      GLuint i = _mesa_ffsll(tmp)-1;
      struct brw_vertex_element *input = &brw->vb.inputs[i];

      tmp &= ~(1<<i);
      enabled[nr_enabled++] = input;

      input->index = i;
      input->element_size = get_size(input->glarray->Type) * input->glarray->Size;
      input->count = input->glarray->StrideB ? max_index + 1 - min_index : 1;

      if (!input->glarray->BufferObj->Name) {
	 if (i == 0) {
	    /* Position array not properly enabled:
	     */
	    if (input->glarray->StrideB == 0)
	       return GL_FALSE;

	    interleave = input->glarray->StrideB;
	    ptr = input->glarray->Ptr;
	 }
	 else if (interleave != input->glarray->StrideB ||
		  (const char *)input->glarray->Ptr - (const char *)ptr < 0 ||
		  (const char *)input->glarray->Ptr - (const char *)ptr > interleave) {
	    interleave = 0;
	 }

	 upload[nr_uploads++] = input;
	 
	 /* We rebase drawing to start at element zero only when
	  * varyings are not in vbos, which means we can end up
	  * uploading non-varying arrays (stride != 0) when min_index
	  * is zero.  This doesn't matter as the amount to upload is
	  * the same for these arrays whether the draw call is rebased
	  * or not - we just have to upload the one element.
	  */
	 assert(min_index == 0 || input->glarray->StrideB == 0);
      }
   }

   /* Upload interleaved arrays if all uploads are interleaved
    */
   if (nr_uploads > 1 && 
       interleave && 
       interleave <= 256) {
      struct brw_vertex_element *input0 = upload[0];

      input0->glarray = copy_array_to_vbo_array(brw, 0,
						input0->glarray, 
						interleave,
						input0->count);

      for (i = 1; i < nr_uploads; i++) {
	 upload[i]->glarray = interleaved_vbo_array(brw,
						    i,
						    input0->glarray,
						    upload[i]->glarray,
						    ptr);
      }
   }
   else {
      for (i = 0; i < nr_uploads; i++) {
	 struct brw_vertex_element *input = upload[i];

	 input->glarray = copy_array_to_vbo_array(brw, i, 
						  input->glarray,
						  input->element_size,
						  input->count);

      }
   }

   /* XXX: In the rare cases where this happens we fallback all
    * the way to software rasterization, although a tnl fallback
    * would be sufficient.  I don't know of *any* real world
    * cases with > 17 vertex attributes enabled, so it probably
    * isn't an issue at this point.
    */
   if (nr_enabled >= BRW_VEP_MAX)
	 return GL_FALSE;

   /* This still defines a hardware VB for each input, even if they
    * are interleaved or from the same VBO.  TBD if this makes a
    * performance difference.
    */
   for (i = 0; i < nr_enabled; i++) {
      struct brw_vertex_element *input = enabled[i];

      input->vep = &vep.ve[i];
      input->vep->ve0.src_format = get_surface_type(input->glarray->Type, 
						    input->glarray->Size,
						    input->glarray->Normalized);
      input->vep->ve0.valid = 1;
      input->vep->ve1.dst_offset = (i) * 4;
      input->vep->ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC;
      input->vep->ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC;
      input->vep->ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC;
      input->vep->ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC;

      switch (input->glarray->Size) {
      case 0: input->vep->ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_0;
      case 1: input->vep->ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0;
      case 2: input->vep->ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0;
      case 3: input->vep->ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT;
	 break;
      }

      input->vep->ve0.vertex_buffer_index = i;
      input->vep->ve0.src_offset = 0;

      vbp.vb[i].vb0.bits.pitch = input->glarray->StrideB;
      vbp.vb[i].vb0.bits.pad = 0;
      vbp.vb[i].vb0.bits.access_type = BRW_VERTEXBUFFER_ACCESS_VERTEXDATA;
      vbp.vb[i].vb0.bits.vb_index = i;
      vbp.vb[i].offset = (GLuint)input->glarray->Ptr;
      vbp.vb[i].buffer = array_buffer(input->glarray);
      vbp.vb[i].max_index = max_index;
   }



   /* Now emit VB and VEP state packets:
    */
   vbp.header.bits.length = (1 + nr_enabled * 4) - 2;
   vbp.header.bits.opcode = CMD_VERTEX_BUFFER;

   BEGIN_BATCH(vbp.header.bits.length+2, 0);
   OUT_BATCH( vbp.header.dword );
   
   for (i = 0; i < nr_enabled; i++) {
      OUT_BATCH( vbp.vb[i].vb0.dword );
      OUT_BATCH( bmBufferOffset(&brw->intel, vbp.vb[i].buffer) + vbp.vb[i].offset);
      OUT_BATCH( vbp.vb[i].max_index );
      OUT_BATCH( vbp.vb[i].instance_data_step_rate );
   }
   ADVANCE_BATCH();

   vep.header.length = (1 + nr_enabled * sizeof(vep.ve[0])/4) - 2;
   vep.header.opcode = CMD_VERTEX_ELEMENT;
   brw_cached_batch_struct(brw, &vep, 4 + nr_enabled * sizeof(vep.ve[0]));

   return GL_TRUE;
}
Ejemplo n.º 7
0
void
intelEmitImmediateColorExpandBlit(struct intel_context *intel,
                                  GLuint cpp,
                                  GLubyte *src_bits, GLuint src_size,
                                  GLuint fg_color,
                                  GLshort dst_pitch,
                                  struct buffer *dst_buffer,
                                  GLuint dst_offset,
                                  GLboolean dst_tiled,
                                  GLshort x, GLshort y,
                                  GLshort w, GLshort h,
                                  GLenum logic_op)
{
    struct xy_setup_blit setup;
    struct xy_text_immediate_blit text;
    int dwords = ((src_size + 7) & ~7) / 4;

    assert( logic_op - GL_CLEAR >= 0 );
    assert( logic_op - GL_CLEAR < 0x10 );

    if (w < 0 || h < 0)
        return;

    dst_pitch *= cpp;

    if (dst_tiled)
        dst_pitch /= 4;

    DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d, %d bytes %d dwords\n",
        __FUNCTION__,
        dst_buffer, dst_pitch, dst_offset, x, y, w, h, src_size, dwords);

    memset(&setup, 0, sizeof(setup));

    setup.br0.client = CLIENT_2D;
    setup.br0.opcode = OPCODE_XY_SETUP_BLT;
    setup.br0.write_alpha = (cpp == 4);
    setup.br0.write_rgb = (cpp == 4);
    setup.br0.dst_tiled = dst_tiled;
    setup.br0.length = (sizeof(setup) / sizeof(int)) - 2;

    setup.br13.dest_pitch = dst_pitch;
    setup.br13.rop = translate_raster_op(logic_op);
    setup.br13.color_depth = (cpp == 4) ? BR13_8888 : BR13_565;
    setup.br13.clipping_enable = 0;
    setup.br13.mono_source_transparency = 1;

    setup.dw2.clip_y1 = 0;
    setup.dw2.clip_x1 = 0;
    setup.dw3.clip_y2 = 100;
    setup.dw3.clip_x2 = 100;

    setup.dest_base_addr = bmBufferOffset(intel, dst_buffer) + dst_offset;
    setup.background_color = 0;
    setup.foreground_color = fg_color;
    setup.pattern_base_addr = 0;

    memset(&text, 0, sizeof(text));
    text.dw0.client = CLIENT_2D;
    text.dw0.opcode = OPCODE_XY_TEXT_IMMEDIATE_BLT;
    text.dw0.pad0 = 0;
    text.dw0.byte_packed = 1;	/* ?maybe? */
    text.dw0.pad1 = 0;
    text.dw0.dst_tiled = dst_tiled;
    text.dw0.pad2 = 0;
    text.dw0.length = (sizeof(text)/sizeof(int)) - 2 + dwords;
    text.dw1.dest_y1 = y;	/* duplicates info in setup blit */
    text.dw1.dest_x1 = x;
    text.dw2.dest_y2 = y + h;
    text.dw2.dest_x2 = x + w;

    intel_batchbuffer_require_space( intel->batch,
                                     sizeof(setup) +
                                     sizeof(text) +
                                     dwords,
                                     INTEL_BATCH_NO_CLIPRECTS );

    intel_batchbuffer_data( intel->batch,
                            &setup,
                            sizeof(setup),
                            INTEL_BATCH_NO_CLIPRECTS );

    intel_batchbuffer_data( intel->batch,
                            &text,
                            sizeof(text),
                            INTEL_BATCH_NO_CLIPRECTS );

    intel_batchbuffer_data( intel->batch,
                            src_bits,
                            dwords * 4,
                            INTEL_BATCH_NO_CLIPRECTS );
}
Ejemplo n.º 8
0
/*
 * Copy the back buffer to the front buffer.
 */
void intelCopyBuffer( const __DRIdrawablePrivate *dPriv,
                      const drm_clip_rect_t *rect )
{
    struct intel_context *intel;
    GLboolean   missed_target;
    int64_t ust;

    DBG("%s\n", __FUNCTION__);

    assert(dPriv);
    assert(dPriv->driContextPriv);
    assert(dPriv->driContextPriv->driverPrivate);

    intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate;
    intelFlush( &intel->ctx );


    bmFinishFenceLock(intel, intel->last_swap_fence);

    /* The LOCK_HARDWARE is required for the cliprects.  Buffer offsets
     * should work regardless.
     */
    LOCK_HARDWARE( intel );

    if (!rect)
    {
        UNLOCK_HARDWARE( intel );
        driWaitForVBlank( dPriv, &intel->vbl_seq, intel->vblank_flags, & missed_target );
        LOCK_HARDWARE( intel );
    }

    {
        intelScreenPrivate *intelScreen = intel->intelScreen;
        __DRIdrawablePrivate *dPriv = intel->driDrawable;
        int nbox = dPriv->numClipRects;
        drm_clip_rect_t *pbox = dPriv->pClipRects;
        int cpp = intelScreen->cpp;
        struct intel_region *src, *dst;
        int BR13, CMD;
        int i;
        int src_pitch, dst_pitch;

        if (intel->sarea->pf_current_page == 0) {
            dst = intel->front_region;
            src = intel->back_region;
        }
        else {
            assert(0);
            src = intel->front_region;
            dst = intel->back_region;
        }

        src_pitch = src->pitch * src->cpp;
        dst_pitch = dst->pitch * dst->cpp;

        if (cpp == 2) {
            BR13 = (0xCC << 16) | (1<<24);
            CMD = XY_SRC_COPY_BLT_CMD;
        }
        else {
            BR13 = (0xCC << 16) | (1<<24) | (1<<25);
            CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
                   XY_SRC_COPY_BLT_WRITE_RGB);
        }

        if (src->tiled) {
            CMD |= XY_SRC_TILED;
            src_pitch /= 4;
        }

        if (dst->tiled) {
            CMD |= XY_DST_TILED;
            dst_pitch /= 4;
        }

        for (i = 0 ; i < nbox; i++, pbox++)
        {
            drm_clip_rect_t tmp = *pbox;

            if (rect) {
                if (!intel_intersect_cliprects(&tmp, &tmp, rect))
                    continue;
            }


            if (tmp.x1 > tmp.x2 ||
                    tmp.y1 > tmp.y2 ||
                    tmp.x2 > intelScreen->width ||
                    tmp.y2 > intelScreen->height)
                continue;

            BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
            OUT_BATCH( CMD );
            OUT_BATCH( dst_pitch | BR13 );
            OUT_BATCH( (tmp.y1 << 16) | tmp.x1 );
            OUT_BATCH( (tmp.y2 << 16) | tmp.x2 );
            OUT_BATCH( bmBufferOffset(intel, dst->buffer) );
            OUT_BATCH( (tmp.y1 << 16) | tmp.x1 );
            OUT_BATCH( src_pitch );
            OUT_BATCH( bmBufferOffset(intel, src->buffer) );
            ADVANCE_BATCH();
        }
    }

    intel_batchbuffer_flush( intel->batch );
    intel->second_last_swap_fence = intel->last_swap_fence;
    intel->last_swap_fence = bmSetFenceLock( intel );
    UNLOCK_HARDWARE( intel );

    if (!rect)
    {
        intel->swap_count++;
        (*dri_interface->getUST)(&ust);
        if (missed_target) {
            intel->swap_missed_count++;
            intel->swap_missed_ust = ust -  intel->swap_ust;
        }

        intel->swap_ust = ust;
    }

}
Ejemplo n.º 9
0
void intelClearWithBlit(GLcontext *ctx, GLbitfield flags)
{
    struct intel_context *intel = intel_context( ctx );
    intelScreenPrivate *intelScreen = intel->intelScreen;
    GLuint clear_depth, clear_color;
    GLint cx, cy, cw, ch;
    GLint cpp = intelScreen->cpp;
    GLboolean all;
    GLint i;
    struct intel_region *front = intel->front_region;
    struct intel_region *back = intel->back_region;
    struct intel_region *depth = intel->depth_region;
    GLuint BR13, FRONT_CMD, BACK_CMD, DEPTH_CMD;
    GLuint front_pitch;
    GLuint back_pitch;
    GLuint depth_pitch;
    BATCH_LOCALS;


    clear_color = intel->ClearColor;
    clear_depth = 0;

    if (flags & BUFFER_BIT_DEPTH) {
        clear_depth = (GLuint)(ctx->Depth.Clear * intel->ClearDepth);
    }

    if (flags & BUFFER_BIT_STENCIL) {
        clear_depth |= (ctx->Stencil.Clear & 0xff) << 24;
    }

    switch(cpp) {
    case 2:
        BR13 = (0xF0 << 16) | (1<<24);
        BACK_CMD  = FRONT_CMD = XY_COLOR_BLT_CMD;
        DEPTH_CMD = XY_COLOR_BLT_CMD;
        break;
    case 4:
        BR13 = (0xF0 << 16) | (1<<24) | (1<<25);
        BACK_CMD = FRONT_CMD = (XY_COLOR_BLT_CMD |
                                XY_COLOR_BLT_WRITE_ALPHA |
                                XY_COLOR_BLT_WRITE_RGB);
        DEPTH_CMD = XY_COLOR_BLT_CMD;
        if (flags & BUFFER_BIT_DEPTH) DEPTH_CMD |= XY_COLOR_BLT_WRITE_RGB;
        if (flags & BUFFER_BIT_STENCIL) DEPTH_CMD |= XY_COLOR_BLT_WRITE_ALPHA;
        break;
    default:
        return;
    }



    intelFlush( &intel->ctx );
    LOCK_HARDWARE( intel );
    {
        /* get clear bounds after locking */
        cx = ctx->DrawBuffer->_Xmin;
        cy = ctx->DrawBuffer->_Ymin;
        ch = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
        cw = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
        all = (cw == ctx->DrawBuffer->Width && ch == ctx->DrawBuffer->Height);

        /* flip top to bottom */
        cy = intel->driDrawable->h - cy - ch;
        cx = cx + intel->drawX;
        cy += intel->drawY;

        /* adjust for page flipping */
        if ( intel->sarea->pf_current_page == 0 ) {
            front = intel->front_region;
            back = intel->back_region;
        }
        else {
            back = intel->front_region;
            front = intel->back_region;
        }

        front_pitch = front->pitch * front->cpp;
        back_pitch = back->pitch * back->cpp;
        depth_pitch = depth->pitch * depth->cpp;

        if (front->tiled) {
            FRONT_CMD |= XY_DST_TILED;
            front_pitch /= 4;
        }

        if (back->tiled) {
            BACK_CMD |= XY_DST_TILED;
            back_pitch /= 4;
        }

        if (depth->tiled) {
            DEPTH_CMD |= XY_DST_TILED;
            depth_pitch /= 4;
        }

        for (i = 0 ; i < intel->numClipRects ; i++)
        {
            drm_clip_rect_t *box = &intel->pClipRects[i];
            drm_clip_rect_t b;

            if (!all) {
                GLint x = box->x1;
                GLint y = box->y1;
                GLint w = box->x2 - x;
                GLint h = box->y2 - y;

                if (x < cx) w -= cx - x, x = cx;
                if (y < cy) h -= cy - y, y = cy;
                if (x + w > cx + cw) w = cx + cw - x;
                if (y + h > cy + ch) h = cy + ch - y;
                if (w <= 0) continue;
                if (h <= 0) continue;

                b.x1 = x;
                b.y1 = y;
                b.x2 = x + w;
                b.y2 = y + h;
            } else {
                b = *box;
            }


            if (b.x1 > b.x2 ||
                    b.y1 > b.y2 ||
                    b.x2 > intelScreen->width ||
                    b.y2 > intelScreen->height)
                continue;

            if ( flags & BUFFER_BIT_FRONT_LEFT ) {
                BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
                OUT_BATCH( FRONT_CMD );
                OUT_BATCH( front_pitch | BR13 );
                OUT_BATCH( (b.y1 << 16) | b.x1 );
                OUT_BATCH( (b.y2 << 16) | b.x2 );
                OUT_BATCH( bmBufferOffset(intel, front->buffer) );
                OUT_BATCH( clear_color );
                ADVANCE_BATCH();
            }

            if ( flags & BUFFER_BIT_BACK_LEFT ) {
                BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
                OUT_BATCH( BACK_CMD );
                OUT_BATCH( back_pitch | BR13 );
                OUT_BATCH( (b.y1 << 16) | b.x1 );
                OUT_BATCH( (b.y2 << 16) | b.x2 );
                OUT_BATCH( bmBufferOffset(intel, back->buffer) );
                OUT_BATCH( clear_color );
                ADVANCE_BATCH();
            }

            if ( flags & (BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH) ) {
                BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
                OUT_BATCH( DEPTH_CMD );
                OUT_BATCH( depth_pitch | BR13 );
                OUT_BATCH( (b.y1 << 16) | b.x1 );
                OUT_BATCH( (b.y2 << 16) | b.x2 );
                OUT_BATCH( bmBufferOffset(intel, depth->buffer) );
                OUT_BATCH( clear_depth );
                ADVANCE_BATCH();
            }
        }
    }
    intel_batchbuffer_flush( intel->batch );
    UNLOCK_HARDWARE( intel );
}
Ejemplo n.º 10
0
/* Copy BitBlt
 */
void intelEmitCopyBlit( struct intel_context *intel,
                        GLuint cpp,
                        GLshort src_pitch,
                        struct buffer *src_buffer,
                        GLuint  src_offset,
                        GLboolean src_tiled,
                        GLshort dst_pitch,
                        struct buffer *dst_buffer,
                        GLuint  dst_offset,
                        GLboolean dst_tiled,
                        GLshort src_x, GLshort src_y,
                        GLshort dst_x, GLshort dst_y,
                        GLshort w, GLshort h,
                        GLenum logic_op )
{
    GLuint CMD, BR13;
    int dst_y2 = dst_y + h;
    int dst_x2 = dst_x + w;
    BATCH_LOCALS;


    DBG("%s src:buf(%d)/%d %d,%d dst:buf(%d)/%d %d,%d sz:%dx%d op:%d\n",
        __FUNCTION__,
        src_buffer, src_pitch, src_x, src_y,
        dst_buffer, dst_pitch, dst_x, dst_y,
        w,h,logic_op);

    assert( logic_op - GL_CLEAR >= 0 );
    assert( logic_op - GL_CLEAR < 0x10 );

    src_pitch *= cpp;
    dst_pitch *= cpp;

    switch(cpp) {
    case 1:
    case 2:
    case 3:
        BR13 = (translate_raster_op(logic_op) << 16) | (1<<24);
        CMD = XY_SRC_COPY_BLT_CMD;
        break;
    case 4:
        BR13 = (translate_raster_op(logic_op) << 16) | (1<<24) |
               (1<<25);
        CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
               XY_SRC_COPY_BLT_WRITE_RGB);
        break;
    default:
        return;
    }

    if (src_tiled) {
        CMD |= XY_SRC_TILED;
        src_pitch /= 4;
    }

    if (dst_tiled) {
        CMD |= XY_DST_TILED;
        dst_pitch /= 4;
    }

    if (dst_y2 < dst_y ||
            dst_x2 < dst_x) {
        return;
    }

    dst_pitch &= 0xffff;
    src_pitch &= 0xffff;

    /* Initial y values don't seem to work with negative pitches.  If
     * we adjust the offsets manually (below), it seems to work fine.
     *
     * On the other hand, if we always adjust, the hardware doesn't
     * know which blit directions to use, so overlapping copypixels get
     * the wrong result.
     */
    if (dst_pitch > 0 && src_pitch > 0) {
        BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
        OUT_BATCH( CMD );
        OUT_BATCH( dst_pitch | BR13 );
        OUT_BATCH( (dst_y << 16) | dst_x );
        OUT_BATCH( (dst_y2 << 16) | dst_x2 );
        OUT_BATCH( bmBufferOffset(intel, dst_buffer) + dst_offset );
        OUT_BATCH( (src_y << 16) | src_x );
        OUT_BATCH( src_pitch );
        OUT_BATCH( bmBufferOffset(intel, src_buffer) + src_offset );
        ADVANCE_BATCH();
    }
    else {
        BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
        OUT_BATCH( CMD );
        OUT_BATCH( (dst_pitch & 0xffff) | BR13 );
        OUT_BATCH( (0 << 16) | dst_x );
        OUT_BATCH( (h << 16) | dst_x2 );
        OUT_BATCH( bmBufferOffset(intel, dst_buffer) + dst_offset + dst_y * dst_pitch );
        OUT_BATCH( (0 << 16) | src_x );
        OUT_BATCH( (src_pitch & 0xffff) );
        OUT_BATCH( bmBufferOffset(intel, src_buffer) + src_offset + src_y * src_pitch );
        ADVANCE_BATCH();
    }
}