Exemple #1
0
void ASPSYoungGen::resize_spaces(size_t requested_eden_size,
                                 size_t requested_survivor_size) {
  assert(UseAdaptiveSizePolicy, "sanity check");
  assert(requested_eden_size > 0 && requested_survivor_size > 0,
         "just checking");

  space_invariants();

  // We require eden and to space to be empty
  if ((!eden_space()->is_empty()) || (!to_space()->is_empty())) {
    return;
  }

  if (PrintAdaptiveSizePolicy && Verbose) {
    gclog_or_tty->print_cr("PSYoungGen::resize_spaces(requested_eden_size: "
                  SIZE_FORMAT
                  ", requested_survivor_size: " SIZE_FORMAT ")",
                  requested_eden_size, requested_survivor_size);
    gclog_or_tty->print_cr("    eden: [" PTR_FORMAT ".." PTR_FORMAT ") "
                  SIZE_FORMAT,
                  eden_space()->bottom(),
                  eden_space()->end(),
                  pointer_delta(eden_space()->end(),
                                eden_space()->bottom(),
                                sizeof(char)));
    gclog_or_tty->print_cr("    from: [" PTR_FORMAT ".." PTR_FORMAT ") "
                  SIZE_FORMAT,
                  from_space()->bottom(),
                  from_space()->end(),
                  pointer_delta(from_space()->end(),
                                from_space()->bottom(),
                                sizeof(char)));
    gclog_or_tty->print_cr("      to: [" PTR_FORMAT ".." PTR_FORMAT ") "
                  SIZE_FORMAT,
                  to_space()->bottom(),
                  to_space()->end(),
                  pointer_delta(  to_space()->end(),
                                  to_space()->bottom(),
                                  sizeof(char)));
  }

  // There's nothing to do if the new sizes are the same as the current
  if (requested_survivor_size == to_space()->capacity_in_bytes() &&
      requested_survivor_size == from_space()->capacity_in_bytes() &&
      requested_eden_size == eden_space()->capacity_in_bytes()) {
    if (PrintAdaptiveSizePolicy && Verbose) {
      gclog_or_tty->print_cr("    capacities are the right sizes, returning");
    }
    return;
  }

  char* eden_start = (char*)virtual_space()->low();
  char* eden_end   = (char*)eden_space()->end();
  char* from_start = (char*)from_space()->bottom();
  char* from_end   = (char*)from_space()->end();
  char* to_start   = (char*)to_space()->bottom();
  char* to_end     = (char*)to_space()->end();

  assert(eden_start < from_start, "Cannot push into from_space");

  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
  const size_t alignment = heap->intra_heap_alignment();
  const bool maintain_minimum =
    (requested_eden_size + 2 * requested_survivor_size) <= min_gen_size();

  bool eden_from_to_order = from_start < to_start;
  // Check whether from space is below to space
  if (eden_from_to_order) {
    // Eden, from, to

    if (PrintAdaptiveSizePolicy && Verbose) {
      gclog_or_tty->print_cr("  Eden, from, to:");
    }

    // Set eden
    // "requested_eden_size" is a goal for the size of eden
    // and may not be attainable.  "eden_size" below is
    // calculated based on the location of from-space and
    // the goal for the size of eden.  from-space is
    // fixed in place because it contains live data.
    // The calculation is done this way to avoid 32bit
    // overflow (i.e., eden_start + requested_eden_size
    // may too large for representation in 32bits).
    size_t eden_size;
    if (maintain_minimum) {
      // Only make eden larger than the requested size if
      // the minimum size of the generation has to be maintained.
      // This could be done in general but policy at a higher
      // level is determining a requested size for eden and that
      // should be honored unless there is a fundamental reason.
      eden_size = pointer_delta(from_start,
                                eden_start,
                                sizeof(char));
    } else {
      eden_size = MIN2(requested_eden_size,
                       pointer_delta(from_start, eden_start, sizeof(char)));
    }

    eden_end = eden_start + eden_size;
    assert(eden_end >= eden_start, "addition overflowed")

    // To may resize into from space as long as it is clear of live data.
    // From space must remain page aligned, though, so we need to do some
    // extra calculations.

    // First calculate an optimal to-space
    to_end   = (char*)virtual_space()->high();
    to_start = (char*)pointer_delta(to_end,
                                    (char*)requested_survivor_size,
                                    sizeof(char));

    // Does the optimal to-space overlap from-space?
    if (to_start < (char*)from_space()->end()) {
      assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");

      // Calculate the minimum offset possible for from_end
      size_t from_size =
        pointer_delta(from_space()->top(), from_start, sizeof(char));

      // Should we be in this method if from_space is empty? Why not the set_space method? FIX ME!
      if (from_size == 0) {
        from_size = alignment;
      } else {
        from_size = align_size_up(from_size, alignment);
      }

      from_end = from_start + from_size;
      assert(from_end > from_start, "addition overflow or from_size problem");

      guarantee(from_end <= (char*)from_space()->end(),
        "from_end moved to the right");

      // Now update to_start with the new from_end
      to_start = MAX2(from_end, to_start);
    }

    guarantee(to_start != to_end, "to space is zero sized");

    if (PrintAdaptiveSizePolicy && Verbose) {
      gclog_or_tty->print_cr("    [eden_start .. eden_end): "
                    "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
                    eden_start,
                    eden_end,
                    pointer_delta(eden_end, eden_start, sizeof(char)));
      gclog_or_tty->print_cr("    [from_start .. from_end): "
                    "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
                    from_start,
                    from_end,
                    pointer_delta(from_end, from_start, sizeof(char)));
      gclog_or_tty->print_cr("    [  to_start ..   to_end): "
                    "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
                    to_start,
                    to_end,
                    pointer_delta(  to_end,   to_start, sizeof(char)));
    }
  } else {
    // Eden, to, from
    if (PrintAdaptiveSizePolicy && Verbose) {
      gclog_or_tty->print_cr("  Eden, to, from:");
    }

    // To space gets priority over eden resizing. Note that we position
    // to space as if we were able to resize from space, even though from
    // space is not modified.
    // Giving eden priority was tried and gave poorer performance.
    to_end   = (char*)pointer_delta(virtual_space()->high(),
                                    (char*)requested_survivor_size,
                                    sizeof(char));
    to_end   = MIN2(to_end, from_start);
    to_start = (char*)pointer_delta(to_end, (char*)requested_survivor_size,
                                    sizeof(char));
    // if the space sizes are to be increased by several times then
    // 'to_start' will point beyond the young generation. In this case
    // 'to_start' should be adjusted.
    to_start = MAX2(to_start, eden_start + alignment);

    // Compute how big eden can be, then adjust end.
    // See  comments above on calculating eden_end.
    size_t eden_size;
    if (maintain_minimum) {
      eden_size = pointer_delta(to_start, eden_start, sizeof(char));
    } else {
      eden_size = MIN2(requested_eden_size,
                       pointer_delta(to_start, eden_start, sizeof(char)));
    }
    eden_end = eden_start + eden_size;
    assert(eden_end >= eden_start, "addition overflowed")

    // Don't let eden shrink down to 0 or less.
    eden_end = MAX2(eden_end, eden_start + alignment);
    to_start = MAX2(to_start, eden_end);

    if (PrintAdaptiveSizePolicy && Verbose) {
      gclog_or_tty->print_cr("    [eden_start .. eden_end): "
                    "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
                    eden_start,
                    eden_end,
                    pointer_delta(eden_end, eden_start, sizeof(char)));
      gclog_or_tty->print_cr("    [  to_start ..   to_end): "
                    "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
                    to_start,
                    to_end,
                    pointer_delta(  to_end,   to_start, sizeof(char)));
      gclog_or_tty->print_cr("    [from_start .. from_end): "
                    "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
                    from_start,
                    from_end,
                    pointer_delta(from_end, from_start, sizeof(char)));
    }
  }


  guarantee((HeapWord*)from_start <= from_space()->bottom(),
            "from start moved to the right");
  guarantee((HeapWord*)from_end >= from_space()->top(),
            "from end moved into live data");
  assert(is_object_aligned((intptr_t)eden_start), "checking alignment");
  assert(is_object_aligned((intptr_t)from_start), "checking alignment");
  assert(is_object_aligned((intptr_t)to_start), "checking alignment");

  MemRegion edenMR((HeapWord*)eden_start, (HeapWord*)eden_end);
  MemRegion toMR  ((HeapWord*)to_start,   (HeapWord*)to_end);
  MemRegion fromMR((HeapWord*)from_start, (HeapWord*)from_end);

  // Let's make sure the call to initialize doesn't reset "top"!
  DEBUG_ONLY(HeapWord* old_from_top = from_space()->top();)
static int
update_tss_binding(struct svga_context *svga, 
                   unsigned dirty )
{
   unsigned i;
   unsigned count = MAX2( svga->curr.num_textures,
                          svga->state.hw_draw.num_views );
   unsigned min_lod;
   unsigned max_lod;


   struct {
      struct {
         unsigned unit;
         struct svga_hw_view_state *view;
      } bind[PIPE_MAX_SAMPLERS];

      unsigned bind_count;
   } queue;

   queue.bind_count = 0;
   
   for (i = 0; i < count; i++) {
      const struct svga_sampler_state *s = svga->curr.sampler[i];
      struct svga_hw_view_state *view = &svga->state.hw_draw.views[i];

      /* get min max lod */
      if (svga->curr.texture[i]) {
         min_lod = MAX2(s->view_min_lod, 0);
         max_lod = MIN2(s->view_max_lod, svga->curr.texture[i]->last_level);
      } else {
         min_lod = 0;
         max_lod = 0;
      }

      if (view->texture != svga->curr.texture[i] ||
          view->min_lod != min_lod ||
          view->max_lod != max_lod) {

         svga_sampler_view_reference(&view->v, NULL);
         pipe_texture_reference( &view->texture, svga->curr.texture[i] );

         view->dirty = TRUE;
         view->min_lod = min_lod;
         view->max_lod = max_lod;

         if (svga->curr.texture[i])
            view->v = svga_get_tex_sampler_view(&svga->pipe, 
                                                svga->curr.texture[i], 
                                                min_lod,
                                                max_lod);
      }

      if (view->dirty) {
         queue.bind[queue.bind_count].unit = i;
         queue.bind[queue.bind_count].view = view;
         queue.bind_count++;
      } 
      else if (view->v) {
         svga_validate_sampler_view(svga, view->v);
      }
   }

   svga->state.hw_draw.num_views = svga->curr.num_textures;

   if (queue.bind_count) {
      SVGA3dTextureState *ts;

      if (SVGA3D_BeginSetTextureState( svga->swc,
                                       &ts,
                                       queue.bind_count ) != PIPE_OK)
         goto fail;

      for (i = 0; i < queue.bind_count; i++) {
         ts[i].stage = queue.bind[i].unit;
         ts[i].name = SVGA3D_TS_BIND_TEXTURE;

         if (queue.bind[i].view->v) {
            svga->swc->surface_relocation(svga->swc,
                                          &ts[i].value,
                                          queue.bind[i].view->v->handle,
                                          PIPE_BUFFER_USAGE_GPU_READ);
         }
         else {
            ts[i].value = SVGA3D_INVALID_ID;
         }
         
         queue.bind[i].view->dirty = FALSE;
      }

      SVGA_FIFOCommitAll( svga->swc );
   }

   return 0;

fail:
   return PIPE_ERROR_OUT_OF_MEMORY;
}
Exemple #3
0
/* Create the device specific context.
 */
GLboolean
r100CreateContext( gl_api api,
		   const struct gl_config *glVisual,
		   __DRIcontext *driContextPriv,
		   unsigned major_version,
		   unsigned minor_version,
		   uint32_t flags,
		   unsigned *error,
		   void *sharedContextPrivate)
{
   __DRIscreen *sPriv = driContextPriv->driScreenPriv;
   radeonScreenPtr screen = (radeonScreenPtr)(sPriv->driverPrivate);
   struct dd_function_table functions;
   r100ContextPtr rmesa;
   struct gl_context *ctx;
   int i;
   int tcl_mode, fthrottle_mode;

   /* API and flag filtering is handled in dri2CreateContextAttribs.
    */
   (void) api;
   (void) flags;

   assert(glVisual);
   assert(driContextPriv);
   assert(screen);

   /* Allocate the Radeon context */
   rmesa = (r100ContextPtr) CALLOC( sizeof(*rmesa) );
   if ( !rmesa ) {
      *error = __DRI_CTX_ERROR_NO_MEMORY;
      return GL_FALSE;
   }

   rmesa->radeon.radeonScreen = screen;
   r100_init_vtbl(&rmesa->radeon);

   /* init exp fog table data */
   radeonInitStaticFogData();
   
   /* Parse configuration files.
    * Do this here so that initialMaxAnisotropy is set before we create
    * the default textures.
    */
   driParseConfigFiles (&rmesa->radeon.optionCache, &screen->optionCache,
			screen->driScreen->myNum, "radeon");
   rmesa->radeon.initialMaxAnisotropy = driQueryOptionf(&rmesa->radeon.optionCache,
                                                 "def_max_anisotropy");

   if ( driQueryOptionb( &rmesa->radeon.optionCache, "hyperz" ) ) {
      if ( sPriv->drm_version.minor < 13 )
	 fprintf( stderr, "DRM version 1.%d too old to support HyperZ, "
			  "disabling.\n", sPriv->drm_version.minor );
      else
	 rmesa->using_hyperz = GL_TRUE;
   }

   if ( sPriv->drm_version.minor >= 15 )
      rmesa->texmicrotile = GL_TRUE;

   /* Init default driver functions then plug in our Radeon-specific functions
    * (the texture functions are especially important)
    */
   _mesa_init_driver_functions( &functions );
   radeonInitTextureFuncs( &rmesa->radeon, &functions );
   radeonInitQueryObjFunctions(&functions);

   if (!radeonInitContext(&rmesa->radeon, &functions,
			  glVisual, driContextPriv,
			  sharedContextPrivate)) {
     FREE(rmesa);
     *error = __DRI_CTX_ERROR_NO_MEMORY;
     return GL_FALSE;
   }

   rmesa->radeon.swtcl.RenderIndex = ~0;
   rmesa->radeon.hw.all_dirty = GL_TRUE;

   /* Set the maximum texture size small enough that we can guarentee that
    * all texture units can bind a maximal texture and have all of them in
    * texturable memory at once. Depending on the allow_large_textures driconf
    * setting allow larger textures.
    */

   ctx = rmesa->radeon.glCtx;
   ctx->Const.MaxTextureUnits = driQueryOptioni (&rmesa->radeon.optionCache,
						 "texture_units");
   ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
   ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
   ctx->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxTextureUnits;

   ctx->Const.StripTextureBorder = GL_TRUE;

   i = driQueryOptioni( &rmesa->radeon.optionCache, "allow_large_textures");

   /* FIXME: When no memory manager is available we should set this 
    * to some reasonable value based on texture memory pool size */
   ctx->Const.MaxTextureLevels = 12;
   ctx->Const.Max3DTextureLevels = 9;
   ctx->Const.MaxCubeTextureLevels = 12;
   ctx->Const.MaxTextureRectSize = 2048;

   ctx->Const.MaxTextureMaxAnisotropy = 16.0;

   /* No wide points.
    */
   ctx->Const.MinPointSize = 1.0;
   ctx->Const.MinPointSizeAA = 1.0;
   ctx->Const.MaxPointSize = 1.0;
   ctx->Const.MaxPointSizeAA = 1.0;

   ctx->Const.MinLineWidth = 1.0;
   ctx->Const.MinLineWidthAA = 1.0;
   ctx->Const.MaxLineWidth = 10.0;
   ctx->Const.MaxLineWidthAA = 10.0;
   ctx->Const.LineWidthGranularity = 0.0625;

   /* Set maxlocksize (and hence vb size) small enough to avoid
    * fallbacks in radeon_tcl.c.  ie. guarentee that all vertices can
    * fit in a single dma buffer for indexed rendering of quad strips,
    * etc.
    */
   ctx->Const.MaxArrayLockSize = 
      MIN2( ctx->Const.MaxArrayLockSize, 
 	    RADEON_BUFFER_SIZE / RADEON_MAX_TCL_VERTSIZE ); 

   rmesa->boxes = 0;

   ctx->Const.MaxDrawBuffers = 1;
   ctx->Const.MaxColorAttachments = 1;
   ctx->Const.MaxRenderbufferSize = 2048;

   _mesa_set_mvp_with_dp4( ctx, GL_TRUE );

   /* Initialize the software rasterizer and helper modules.
    */
   _swrast_CreateContext( ctx );
   _vbo_CreateContext( ctx );
   _tnl_CreateContext( ctx );
   _swsetup_CreateContext( ctx );
   _ae_create_context( ctx );

   /* Install the customized pipeline:
    */
   _tnl_destroy_pipeline( ctx );
   _tnl_install_pipeline( ctx, radeon_pipeline );

   /* Try and keep materials and vertices separate:
    */
/*    _tnl_isolate_materials( ctx, GL_TRUE ); */

   /* Configure swrast and T&L to match hardware characteristics:
    */
   _swrast_allow_pixel_fog( ctx, GL_FALSE );
   _swrast_allow_vertex_fog( ctx, GL_TRUE );
   _tnl_allow_pixel_fog( ctx, GL_FALSE );
   _tnl_allow_vertex_fog( ctx, GL_TRUE );


   for ( i = 0 ; i < RADEON_MAX_TEXTURE_UNITS ; i++ ) {
      _math_matrix_ctr( &rmesa->TexGenMatrix[i] );
      _math_matrix_ctr( &rmesa->tmpmat[i] );
      _math_matrix_set_identity( &rmesa->TexGenMatrix[i] );
      _math_matrix_set_identity( &rmesa->tmpmat[i] );
   }

   ctx->Extensions.ARB_texture_border_clamp = true;
   ctx->Extensions.ARB_texture_env_combine = true;
   ctx->Extensions.ARB_texture_env_crossbar = true;
   ctx->Extensions.ARB_texture_env_dot3 = true;
   ctx->Extensions.EXT_fog_coord = true;
   ctx->Extensions.EXT_packed_depth_stencil = true;
   ctx->Extensions.EXT_secondary_color = true;
   ctx->Extensions.EXT_texture_env_dot3 = true;
   ctx->Extensions.EXT_texture_filter_anisotropic = true;
   ctx->Extensions.EXT_texture_mirror_clamp = true;
   ctx->Extensions.ATI_texture_env_combine3 = true;
   ctx->Extensions.ATI_texture_mirror_once = true;
   ctx->Extensions.MESA_ycbcr_texture = true;
   ctx->Extensions.NV_blend_square = true;
#if FEATURE_OES_EGL_image
   ctx->Extensions.OES_EGL_image = true;
#endif

   ctx->Extensions.EXT_framebuffer_object = true;

   ctx->Extensions.ARB_texture_cube_map = true;

   if (rmesa->radeon.glCtx->Mesa_DXTn) {
      ctx->Extensions.EXT_texture_compression_s3tc = true;
      ctx->Extensions.S3_s3tc = true;
   }
   else if (driQueryOptionb (&rmesa->radeon.optionCache, "force_s3tc_enable")) {
      ctx->Extensions.EXT_texture_compression_s3tc = true;
   }

   ctx->Extensions.NV_texture_rectangle = true;
   ctx->Extensions.ARB_occlusion_query = true;

   /* XXX these should really go right after _mesa_init_driver_functions() */
   radeon_fbo_init(&rmesa->radeon);
   radeonInitSpanFuncs( ctx );
   radeonInitIoctlFuncs( ctx );
   radeonInitStateFuncs( ctx );
   radeonInitState( rmesa );
   radeonInitSwtcl( ctx );

   _mesa_vector4f_alloc( &rmesa->tcl.ObjClean, 0, 
			 ctx->Const.MaxArrayLockSize, 32 );

   fthrottle_mode = driQueryOptioni(&rmesa->radeon.optionCache, "fthrottle_mode");
   rmesa->radeon.iw.irq_seq = -1;
   rmesa->radeon.irqsEmitted = 0;
   rmesa->radeon.do_irqs = (rmesa->radeon.radeonScreen->irq != 0 &&
			    fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS);

   rmesa->radeon.do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);


#if DO_DEBUG
   RADEON_DEBUG = driParseDebugString( getenv( "RADEON_DEBUG" ),
				       debug_control );
#endif

   tcl_mode = driQueryOptioni(&rmesa->radeon.optionCache, "tcl_mode");
   if (driQueryOptionb(&rmesa->radeon.optionCache, "no_rast")) {
      fprintf(stderr, "disabling 3D acceleration\n");
      FALLBACK(rmesa, RADEON_FALLBACK_DISABLE, 1);
   } else if (tcl_mode == DRI_CONF_TCL_SW ||
	      !(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) {
      if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
	 rmesa->radeon.radeonScreen->chip_flags &= ~RADEON_CHIPSET_TCL;
	 fprintf(stderr, "Disabling HW TCL support\n");
      }
      TCL_FALLBACK(rmesa->radeon.glCtx, RADEON_TCL_FALLBACK_TCL_DISABLE, 1);
   }

   if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
/*       _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); */
   }

   _mesa_compute_version(ctx);
   if (ctx->VersionMajor < major_version
       || (ctx->VersionMajor == major_version
	   && ctx->VersionMinor < minor_version)) {
      radeonDestroyContext(driContextPriv);
      *error = __DRI_CTX_ERROR_BAD_VERSION;
      return GL_FALSE;
   }

   *error = __DRI_CTX_ERROR_SUCCESS;
   return GL_TRUE;
}
Exemple #4
0
static void
brw_initialize_context_constants(struct brw_context *brw)
{
   struct gl_context *ctx = &brw->ctx;

   ctx->Const.QueryCounterBits.Timestamp = 36;

   ctx->Const.StripTextureBorder = true;

   ctx->Const.MaxDualSourceDrawBuffers = 1;
   ctx->Const.MaxDrawBuffers = BRW_MAX_DRAW_BUFFERS;
   ctx->Const.FragmentProgram.MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
   ctx->Const.MaxTextureCoordUnits = 8; /* Mesa limit */
   ctx->Const.MaxTextureUnits =
      MIN2(ctx->Const.MaxTextureCoordUnits,
           ctx->Const.FragmentProgram.MaxTextureImageUnits);
   ctx->Const.VertexProgram.MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
   if (brw->gen >= 7)
      ctx->Const.GeometryProgram.MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
   else
      ctx->Const.GeometryProgram.MaxTextureImageUnits = 0;
   ctx->Const.MaxCombinedTextureImageUnits =
      ctx->Const.VertexProgram.MaxTextureImageUnits +
      ctx->Const.FragmentProgram.MaxTextureImageUnits +
      ctx->Const.GeometryProgram.MaxTextureImageUnits;

   ctx->Const.MaxTextureLevels = 14; /* 8192 */
   if (ctx->Const.MaxTextureLevels > MAX_TEXTURE_LEVELS)
      ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
   ctx->Const.Max3DTextureLevels = 9;
   ctx->Const.MaxCubeTextureLevels = 12;

   if (brw->gen >= 7)
      ctx->Const.MaxArrayTextureLayers = 2048;
   else
      ctx->Const.MaxArrayTextureLayers = 512;

   ctx->Const.MaxTextureRectSize = 1 << 12;
   
   ctx->Const.MaxTextureMaxAnisotropy = 16.0;

   ctx->Const.MaxRenderbufferSize = 8192;

   /* Hardware only supports a limited number of transform feedback buffers.
    * So we need to override the Mesa default (which is based only on software
    * limits).
    */
   ctx->Const.MaxTransformFeedbackBuffers = BRW_MAX_SOL_BUFFERS;

   /* On Gen6, in the worst case, we use up one binding table entry per
    * transform feedback component (see comments above the definition of
    * BRW_MAX_SOL_BINDINGS, in brw_context.h), so we need to advertise a value
    * for MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS equal to
    * BRW_MAX_SOL_BINDINGS.
    *
    * In "separate components" mode, we need to divide this value by
    * BRW_MAX_SOL_BUFFERS, so that the total number of binding table entries
    * used up by all buffers will not exceed BRW_MAX_SOL_BINDINGS.
    */
   ctx->Const.MaxTransformFeedbackInterleavedComponents = BRW_MAX_SOL_BINDINGS;
   ctx->Const.MaxTransformFeedbackSeparateComponents =
      BRW_MAX_SOL_BINDINGS / BRW_MAX_SOL_BUFFERS;

   ctx->Const.AlwaysUseGetTransformFeedbackVertexCount = true;

   const int max_samples = brw_supported_msaa_modes(brw)[0];
   ctx->Const.MaxSamples = max_samples;
   ctx->Const.MaxColorTextureSamples = max_samples;
   ctx->Const.MaxDepthTextureSamples = max_samples;
   ctx->Const.MaxIntegerSamples = max_samples;

   if (brw->gen >= 7)
      ctx->Const.MaxProgramTextureGatherComponents = 4;

   ctx->Const.MinLineWidth = 1.0;
   ctx->Const.MinLineWidthAA = 1.0;
   ctx->Const.MaxLineWidth = 5.0;
   ctx->Const.MaxLineWidthAA = 5.0;
   ctx->Const.LineWidthGranularity = 0.5;

   ctx->Const.MinPointSize = 1.0;
   ctx->Const.MinPointSizeAA = 1.0;
   ctx->Const.MaxPointSize = 255.0;
   ctx->Const.MaxPointSizeAA = 255.0;
   ctx->Const.PointSizeGranularity = 1.0;

   if (brw->gen >= 5 || brw->is_g4x)
      ctx->Const.MaxClipPlanes = 8;

   ctx->Const.VertexProgram.MaxNativeInstructions = 16 * 1024;
   ctx->Const.VertexProgram.MaxAluInstructions = 0;
   ctx->Const.VertexProgram.MaxTexInstructions = 0;
   ctx->Const.VertexProgram.MaxTexIndirections = 0;
   ctx->Const.VertexProgram.MaxNativeAluInstructions = 0;
   ctx->Const.VertexProgram.MaxNativeTexInstructions = 0;
   ctx->Const.VertexProgram.MaxNativeTexIndirections = 0;
   ctx->Const.VertexProgram.MaxNativeAttribs = 16;
   ctx->Const.VertexProgram.MaxNativeTemps = 256;
   ctx->Const.VertexProgram.MaxNativeAddressRegs = 1;
   ctx->Const.VertexProgram.MaxNativeParameters = 1024;
   ctx->Const.VertexProgram.MaxEnvParams =
      MIN2(ctx->Const.VertexProgram.MaxNativeParameters,
	   ctx->Const.VertexProgram.MaxEnvParams);

   ctx->Const.FragmentProgram.MaxNativeInstructions = 1024;
   ctx->Const.FragmentProgram.MaxNativeAluInstructions = 1024;
   ctx->Const.FragmentProgram.MaxNativeTexInstructions = 1024;
   ctx->Const.FragmentProgram.MaxNativeTexIndirections = 1024;
   ctx->Const.FragmentProgram.MaxNativeAttribs = 12;
   ctx->Const.FragmentProgram.MaxNativeTemps = 256;
   ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0;
   ctx->Const.FragmentProgram.MaxNativeParameters = 1024;
   ctx->Const.FragmentProgram.MaxEnvParams =
      MIN2(ctx->Const.FragmentProgram.MaxNativeParameters,
	   ctx->Const.FragmentProgram.MaxEnvParams);

   /* Fragment shaders use real, 32-bit twos-complement integers for all
    * integer types.
    */
   ctx->Const.FragmentProgram.LowInt.RangeMin = 31;
   ctx->Const.FragmentProgram.LowInt.RangeMax = 30;
   ctx->Const.FragmentProgram.LowInt.Precision = 0;
   ctx->Const.FragmentProgram.HighInt = ctx->Const.FragmentProgram.LowInt;
   ctx->Const.FragmentProgram.MediumInt = ctx->Const.FragmentProgram.LowInt;

   if (brw->gen >= 7) {
      ctx->Const.FragmentProgram.MaxAtomicCounters = MAX_ATOMIC_COUNTERS;
      ctx->Const.VertexProgram.MaxAtomicCounters = MAX_ATOMIC_COUNTERS;
      ctx->Const.GeometryProgram.MaxAtomicCounters = MAX_ATOMIC_COUNTERS;
      ctx->Const.FragmentProgram.MaxAtomicBuffers = BRW_MAX_ABO;
      ctx->Const.VertexProgram.MaxAtomicBuffers = BRW_MAX_ABO;
      ctx->Const.GeometryProgram.MaxAtomicBuffers = BRW_MAX_ABO;
      ctx->Const.MaxCombinedAtomicBuffers = 3 * BRW_MAX_ABO;
   }

   /* Gen6 converts quads to polygon in beginning of 3D pipeline,
    * but we're not sure how it's actually done for vertex order,
    * that affect provoking vertex decision. Always use last vertex
    * convention for quad primitive which works as expected for now.
    */
   if (brw->gen >= 6)
      ctx->Const.QuadsFollowProvokingVertexConvention = false;

   ctx->Const.NativeIntegers = true;
   ctx->Const.UniformBooleanTrue = 1;

   /* From the gen4 PRM, volume 4 page 127:
    *
    *     "For SURFTYPE_BUFFER non-rendertarget surfaces, this field specifies
    *      the base address of the first element of the surface, computed in
    *      software by adding the surface base address to the byte offset of
    *      the element in the buffer."
    *
    * However, unaligned accesses are slower, so enforce buffer alignment.
    */
   ctx->Const.UniformBufferOffsetAlignment = 16;
   ctx->Const.TextureBufferOffsetAlignment = 16;

   if (brw->gen >= 6) {
      ctx->Const.MaxVarying = 32;
      ctx->Const.VertexProgram.MaxOutputComponents = 128;
      ctx->Const.GeometryProgram.MaxInputComponents = 64;
      ctx->Const.GeometryProgram.MaxOutputComponents = 128;
      ctx->Const.FragmentProgram.MaxInputComponents = 128;
   }

   /* We want the GLSL compiler to emit code that uses condition codes */
   for (int i = 0; i < MESA_SHADER_TYPES; i++) {
      ctx->ShaderCompilerOptions[i].MaxIfDepth = brw->gen < 6 ? 16 : UINT_MAX;
      ctx->ShaderCompilerOptions[i].EmitCondCodes = true;
      ctx->ShaderCompilerOptions[i].EmitNoNoise = true;
      ctx->ShaderCompilerOptions[i].EmitNoMainReturn = true;
      ctx->ShaderCompilerOptions[i].EmitNoIndirectInput = true;
      ctx->ShaderCompilerOptions[i].EmitNoIndirectOutput = true;

      ctx->ShaderCompilerOptions[i].EmitNoIndirectUniform =
	 (i == MESA_SHADER_FRAGMENT);
      ctx->ShaderCompilerOptions[i].EmitNoIndirectTemp =
	 (i == MESA_SHADER_FRAGMENT);
      ctx->ShaderCompilerOptions[i].LowerClipDistance = true;
   }

   ctx->ShaderCompilerOptions[MESA_SHADER_VERTEX].PreferDP4 = true;
}
Exemple #5
0
/*
 * As above, but write stencil values.
 */
void
_swrast_write_zoomed_stencil_span( GLcontext *ctx,
                                 GLuint n, GLint x, GLint y,
                                 const GLstencil stencil[], GLint y0,
                                 GLint skipPixels )
{
   GLint m;
   GLint r0, r1, row, r;
   GLint i, j, skipcol;
   GLstencil zstencil[MAX_WIDTH];  /* zoomed stencil values */
   GLint maxwidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH );

   (void) skipPixels;  /* XXX this shouldn't be ignored */

   /* compute width of output row */
   m = (GLint) FABSF( n * ctx->Pixel.ZoomX );
   if (m==0) {
      return;
   }
   if (ctx->Pixel.ZoomX<0.0) {
      /* adjust x coordinate for left/right mirroring */
      x = x - m;
   }

   /* compute which rows to draw */
   row = y - y0;
   r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
   r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
   if (r0==r1) {
      return;
   }
   else if (r1<r0) {
      GLint rtmp = r1;
      r1 = r0;
      r0 = rtmp;
   }

   /* return early if r0...r1 is above or below window */
   if (r0<0 && r1<0) {
      /* below window */
      return;
   }
   if (r0 >= (GLint) ctx->DrawBuffer->Height &&
       r1 >= (GLint) ctx->DrawBuffer->Height) {
      /* above window */
      return;
   }

   /* check if left edge is outside window */
   skipcol = 0;
   if (x<0) {
      skipcol = -x;
      m += x;
   }
   /* make sure span isn't too long or short */
   if (m>maxwidth) {
      m = maxwidth;
   }
   else if (m<=0) {
      return;
   }

   ASSERT( m <= MAX_WIDTH );

   /* zoom the span horizontally */
   if (ctx->Pixel.ZoomX==-1.0F) {
      /* n==m */
      for (j=0;j<m;j++) {
         i = n - (j+skipcol) - 1;
         zstencil[j] = stencil[i];
      }
   }
   else {
      GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
      for (j=0;j<m;j++) {
         i = (GLint) ((j+skipcol) * xscale);
         if (i<0)  i = n + i - 1;
         zstencil[j] = stencil[i];
      }
   }

   /* write the span */
   for (r=r0; r<r1; r++) {
      _swrast_write_stencil_span( ctx, m, x+skipcol, r, zstencil );
   }
}
Exemple #6
0
/* called from within the core where_is_pose loop, all animsystems and constraints
were executed & assigned. Now as last we do an IK pass */
static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree)
{
    float R_parmat[3][3], identity[3][3];
    float iR_parmat[3][3];
    float R_bonemat[3][3];
    float goalrot[3][3], goalpos[3];
    float rootmat[4][4], imat[4][4];
    float goal[4][4], goalinv[4][4];
    float irest_basis[3][3], full_basis[3][3];
    float end_pose[4][4], world_pose[4][4];
    float length, basis[3][3], rest_basis[3][3], start[3], *ikstretch=NULL;
    float resultinf=0.0f;
    int a, flag, hasstretch=0, resultblend=0;
    bPoseChannel *pchan;
    IK_Segment *seg, *parent, **iktree, *iktarget;
    IK_Solver *solver;
    PoseTarget *target;
    bKinematicConstraint *data, *poleangledata=NULL;
    Bone *bone;

    if (tree->totchannel == 0)
        return;

    iktree= MEM_mallocN(sizeof(void*)*tree->totchannel, "ik tree");

    for(a=0; a<tree->totchannel; a++) {
        pchan= tree->pchan[a];
        bone= pchan->bone;

        /* set DoF flag */
        flag= 0;
        if(!(pchan->ikflag & BONE_IK_NO_XDOF) && !(pchan->ikflag & BONE_IK_NO_XDOF_TEMP))
            flag |= IK_XDOF;
        if(!(pchan->ikflag & BONE_IK_NO_YDOF) && !(pchan->ikflag & BONE_IK_NO_YDOF_TEMP))
            flag |= IK_YDOF;
        if(!(pchan->ikflag & BONE_IK_NO_ZDOF) && !(pchan->ikflag & BONE_IK_NO_ZDOF_TEMP))
            flag |= IK_ZDOF;

        if(tree->stretch && (pchan->ikstretch > 0.0)) {
            flag |= IK_TRANS_YDOF;
            hasstretch = 1;
        }

        seg= iktree[a]= IK_CreateSegment(flag);

        /* find parent */
        if(a == 0)
            parent= NULL;
        else
            parent= iktree[tree->parent[a]];

        IK_SetParent(seg, parent);

        /* get the matrix that transforms from prevbone into this bone */
        copy_m3_m4(R_bonemat, pchan->pose_mat);

        /* gather transformations for this IK segment */

        if (pchan->parent)
            copy_m3_m4(R_parmat, pchan->parent->pose_mat);
        else
            unit_m3(R_parmat);

        /* bone offset */
        if (pchan->parent && (a > 0))
            sub_v3_v3v3(start, pchan->pose_head, pchan->parent->pose_tail);
        else
            /* only root bone (a = 0) has no parent */
            start[0]= start[1]= start[2]= 0.0f;

        /* change length based on bone size */
        length= bone->length*len_v3(R_bonemat[1]);

        /* compute rest basis and its inverse */
        copy_m3_m3(rest_basis, bone->bone_mat);
        copy_m3_m3(irest_basis, bone->bone_mat);
        transpose_m3(irest_basis);

        /* compute basis with rest_basis removed */
        invert_m3_m3(iR_parmat, R_parmat);
        mul_m3_m3m3(full_basis, iR_parmat, R_bonemat);
        mul_m3_m3m3(basis, irest_basis, full_basis);

        /* basis must be pure rotation */
        normalize_m3(basis);

        /* transform offset into local bone space */
        normalize_m3(iR_parmat);
        mul_m3_v3(iR_parmat, start);

        IK_SetTransform(seg, start, rest_basis, basis, length);

        if (pchan->ikflag & BONE_IK_XLIMIT)
            IK_SetLimit(seg, IK_X, pchan->limitmin[0], pchan->limitmax[0]);
        if (pchan->ikflag & BONE_IK_YLIMIT)
            IK_SetLimit(seg, IK_Y, pchan->limitmin[1], pchan->limitmax[1]);
        if (pchan->ikflag & BONE_IK_ZLIMIT)
            IK_SetLimit(seg, IK_Z, pchan->limitmin[2], pchan->limitmax[2]);

        IK_SetStiffness(seg, IK_X, pchan->stiffness[0]);
        IK_SetStiffness(seg, IK_Y, pchan->stiffness[1]);
        IK_SetStiffness(seg, IK_Z, pchan->stiffness[2]);

        if(tree->stretch && (pchan->ikstretch > 0.0)) {
            float ikstretch = pchan->ikstretch*pchan->ikstretch;
            IK_SetStiffness(seg, IK_TRANS_Y, MIN2(1.0-ikstretch, 0.99));
            IK_SetLimit(seg, IK_TRANS_Y, 0.001, 1e10);
        }
    }

    solver= IK_CreateSolver(iktree[0]);

    /* set solver goals */

    /* first set the goal inverse transform, assuming the root of tree was done ok! */
    pchan= tree->pchan[0];
    if (pchan->parent)
        /* transform goal by parent mat, so this rotation is not part of the
           segment's basis. otherwise rotation limits do not work on the
           local transform of the segment itself. */
        copy_m4_m4(rootmat, pchan->parent->pose_mat);
    else
        unit_m4(rootmat);
    VECCOPY(rootmat[3], pchan->pose_head);

    mul_m4_m4m4(imat, rootmat, ob->obmat);
    invert_m4_m4(goalinv, imat);

    for (target=tree->targets.first; target; target=target->next) {
        float polepos[3];
        int poleconstrain= 0;

        data= (bKinematicConstraint*)target->con->data;

        /* 1.0=ctime, we pass on object for auto-ik (owner-type here is object, even though
         * strictly speaking, it is a posechannel)
         */
        get_constraint_target_matrix(scene, target->con, 0, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);

        /* and set and transform goal */
        mul_m4_m4m4(goal, rootmat, goalinv);

        VECCOPY(goalpos, goal[3]);
        copy_m3_m4(goalrot, goal);

        /* same for pole vector target */
        if(data->poletar) {
            get_constraint_target_matrix(scene, target->con, 1, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);

            if(data->flag & CONSTRAINT_IK_SETANGLE) {
                /* don't solve IK when we are setting the pole angle */
                break;
            }
            else {
                mul_m4_m4m4(goal, rootmat, goalinv);
                VECCOPY(polepos, goal[3]);
                poleconstrain= 1;

                /* for pole targets, we blend the result of the ik solver
                 * instead of the target position, otherwise we can't get
                 * a smooth transition */
                resultblend= 1;
                resultinf= target->con->enforce;

                if(data->flag & CONSTRAINT_IK_GETANGLE) {
                    poleangledata= data;
                    data->flag &= ~CONSTRAINT_IK_GETANGLE;
                }
            }
        }

        /* do we need blending? */
        if (!resultblend && target->con->enforce!=1.0) {
            float q1[4], q2[4], q[4];
            float fac= target->con->enforce;
            float mfac= 1.0-fac;

            pchan= tree->pchan[target->tip];

            /* end effector in world space */
            copy_m4_m4(end_pose, pchan->pose_mat);
            VECCOPY(end_pose[3], pchan->pose_tail);
            mul_serie_m4(world_pose, goalinv, ob->obmat, end_pose, NULL, NULL, NULL, NULL, NULL);

            /* blend position */
            goalpos[0]= fac*goalpos[0] + mfac*world_pose[3][0];
            goalpos[1]= fac*goalpos[1] + mfac*world_pose[3][1];
            goalpos[2]= fac*goalpos[2] + mfac*world_pose[3][2];

            /* blend rotation */
            mat3_to_quat( q1,goalrot);
            mat4_to_quat( q2,world_pose);
            interp_qt_qtqt(q, q1, q2, mfac);
            quat_to_mat3( goalrot,q);
        }

        iktarget= iktree[target->tip];

        if(data->weight != 0.0) {
            if(poleconstrain)
                IK_SolverSetPoleVectorConstraint(solver, iktarget, goalpos,
                                                 polepos, data->poleangle, (poleangledata == data));
            IK_SolverAddGoal(solver, iktarget, goalpos, data->weight);
        }
        if((data->flag & CONSTRAINT_IK_ROT) && (data->orientweight != 0.0))
            if((data->flag & CONSTRAINT_IK_AUTO)==0)
                IK_SolverAddGoalOrientation(solver, iktarget, goalrot,
                                            data->orientweight);
    }

    /* solve */
    IK_Solve(solver, 0.0f, tree->iterations);

    if(poleangledata)
        poleangledata->poleangle= IK_SolverGetPoleAngle(solver);

    IK_FreeSolver(solver);

    /* gather basis changes */
    tree->basis_change= MEM_mallocN(sizeof(float[3][3])*tree->totchannel, "ik basis change");
    if(hasstretch)
        ikstretch= MEM_mallocN(sizeof(float)*tree->totchannel, "ik stretch");

    for(a=0; a<tree->totchannel; a++) {
        IK_GetBasisChange(iktree[a], tree->basis_change[a]);

        if(hasstretch) {
            /* have to compensate for scaling received from parent */
            float parentstretch, stretch;

            pchan= tree->pchan[a];
            parentstretch= (tree->parent[a] >= 0)? ikstretch[tree->parent[a]]: 1.0;

            if(tree->stretch && (pchan->ikstretch > 0.0)) {
                float trans[3], length;

                IK_GetTranslationChange(iktree[a], trans);
                length= pchan->bone->length*len_v3(pchan->pose_mat[1]);

                ikstretch[a]= (length == 0.0)? 1.0: (trans[1]+length)/length;
            }
            else
                ikstretch[a] = 1.0;

            stretch= (parentstretch == 0.0)? 1.0: ikstretch[a]/parentstretch;

            mul_v3_fl(tree->basis_change[a][0], stretch);
            mul_v3_fl(tree->basis_change[a][1], stretch);
            mul_v3_fl(tree->basis_change[a][2], stretch);
        }

        if(resultblend && resultinf!=1.0f) {
            unit_m3(identity);
            blend_m3_m3m3(tree->basis_change[a], identity,
                          tree->basis_change[a], resultinf);
        }

        IK_FreeSegment(iktree[a]);
    }

    MEM_freeN(iktree);
    if(ikstretch) MEM_freeN(ikstretch);
}
Exemple #7
0
void Klass::initialize_supers(Klass* k, TRAPS) {
  if (FastSuperclassLimit == 0) {
    // None of the other machinery matters.
    set_super(k);
    return;
  }
  if (k == NULL) {
    set_super(NULL);
    _primary_supers[0] = this;
    assert(super_depth() == 0, "Object must already be initialized properly");
  } else if (k != super() || k == SystemDictionary::Object_klass()) {
    assert(super() == NULL || super() == SystemDictionary::Object_klass(),
           "initialize this only once to a non-trivial value");
    set_super(k);
    Klass* sup = k;
    int sup_depth = sup->super_depth();
    juint my_depth  = MIN2(sup_depth + 1, (int)primary_super_limit());
    if (!can_be_primary_super_slow())
      my_depth = primary_super_limit();
    for (juint i = 0; i < my_depth; i++) {
      _primary_supers[i] = sup->_primary_supers[i];
    }
    Klass* *super_check_cell;
    if (my_depth < primary_super_limit()) {
      _primary_supers[my_depth] = this;
      super_check_cell = &_primary_supers[my_depth];
    } else {
      // Overflow of the primary_supers array forces me to be secondary.
      super_check_cell = &_secondary_super_cache;
    }
    set_super_check_offset((address)super_check_cell - (address) this);

#ifdef ASSERT
    {
      juint j = super_depth();
      assert(j == my_depth, "computed accessor gets right answer");
      Klass* t = this;
      while (!t->can_be_primary_super()) {
        t = t->super();
        j = t->super_depth();
      }
      for (juint j1 = j+1; j1 < primary_super_limit(); j1++) {
        assert(primary_super_of_depth(j1) == NULL, "super list padding");
      }
      while (t != NULL) {
        assert(primary_super_of_depth(j) == t, "super list initialization");
        t = t->super();
        --j;
      }
      assert(j == (juint)-1, "correct depth count");
    }
#endif
  }

  if (secondary_supers() == NULL) {
    KlassHandle this_kh (THREAD, this);

    // Now compute the list of secondary supertypes.
    // Secondaries can occasionally be on the super chain,
    // if the inline "_primary_supers" array overflows.
    int extras = 0;
    Klass* p;
    for (p = super(); !(p == NULL || p->can_be_primary_super()); p = p->super()) {
      ++extras;
    }

    ResourceMark rm(THREAD);  // need to reclaim GrowableArrays allocated below

    // Compute the "real" non-extra secondaries.
    GrowableArray<Klass*>* secondaries = compute_secondary_supers(extras);
    if (secondaries == NULL) {
      // secondary_supers set by compute_secondary_supers
      return;
    }

    GrowableArray<Klass*>* primaries = new GrowableArray<Klass*>(extras);

    for (p = this_kh->super(); !(p == NULL || p->can_be_primary_super()); p = p->super()) {
      int i;                    // Scan for overflow primaries being duplicates of 2nd'arys

      // This happens frequently for very deeply nested arrays: the
      // primary superclass chain overflows into the secondary.  The
      // secondary list contains the element_klass's secondaries with
      // an extra array dimension added.  If the element_klass's
      // secondary list already contains some primary overflows, they
      // (with the extra level of array-ness) will collide with the
      // normal primary superclass overflows.
      for( i = 0; i < secondaries->length(); i++ ) {
        if( secondaries->at(i) == p )
          break;
      }
      if( i < secondaries->length() )
        continue;               // It's a dup, don't put it in
      primaries->push(p);
    }
    // Combine the two arrays into a metadata object to pack the array.
    // The primaries are added in the reverse order, then the secondaries.
    int new_length = primaries->length() + secondaries->length();
    Array<Klass*>* s2 = MetadataFactory::new_array<Klass*>(
                                       class_loader_data(), new_length, CHECK);
    int fill_p = primaries->length();
    for (int j = 0; j < fill_p; j++) {
      s2->at_put(j, primaries->pop());  // add primaries in reverse order.
    }
    for( int j = 0; j < secondaries->length(); j++ ) {
      s2->at_put(j+fill_p, secondaries->at(j));  // add secondaries on the end.
    }

  #ifdef ASSERT
      // We must not copy any NULL placeholders left over from bootstrap.
    for (int j = 0; j < s2->length(); j++) {
      assert(s2->at(j) != NULL, "correct bootstrapping order");
    }
  #endif

    this_kh->set_secondary_supers(s2);
  }
}
/**
 * Compute which mipmap levels that really need to be sent to the hardware.
 * This depends on the base image size, GL_TEXTURE_MIN_LOD,
 * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
 */
static void
intel_calculate_first_last_level(struct intel_texture_object *intelObj)
{
   struct gl_texture_object *tObj = &intelObj->base;
   const struct gl_texture_image *const baseImage =
      tObj->Image[0][tObj->BaseLevel];

   /* These must be signed values.  MinLod and MaxLod can be negative numbers,
    * and having firstLevel and lastLevel as signed prevents the need for
    * extra sign checks.
    */
   int firstLevel;
   int lastLevel;

   /* Yes, this looks overly complicated, but it's all needed.
    */
   switch (tObj->Target) {
   case GL_TEXTURE_1D:
   case GL_TEXTURE_2D:
   case GL_TEXTURE_3D:
   case GL_TEXTURE_CUBE_MAP:
      if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
         /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL.
          */
         firstLevel = lastLevel = tObj->BaseLevel;
      }
      else {
#ifdef I915
         firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5);
         firstLevel = MAX2(firstLevel, tObj->BaseLevel);
         firstLevel = MIN2(firstLevel, tObj->BaseLevel + baseImage->MaxLog2);
         lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5);
         lastLevel = MAX2(lastLevel, tObj->BaseLevel);
         lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
         lastLevel = MIN2(lastLevel, tObj->MaxLevel);
         lastLevel = MAX2(firstLevel, lastLevel);       /* need at least one level */
#else
	 /* Currently not taking min/max lod into account here, those
	  * values are programmed as sampler state elsewhere and we
	  * upload the same mipmap levels regardless.  Not sure if
	  * this makes sense as it means it isn't possible for the app
	  * to use min/max lod to reduce texture memory pressure:
	  */
	 firstLevel = tObj->BaseLevel;
	 lastLevel = MIN2(tObj->BaseLevel + baseImage->MaxLog2,
			  tObj->MaxLevel);
	 lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
#endif
      }
      break;
   case GL_TEXTURE_RECTANGLE_NV:
   case GL_TEXTURE_4D_SGIS:
      firstLevel = lastLevel = 0;
      break;
   default:
      return;
   }

   /* save these values */
   intelObj->firstLevel = firstLevel;
   intelObj->lastLevel = lastLevel;
}
Exemple #9
0
/* only creates a table for a single channel in CurveMapping */
static void curvemap_make_table(CurveMap *cuma, rctf *clipr)
{
	CurveMapPoint *cmp= cuma->curve;
	BezTriple *bezt;
	float *fp, *allpoints, *lastpoint, curf, range;
	int a, totpoint;
	
	if(cuma->curve==NULL) return;
	
	/* default rect also is table range */
	cuma->mintable= clipr->xmin;
	cuma->maxtable= clipr->xmax;
	
	/* hrmf... we now rely on blender ipo beziers, these are more advanced */
	bezt= MEM_callocN(cuma->totpoint*sizeof(BezTriple), "beztarr");
	
	for(a=0; a<cuma->totpoint; a++) {
		cuma->mintable= MIN2(cuma->mintable, cmp[a].x);
		cuma->maxtable= MAX2(cuma->maxtable, cmp[a].x);
		bezt[a].vec[1][0]= cmp[a].x;
		bezt[a].vec[1][1]= cmp[a].y;
		if(cmp[a].flag & CUMA_VECTOR)
			bezt[a].h1= bezt[a].h2= HD_VECT;
		else
			bezt[a].h1= bezt[a].h2= HD_AUTO;
	}
	
	for(a=0; a<cuma->totpoint; a++) {
		if(a==0)
			calchandle_curvemap(bezt, NULL, bezt+1, 0);
		else if(a==cuma->totpoint-1)
			calchandle_curvemap(bezt+a, bezt+a-1, NULL, 0);
		else
			calchandle_curvemap(bezt+a, bezt+a-1, bezt+a+1, 0);
	}
	
	/* first and last handle need correction, instead of pointing to center of next/prev, 
		we let it point to the closest handle */
	if(cuma->totpoint>2) {
		float hlen, nlen, vec[3];
		
		if(bezt[0].h2==HD_AUTO) {
			
			hlen= len_v3v3(bezt[0].vec[1], bezt[0].vec[2]);	/* original handle length */
			/* clip handle point */
			VECCOPY(vec, bezt[1].vec[0]);
			if(vec[0] < bezt[0].vec[1][0])
				vec[0]= bezt[0].vec[1][0];
			
			sub_v3_v3(vec, bezt[0].vec[1]);
			nlen= len_v3(vec);
			if(nlen>FLT_EPSILON) {
				mul_v3_fl(vec, hlen/nlen);
				add_v3_v3v3(bezt[0].vec[2], vec, bezt[0].vec[1]);
				sub_v3_v3v3(bezt[0].vec[0], bezt[0].vec[1], vec);
			}
		}
		a= cuma->totpoint-1;
		if(bezt[a].h2==HD_AUTO) {
			
			hlen= len_v3v3(bezt[a].vec[1], bezt[a].vec[0]);	/* original handle length */
			/* clip handle point */
			VECCOPY(vec, bezt[a-1].vec[2]);
			if(vec[0] > bezt[a].vec[1][0])
				vec[0]= bezt[a].vec[1][0];
			
			sub_v3_v3(vec, bezt[a].vec[1]);
			nlen= len_v3(vec);
			if(nlen>FLT_EPSILON) {
				mul_v3_fl(vec, hlen/nlen);
				add_v3_v3v3(bezt[a].vec[0], vec, bezt[a].vec[1]);
				sub_v3_v3v3(bezt[a].vec[2], bezt[a].vec[1], vec);
			}
		}
	}	
	/* make the bezier curve */
	if(cuma->table)
		MEM_freeN(cuma->table);
	totpoint= (cuma->totpoint-1)*CM_RESOL;
	fp= allpoints= MEM_callocN(totpoint*2*sizeof(float), "table");
	
	for(a=0; a<cuma->totpoint-1; a++, fp += 2*CM_RESOL) {
		correct_bezpart(bezt[a].vec[1], bezt[a].vec[2], bezt[a+1].vec[0], bezt[a+1].vec[1]);
		forward_diff_bezier(bezt[a].vec[1][0], bezt[a].vec[2][0], bezt[a+1].vec[0][0], bezt[a+1].vec[1][0], fp, CM_RESOL-1, 2*sizeof(float));	
		forward_diff_bezier(bezt[a].vec[1][1], bezt[a].vec[2][1], bezt[a+1].vec[0][1], bezt[a+1].vec[1][1], fp+1, CM_RESOL-1, 2*sizeof(float));
	}
	
	/* store first and last handle for extrapolation, unit length */
	cuma->ext_in[0]= bezt[0].vec[0][0] - bezt[0].vec[1][0];
	cuma->ext_in[1]= bezt[0].vec[0][1] - bezt[0].vec[1][1];
	range= sqrt(cuma->ext_in[0]*cuma->ext_in[0] + cuma->ext_in[1]*cuma->ext_in[1]);
	cuma->ext_in[0]/= range;
	cuma->ext_in[1]/= range;
	
	a= cuma->totpoint-1;
	cuma->ext_out[0]= bezt[a].vec[1][0] - bezt[a].vec[2][0];
	cuma->ext_out[1]= bezt[a].vec[1][1] - bezt[a].vec[2][1];
	range= sqrt(cuma->ext_out[0]*cuma->ext_out[0] + cuma->ext_out[1]*cuma->ext_out[1]);
	cuma->ext_out[0]/= range;
	cuma->ext_out[1]/= range;
	
	/* cleanup */
	MEM_freeN(bezt);

	range= CM_TABLEDIV*(cuma->maxtable - cuma->mintable);
	cuma->range= 1.0f/range;
	
	/* now make a table with CM_TABLE equal x distances */
	fp= allpoints;
	lastpoint= allpoints + 2*(totpoint-1);
	cmp= MEM_callocN((CM_TABLE+1)*sizeof(CurveMapPoint), "dist table");
	
	for(a=0; a<=CM_TABLE; a++) {
		curf= cuma->mintable + range*(float)a;
		cmp[a].x= curf;
		
		/* get the first x coordinate larger than curf */
		while(curf >= fp[0] && fp!=lastpoint) {
			fp+=2;
		}
		if(fp==allpoints || (curf >= fp[0] && fp==lastpoint))
			cmp[a].y= curvemap_calc_extend(cuma, curf, allpoints, lastpoint);
		else {
			float fac1= fp[0] - fp[-2];
			float fac2= fp[0] - curf;
			if(fac1 > FLT_EPSILON)
				fac1= fac2/fac1;
			else
				fac1= 0.0f;
			cmp[a].y= fac1*fp[-1] + (1.0f-fac1)*fp[1];
		}
	}
	
	MEM_freeN(allpoints);
	cuma->table= cmp;
}
Exemple #10
0
/**
 * Draw vertex arrays.
 * This is the main entrypoint into the drawing module.  If drawing an indexed
 * primitive, the draw_set_indexes() function should have already been called
 * to specify the element/index buffer information.
 */
void
draw_vbo(struct draw_context *draw,
         const struct pipe_draw_info *info)
{
   unsigned instance;
   unsigned index_limit;
   unsigned count;
   assert(info->instance_count > 0);
   if (info->indexed)
      assert(draw->pt.user.elts);

   draw->pt.user.eltBias = info->index_bias;
   draw->pt.user.min_index = info->min_index;
   draw->pt.user.max_index = info->max_index;
   draw->pt.user.eltSize = info->indexed ? draw->pt.user.eltSizeIB : 0;

   if (0)
      debug_printf("draw_vbo(mode=%u start=%u count=%u):\n",
                   info->mode, info->start, info->count);

   if (0)
      tgsi_dump(draw->vs.vertex_shader->state.tokens, 0);

   if (0) {
      unsigned int i;
      debug_printf("Elements:\n");
      for (i = 0; i < draw->pt.nr_vertex_elements; i++) {
         debug_printf("  %u: src_offset=%u  inst_div=%u   vbuf=%u  format=%s\n",
                      i,
                      draw->pt.vertex_element[i].src_offset,
                      draw->pt.vertex_element[i].instance_divisor,
                      draw->pt.vertex_element[i].vertex_buffer_index,
                      util_format_name(draw->pt.vertex_element[i].src_format));
      }
      debug_printf("Buffers:\n");
      for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
         debug_printf("  %u: stride=%u offset=%u ptr=%p\n",
                      i,
                      draw->pt.vertex_buffer[i].stride,
                      draw->pt.vertex_buffer[i].buffer_offset,
                      draw->pt.user.vbuffer[i]);
      }
   }

   if (0)
      draw_print_arrays(draw, info->mode, info->start, MIN2(info->count, 20));

   index_limit = util_draw_max_index(draw->pt.vertex_buffer,
                                     draw->pt.vertex_element,
                                     draw->pt.nr_vertex_elements,
                                     info);

   if (index_limit == 0) {
      /* one of the buffers is too small to do any valid drawing */
      debug_warning("draw: VBO too small to draw anything\n");
      return;
   }

   draw->pt.max_index = index_limit - 1;

   count = info->count;
   if (count == 0) {
      if (info->count_from_stream_output)
         count = draw->pt.max_index + 1;
   }

   /*
    * TODO: We could use draw->pt.max_index to further narrow
    * the min_index/max_index hints given by the state tracker.
    */

   for (instance = 0; instance < info->instance_count; instance++) {
      draw->instance_id = instance + info->start_instance;

      if (info->primitive_restart) {
         draw_pt_arrays_restart(draw, info);
      }
      else {
         draw_pt_arrays(draw, info->mode, info->start, count);
      }
   }
}
Exemple #11
0
int
vc4_simulator_flush(struct vc4_context *vc4, struct drm_vc4_submit_cl *args)
{
        struct vc4_screen *screen = vc4->screen;
        struct vc4_surface *csurf = vc4_surface(vc4->framebuffer.cbufs[0]);
        struct vc4_resource *ctex = csurf ? vc4_resource(csurf->base.texture) : NULL;
        uint32_t winsys_stride = ctex ? ctex->bo->simulator_winsys_stride : 0;
        uint32_t sim_stride = ctex ? ctex->slices[0].stride : 0;
        uint32_t row_len = MIN2(sim_stride, winsys_stride);
        struct vc4_exec_info exec;
        struct drm_device local_dev = {
                .vc4 = vc4,
                .simulator_mem_next = OVERFLOW_SIZE,
        };
        struct drm_device *dev = &local_dev;
        int ret;

        memset(&exec, 0, sizeof(exec));
        list_inithead(&exec.unref_list);

        if (ctex && ctex->bo->simulator_winsys_map) {
#if 0
                fprintf(stderr, "%dx%d %d %d %d\n",
                        ctex->base.b.width0, ctex->base.b.height0,
                        winsys_stride,
                        sim_stride,
                        ctex->bo->size);
#endif

                for (int y = 0; y < ctex->base.b.height0; y++) {
                        memcpy(ctex->bo->map + y * sim_stride,
                               ctex->bo->simulator_winsys_map + y * winsys_stride,
                               row_len);
                }
        }

        exec.args = args;

        ret = vc4_simulator_pin_bos(dev, &exec);
        if (ret)
                return ret;

        ret = vc4_cl_validate(dev, &exec);
        if (ret)
                return ret;

        if (vc4_debug & VC4_DEBUG_CL) {
                fprintf(stderr, "RCL:\n");
                vc4_dump_cl(screen->simulator_mem_base + exec.ct1ca,
                            exec.ct1ea - exec.ct1ca, true);
        }

        if (exec.ct0ca != exec.ct0ea) {
                int bfc = simpenrose_do_binning(exec.ct0ca, exec.ct0ea);
                if (bfc != 1) {
                        fprintf(stderr, "Binning returned %d flushes, should be 1.\n",
                                bfc);
                        fprintf(stderr, "Relocated binning command list:\n");
                        vc4_dump_cl(screen->simulator_mem_base + exec.ct0ca,
                                    exec.ct0ea - exec.ct0ca, false);
                        abort();
                }
        }
        int rfc = simpenrose_do_rendering(exec.ct1ca, exec.ct1ea);
        if (rfc != 1) {
                fprintf(stderr, "Rendering returned %d frames, should be 1.\n",
                        rfc);
                fprintf(stderr, "Relocated render command list:\n");
                vc4_dump_cl(screen->simulator_mem_base + exec.ct1ca,
                            exec.ct1ea - exec.ct1ca, true);
                abort();
        }

        ret = vc4_simulator_unpin_bos(&exec);
        if (ret)
                return ret;

        list_for_each_entry_safe(struct drm_vc4_bo, bo, &exec.unref_list,
                                 unref_head) {
		list_del(&bo->unref_head);
                assert(*(uint32_t *)(bo->base.vaddr + bo->bo->size) ==
                       BO_SENTINEL);
                vc4_bo_unreference(&bo->bo);
                free(bo);
        }

        if (ctex && ctex->bo->simulator_winsys_map) {
                for (int y = 0; y < ctex->base.b.height0; y++) {
                        memcpy(ctex->bo->simulator_winsys_map + y * winsys_stride,
                               ctex->bo->map + y * sim_stride,
                               row_len);
                }
        }

        return 0;
}
Exemple #12
0
static void view3d_select_loop(ViewContext *vc, Scene *scene, View3D *v3d, ARegion *ar, bool use_obedit_skip)
{
	short code = 1;
	char dt;
	short dtx;

	if (vc->obedit && vc->obedit->type == OB_MBALL) {
		draw_object(scene, ar, v3d, BASACT, DRAW_PICKING | DRAW_CONSTCOLOR);
	}
	else if ((vc->obedit && vc->obedit->type == OB_ARMATURE)) {
		/* if not drawing sketch, draw bones */
		if (!BDR_drawSketchNames(vc)) {
			draw_object(scene, ar, v3d, BASACT, DRAW_PICKING | DRAW_CONSTCOLOR);
		}
	}
	else {
		Base *base;

		v3d->xray = true;  /* otherwise it postpones drawing */
		for (base = scene->base.first; base; base = base->next) {
			if (base->lay & v3d->lay) {

				if ((base->object->restrictflag & OB_RESTRICT_SELECT) ||
				    (use_obedit_skip && (scene->obedit->data == base->object->data)))
				{
					base->selcol = 0;
				}
				else {
					base->selcol = code;

					if (GPU_select_load_id(code)) {
						draw_object(scene, ar, v3d, base, DRAW_PICKING | DRAW_CONSTCOLOR);

						/* we draw duplicators for selection too */
						if ((base->object->transflag & OB_DUPLI)) {
							ListBase *lb;
							DupliObject *dob;
							Base tbase;

							tbase.flag = OB_FROMDUPLI;
							lb = object_duplilist(G.main->eval_ctx, scene, base->object);

							for (dob = lb->first; dob; dob = dob->next) {
								float omat[4][4];

								tbase.object = dob->ob;
								copy_m4_m4(omat, dob->ob->obmat);
								copy_m4_m4(dob->ob->obmat, dob->mat);

								/* extra service: draw the duplicator in drawtype of parent */
								/* MIN2 for the drawtype to allow bounding box objects in groups for lods */
								dt = tbase.object->dt;   tbase.object->dt = MIN2(tbase.object->dt, base->object->dt);
								dtx = tbase.object->dtx; tbase.object->dtx = base->object->dtx;

								draw_object(scene, ar, v3d, &tbase, DRAW_PICKING | DRAW_CONSTCOLOR);

								tbase.object->dt = dt;
								tbase.object->dtx = dtx;

								copy_m4_m4(dob->ob->obmat, omat);
							}
							free_object_duplilist(lb);
						}
					}
					code++;
				}
			}
		}
		v3d->xray = false;  /* restore */
	}
}
static void brw_update_sampler_state( const struct pipe_sampler_state *pipe_sampler,
				      unsigned sdc_gs_offset,
				      struct brw_sampler_state *sampler)
{
   memset(sampler, 0, sizeof(*sampler));

   switch (pipe_sampler->min_mip_filter) {
   case PIPE_TEX_FILTER_NEAREST:
      sampler->ss0.min_filter = BRW_MAPFILTER_NEAREST;
      break;
   case PIPE_TEX_FILTER_LINEAR:
      sampler->ss0.min_filter = BRW_MAPFILTER_LINEAR;
      break;
   case PIPE_TEX_FILTER_ANISO:
      sampler->ss0.min_filter = BRW_MAPFILTER_ANISOTROPIC;
      break;
   default:
      break;
   }

   switch (pipe_sampler->min_mip_filter) {
   case PIPE_TEX_MIPFILTER_NEAREST:
      sampler->ss0.mip_filter = BRW_MIPFILTER_NEAREST;
      break;
   case PIPE_TEX_MIPFILTER_LINEAR:
      sampler->ss0.mip_filter = BRW_MIPFILTER_LINEAR;
      break;
   case PIPE_TEX_MIPFILTER_NONE:
      sampler->ss0.mip_filter = BRW_MIPFILTER_NONE;
      break;
   default:
      break;
   }
   /* Set Anisotropy:
    */
   switch (pipe_sampler->mag_img_filter) {
   case PIPE_TEX_FILTER_NEAREST:
      sampler->ss0.mag_filter = BRW_MAPFILTER_NEAREST;
      break;
   case PIPE_TEX_FILTER_LINEAR:
      sampler->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
      break;
   case PIPE_TEX_FILTER_ANISO:
      sampler->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
      break;
   default:
      break;
   }

   if (pipe_sampler->max_anisotropy > 2.0) {
      sampler->ss3.max_aniso = MAX2((pipe_sampler->max_anisotropy - 2) / 2,
                                    BRW_ANISORATIO_16);
   }

   sampler->ss1.s_wrap_mode = translate_wrap_mode(pipe_sampler->wrap_s);
   sampler->ss1.r_wrap_mode = translate_wrap_mode(pipe_sampler->wrap_r);
   sampler->ss1.t_wrap_mode = translate_wrap_mode(pipe_sampler->wrap_t);

   /* Fulsim complains if I don't do this.  Hardware doesn't mind:
    */
#if 0
   if (texObj->Target == GL_TEXTURE_CUBE_MAP_ARB) {
      sampler->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CUBE;
      sampler->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CUBE;
      sampler->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CUBE;
   }
#endif

   /* Set shadow function:
    */
   if (pipe_sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
      /* Shadowing is "enabled" by emitting a particular sampler
       * message (sample_c).  So need to recompile WM program when
       * shadow comparison is enabled on each/any texture unit.
       */
      sampler->ss0.shadow_function = intel_translate_shadow_compare_func(pipe_sampler->compare_func);
   }

   /* Set LOD bias:
    */
   sampler->ss0.lod_bias = S_FIXED(CLAMP(pipe_sampler->lod_bias, -16, 15), 6);

   sampler->ss0.lod_preclamp = 1; /* OpenGL mode */
   sampler->ss0.default_color_mode = 0; /* OpenGL/DX10 mode */

   /* Set BaseMipLevel, MaxLOD, MinLOD:
    *
    * XXX: I don't think that using firstLevel, lastLevel works,
    * because we always setup the surface state as if firstLevel ==
    * level zero.  Probably have to subtract firstLevel from each of
    * these:
    */
   sampler->ss0.base_level = U_FIXED(0, 1);

   sampler->ss1.max_lod = U_FIXED(MIN2(MAX2(pipe_sampler->max_lod, 0), 13), 6);
   sampler->ss1.min_lod = U_FIXED(MIN2(MAX2(pipe_sampler->min_lod, 0), 13), 6);

   sampler->ss2.default_color_pointer = sdc_gs_offset >> 5;
}
Exemple #14
0
void
piglit_init(int argc, char **argv)
{
	GLuint vs_spiral, gs_spiral, vs_ref_main, vs_test_main, gs_test_main,
		gs_layout, fs_main, vao, element_buf;
	GLint max_gs_out_vertices, max_gs_out_components;
	int max_testable_vertices;
	char *text, *endptr;

	/* parse args */
	if (argc != 2)
		print_usage_and_exit(argv[0]);
	endptr = NULL;
	num_vertices = strtol(argv[1], &endptr, 0);
	if (endptr != argv[1] + strlen(argv[1]))
		print_usage_and_exit(argv[0]);

	/* Figure out the maximum number of vertices we can test. */
	glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &max_gs_out_vertices);
	glGetIntegerv(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS,
		      &max_gs_out_components);
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);
	max_testable_vertices = MIN2(max_gs_out_vertices,
				     max_gs_out_components / 4);

	/* If num_vertices == 0, test the maximum possible number of
	 * vertices.  Otherwise ensure that the requested number is
	 * supported by the implementation.
	 */
	if (num_vertices == 0)
		num_vertices = max_testable_vertices;
	else if (num_vertices > max_testable_vertices) {
		printf("Can't test more than %d vertices\n",
		       max_testable_vertices);
		piglit_report_result(PIGLIT_SKIP);
	}

	/* Compile shaders */
	vs_spiral = piglit_compile_shader_text(GL_VERTEX_SHADER, spiral_text);
	gs_spiral = piglit_compile_shader_text(GL_GEOMETRY_SHADER,
					       spiral_text);
	vs_ref_main = piglit_compile_shader_text(GL_VERTEX_SHADER,
						 vs_ref_text);
	vs_test_main = piglit_compile_shader_text(GL_VERTEX_SHADER,
						  vs_test_text);
	gs_test_main = piglit_compile_shader_text(GL_GEOMETRY_SHADER,
						  gs_test_text);
	asprintf(&text, gs_layout_template, num_vertices);
	gs_layout = piglit_compile_shader_text(GL_GEOMETRY_SHADER, text);
	free(text);
	fs_main = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_text);

	prog_ref = glCreateProgram();
	glAttachShader(prog_ref, vs_ref_main);
	glAttachShader(prog_ref, vs_spiral);
	glAttachShader(prog_ref, fs_main);
	glLinkProgram(prog_ref);
	if (!piglit_link_check_status(prog_ref))
		piglit_report_result(PIGLIT_FAIL);

	prog_test = glCreateProgram();
	glAttachShader(prog_test, vs_test_main);
	glAttachShader(prog_test, gs_test_main);
	glAttachShader(prog_test, gs_spiral);
	glAttachShader(prog_test, gs_layout);
	glAttachShader(prog_test, fs_main);
	glLinkProgram(prog_test);
	if (!piglit_link_check_status(prog_test))
		piglit_report_result(PIGLIT_FAIL);

	glDeleteShader(vs_spiral);
	glDeleteShader(gs_spiral);
	glDeleteShader(vs_ref_main);
	glDeleteShader(vs_test_main);
	glDeleteShader(gs_test_main);
	glDeleteShader(gs_layout);
	glDeleteShader(fs_main);

	/* Various other GL objects needed by the test */
	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);
	glGenBuffers(1, &element_buf);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buf);

	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);
}
Exemple #15
0
/* Helper function for si_blit_decompress_zs_in_place.
 */
static void
si_blit_decompress_zs_planes_in_place(struct si_context *sctx,
				      struct r600_texture *texture,
				      unsigned planes, unsigned level_mask,
				      unsigned first_layer, unsigned last_layer)
{
	struct pipe_surface *zsurf, surf_tmpl = {{0}};
	unsigned layer, max_layer, checked_last_layer;
	unsigned fully_decompressed_mask = 0;

	if (!level_mask)
		return;

	if (planes & PIPE_MASK_S)
		sctx->db_flush_stencil_inplace = true;
	if (planes & PIPE_MASK_Z)
		sctx->db_flush_depth_inplace = true;
	si_mark_atom_dirty(sctx, &sctx->db_render_state);

	surf_tmpl.format = texture->resource.b.b.format;

	while (level_mask) {
		unsigned level = u_bit_scan(&level_mask);

		surf_tmpl.u.tex.level = level;

		/* The smaller the mipmap level, the less layers there are
		 * as far as 3D textures are concerned. */
		max_layer = util_max_layer(&texture->resource.b.b, level);
		checked_last_layer = MIN2(last_layer, max_layer);

		for (layer = first_layer; layer <= checked_last_layer; layer++) {
			surf_tmpl.u.tex.first_layer = layer;
			surf_tmpl.u.tex.last_layer = layer;

			zsurf = sctx->b.b.create_surface(&sctx->b.b, &texture->resource.b.b, &surf_tmpl);

			si_blitter_begin(&sctx->b.b, SI_DECOMPRESS);
			util_blitter_custom_depth_stencil(sctx->blitter, zsurf, NULL, ~0,
							  sctx->custom_dsa_flush,
							  1.0f);
			si_blitter_end(&sctx->b.b);

			pipe_surface_reference(&zsurf, NULL);
		}

		/* The texture will always be dirty if some layers aren't flushed.
		 * I don't think this case occurs often though. */
		if (first_layer == 0 && last_layer == max_layer) {
			fully_decompressed_mask |= 1u << level;
		}
	}

	if (planes & PIPE_MASK_Z)
		texture->dirty_level_mask &= ~fully_decompressed_mask;
	if (planes & PIPE_MASK_S)
		texture->stencil_dirty_level_mask &= ~fully_decompressed_mask;

	sctx->db_flush_depth_inplace = false;
	sctx->db_flush_stencil_inplace = false;
	si_mark_atom_dirty(sctx, &sctx->db_render_state);
}
static boolean
try_setup_point( struct lp_setup_context *setup,
                 const float (*v0)[4] )
{
    struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe;
    /* x/y positions in fixed point */
    const struct lp_setup_variant_key *key = &setup->setup.variant->key;
    const int sizeAttr = setup->psize_slot;
    const float size
        = (setup->point_size_per_vertex && sizeAttr > 0) ? v0[sizeAttr][0]
          : setup->point_size;

    /* Yes this is necessary to accurately calculate bounding boxes
     * with the two fill-conventions we support.  GL (normally) ends
     * up needing a bottom-left fill convention, which requires
     * slightly different rounding.
     */
    int adj = (setup->bottom_edge_rule != 0) ? 1 : 0;

    struct lp_scene *scene = setup->scene;
    struct lp_rast_triangle *point;
    unsigned bytes;
    struct u_rect bbox;
    unsigned nr_planes = 4;
    struct point_info info;
    unsigned viewport_index = 0;
    unsigned layer = 0;
    int fixed_width;

    if (setup->viewport_index_slot > 0) {
        unsigned *udata = (unsigned*)v0[setup->viewport_index_slot];
        viewport_index = lp_clamp_viewport_idx(*udata);
    }
    if (setup->layer_slot > 0) {
        layer = *(unsigned*)v0[setup->layer_slot];
        layer = MIN2(layer, scene->fb_max_layer);
    }

    if (0)
        print_point(setup, v0, size);

    /* Bounding rectangle (in pixels) */
    if (!lp_context->rasterizer ||
            lp_context->rasterizer->point_quad_rasterization) {
        /*
         * Rasterize points as quads.
         */
        int x0, y0;
        /* Point size as fixed point integer, remove rounding errors
         * and gives minimum width for very small points.
         */
        fixed_width = MAX2(FIXED_ONE, subpixel_snap(size));

        x0 = subpixel_snap(v0[0][0] - setup->pixel_offset) - fixed_width/2;
        y0 = subpixel_snap(v0[0][1] - setup->pixel_offset) - fixed_width/2;

        bbox.x0 = (x0 + (FIXED_ONE-1)) >> FIXED_ORDER;
        bbox.x1 = (x0 + fixed_width + (FIXED_ONE-1)) >> FIXED_ORDER;
        bbox.y0 = (y0 + (FIXED_ONE-1) + adj) >> FIXED_ORDER;
        bbox.y1 = (y0 + fixed_width + (FIXED_ONE-1) + adj) >> FIXED_ORDER;

        /* Inclusive coordinates:
         */
        bbox.x1--;
        bbox.y1--;
    } else {
/**
 * Create a new pipe_screen object
 * Note: we're not presently subclassing pipe_screen (no llvmpipe_screen).
 */
struct pipe_screen *
llvmpipe_create_screen(struct sw_winsys *winsys)
{
   struct llvmpipe_screen *screen;

   util_cpu_detect();

#if defined(PIPE_ARCH_X86) && HAVE_LLVM < 0x0302
   /* require SSE2 due to LLVM PR6960. */
   if (!util_cpu_caps.has_sse2)
       return NULL;
#endif

#ifdef DEBUG
   LP_DEBUG = debug_get_flags_option("LP_DEBUG", lp_debug_flags, 0 );
#endif

   LP_PERF = debug_get_flags_option("LP_PERF", lp_perf_flags, 0 );

   screen = CALLOC_STRUCT(llvmpipe_screen);
   if (!screen)
      return NULL;

   screen->winsys = winsys;

   screen->base.destroy = llvmpipe_destroy_screen;

   screen->base.get_name = llvmpipe_get_name;
   screen->base.get_vendor = llvmpipe_get_vendor;
   screen->base.get_param = llvmpipe_get_param;
   screen->base.get_shader_param = llvmpipe_get_shader_param;
   screen->base.get_paramf = llvmpipe_get_paramf;
   screen->base.is_format_supported = llvmpipe_is_format_supported;

   screen->base.context_create = llvmpipe_create_context;
   screen->base.flush_frontbuffer = llvmpipe_flush_frontbuffer;
   screen->base.fence_reference = llvmpipe_fence_reference;
   screen->base.fence_signalled = llvmpipe_fence_signalled;
   screen->base.fence_finish = llvmpipe_fence_finish;

   screen->base.get_timestamp = llvmpipe_get_timestamp;

   llvmpipe_init_screen_resource_funcs(&screen->base);

   lp_jit_screen_init(screen);

   screen->num_threads = util_cpu_caps.nr_cpus > 1 ? util_cpu_caps.nr_cpus : 0;
#ifdef PIPE_SUBSYSTEM_EMBEDDED
   screen->num_threads = 0;
#endif
   screen->num_threads = debug_get_num_option("LP_NUM_THREADS", screen->num_threads);
   screen->num_threads = MIN2(screen->num_threads, LP_MAX_THREADS);

   screen->rast = lp_rast_create(screen->num_threads);
   if (!screen->rast) {
      lp_jit_screen_cleanup(screen);
      FREE(screen);
      return NULL;
   }
   pipe_mutex_init(screen->rast_mutex);

   util_format_s3tc_init();

   return &screen->base;
}
Exemple #18
0
/**
 * Set up for drawing interleaved arrays that all live in one VBO
 * or all live in user space.
 * \param vbuffer  returns vertex buffer info
 * \param velements  returns vertex element info
 */
static boolean
setup_interleaved_attribs(struct st_context *st,
                          const struct st_vertex_program *vp,
                          const struct st_vp_variant *vpv,
                          const struct gl_vertex_array **arrays,
                          struct pipe_vertex_buffer *vbuffer,
                          struct pipe_vertex_element velements[])
{
    GLuint attr;
    const GLubyte *low_addr = NULL;
    GLboolean usingVBO;      /* all arrays in a VBO? */
    struct gl_buffer_object *bufobj;
    GLsizei stride;

    /* Find the lowest address of the arrays we're drawing,
     * Init bufobj and stride.
     */
    if (vpv->num_inputs) {
        const struct gl_vertex_array *array;

        array = get_client_array(vp, arrays, 0);
        assert(array);

        /* Since we're doing interleaved arrays, we know there'll be at most
         * one buffer object and the stride will be the same for all arrays.
         * Grab them now.
         */
        bufobj = array->BufferObj;
        stride = array->StrideB;

        low_addr = arrays[vp->index_to_input[0]]->Ptr;

        for (attr = 1; attr < vpv->num_inputs; attr++) {
            const GLubyte *start;
            array = get_client_array(vp, arrays, attr);
            if (!array)
                continue;
            start = array->Ptr;
            low_addr = MIN2(low_addr, start);
        }
    }
    else {
        /* not sure we'll ever have zero inputs, but play it safe */
        bufobj = NULL;
        stride = 0;
        low_addr = 0;
    }

    /* are the arrays in user space? */
    usingVBO = _mesa_is_bufferobj(bufobj);

    for (attr = 0; attr < vpv->num_inputs;) {
        const struct gl_vertex_array *array;
        unsigned src_offset;
        unsigned src_format;

        array = get_client_array(vp, arrays, attr);
        assert(array);

        src_offset = (unsigned) (array->Ptr - low_addr);
        assert(array->_ElementSize ==
               _mesa_bytes_per_vertex_attrib(array->Size, array->Type));

        src_format = st_pipe_vertex_format(array->Type,
                                           array->Size,
                                           array->Format,
                                           array->Normalized,
                                           array->Integer);

        init_velement_lowered(st, vp, velements, src_offset, src_format,
                              array->InstanceDivisor, 0,
                              array->Size, array->Doubles, &attr);
    }

    /*
     * Return the vbuffer info and setup user-space attrib info, if needed.
     */
    if (vpv->num_inputs == 0) {
        /* just defensive coding here */
        vbuffer->buffer = NULL;
        vbuffer->user_buffer = NULL;
        vbuffer->buffer_offset = 0;
        vbuffer->stride = 0;
    }
    else if (usingVBO) {
        /* all interleaved arrays in a VBO */
        struct st_buffer_object *stobj = st_buffer_object(bufobj);

        if (!stobj || !stobj->buffer) {
            return FALSE; /* out-of-memory error probably */
        }

        vbuffer->buffer = stobj->buffer;
        vbuffer->user_buffer = NULL;
        vbuffer->buffer_offset = pointer_to_offset(low_addr);
        vbuffer->stride = stride;
    }
    else {
        /* all interleaved arrays in user memory */
        vbuffer->buffer = NULL;
        vbuffer->user_buffer = low_addr;
        vbuffer->buffer_offset = 0;
        vbuffer->stride = stride;
    }
    return TRUE;
}
Exemple #19
0
/* Note: detecting the IK chain is duplicate code... in drawarmature.c and in transform_conversions.c */
static void initialize_posetree(struct Object *UNUSED(ob), bPoseChannel *pchan_tip)
{
    bPoseChannel *curchan, *pchan_root=NULL, *chanlist[256], **oldchan;
    PoseTree *tree;
    PoseTarget *target;
    bConstraint *con;
    bKinematicConstraint *data;
    int a, segcount= 0, size, newsize, *oldparent, parent;

    /* find IK constraint, and validate it */
    for(con= pchan_tip->constraints.first; con; con= con->next) {
        if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
            data=(bKinematicConstraint*)con->data;
            if (data->flag & CONSTRAINT_IK_AUTO) break;
            if (data->tar==NULL) continue;
            if (data->tar->type==OB_ARMATURE && data->subtarget[0]==0) continue;
            if ((con->flag & (CONSTRAINT_DISABLE|CONSTRAINT_OFF))==0 && (con->enforce!=0.0)) break;
        }
    }
    if(con==NULL) return;

    /* exclude tip from chain? */
    if(!(data->flag & CONSTRAINT_IK_TIP))
        pchan_tip= pchan_tip->parent;

    /* Find the chain's root & count the segments needed */
    for (curchan = pchan_tip; curchan; curchan=curchan->parent) {
        pchan_root = curchan;

        curchan->flag |= POSE_CHAIN;	// don't forget to clear this
        chanlist[segcount]=curchan;
        segcount++;

        if(segcount==data->rootbone || segcount>255) break; // 255 is weak
    }
    if (!segcount) return;

    /* setup the chain data */

    /* we make tree-IK, unless all existing targets are in this chain */
    for(tree= pchan_root->iktree.first; tree; tree= tree->next) {
        for(target= tree->targets.first; target; target= target->next) {
            curchan= tree->pchan[target->tip];
            if(curchan->flag & POSE_CHAIN)
                curchan->flag &= ~POSE_CHAIN;
            else
                break;
        }
        if(target) break;
    }

    /* create a target */
    target= MEM_callocN(sizeof(PoseTarget), "posetarget");
    target->con= con;
    pchan_tip->flag &= ~POSE_CHAIN;

    if(tree==NULL) {
        /* make new tree */
        tree= MEM_callocN(sizeof(PoseTree), "posetree");

        tree->type= CONSTRAINT_TYPE_KINEMATIC;

        tree->iterations= data->iterations;
        tree->totchannel= segcount;
        tree->stretch = (data->flag & CONSTRAINT_IK_STRETCH);

        tree->pchan= MEM_callocN(segcount*sizeof(void*), "ik tree pchan");
        tree->parent= MEM_callocN(segcount*sizeof(int), "ik tree parent");
        for(a=0; a<segcount; a++) {
            tree->pchan[a]= chanlist[segcount-a-1];
            tree->parent[a]= a-1;
        }
        target->tip= segcount-1;

        /* AND! link the tree to the root */
        BLI_addtail(&pchan_root->iktree, tree);
    }
    else {
        tree->iterations= MAX2(data->iterations, tree->iterations);
        tree->stretch= tree->stretch && !(data->flag & CONSTRAINT_IK_STRETCH);

        /* skip common pose channels and add remaining*/
        size= MIN2(segcount, tree->totchannel);
        for(a=0; a<size && tree->pchan[a]==chanlist[segcount-a-1]; a++);
        parent= a-1;

        segcount= segcount-a;
        target->tip= tree->totchannel + segcount - 1;

        if (segcount > 0) {
            /* resize array */
            newsize= tree->totchannel + segcount;
            oldchan= tree->pchan;
            oldparent= tree->parent;

            tree->pchan= MEM_callocN(newsize*sizeof(void*), "ik tree pchan");
            tree->parent= MEM_callocN(newsize*sizeof(int), "ik tree parent");
            memcpy(tree->pchan, oldchan, sizeof(void*)*tree->totchannel);
            memcpy(tree->parent, oldparent, sizeof(int)*tree->totchannel);
            MEM_freeN(oldchan);
            MEM_freeN(oldparent);

            /* add new pose channels at the end, in reverse order */
            for(a=0; a<segcount; a++) {
                tree->pchan[tree->totchannel+a]= chanlist[segcount-a-1];
                tree->parent[tree->totchannel+a]= tree->totchannel+a-1;
            }
            tree->parent[tree->totchannel]= parent;

            tree->totchannel= newsize;
        }

        /* move tree to end of list, for correct evaluation order */
        BLI_remlink(&pchan_root->iktree, tree);
        BLI_addtail(&pchan_root->iktree, tree);
    }

    /* add target to the tree */
    BLI_addtail(&tree->targets, target);
    /* mark root channel having an IK tree */
    pchan_root->flag |= POSE_IKTREE;
}
Exemple #20
0
static int
svga_get_param(struct pipe_screen *screen, enum pipe_cap param)
{
   struct svga_screen *svgascreen = svga_screen(screen);
   struct svga_winsys_screen *sws = svgascreen->sws;
   SVGA3dDevCapResult result;

   switch (param) {
   case PIPE_CAP_NPOT_TEXTURES:
   case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
   case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
      return 1;
   case PIPE_CAP_TWO_SIDED_STENCIL:
      return 1;
   case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
      /*
       * "In virtually every OpenGL implementation and hardware,
       * GL_MAX_DUAL_SOURCE_DRAW_BUFFERS is 1"
       * http://www.opengl.org/wiki/Blending
       */
      return sws->have_vgpu10 ? 1 : 0;
   case PIPE_CAP_ANISOTROPIC_FILTER:
      return 1;
   case PIPE_CAP_POINT_SPRITE:
      return 1;
   case PIPE_CAP_TGSI_TEXCOORD:
      return 0;
   case PIPE_CAP_MAX_RENDER_TARGETS:
      return svgascreen->max_color_buffers;
   case PIPE_CAP_OCCLUSION_QUERY:
      return 1;
   case PIPE_CAP_QUERY_TIME_ELAPSED:
      return 0;
   case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
      return sws->have_vgpu10;
   case PIPE_CAP_TEXTURE_SHADOW_MAP:
      return 1;
   case PIPE_CAP_TEXTURE_SWIZZLE:
      return 1;
   case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
      return 0;
   case PIPE_CAP_USER_VERTEX_BUFFERS:
   case PIPE_CAP_USER_INDEX_BUFFERS:
      return 0;
   case PIPE_CAP_USER_CONSTANT_BUFFERS:
      return 1;
   case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
      return 256;

   case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
      {
         unsigned levels = SVGA_MAX_TEXTURE_LEVELS;
         if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH, &result))
            levels = MIN2(util_logbase2(result.u) + 1, levels);
         else
            levels = 12 /* 2048x2048 */;
         if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT, &result))
            levels = MIN2(util_logbase2(result.u) + 1, levels);
         else
            levels = 12 /* 2048x2048 */;
         return levels;
      }

   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
      if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VOLUME_EXTENT, &result))
         return 8;  /* max 128x128x128 */
      return MIN2(util_logbase2(result.u) + 1, SVGA_MAX_TEXTURE_LEVELS);

   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
      /*
       * No mechanism to query the host, and at least limited to 2048x2048 on
       * certain hardware.
       */
      return MIN2(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS),
                  12 /* 2048x2048 */);

   case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
      return sws->have_vgpu10 ? SVGA3D_MAX_SURFACE_ARRAYSIZE : 0;

   case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */
      return 1;

   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
      return 1;
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
      return sws->have_vgpu10;
   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
      return 0;
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
      return !sws->have_vgpu10;

   case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
      return 1; /* The color outputs of vertex shaders are not clamped */
   case PIPE_CAP_VERTEX_COLOR_CLAMPED:
      return 0; /* The driver can't clamp vertex colors */
   case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
      return 0; /* The driver can't clamp fragment colors */

   case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
      return 1; /* expected for GL_ARB_framebuffer_object */

   case PIPE_CAP_GLSL_FEATURE_LEVEL:
      return sws->have_vgpu10 ? 330 : 120;

   case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
      return 0;

   case PIPE_CAP_SM3:
      return 1;

   case PIPE_CAP_DEPTH_CLIP_DISABLE:
   case PIPE_CAP_INDEP_BLEND_ENABLE:
   case PIPE_CAP_CONDITIONAL_RENDER:
   case PIPE_CAP_QUERY_TIMESTAMP:
   case PIPE_CAP_TGSI_INSTANCEID:
   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
   case PIPE_CAP_SEAMLESS_CUBE_MAP:
   case PIPE_CAP_FAKE_SW_MSAA:
      return sws->have_vgpu10;

   case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
      return sws->have_vgpu10 ? SVGA3D_DX_MAX_SOTARGETS : 0;
   case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
      return sws->have_vgpu10 ? 4 : 0;
   case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
      return sws->have_vgpu10 ? SVGA3D_MAX_STREAMOUT_DECLS : 0;
   case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
   case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
      return 0;
   case PIPE_CAP_TEXTURE_MULTISAMPLE:
      return svgascreen->ms_samples ? 1 : 0;

   case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
      return SVGA3D_DX_MAX_RESOURCE_SIZE;

   case PIPE_CAP_MIN_TEXEL_OFFSET:
      return sws->have_vgpu10 ? VGPU10_MIN_TEXEL_FETCH_OFFSET : 0;
   case PIPE_CAP_MAX_TEXEL_OFFSET:
      return sws->have_vgpu10 ? VGPU10_MAX_TEXEL_FETCH_OFFSET : 0;

   case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
   case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
      return 0;

   case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
      return sws->have_vgpu10 ? 256 : 0;
   case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
      return sws->have_vgpu10 ? 1024 : 0;

   case PIPE_CAP_PRIMITIVE_RESTART:
      return 1; /* may be a sw fallback, depending on restart index */

   case PIPE_CAP_GENERATE_MIPMAP:
      return sws->have_generate_mipmap_cmd;

   /* Unsupported features */
   case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
   case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
   case PIPE_CAP_SHADER_STENCIL_EXPORT:
   case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
   case PIPE_CAP_INDEP_BLEND_FUNC:
   case PIPE_CAP_TEXTURE_BARRIER:
   case PIPE_CAP_MAX_VERTEX_STREAMS:
   case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
   case PIPE_CAP_COMPUTE:
   case PIPE_CAP_START_INSTANCE:
   case PIPE_CAP_CUBE_MAP_ARRAY:
   case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
   case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
   case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
   case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
   case PIPE_CAP_TEXTURE_GATHER_SM5:
   case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
   case PIPE_CAP_TEXTURE_QUERY_LOD:
   case PIPE_CAP_SAMPLE_SHADING:
   case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
   case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
   case PIPE_CAP_DRAW_INDIRECT:
   case PIPE_CAP_MULTI_DRAW_INDIRECT:
   case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
   case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
   case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
   case PIPE_CAP_SAMPLER_VIEW_TARGET:
   case PIPE_CAP_CLIP_HALFZ:
   case PIPE_CAP_VERTEXID_NOBASE:
   case PIPE_CAP_POLYGON_OFFSET_CLAMP:
   case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
   case PIPE_CAP_TGSI_PACK_HALF_FLOAT:
   case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
   case PIPE_CAP_INVALIDATE_BUFFER:
   case PIPE_CAP_STRING_MARKER:
   case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
   case PIPE_CAP_QUERY_MEMORY_INFO:
   case PIPE_CAP_PCI_GROUP:
   case PIPE_CAP_PCI_BUS:
   case PIPE_CAP_PCI_DEVICE:
   case PIPE_CAP_PCI_FUNCTION:
   case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
      return 0;
   case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
      return 64;
   case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
   case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
   case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
      return 1;  /* need 4-byte alignment for all offsets and strides */
   case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
      return 2048;
   case PIPE_CAP_MAX_VIEWPORTS:
      return 1;
   case PIPE_CAP_ENDIANNESS:
      return PIPE_ENDIAN_LITTLE;

   case PIPE_CAP_VENDOR_ID:
      return 0x15ad; /* VMware Inc. */
   case PIPE_CAP_DEVICE_ID:
      return 0x0405; /* assume SVGA II */
   case PIPE_CAP_ACCELERATED:
      return 0; /* XXX: */
   case PIPE_CAP_VIDEO_MEMORY:
      /* XXX: Query the host ? */
      return 1;
   case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
      return sws->have_vgpu10;
   case PIPE_CAP_CLEAR_TEXTURE:
      return sws->have_vgpu10;
   case PIPE_CAP_UMA:
   case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
   case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
   case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
   case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
   case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
   case PIPE_CAP_DEPTH_BOUNDS_TEST:
   case PIPE_CAP_TGSI_TXQS:
   case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
   case PIPE_CAP_SHAREABLE_SHADERS:
   case PIPE_CAP_DRAW_PARAMETERS:
   case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
   case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
   case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY:
   case PIPE_CAP_QUERY_BUFFER_OBJECT:
   case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
   case PIPE_CAP_CULL_DISTANCE:
   case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES:
   case PIPE_CAP_TGSI_VOTE:
   case PIPE_CAP_MAX_WINDOW_RECTANGLES:
   case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED:
   case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS:
   case PIPE_CAP_TGSI_ARRAY_COMPONENTS:
      return 0;
   }

   debug_printf("Unexpected PIPE_CAP_ query %u\n", param);
   return 0;
}
int Read_EntryProc_Config( config_file_t config, void *module_config,
                           char *msg_out, int for_reload )
{
    int            rc, blc_index, i;
    int            tmpval;
    entry_proc_config_t *conf = ( entry_proc_config_t * ) module_config;

    char           pipeline_names[PIPELINE_STAGE_COUNT][256];
    char          *entry_proc_allowed[PIPELINE_STAGE_COUNT + 5];

    entry_proc_allowed[0] = "nb_threads";
    entry_proc_allowed[1] = "max_pending_operations";
    entry_proc_allowed[2] = "match_classes";
    entry_proc_allowed[3] = ALERT_BLOCK;

    entry_proc_allowed[PIPELINE_STAGE_COUNT + 4] = NULL;        /* PIPELINE_STAGE_COUNT+4 = last slot */

    /* get EntryProcessor block */

    config_item_t  entryproc_block = rh_config_FindItemByName( config, ENTRYPROC_CONFIG_BLOCK );

    if ( entryproc_block == NULL )
    {
        strcpy( msg_out, "Missing configuration block '" ENTRYPROC_CONFIG_BLOCK "'" );
        /* No error because no parameter is mandatory  */
        return 0;
    }

    if ( rh_config_ItemType( entryproc_block ) != CONFIG_ITEM_BLOCK )
    {
        strcpy( msg_out, "A block is expected for '" ENTRYPROC_CONFIG_BLOCK "' item" );
        return EINVAL;
    }

    /* retrieve parameters */

    rc = GetIntParam( entryproc_block, ENTRYPROC_CONFIG_BLOCK, "nb_threads",
                      INT_PARAM_POSITIVE | INT_PARAM_NOT_NULL,
                      ( int * ) &conf->nb_thread, NULL, NULL, msg_out );
    if ( ( rc != 0 ) && ( rc != ENOENT ) )
        return rc;

    rc = GetIntParam( entryproc_block, ENTRYPROC_CONFIG_BLOCK, "max_pending_operations",
                      INT_PARAM_POSITIVE,
                      ( int * ) &conf->max_pending_operations, NULL, NULL, msg_out );
    if ( ( rc != 0 ) && ( rc != ENOENT ) )
        return rc;

    rc = GetBoolParam( entryproc_block, ENTRYPROC_CONFIG_BLOCK, "match_classes",
                       0, &conf->match_classes, NULL, NULL, msg_out );
    if ( ( rc != 0 ) && ( rc != ENOENT ) )
        return rc;


    /* look for '<stage>_thread_max' parameters */
    for ( i = 0; i < PIPELINE_STAGE_COUNT; i++ )
    {
        char           varname[256];

        snprintf( varname, 256, "%s_threads_max", entry_proc_pipeline[i].stage_name );

        strncpy( pipeline_names[i], varname, 256 );
        entry_proc_allowed[i + 4] = pipeline_names[i];

        rc = GetIntParam( entryproc_block, ENTRYPROC_CONFIG_BLOCK, varname,
                          INT_PARAM_POSITIVE, &tmpval, NULL, NULL, msg_out );

        if ( ( rc != 0 ) && ( rc != ENOENT ) )
            return rc;
        else if ( ( rc != ENOENT ) && ( tmpval > 0 ) )  /* 0: keep default */
        {
            if ( entry_proc_pipeline[i].stage_flags & STAGE_FLAG_MAX_THREADS )
                entry_proc_pipeline[i].max_thread_count =
                    MIN2( entry_proc_pipeline[i].max_thread_count, tmpval );
            else if ( entry_proc_pipeline[i].stage_flags & STAGE_FLAG_PARALLEL )
            {
                /* the stqge is no more parallel, it has a limited number of threads */
                entry_proc_pipeline[i].stage_flags &= ~STAGE_FLAG_PARALLEL;
                entry_proc_pipeline[i].stage_flags |= STAGE_FLAG_MAX_THREADS;
                entry_proc_pipeline[i].max_thread_count = tmpval;
            }
            else if ( ( entry_proc_pipeline[i].stage_flags & STAGE_FLAG_SEQUENTIAL )
                      && ( tmpval != 1 ) )
            {
                sprintf( msg_out, "%s is sequential. Cannot use %u threads at this stage.",
                         entry_proc_pipeline[i].stage_name, tmpval );
                return EINVAL;
            }
        }

    }

    /* Find and parse "Alert" blocks */
    for ( blc_index = 0; blc_index < rh_config_GetNbItems( entryproc_block ); blc_index++ )
    {
        char          *block_name;
        config_item_t  curr_item = rh_config_GetItemByIndex( entryproc_block, blc_index );
        critical_err_check( curr_item, ENTRYPROC_CONFIG_BLOCK );

        if ( rh_config_ItemType( curr_item ) != CONFIG_ITEM_BLOCK )
            continue;

        block_name = rh_config_GetBlockName( curr_item );
        critical_err_check( curr_item, ENTRYPROC_CONFIG_BLOCK );

        if ( !strcasecmp( block_name, ALERT_BLOCK ) )
        {
            char * alert_title = NULL;

            if ( conf->alert_count == 0 )
                conf->alert_list = ( alert_item_t * ) malloc( sizeof( alert_item_t ) );
            else
                conf->alert_list =
                    ( alert_item_t * ) realloc( conf->alert_list,
                                                ( conf->alert_count + 1 )
                                                * sizeof( alert_item_t ) );

            conf->alert_count++;

            alert_title = rh_config_GetBlockId( curr_item );
            if ( alert_title != NULL )
                strncpy( conf->alert_list[conf->alert_count - 1].title,
                         alert_title, ALERT_TITLE_MAX );
            else
                conf->alert_list[conf->alert_count - 1].title[0] = '\0';

            /* analyze boolean expression */
            rc = GetBoolExpr( curr_item, block_name,
                              &conf->alert_list[conf->alert_count - 1].boolexpr,
                              &conf->alert_list[conf->alert_count - 1].attr_mask, msg_out );

            if ( rc )
                return rc;

            conf->alert_attr_mask |= conf->alert_list[conf->alert_count - 1].attr_mask;
        }
    }                           /* Loop on subblocks */

    CheckUnknownParameters( entryproc_block, ENTRYPROC_CONFIG_BLOCK,
                            ( const char ** ) entry_proc_allowed );

    return 0;
}
Exemple #22
0
static int
vgpu9_get_shader_param(struct pipe_screen *screen, unsigned shader,
                       enum pipe_shader_cap param)
{
   struct svga_screen *svgascreen = svga_screen(screen);
   struct svga_winsys_screen *sws = svgascreen->sws;
   unsigned val;

   assert(!sws->have_vgpu10);

   switch (shader)
   {
   case PIPE_SHADER_FRAGMENT:
      switch (param)
      {
      case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
      case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
         return get_uint_cap(sws,
                             SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_INSTRUCTIONS,
                             512);
      case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
      case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
         return 512;
      case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
         return SVGA3D_MAX_NESTING_LEVEL;
      case PIPE_SHADER_CAP_MAX_INPUTS:
         return 10;
      case PIPE_SHADER_CAP_MAX_OUTPUTS:
         return svgascreen->max_color_buffers;
      case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
         return 224 * sizeof(float[4]);
      case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
         return 1;
      case PIPE_SHADER_CAP_MAX_TEMPS:
         val = get_uint_cap(sws, SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS, 32);
         return MIN2(val, SVGA3D_TEMPREG_MAX);
      case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
	 /* 
	  * Although PS 3.0 has some addressing abilities it can only represent
	  * loops that can be statically determined and unrolled. Given we can
	  * only handle a subset of the cases that the state tracker already
	  * does it is better to defer loop unrolling to the state tracker.
	  */
         return 0;
      case PIPE_SHADER_CAP_MAX_PREDS:
         return 1;
      case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
         return 0;
      case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
         return 0;
      case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
      case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
      case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
         return 0;
      case PIPE_SHADER_CAP_SUBROUTINES:
         return 0;
      case PIPE_SHADER_CAP_INTEGERS:
         return 0;
      case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
      case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
         return 16;
      case PIPE_SHADER_CAP_PREFERRED_IR:
         return PIPE_SHADER_IR_TGSI;
      case PIPE_SHADER_CAP_SUPPORTED_IRS:
         return 0;
      case PIPE_SHADER_CAP_DOUBLES:
      case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
      case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
      case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
      case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
      case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
      case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
         return 0;
      case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
         return 32;
      }
      /* If we get here, we failed to handle a cap above */
      debug_printf("Unexpected fragment shader query %u\n", param);
      return 0;
   case PIPE_SHADER_VERTEX:
      switch (param)
      {
      case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
      case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
         return get_uint_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS,
                             512);
      case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
      case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
         /* XXX: until we have vertex texture support */
         return 0;
      case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
         return SVGA3D_MAX_NESTING_LEVEL;
      case PIPE_SHADER_CAP_MAX_INPUTS:
         return 16;
      case PIPE_SHADER_CAP_MAX_OUTPUTS:
         return 10;
      case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
         return 256 * sizeof(float[4]);
      case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
         return 1;
      case PIPE_SHADER_CAP_MAX_TEMPS:
         val = get_uint_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS, 32);
         return MIN2(val, SVGA3D_TEMPREG_MAX);
      case PIPE_SHADER_CAP_MAX_PREDS:
         return 1;
      case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
         return 0;
      case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
         return 0;
      case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
      case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
         return 1;
      case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
         return 0;
      case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
         return 1;
      case PIPE_SHADER_CAP_SUBROUTINES:
         return 0;
      case PIPE_SHADER_CAP_INTEGERS:
         return 0;
      case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
      case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
         return 0;
      case PIPE_SHADER_CAP_PREFERRED_IR:
         return PIPE_SHADER_IR_TGSI;
      case PIPE_SHADER_CAP_SUPPORTED_IRS:
         return 0;
      case PIPE_SHADER_CAP_DOUBLES:
      case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
      case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
      case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
      case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
      case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
      case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
         return 0;
      case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
         return 32;
      }
      /* If we get here, we failed to handle a cap above */
      debug_printf("Unexpected vertex shader query %u\n", param);
      return 0;
   case PIPE_SHADER_GEOMETRY:
   case PIPE_SHADER_COMPUTE:
   case PIPE_SHADER_TESS_CTRL:
   case PIPE_SHADER_TESS_EVAL:
      /* no support for geometry, tess or compute shaders at this time */
      return 0;
   default:
      debug_printf("Unexpected shader type (%u) query\n", shader);
      return 0;
   }
   return 0;
}
MethodLiveness::MethodLiveness(Arena* arena, ciMethod* method) 
  : _bci_block_start((uintptr_t*)arena->Amalloc((method->code_size() >> LogBitsPerByte) + 1), method->code_size())
{
  _arena = arena;
  _method = method;
  _bit_map_size_bits = method->max_locals();
  _bit_map_size_words = (_bit_map_size_bits / sizeof(unsigned int)) + 1;

  _bci_block_start.clear();
}

void MethodLiveness::compute_liveness() {
#ifndef PRODUCT
  if (TraceLivenessGen) {
    tty->print_cr("################################################################");
    tty->print("# Computing liveness information for ");
    method()->print_short_name();
  }

  if (TimeLivenessAnalysis) _time_total.start();
#endif

  {
    TraceTime buildGraph(NULL, &_time_build_graph, TimeLivenessAnalysis);
    init_basic_blocks();
  }
  {
    TraceTime genKill(NULL, &_time_gen_kill, TimeLivenessAnalysis);
    init_gen_kill();
  }
  {
    TraceTime flow(NULL, &_time_flow, TimeLivenessAnalysis);
    propagate_liveness();
  }

#ifndef PRODUCT
  if (TimeLivenessAnalysis) _time_total.stop();

  if (TimeLivenessAnalysis) {
    // Collect statistics
    _total_bytes += method()->code_size();
    _total_methods++;

    int num_blocks = _block_count;
    _total_blocks += num_blocks;
    _max_method_blocks = MAX2(num_blocks,_max_method_blocks);

    for (int i=0; i<num_blocks; i++) {
      BasicBlock *block = _block_list[i];

      int numEdges = block->_normal_predecessors->length();
      int numExcEdges = block->_exception_predecessors->length();

      _total_edges += numEdges;
      _total_exc_edges += numExcEdges;
      _max_block_edges = MAX2(numEdges,_max_block_edges);
      _max_block_exc_edges = MAX2(numExcEdges,_max_block_exc_edges);
    }

    int numLocals = _bit_map_size_bits;
    _total_method_locals += numLocals;
    _max_method_locals = MAX2(numLocals,_max_method_locals);
  }
#endif
}


void MethodLiveness::init_basic_blocks() {
  bool bailout = false;

  int method_len = method()->code_size();
  ciMethodBlocks *mblocks = method()->get_method_blocks();

  // Create an array to store the bci->BasicBlock mapping.
  _block_map = new (arena()) GrowableArray<BasicBlock*>(arena(), method_len, method_len, NULL);

  _block_count = mblocks->num_blocks();
  _block_list = (BasicBlock **) arena()->Amalloc(sizeof(BasicBlock *) * _block_count);

  // Used for patching up jsr/ret control flow.
  GrowableArray<BasicBlock*>* jsr_exit_list = new GrowableArray<BasicBlock*>(5);
  GrowableArray<BasicBlock*>* ret_list = new GrowableArray<BasicBlock*>(5);

  // generate our block list from ciMethodBlocks
  for (int blk = 0; blk < _block_count; blk++) {
    ciBlock *cib = mblocks->block(blk);
     int start_bci = cib->start_bci();
    _block_list[blk] = new (arena()) BasicBlock(this, start_bci, cib->limit_bci());
    _block_map->at_put(start_bci, _block_list[blk]);
    // mark all bcis where a new basic block starts
    _bci_block_start.set_bit(start_bci);
  }
  // fill in the predecessors of blocks
  ciBytecodeStream bytes(method());

  for (int blk = 0; blk < _block_count; blk++) {
    BasicBlock *current_block = _block_list[blk];
    int bci =  mblocks->block(blk)->control_bci();

    if (bci == ciBlock::fall_through_bci) {
      int limit = current_block->limit_bci();
      if (limit < method_len) {
        BasicBlock *next = _block_map->at(limit);
        assert( next != NULL, "must be a block immediately following this one.");
        next->add_normal_predecessor(current_block);
      }
      continue;
    }
    bytes.reset_to_bci(bci);
    Bytecodes::Code code = bytes.next();
    BasicBlock *dest;

    // Now we need to interpret the instruction's effect
    // on control flow.
    assert (current_block != NULL, "we must have a current block");
    switch (code) {
      case Bytecodes::_ifeq:
      case Bytecodes::_ifne:
      case Bytecodes::_iflt:
      case Bytecodes::_ifge:
      case Bytecodes::_ifgt:
      case Bytecodes::_ifle:
      case Bytecodes::_if_icmpeq:
      case Bytecodes::_if_icmpne:
      case Bytecodes::_if_icmplt:
      case Bytecodes::_if_icmpge:
      case Bytecodes::_if_icmpgt:
      case Bytecodes::_if_icmple:
      case Bytecodes::_if_acmpeq:
      case Bytecodes::_if_acmpne:
      case Bytecodes::_ifnull:   
      case Bytecodes::_ifnonnull:
        // Two way branch.  Set predecessors at each destination.
        dest = _block_map->at(bytes.next_bci());
        assert(dest != NULL, "must be a block immediately following this one.");
        dest->add_normal_predecessor(current_block);

        dest = _block_map->at(bytes.get_dest());
        assert(dest != NULL, "branch desination must start a block.");
        dest->add_normal_predecessor(current_block);
        break;
      case Bytecodes::_goto:
        dest = _block_map->at(bytes.get_dest());
        assert(dest != NULL, "branch desination must start a block.");
        dest->add_normal_predecessor(current_block);
        break;
      case Bytecodes::_goto_w:         
        dest = _block_map->at(bytes.get_far_dest());
        assert(dest != NULL, "branch desination must start a block.");
        dest->add_normal_predecessor(current_block);
        break;
      case Bytecodes::_tableswitch:  
        {
          Bytecode_tableswitch *tableswitch =
            Bytecode_tableswitch_at(bytes.cur_bcp());

          int len = tableswitch->length();        
        
          dest = _block_map->at(bci + tableswitch->default_offset());
          assert(dest != NULL, "branch desination must start a block.");
          dest->add_normal_predecessor(current_block);
          while (--len >= 0) {
            dest = _block_map->at(bci + tableswitch->dest_offset_at(len));
            assert(dest != NULL, "branch desination must start a block.");
            dest->add_normal_predecessor(current_block);
          }
          break; 
        }

      case Bytecodes::_lookupswitch:
        {
          Bytecode_lookupswitch *lookupswitch =
            Bytecode_lookupswitch_at(bytes.cur_bcp());
          
          int npairs = lookupswitch->number_of_pairs(); 
        
          dest = _block_map->at(bci + lookupswitch->default_offset());
          assert(dest != NULL, "branch desination must start a block.");
          dest->add_normal_predecessor(current_block);
          while(--npairs >= 0) {
            LookupswitchPair *pair = lookupswitch->pair_at(npairs);
            dest = _block_map->at( bci + pair->offset());
            assert(dest != NULL, "branch desination must start a block.");
            dest->add_normal_predecessor(current_block);
          }
          break; 
        }

      case Bytecodes::_jsr: 
        {
          assert(bytes.is_wide()==false, "sanity check");
          dest = _block_map->at(bytes.get_dest());
          assert(dest != NULL, "branch desination must start a block.");
          dest->add_normal_predecessor(current_block);
          BasicBlock *jsrExit = _block_map->at(current_block->limit_bci());
          assert(jsrExit != NULL, "jsr return bci must start a block.");
          jsr_exit_list->append(jsrExit);
          break;
        }
      case Bytecodes::_jsr_w:
        {       
          dest = _block_map->at(bytes.get_far_dest());
          assert(dest != NULL, "branch desination must start a block.");
          dest->add_normal_predecessor(current_block);
          BasicBlock *jsrExit = _block_map->at(current_block->limit_bci());
          assert(jsrExit != NULL, "jsr return bci must start a block.");
          jsr_exit_list->append(jsrExit);
          break;
        }

      case Bytecodes::_wide:           
        assert(false, "wide opcodes should not be seen here");
        break;
      case Bytecodes::_athrow:
      case Bytecodes::_ireturn:
      case Bytecodes::_lreturn:
      case Bytecodes::_freturn:
      case Bytecodes::_dreturn:
      case Bytecodes::_areturn:
      case Bytecodes::_return:         
        // These opcodes are  not the normal predecessors of any other opcodes.
        break;
      case Bytecodes::_ret:
        // We will patch up jsr/rets in a subsequent pass.
        ret_list->append(current_block);
        break;
      case Bytecodes::_breakpoint:
        // Bail out of there are breakpoints in here.
        bailout = true;
        break;
      default:                 
        // Do nothing.
        break;
    }
  }
  // Patch up the jsr/ret's.  We conservatively assume that any ret
  // can return to any jsr site.
  int ret_list_len = ret_list->length();
  int jsr_exit_list_len = jsr_exit_list->length();
  if (ret_list_len > 0 && jsr_exit_list_len > 0) {
    for (int i = jsr_exit_list_len - 1; i >= 0; i--) {
      BasicBlock *jsrExit = jsr_exit_list->at(i);
      for (int i = ret_list_len - 1; i >= 0; i--) {
        jsrExit->add_normal_predecessor(ret_list->at(i));
      }
    }
  }

  // Compute exception edges.
  for (int b=_block_count-1; b >= 0; b--) {
    BasicBlock *block = _block_list[b];
    int block_start = block->start_bci();
    int block_limit = block->limit_bci();
    ciExceptionHandlerStream handlers(method());
    for (; !handlers.is_done(); handlers.next()) {
      ciExceptionHandler* handler = handlers.handler();
      int start       = handler->start();
      int limit       = handler->limit();
      int handler_bci = handler->handler_bci();

      int intersect_start = MAX2(block_start, start);
      int intersect_limit = MIN2(block_limit, limit);
      if (intersect_start < intersect_limit) {
        // The catch range has a nonempty intersection with this
        // basic block.  That means this basic block can be an
        // exceptional predecessor.
        _block_map->at(handler_bci)->add_exception_predecessor(block);

        if (handler->is_catch_all()) {
          // This is a catch-all block.
          if (intersect_start == block_start && intersect_limit == block_limit) {
            // The basic block is entirely contained in this catch-all block.
            // Skip the rest of the exception handlers -- they can never be
            // reached in execution.
            break;
          }
        }
      }
    }
  }
}
Exemple #24
0
/**
 * Create a new svga_screen object
 */
struct pipe_screen *
svga_screen_create(struct svga_winsys_screen *sws)
{
   struct svga_screen *svgascreen;
   struct pipe_screen *screen;

#ifdef DEBUG
   SVGA_DEBUG = debug_get_flags_option("SVGA_DEBUG", svga_debug_flags, 0 );
#endif

   svgascreen = CALLOC_STRUCT(svga_screen);
   if (!svgascreen)
      goto error1;

   svgascreen->debug.force_level_surface_view =
      debug_get_bool_option("SVGA_FORCE_LEVEL_SURFACE_VIEW", FALSE);
   svgascreen->debug.force_surface_view =
      debug_get_bool_option("SVGA_FORCE_SURFACE_VIEW", FALSE);
   svgascreen->debug.force_sampler_view =
      debug_get_bool_option("SVGA_FORCE_SAMPLER_VIEW", FALSE);
   svgascreen->debug.no_surface_view =
      debug_get_bool_option("SVGA_NO_SURFACE_VIEW", FALSE);
   svgascreen->debug.no_sampler_view =
      debug_get_bool_option("SVGA_NO_SAMPLER_VIEW", FALSE);
   svgascreen->debug.no_cache_index_buffers =
      debug_get_bool_option("SVGA_NO_CACHE_INDEX_BUFFERS", FALSE);

   screen = &svgascreen->screen;

   screen->destroy = svga_destroy_screen;
   screen->get_name = svga_get_name;
   screen->get_vendor = svga_get_vendor;
   screen->get_device_vendor = svga_get_vendor; // TODO actual device vendor
   screen->get_param = svga_get_param;
   screen->get_shader_param = svga_get_shader_param;
   screen->get_paramf = svga_get_paramf;
   screen->get_timestamp = NULL;
   screen->is_format_supported = svga_is_format_supported;
   screen->context_create = svga_context_create;
   screen->fence_reference = svga_fence_reference;
   screen->fence_finish = svga_fence_finish;
   screen->get_driver_query_info = svga_get_driver_query_info;
   svgascreen->sws = sws;

   svga_init_screen_resource_functions(svgascreen);

   if (sws->get_hw_version) {
      svgascreen->hw_version = sws->get_hw_version(sws);
   } else {
      svgascreen->hw_version = SVGA3D_HWVERSION_WS65_B1;
   }

   /*
    * The D16, D24X8, and D24S8 formats always do an implicit shadow compare
    * when sampled from, where as the DF16, DF24, and D24S8_INT do not.  So
    * we prefer the later when available.
    *
    * This mimics hardware vendors extensions for D3D depth sampling. See also
    * http://aras-p.info/texts/D3D9GPUHacks.html
    */

   {
      boolean has_df16, has_df24, has_d24s8_int;
      SVGA3dSurfaceFormatCaps caps;
      SVGA3dSurfaceFormatCaps mask;
      mask.value = 0;
      mask.zStencil = 1;
      mask.texture = 1;

      svgascreen->depth.z16 = SVGA3D_Z_D16;
      svgascreen->depth.x8z24 = SVGA3D_Z_D24X8;
      svgascreen->depth.s8z24 = SVGA3D_Z_D24S8;

      svga_get_format_cap(svgascreen, SVGA3D_Z_DF16, &caps);
      has_df16 = (caps.value & mask.value) == mask.value;

      svga_get_format_cap(svgascreen, SVGA3D_Z_DF24, &caps);
      has_df24 = (caps.value & mask.value) == mask.value;

      svga_get_format_cap(svgascreen, SVGA3D_Z_D24S8_INT, &caps);
      has_d24s8_int = (caps.value & mask.value) == mask.value;

      /* XXX: We might want some other logic here.
       * Like if we only have d24s8_int we should
       * emulate the other formats with that.
       */
      if (has_df16) {
         svgascreen->depth.z16 = SVGA3D_Z_DF16;
      }
      if (has_df24) {
         svgascreen->depth.x8z24 = SVGA3D_Z_DF24;
      }
      if (has_d24s8_int) {
         svgascreen->depth.s8z24 = SVGA3D_Z_D24S8_INT;
      }
   }

   /* Query device caps
    */
   if (sws->have_vgpu10) {
      svgascreen->haveProvokingVertex
         = get_bool_cap(sws, SVGA3D_DEVCAP_DX_PROVOKING_VERTEX, FALSE);
      svgascreen->haveLineSmooth = TRUE;
      svgascreen->maxPointSize = 80.0F;
      svgascreen->max_color_buffers = SVGA3D_DX_MAX_RENDER_TARGETS;

      /* Multisample samples per pixel */
      if (debug_get_bool_option("SVGA_MSAA", TRUE)) {
         svgascreen->ms_samples =
            get_uint_cap(sws, SVGA3D_DEVCAP_MULTISAMPLE_MASKABLESAMPLES, 0);
      }

      /* Maximum number of constant buffers */
      svgascreen->max_const_buffers =
         get_uint_cap(sws, SVGA3D_DEVCAP_DX_MAX_CONSTANT_BUFFERS, 1);
      assert(svgascreen->max_const_buffers <= SVGA_MAX_CONST_BUFS);
   }
   else {
      /* VGPU9 */
      unsigned vs_ver = get_uint_cap(sws, SVGA3D_DEVCAP_VERTEX_SHADER_VERSION,
                                     SVGA3DVSVERSION_NONE);
      unsigned fs_ver = get_uint_cap(sws, SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION,
                                     SVGA3DPSVERSION_NONE);

      /* we require Shader model 3.0 or later */
      if (fs_ver < SVGA3DPSVERSION_30 || vs_ver < SVGA3DVSVERSION_30) {
         goto error2;
      }

      svgascreen->haveProvokingVertex = FALSE;

      svgascreen->haveLineSmooth =
         get_bool_cap(sws, SVGA3D_DEVCAP_LINE_AA, FALSE);

      svgascreen->maxPointSize =
         get_float_cap(sws, SVGA3D_DEVCAP_MAX_POINT_SIZE, 1.0f);
      /* Keep this to a reasonable size to avoid failures in conform/pntaa.c */
      svgascreen->maxPointSize = MIN2(svgascreen->maxPointSize, 80.0f);

      /* The SVGA3D device always supports 4 targets at this time, regardless
       * of what querying SVGA3D_DEVCAP_MAX_RENDER_TARGETS might return.
       */
      svgascreen->max_color_buffers = 4;

      /* Only support one constant buffer
       */
      svgascreen->max_const_buffers = 1;

      /* No multisampling */
      svgascreen->ms_samples = 0;
   }

   /* common VGPU9 / VGPU10 caps */
   svgascreen->haveLineStipple =
      get_bool_cap(sws, SVGA3D_DEVCAP_LINE_STIPPLE, FALSE);

   svgascreen->maxLineWidth =
      get_float_cap(sws, SVGA3D_DEVCAP_MAX_LINE_WIDTH, 1.0f);

   svgascreen->maxLineWidthAA =
      get_float_cap(sws, SVGA3D_DEVCAP_MAX_AA_LINE_WIDTH, 1.0f);

   if (0) {
      debug_printf("svga: haveProvokingVertex %u\n",
                   svgascreen->haveProvokingVertex);
      debug_printf("svga: haveLineStip %u  "
                   "haveLineSmooth %u  maxLineWidth %f\n",
                   svgascreen->haveLineStipple, svgascreen->haveLineSmooth,
                   svgascreen->maxLineWidth);
      debug_printf("svga: maxPointSize %g\n", svgascreen->maxPointSize);
      debug_printf("svga: msaa samples mask: 0x%x\n", svgascreen->ms_samples);
   }

   pipe_mutex_init(svgascreen->tex_mutex);
   pipe_mutex_init(svgascreen->swc_mutex);

   svga_screen_cache_init(svgascreen);

   return screen;
error2:
   FREE(svgascreen);
error1:
   return NULL;
}
Exemple #25
0
/*
 * Helper function called from _swrast_write_zoomed_rgba/rgb/index_span().
 */
static void
zoom_span( GLcontext *ctx, const struct sw_span *span,
           const GLvoid *src, GLint y0, GLenum format, GLint skipPixels )
{
   GLint r0, r1, row;
   GLint c0, c1, skipCol;
   GLint i, j;
   const GLuint maxWidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH );
   struct sw_span zoomed;
   struct span_arrays zoomed_arrays;  /* this is big! */

   /* no pixel arrays! must be horizontal spans. */
   ASSERT((span->arrayMask & SPAN_XY) == 0);
   ASSERT(span->primitive == GL_BITMAP);

   INIT_SPAN(zoomed, GL_BITMAP, 0, 0, 0);
   zoomed.array = &zoomed_arrays;

   /* copy fog interp info */
   zoomed.fog = span->fog;
   zoomed.fogStep = span->fogStep;
   /* XXX copy texcoord info? */

   if (format == GL_RGBA || format == GL_RGB) {
      /* copy Z info */
      zoomed.z = span->z;
      zoomed.zStep = span->zStep;
      /* we'll generate an array of colorss */
      zoomed.interpMask = span->interpMask & ~SPAN_RGBA;
      zoomed.arrayMask |= SPAN_RGBA;
   }
   else if (format == GL_COLOR_INDEX) {
      /* copy Z info */
      zoomed.z = span->z;
      zoomed.zStep = span->zStep;
      /* we'll generate an array of color indexes */
      zoomed.interpMask = span->interpMask & ~SPAN_INDEX;
      zoomed.arrayMask |= SPAN_INDEX;
   }
   else {
      assert(format == GL_DEPTH_COMPONENT);
      /* Copy color info */
      zoomed.red = span->red;
      zoomed.green = span->green;
      zoomed.blue = span->blue;
      zoomed.alpha = span->alpha;
      zoomed.redStep = span->redStep;
      zoomed.greenStep = span->greenStep;
      zoomed.blueStep = span->blueStep;
      zoomed.alphaStep = span->alphaStep;
      /* we'll generate an array of depth values */
      zoomed.interpMask = span->interpMask & ~SPAN_Z;
      zoomed.arrayMask |= SPAN_Z;
   }

   /*
    * Compute which columns to draw: [c0, c1)
    */
   c0 = (GLint) (span->x + skipPixels * ctx->Pixel.ZoomX);
   c1 = (GLint) (span->x + (skipPixels + span->end) * ctx->Pixel.ZoomX);
   if (c0 == c1) {
      return;
   }
   else if (c1 < c0) {
      /* swap */
      GLint ctmp = c1;
      c1 = c0;
      c0 = ctmp;
   }
   if (c0 < 0) {
      zoomed.x = 0;
      zoomed.start = 0;
      zoomed.end = c1;
      skipCol = -c0;
   }
   else {
      zoomed.x = c0;
      zoomed.start = 0;
      zoomed.end = c1 - c0;
      skipCol = 0;
   }
   if (zoomed.end > maxWidth)
      zoomed.end = maxWidth;

   /*
    * Compute which rows to draw: [r0, r1)
    */
   row = span->y - y0;
   r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
   r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
   if (r0 == r1) {
      return;
   }
   else if (r1 < r0) {
      /* swap */
      GLint rtmp = r1;
      r1 = r0;
      r0 = rtmp;
   }

   ASSERT(r0 < r1);
   ASSERT(c0 < c1);

   /*
    * Trivial clip rejection testing.
    */
   if (r1 < 0) /* below window */
      return;
   if (r0 >= (GLint) ctx->DrawBuffer->Height) /* above window */
      return;
   if (c1 < 0) /* left of window */
      return;
   if (c0 >= (GLint) ctx->DrawBuffer->Width) /* right of window */
      return;

   /* zoom the span horizontally */
   if (format == GL_RGBA) {
      const GLchan (*rgba)[4] = (const GLchan (*)[4]) src;
      if (ctx->Pixel.ZoomX == -1.0F) {
         /* common case */
         for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
            i = span->end - (j + skipCol) - 1;
            COPY_CHAN4(zoomed.array->rgba[j], rgba[i]);
         }
      }
      else {
         /* general solution */
         const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
         for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
            i = (GLint) ((j + skipCol) * xscale);
            if (ctx->Pixel.ZoomX < 0.0) {
               ASSERT(i <= 0);
               i = span->end + i - 1;
            }
            ASSERT(i >= 0);
            ASSERT(i < (GLint)  span->end);
            COPY_CHAN4(zoomed.array->rgba[j], rgba[i]);
         }
      }
   }
   else if (format == GL_RGB) {
      const GLchan (*rgb)[3] = (const GLchan (*)[3]) src;
      if (ctx->Pixel.ZoomX == -1.0F) {
         /* common case */
         for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
            i = span->end - (j + skipCol) - 1;
            zoomed.array->rgba[j][0] = rgb[i][0];
            zoomed.array->rgba[j][1] = rgb[i][1];
            zoomed.array->rgba[j][2] = rgb[i][2];
            zoomed.array->rgba[j][3] = CHAN_MAX;
         }
      }
      else {
         /* general solution */
         const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
         for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
            i = (GLint) ((j + skipCol) * xscale);
            if (ctx->Pixel.ZoomX < 0.0) {
               ASSERT(i <= 0);
               i = span->end + i - 1;
            }
            ASSERT(i >= 0);
            ASSERT(i < (GLint) span->end);
            zoomed.array->rgba[j][0] = rgb[i][0];
            zoomed.array->rgba[j][1] = rgb[i][1];
            zoomed.array->rgba[j][2] = rgb[i][2];
            zoomed.array->rgba[j][3] = CHAN_MAX;
         }
      }
   }
   else if (format == GL_COLOR_INDEX) {
      const GLuint *indexes = (const GLuint *) src;
      if (ctx->Pixel.ZoomX == -1.0F) {
         /* common case */
         for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
            i = span->end - (j + skipCol) - 1;
            zoomed.array->index[j] = indexes[i];
         }
      }
      else {
         /* general solution */
         const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
         for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
            i = (GLint) ((j + skipCol) * xscale);
            if (ctx->Pixel.ZoomX < 0.0) {
               ASSERT(i <= 0);
               i = span->end + i - 1;
            }
            ASSERT(i >= 0);
            ASSERT(i < (GLint) span->end);
            zoomed.array->index[j] = indexes[i];
         }
      }
   }
   else {
      const GLdepth *zValues = (const GLuint *) src;
      assert(format == GL_DEPTH_COMPONENT);
      if (ctx->Pixel.ZoomX == -1.0F) {
         /* common case */
         for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
            i = span->end - (j + skipCol) - 1;
            zoomed.array->z[j] = zValues[i];
         }
      }
      else {
         /* general solution */
         const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
         for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
            i = (GLint) ((j + skipCol) * xscale);
            if (ctx->Pixel.ZoomX < 0.0) {
               ASSERT(i <= 0);
               i = span->end + i - 1;
            }
            ASSERT(i >= 0);
            ASSERT(i < (GLint) span->end);
            zoomed.array->z[j] = zValues[i];
         }
      }
      /* Now, fall into either the RGB or COLOR_INDEX path below */
      if (ctx->Visual.rgbMode)
         format = GL_RGBA;
      else
         format = GL_COLOR_INDEX;
   }


   /* write the span in rows [r0, r1) */
   if (format == GL_RGBA || format == GL_RGB) {
      /* Writing the span may modify the colors, so make a backup now if we're
       * going to call _swrast_write_zoomed_span() more than once.
       * Also, clipping may change the span end value, so store it as well.
       */
      GLchan rgbaSave[MAX_WIDTH][4];
      const GLint end = zoomed.end; /* save */
      if (r1 - r0 > 1) {
         MEMCPY(rgbaSave, zoomed.array->rgba, zoomed.end * 4 * sizeof(GLchan));
      }
      for (zoomed.y = r0; zoomed.y < r1; zoomed.y++) {
         _swrast_write_rgba_span(ctx, &zoomed);
         zoomed.end = end;  /* restore */
         if (r1 - r0 > 1) {
            /* restore the colors */
            MEMCPY(zoomed.array->rgba, rgbaSave, zoomed.end*4 * sizeof(GLchan));
         }
      }
   }
   else if (format == GL_COLOR_INDEX) {
      GLuint indexSave[MAX_WIDTH];
      const GLint end = zoomed.end; /* save */
      if (r1 - r0 > 1) {
         MEMCPY(indexSave, zoomed.array->index, zoomed.end * sizeof(GLuint));
      }
      for (zoomed.y = r0; zoomed.y < r1; zoomed.y++) {
         _swrast_write_index_span(ctx, &zoomed);
         zoomed.end = end;  /* restore */
         if (r1 - r0 > 1) {
            /* restore the colors */
            MEMCPY(zoomed.array->index, indexSave, zoomed.end * sizeof(GLuint));
         }
      }
   }
}
Exemple #26
0
/**
 * Examine a texture object to determine if it is complete.
 *
 * The gl_texture_object::Complete flag will be set to GL_TRUE or GL_FALSE
 * accordingly.
 *
 * \param ctx GL context.
 * \param t texture object.
 *
 * According to the texture target, verifies that each of the mipmaps is
 * present and has the expected size.
 */
void
_mesa_test_texobj_completeness( const GLcontext *ctx,
                                struct gl_texture_object *t )
{
   const GLint baseLevel = t->BaseLevel;
   GLint maxLog2 = 0, maxLevels = 0;

   t->Complete = GL_TRUE;  /* be optimistic */
   t->_IsPowerOfTwo = GL_TRUE;  /* may be set FALSE below */

   /* Always need the base level image */
   if (!t->Image[baseLevel]) {
      char s[100];
      sprintf(s, "obj %p (%d) Image[baseLevel=%d] == NULL",
              (void *) t, t->Name, baseLevel);
      incomplete(t, s);
      t->Complete = GL_FALSE;
      return;
   }

   /* Check width/height/depth for zero */
   if (t->Image[baseLevel]->Width == 0 ||
       t->Image[baseLevel]->Height == 0 ||
       t->Image[baseLevel]->Depth == 0) {
      incomplete(t, "texture width = 0");
      t->Complete = GL_FALSE;
      return;
   }

   /* Compute _MaxLevel */
   if (t->Target == GL_TEXTURE_1D) {
      maxLog2 = t->Image[baseLevel]->WidthLog2;
      maxLevels = ctx->Const.MaxTextureLevels;
   }
   else if (t->Target == GL_TEXTURE_2D) {
      maxLog2 = MAX2(t->Image[baseLevel]->WidthLog2,
                     t->Image[baseLevel]->HeightLog2);
      maxLevels = ctx->Const.MaxTextureLevels;
   }
   else if (t->Target == GL_TEXTURE_3D) {
      GLint max = MAX2(t->Image[baseLevel]->WidthLog2,
                       t->Image[baseLevel]->HeightLog2);
      maxLog2 = MAX2(max, (GLint)(t->Image[baseLevel]->DepthLog2));
      maxLevels = ctx->Const.Max3DTextureLevels;
   }
   else if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) {
      maxLog2 = MAX2(t->Image[baseLevel]->WidthLog2,
                     t->Image[baseLevel]->HeightLog2);
      maxLevels = ctx->Const.MaxCubeTextureLevels;
   }
   else if (t->Target == GL_TEXTURE_RECTANGLE_NV) {
      maxLog2 = 0;  /* not applicable */
      maxLevels = 1;  /* no mipmapping */
   }
   else {
      _mesa_problem(ctx, "Bad t->Target in _mesa_test_texobj_completeness");
      return;
   }

   ASSERT(maxLevels > 0);

   t->_MaxLevel = baseLevel + maxLog2;
   t->_MaxLevel = MIN2(t->_MaxLevel, t->MaxLevel);
   t->_MaxLevel = MIN2(t->_MaxLevel, maxLevels - 1);

   /* Compute _MaxLambda = q - b (see the 1.2 spec) used during mipmapping */
   t->_MaxLambda = (GLfloat) (t->_MaxLevel - t->BaseLevel);

   if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) {
      /* make sure that all six cube map level 0 images are the same size */
      const GLuint w = t->Image[baseLevel]->Width2;
      const GLuint h = t->Image[baseLevel]->Height2;
      if (!t->NegX[baseLevel] ||
          t->NegX[baseLevel]->Width2 != w ||
          t->NegX[baseLevel]->Height2 != h ||
          !t->PosY[baseLevel] ||
          t->PosY[baseLevel]->Width2 != w ||
          t->PosY[baseLevel]->Height2 != h ||
          !t->NegY[baseLevel] ||
          t->NegY[baseLevel]->Width2 != w ||
          t->NegY[baseLevel]->Height2 != h ||
          !t->PosZ[baseLevel] ||
          t->PosZ[baseLevel]->Width2 != w ||
          t->PosZ[baseLevel]->Height2 != h ||
          !t->NegZ[baseLevel] ||
          t->NegZ[baseLevel]->Width2 != w ||
          t->NegZ[baseLevel]->Height2 != h) {
         t->Complete = GL_FALSE;
         incomplete(t, "Non-quare cubemap image");
         return;
      }
   }

   /* check for non power of two */
   if (!t->Image[baseLevel]->_IsPowerOfTwo) {
      t->_IsPowerOfTwo = GL_FALSE;
   }

   /* extra checking for mipmaps */
   if (t->MinFilter != GL_NEAREST && t->MinFilter != GL_LINEAR) {
      /*
       * Mipmapping: determine if we have a complete set of mipmaps
       */
      GLint i;
      GLint minLevel = baseLevel;
      GLint maxLevel = t->_MaxLevel;

      if (minLevel > maxLevel) {
         t->Complete = GL_FALSE;
         incomplete(t, "minLevel > maxLevel");
         return;
      }

      /* Test dimension-independent attributes */
      for (i = minLevel; i <= maxLevel; i++) {
         if (t->Image[i]) {
            if (t->Image[i]->TexFormat != t->Image[baseLevel]->TexFormat) {
               t->Complete = GL_FALSE;
               incomplete(t, "Format[i] != Format[baseLevel]");
               return;
            }
            if (t->Image[i]->Border != t->Image[baseLevel]->Border) {
               t->Complete = GL_FALSE;
               incomplete(t, "Border[i] != Border[baseLevel]");
               return;
            }
         }
      }

      /* Test things which depend on number of texture image dimensions */
      if (t->Target == GL_TEXTURE_1D) {
         /* Test 1-D mipmaps */
         GLuint width = t->Image[baseLevel]->Width2;
         for (i = baseLevel + 1; i < maxLevels; i++) {
            if (width > 1) {
               width /= 2;
            }
            if (i >= minLevel && i <= maxLevel) {
               if (!t->Image[i]) {
                  t->Complete = GL_FALSE;
                  incomplete(t, "1D Image[i] == NULL");
                  return;
               }
               if (t->Image[i]->Width2 != width ) {
                  t->Complete = GL_FALSE;
                  incomplete(t, "1D Image[i] bad width");
                  return;
               }
            }
            if (width == 1) {
               return;  /* found smallest needed mipmap, all done! */
            }
         }
      }
      else if (t->Target == GL_TEXTURE_2D) {
         /* Test 2-D mipmaps */
         GLuint width = t->Image[baseLevel]->Width2;
         GLuint height = t->Image[baseLevel]->Height2;
         for (i = baseLevel + 1; i < maxLevels; i++) {
            if (width > 1) {
               width /= 2;
            }
            if (height > 1) {
               height /= 2;
            }
            if (i >= minLevel && i <= maxLevel) {
               if (!t->Image[i]) {
                  t->Complete = GL_FALSE;
                  incomplete(t, "2D Image[i] == NULL");
                  return;
               }
               if (t->Image[i]->Width2 != width) {
                  t->Complete = GL_FALSE;
                  incomplete(t, "2D Image[i] bad width");
                  return;
               }
               if (t->Image[i]->Height2 != height) {
                  t->Complete = GL_FALSE;
                  incomplete(t, "2D Image[i] bad height");
                  return;
               }
               if (width==1 && height==1) {
                  return;  /* found smallest needed mipmap, all done! */
               }
            }
         }
      }
      else if (t->Target == GL_TEXTURE_3D) {
         /* Test 3-D mipmaps */
         GLuint width = t->Image[baseLevel]->Width2;
         GLuint height = t->Image[baseLevel]->Height2;
         GLuint depth = t->Image[baseLevel]->Depth2;
	 for (i = baseLevel + 1; i < maxLevels; i++) {
            if (width > 1) {
               width /= 2;
            }
            if (height > 1) {
               height /= 2;
            }
            if (depth > 1) {
               depth /= 2;
            }
            if (i >= minLevel && i <= maxLevel) {
               if (!t->Image[i]) {
                  incomplete(t, "3D Image[i] == NULL");
                  t->Complete = GL_FALSE;
                  return;
               }
               if (t->Image[i]->Format == GL_DEPTH_COMPONENT) {
                  t->Complete = GL_FALSE;
                  incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
                  return;
               }
               if (t->Image[i]->Width2 != width) {
                  t->Complete = GL_FALSE;
                  incomplete(t, "3D Image[i] bad width");
                  return;
               }
               if (t->Image[i]->Height2 != height) {
                  t->Complete = GL_FALSE;
                  incomplete(t, "3D Image[i] bad height");
                  return;
               }
               if (t->Image[i]->Depth2 != depth) {
                  t->Complete = GL_FALSE;
                  incomplete(t, "3D Image[i] bad depth");
                  return;
               }
            }
            if (width == 1 && height == 1 && depth == 1) {
               return;  /* found smallest needed mipmap, all done! */
            }
         }
      }
      else if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) {
         /* make sure 6 cube faces are consistant */
         GLuint width = t->Image[baseLevel]->Width2;
         GLuint height = t->Image[baseLevel]->Height2;
	 for (i = baseLevel + 1; i < maxLevels; i++) {
            if (width > 1) {
               width /= 2;
            }
            if (height > 1) {
               height /= 2;
            }
            if (i >= minLevel && i <= maxLevel) {
               /* check that we have images defined */
               if (!t->Image[i] || !t->NegX[i] ||
                   !t->PosY[i]  || !t->NegY[i] ||
                   !t->PosZ[i]  || !t->NegZ[i]) {
                  t->Complete = GL_FALSE;
                  incomplete(t, "CubeMap Image[i] == NULL");
                  return;
               }
               /* Don't support GL_DEPTH_COMPONENT for cube maps */
               if (t->Image[i]->Format == GL_DEPTH_COMPONENT) {
                  t->Complete = GL_FALSE;
                  incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
                  return;
               }
               /* check that all six images have same size */
               if (t->NegX[i]->Width2!=width || t->NegX[i]->Height2!=height ||
                   t->PosY[i]->Width2!=width || t->PosY[i]->Height2!=height ||
                   t->NegY[i]->Width2!=width || t->NegY[i]->Height2!=height ||
                   t->PosZ[i]->Width2!=width || t->PosZ[i]->Height2!=height ||
                   t->NegZ[i]->Width2!=width || t->NegZ[i]->Height2!=height) {
                  t->Complete = GL_FALSE;
                  incomplete(t, "CubeMap Image[i] bad size");
                  return;
               }
            }
            if (width == 1 && height == 1) {
               return;  /* found smallest needed mipmap, all done! */
            }
         }
      }
      else if (t->Target == GL_TEXTURE_RECTANGLE_NV) {
         /* XXX special checking? */
      }
      else {
         /* Target = ??? */
         _mesa_problem(ctx, "Bug in gl_test_texture_object_completeness\n");
      }
   }
}
Exemple #27
0
static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args )
{
	VectorObject *line_a1, *line_a2, *line_b1, *line_b2;
	float a1x, a1y, a2x, a2y,  b1x, b1y, b2x, b2y, xi, yi, a1,a2,b1,b2, newvec[2];
	if( !PyArg_ParseTuple ( args, "O!O!O!O!",
	  &vector_Type, &line_a1,
	  &vector_Type, &line_a2,
	  &vector_Type, &line_b1,
	  &vector_Type, &line_b2)
	) {
		PyErr_SetString( PyExc_TypeError, "expected 4 vector types\n" );
		return NULL;
	}
	
	if(!BaseMath_ReadCallback(line_a1) || !BaseMath_ReadCallback(line_a2) || !BaseMath_ReadCallback(line_b1) || !BaseMath_ReadCallback(line_b2))
		return NULL;
	
	a1x= line_a1->vec[0];
	a1y= line_a1->vec[1];
	a2x= line_a2->vec[0];
	a2y= line_a2->vec[1];

	b1x= line_b1->vec[0];
	b1y= line_b1->vec[1];
	b2x= line_b2->vec[0];
	b2y= line_b2->vec[1];
	
	if((MIN2(a1x, a2x) > MAX2(b1x, b2x)) ||
	   (MAX2(a1x, a2x) < MIN2(b1x, b2x)) ||
	   (MIN2(a1y, a2y) > MAX2(b1y, b2y)) ||
	   (MAX2(a1y, a2y) < MIN2(b1y, b2y))  ) {
		Py_RETURN_NONE;
	}
	/* Make sure the hoz/vert line comes first. */
	if (fabs(b1x - b2x) < eul || fabs(b1y - b2y) < eul) {
		SWAP_FLOAT(a1x, b1x, xi); /*abuse xi*/
		SWAP_FLOAT(a1y, b1y, xi);
		SWAP_FLOAT(a2x, b2x, xi);
		SWAP_FLOAT(a2y, b2y, xi);
	}
	
	if (fabs(a1x-a2x) < eul) { /* verticle line */
		if (fabs(b1x-b2x) < eul){ /*verticle second line */
			Py_RETURN_NONE; /* 2 verticle lines dont intersect. */
		}
		else if (fabs(b1y-b2y) < eul) {
			/*X of vert, Y of hoz. no calculation needed */
			newvec[0]= a1x;
			newvec[1]= b1y;
			return newVectorObject(newvec, 2, Py_NEW, NULL);
		}
		
		yi = (float)(((b1y / fabs(b1x - b2x)) * fabs(b2x - a1x)) + ((b2y / fabs(b1x - b2x)) * fabs(b1x - a1x)));
		
		if (yi > MAX2(a1y, a2y)) {/* New point above seg1's vert line */
			Py_RETURN_NONE;
		} else if (yi < MIN2(a1y, a2y)) { /* New point below seg1's vert line */
			Py_RETURN_NONE;
		}
		newvec[0]= a1x;
		newvec[1]= yi;
		return newVectorObject(newvec, 2, Py_NEW, NULL);
	} else if (fabs(a2y-a1y) < eul) {  /* hoz line1 */
		if (fabs(b2y-b1y) < eul) { /*hoz line2*/
			Py_RETURN_NONE; /*2 hoz lines dont intersect*/
		}
		
		/* Can skip vert line check for seg 2 since its covered above. */
		xi = (float)(((b1x / fabs(b1y - b2y)) * fabs(b2y - a1y)) + ((b2x / fabs(b1y - b2y)) * fabs(b1y - a1y)));
		if (xi > MAX2(a1x, a2x)) { /* New point right of hoz line1's */
			Py_RETURN_NONE;
		} else if (xi < MIN2(a1x, a2x)) { /*New point left of seg1's hoz line */
			Py_RETURN_NONE;
		}
		newvec[0]= xi;
		newvec[1]= a1y;
		return newVectorObject(newvec, 2, Py_NEW, NULL);
	}
	
	b1 = (a2y-a1y)/(a2x-a1x);
	b2 = (b2y-b1y)/(b2x-b1x);
	a1 = a1y-b1*a1x;
	a2 = b1y-b2*b1x;
	
	if (b1 - b2 == 0.0) {
		Py_RETURN_NONE;
	}
	
	xi = - (a1-a2)/(b1-b2);
	yi = a1+b1*xi;
	if ((a1x-xi)*(xi-a2x) >= 0 && (b1x-xi)*(xi-b2x) >= 0 && (a1y-yi)*(yi-a2y) >= 0 && (b1y-yi)*(yi-b2y)>=0) {
		newvec[0]= xi;
		newvec[1]= yi;
		return newVectorObject(newvec, 2, Py_NEW, NULL);
	}
	Py_RETURN_NONE;
}
Exemple #28
0
static void si_blit_decompress_depth(struct pipe_context *ctx,
				     struct r600_texture *texture,
				     struct r600_texture *staging,
				     unsigned first_level, unsigned last_level,
				     unsigned first_layer, unsigned last_layer,
				     unsigned first_sample, unsigned last_sample)
{
	struct si_context *sctx = (struct si_context *)ctx;
	unsigned layer, level, sample, checked_last_layer, max_layer;
	float depth = 1.0f;
	const struct util_format_description *desc;

	assert(staging != NULL && "use si_blit_decompress_zs_in_place instead");

	desc = util_format_description(staging->resource.b.b.format);

	if (util_format_has_depth(desc))
		sctx->dbcb_depth_copy_enabled = true;
	if (util_format_has_stencil(desc))
		sctx->dbcb_stencil_copy_enabled = true;

	assert(sctx->dbcb_depth_copy_enabled || sctx->dbcb_stencil_copy_enabled);

	for (level = first_level; level <= last_level; level++) {
		/* The smaller the mipmap level, the less layers there are
		 * as far as 3D textures are concerned. */
		max_layer = util_max_layer(&texture->resource.b.b, level);
		checked_last_layer = MIN2(last_layer, max_layer);

		for (layer = first_layer; layer <= checked_last_layer; layer++) {
			for (sample = first_sample; sample <= last_sample; sample++) {
				struct pipe_surface *zsurf, *cbsurf, surf_tmpl;

				sctx->dbcb_copy_sample = sample;
				si_mark_atom_dirty(sctx, &sctx->db_render_state);

				surf_tmpl.format = texture->resource.b.b.format;
				surf_tmpl.u.tex.level = level;
				surf_tmpl.u.tex.first_layer = layer;
				surf_tmpl.u.tex.last_layer = layer;

				zsurf = ctx->create_surface(ctx, &texture->resource.b.b, &surf_tmpl);

				surf_tmpl.format = staging->resource.b.b.format;
				cbsurf = ctx->create_surface(ctx,
						(struct pipe_resource*)staging, &surf_tmpl);

				si_blitter_begin(ctx, SI_DECOMPRESS);
				util_blitter_custom_depth_stencil(sctx->blitter, zsurf, cbsurf, 1 << sample,
								  sctx->custom_dsa_flush, depth);
				si_blitter_end(ctx);

				pipe_surface_reference(&zsurf, NULL);
				pipe_surface_reference(&cbsurf, NULL);
			}
		}
	}

	sctx->dbcb_depth_copy_enabled = false;
	sctx->dbcb_stencil_copy_enabled = false;
	si_mark_atom_dirty(sctx, &sctx->db_render_state);
}
Exemple #29
0
/**
 * Copy pixel block from src surface to dst surface.
 * Overlapping regions are acceptable.
 * Flipping and stretching are supported.
 * \param filter  one of PIPE_TEX_MIPFILTER_NEAREST/LINEAR
 * \param writemask  controls which channels in the dest surface are sourced
 *                   from the src surface.  Disabled channels are sourced
 *                   from (0,0,0,1).
 */
void
util_blit_pixels(struct blit_state *ctx,
                 struct pipe_resource *src_tex,
                 unsigned src_level,
                 int srcX0, int srcY0,
                 int srcX1, int srcY1,
                 int srcZ0,
                 struct pipe_surface *dst,
                 int dstX0, int dstY0,
                 int dstX1, int dstY1,
                 float z, uint filter,
                 uint writemask, uint zs_writemask)
{
   struct pipe_context *pipe = ctx->pipe;
   struct pipe_screen *screen = pipe->screen;
   enum pipe_format src_format, dst_format;
   struct pipe_sampler_view *sampler_view = NULL;
   struct pipe_sampler_view sv_templ;
   struct pipe_surface *dst_surface;
   struct pipe_framebuffer_state fb;
   const int srcW = abs(srcX1 - srcX0);
   const int srcH = abs(srcY1 - srcY0);
   unsigned offset;
   boolean overlap;
   float s0, t0, s1, t1;
   boolean normalized;
   boolean is_stencil, is_depth, blit_depth, blit_stencil;
   const struct util_format_description *src_desc =
         util_format_description(src_tex->format);

   assert(filter == PIPE_TEX_MIPFILTER_NEAREST ||
          filter == PIPE_TEX_MIPFILTER_LINEAR);

   assert(src_level <= src_tex->last_level);

   /* do the regions overlap? */
   overlap = src_tex == dst->texture &&
             dst->u.tex.level == src_level &&
             dst->u.tex.first_layer == srcZ0 &&
      regions_overlap(srcX0, srcY0, srcX1, srcY1,
                      dstX0, dstY0, dstX1, dstY1);

   src_format = util_format_linear(src_tex->format);
   dst_format = util_format_linear(dst->texture->format);

   /* See whether we will blit depth or stencil. */
   is_depth = util_format_has_depth(src_desc);
   is_stencil = util_format_has_stencil(src_desc);

   blit_depth = is_depth && (zs_writemask & BLIT_WRITEMASK_Z);
   blit_stencil = is_stencil && (zs_writemask & BLIT_WRITEMASK_STENCIL);

   assert((writemask && !zs_writemask && !is_depth && !is_stencil) ||
          (!writemask && (blit_depth || blit_stencil)));

   /*
    * Check for simple case:  no format conversion, no flipping, no stretching,
    * no overlapping, same number of samples.
    * Filter mode should not matter since there's no stretching.
    */
   if (formats_compatible(src_format, dst_format) &&
       src_tex->nr_samples == dst->texture->nr_samples &&
       is_stencil == blit_stencil &&
       is_depth == blit_depth &&
       srcX0 < srcX1 &&
       dstX0 < dstX1 &&
       srcY0 < srcY1 &&
       dstY0 < dstY1 &&
       (dstX1 - dstX0) == (srcX1 - srcX0) &&
       (dstY1 - dstY0) == (srcY1 - srcY0) &&
       !overlap) {
      struct pipe_box src_box;
      src_box.x = srcX0;
      src_box.y = srcY0;
      src_box.z = srcZ0;
      src_box.width = srcW;
      src_box.height = srcH;
      src_box.depth = 1;
      pipe->resource_copy_region(pipe,
                                 dst->texture, dst->u.tex.level,
                                 dstX0, dstY0, dst->u.tex.first_layer,/* dest */
                                 src_tex, src_level,
                                 &src_box);
      return;
   }

   /* XXX Reading multisample textures is unimplemented. */
   assert(src_tex->nr_samples <= 1);
   if (src_tex->nr_samples > 1) {
      return;
   }

   /* It's a mistake to call this function with a stencil format and
    * without shader stencil export. We don't do software fallbacks here.
    * Ignore stencil and only copy depth.
    */
   if (blit_stencil && !ctx->has_stencil_export) {
      blit_stencil = FALSE;

      if (!blit_depth)
         return;
   }

   if (dst_format == dst->format) {
      dst_surface = dst;
   } else {
      struct pipe_surface templ = *dst;
      templ.format = dst_format;
      dst_surface = pipe->create_surface(pipe, dst->texture, &templ);
   }

   /* Create a temporary texture when src and dest alias.
    */
   if (src_tex == dst_surface->texture &&
       dst_surface->u.tex.level == src_level &&
       dst_surface->u.tex.first_layer == srcZ0) {
      /* Make a temporary texture which contains a copy of the source pixels.
       * Then we'll sample from the temporary texture.
       */
      struct pipe_resource texTemp;
      struct pipe_resource *tex;
      struct pipe_sampler_view sv_templ;
      struct pipe_box src_box;
      const int srcLeft = MIN2(srcX0, srcX1);
      const int srcTop = MIN2(srcY0, srcY1);

      if (srcLeft != srcX0) {
         /* left-right flip */
         int tmp = dstX0;
         dstX0 = dstX1;
         dstX1 = tmp;
      }

      if (srcTop != srcY0) {
         /* up-down flip */
         int tmp = dstY0;
         dstY0 = dstY1;
         dstY1 = tmp;
      }

      /* create temp texture */
      memset(&texTemp, 0, sizeof(texTemp));
      texTemp.target = ctx->internal_target;
      texTemp.format = src_format;
      texTemp.last_level = 0;
      texTemp.width0 = srcW;
      texTemp.height0 = srcH;
      texTemp.depth0 = 1;
      texTemp.array_size = 1;
      texTemp.bind = PIPE_BIND_SAMPLER_VIEW;

      tex = screen->resource_create(screen, &texTemp);
      if (!tex)
         return;

      src_box.x = srcLeft;
      src_box.y = srcTop;
      src_box.z = srcZ0;
      src_box.width = srcW;
      src_box.height = srcH;
      src_box.depth = 1;
      /* load temp texture */
      pipe->resource_copy_region(pipe,
                                 tex, 0, 0, 0, 0,  /* dest */
                                 src_tex, src_level, &src_box);

      normalized = tex->target != PIPE_TEXTURE_RECT;
      if(normalized) {
         s0 = 0.0f;
         s1 = 1.0f;
         t0 = 0.0f;
         t1 = 1.0f;
      }
      else {
         s0 = 0;
         s1 = srcW;
         t0 = 0;
         t1 = srcH;
      }

      u_sampler_view_default_template(&sv_templ, tex, tex->format);
      if (!blit_depth && blit_stencil) {
         /* set a stencil-only format, e.g. Z24S8 --> X24S8 */
         sv_templ.format = util_format_stencil_only(tex->format);
         assert(sv_templ.format != PIPE_FORMAT_NONE);
      }
      sampler_view = pipe->create_sampler_view(pipe, tex, &sv_templ);

      if (!sampler_view) {
         pipe_resource_reference(&tex, NULL);
         return;
      }
      pipe_resource_reference(&tex, NULL);
   }
   else {
      /* Directly sample from the source resource/texture */
      u_sampler_view_default_template(&sv_templ, src_tex, src_format);
      if (!blit_depth && blit_stencil) {
         /* set a stencil-only format, e.g. Z24S8 --> X24S8 */
         sv_templ.format = util_format_stencil_only(src_format);
         assert(sv_templ.format != PIPE_FORMAT_NONE);
      }
      sampler_view = pipe->create_sampler_view(pipe, src_tex, &sv_templ);

      if (!sampler_view) {
         return;
      }

      s0 = srcX0;
      s1 = srcX1;
      t0 = srcY0;
      t1 = srcY1;
      normalized = sampler_view->texture->target != PIPE_TEXTURE_RECT;
      if(normalized)
      {
         s0 /= (float)(u_minify(sampler_view->texture->width0, src_level));
         s1 /= (float)(u_minify(sampler_view->texture->width0, src_level));
         t0 /= (float)(u_minify(sampler_view->texture->height0, src_level));
         t1 /= (float)(u_minify(sampler_view->texture->height0, src_level));
      }
   }

   assert(screen->is_format_supported(screen, sampler_view->format,
                     ctx->internal_target, sampler_view->texture->nr_samples,
                     PIPE_BIND_SAMPLER_VIEW));
   assert(screen->is_format_supported(screen, dst_format, ctx->internal_target,
                     dst_surface->texture->nr_samples,
                     is_depth || is_stencil ? PIPE_BIND_DEPTH_STENCIL :
                                              PIPE_BIND_RENDER_TARGET));

   /* save state (restored below) */
   cso_save_blend(ctx->cso);
   cso_save_depth_stencil_alpha(ctx->cso);
   cso_save_rasterizer(ctx->cso);
   cso_save_sample_mask(ctx->cso);
   cso_save_samplers(ctx->cso, PIPE_SHADER_FRAGMENT);
   cso_save_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT);
   cso_save_stream_outputs(ctx->cso);
   cso_save_viewport(ctx->cso);
   cso_save_framebuffer(ctx->cso);
   cso_save_fragment_shader(ctx->cso);
   cso_save_vertex_shader(ctx->cso);
   cso_save_geometry_shader(ctx->cso);
   cso_save_vertex_elements(ctx->cso);
   cso_save_aux_vertex_buffer_slot(ctx->cso);
   cso_save_render_condition(ctx->cso);

   /* set misc state we care about */
   if (writemask)
      cso_set_blend(ctx->cso, &ctx->blend_write_color);
   else
      cso_set_blend(ctx->cso, &ctx->blend_keep_color);

   cso_set_sample_mask(ctx->cso, ~0);
   cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
   cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
   cso_set_stream_outputs(ctx->cso, 0, NULL, 0);
   cso_set_render_condition(ctx->cso, NULL, 0);

   /* default sampler state */
   ctx->sampler.normalized_coords = normalized;
   ctx->sampler.min_img_filter = filter;
   ctx->sampler.mag_img_filter = filter;
   ctx->sampler.min_lod = src_level;
   ctx->sampler.max_lod = src_level;

   /* Depth stencil state, fragment shader and sampler setup depending on what
    * we blit.
    */
   if (blit_depth && blit_stencil) {
      cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler);
      /* don't filter stencil */
      ctx->sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
      ctx->sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
      cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 1, &ctx->sampler);

      cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_write_depthstencil);
      set_depthstencil_fragment_shader(ctx, sampler_view->texture->target);
   }
   else if (blit_depth) {
      cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler);
      cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_write_depth);
      set_depth_fragment_shader(ctx, sampler_view->texture->target);
   }
   else if (blit_stencil) {
      /* don't filter stencil */
      ctx->sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
      ctx->sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
      cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler);

      cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_write_stencil);
      set_stencil_fragment_shader(ctx, sampler_view->texture->target);
   }
   else { /* color */
      cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler);
      cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_keep_depthstencil);
      set_fragment_shader(ctx, writemask, sampler_view->texture->target);
   }
   cso_single_sampler_done(ctx->cso, PIPE_SHADER_FRAGMENT);

   /* textures */
   if (blit_depth && blit_stencil) {
      /* Setup two samplers, one for depth and the other one for stencil. */
      struct pipe_sampler_view templ;
      struct pipe_sampler_view *views[2];

      templ = *sampler_view;
      templ.format = util_format_stencil_only(templ.format);
      assert(templ.format != PIPE_FORMAT_NONE);

      views[0] = sampler_view;
      views[1] = pipe->create_sampler_view(pipe, views[0]->texture, &templ);
      cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, 2, views);

      pipe_sampler_view_reference(&views[1], NULL);
   }
   else {
      cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, 1, &sampler_view);
   }

   /* viewport */
   ctx->viewport.scale[0] = 0.5f * dst_surface->width;
   ctx->viewport.scale[1] = 0.5f * dst_surface->height;
   ctx->viewport.scale[2] = 0.5f;
   ctx->viewport.scale[3] = 1.0f;
   ctx->viewport.translate[0] = 0.5f * dst_surface->width;
   ctx->viewport.translate[1] = 0.5f * dst_surface->height;
   ctx->viewport.translate[2] = 0.5f;
   ctx->viewport.translate[3] = 0.0f;
   cso_set_viewport(ctx->cso, &ctx->viewport);

   set_vertex_shader(ctx);
   cso_set_geometry_shader_handle(ctx->cso, NULL);

   /* drawing dest */
   memset(&fb, 0, sizeof(fb));
   fb.width = dst_surface->width;
   fb.height = dst_surface->height;
   if (blit_depth || blit_stencil) {
      fb.zsbuf = dst_surface;
   } else {
      fb.nr_cbufs = 1;
      fb.cbufs[0] = dst_surface;
   }
   cso_set_framebuffer(ctx->cso, &fb);

   /* draw quad */
   offset = setup_vertex_data_tex(ctx,
                                  (float) dstX0 / dst_surface->width * 2.0f - 1.0f,
                                  (float) dstY0 / dst_surface->height * 2.0f - 1.0f,
                                  (float) dstX1 / dst_surface->width * 2.0f - 1.0f,
                                  (float) dstY1 / dst_surface->height * 2.0f - 1.0f,
                                  s0, t0,
                                  s1, t1,
                                  z);

   if (ctx->vbuf) {
      util_draw_vertex_buffer(ctx->pipe, ctx->cso, ctx->vbuf,
                              cso_get_aux_vertex_buffer_slot(ctx->cso),
                              offset,
                              PIPE_PRIM_TRIANGLE_FAN,
                              4,  /* verts */
                              2); /* attribs/vert */
   }

   /* restore state we changed */
   cso_restore_blend(ctx->cso);
   cso_restore_depth_stencil_alpha(ctx->cso);
   cso_restore_rasterizer(ctx->cso);
   cso_restore_sample_mask(ctx->cso);
   cso_restore_samplers(ctx->cso, PIPE_SHADER_FRAGMENT);
   cso_restore_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT);
   cso_restore_viewport(ctx->cso);
   cso_restore_framebuffer(ctx->cso);
   cso_restore_fragment_shader(ctx->cso);
   cso_restore_vertex_shader(ctx->cso);
   cso_restore_geometry_shader(ctx->cso);
   cso_restore_vertex_elements(ctx->cso);
   cso_restore_aux_vertex_buffer_slot(ctx->cso);
   cso_restore_stream_outputs(ctx->cso);
   cso_restore_render_condition(ctx->cso);

   pipe_sampler_view_reference(&sampler_view, NULL);
   if (dst_surface != dst)
      pipe_surface_reference(&dst_surface, NULL);
}
Exemple #30
0
// Similar to PSYoungGen::resize_generation() but
//  allows sum of eden_size and 2 * survivor_size to exceed _max_gen_size
//  expands at the low end of the virtual space
//  moves the boundary between the generations in order to expand
//  some additional diagnostics
// If no additional changes are required, this can be deleted
// and the changes factored back into PSYoungGen::resize_generation().
bool ASPSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) {
  const size_t alignment = virtual_space()->alignment();
  size_t orig_size = virtual_space()->committed_size();
  bool size_changed = false;

  // There used to be a guarantee here that
  //   (eden_size + 2*survivor_size)  <= _max_gen_size
  // This requirement is enforced by the calculation of desired_size
  // below.  It may not be true on entry since the size of the
  // eden_size is no bounded by the generation size.

  assert(max_size() == reserved().byte_size(), "max gen size problem?");
  assert(min_gen_size() <= orig_size && orig_size <= max_size(),
         "just checking");

  // Adjust new generation size
  const size_t eden_plus_survivors =
    align_size_up(eden_size + 2 * survivor_size, alignment);
  size_t desired_size = MAX2(MIN2(eden_plus_survivors, gen_size_limit()),
                             min_gen_size());
  assert(desired_size <= gen_size_limit(), "just checking");

  if (desired_size > orig_size) {
    // Grow the generation
    size_t change = desired_size - orig_size;
    HeapWord* prev_low = (HeapWord*) virtual_space()->low();
    if (!virtual_space()->expand_by(change)) {
      return false;
    }
    if (ZapUnusedHeapArea) {
      // Mangle newly committed space immediately because it
      // can be done here more simply that after the new
      // spaces have been computed.
      HeapWord* new_low = (HeapWord*) virtual_space()->low();
      assert(new_low < prev_low, "Did not grow");

      MemRegion mangle_region(new_low, prev_low);
      SpaceMangler::mangle_region(mangle_region);
    }
    size_changed = true;
  } else if (desired_size < orig_size) {
    size_t desired_change = orig_size - desired_size;

    // How much is available for shrinking.
    size_t available_bytes = limit_gen_shrink(desired_change);
    size_t change = MIN2(desired_change, available_bytes);
    virtual_space()->shrink_by(change);
    size_changed = true;
  } else {
    if (Verbose && PrintGC) {
      if (orig_size == gen_size_limit()) {
        gclog_or_tty->print_cr("ASPSYoung generation size at maximum: "
          SIZE_FORMAT "K", orig_size/K);
      } else if (orig_size == min_gen_size()) {
        gclog_or_tty->print_cr("ASPSYoung generation size at minium: "
          SIZE_FORMAT "K", orig_size/K);
      }
    }
  }

  if (size_changed) {
    reset_after_change();
    if (Verbose && PrintGC) {
      size_t current_size  = virtual_space()->committed_size();
      gclog_or_tty->print_cr("ASPSYoung generation size changed: "
        SIZE_FORMAT "K->" SIZE_FORMAT "K",
        orig_size/K, current_size/K);
    }
  }

  guarantee(eden_plus_survivors <= virtual_space()->committed_size() ||
            virtual_space()->committed_size() == max_size(), "Sanity");

  return true;
}