Beispiel #1
0
/**
 * Copy image data from application memory in a specific indexed format to
 * a VdpOutputSurface.
 */
VdpStatus
vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface,
                                 VdpIndexedFormat source_indexed_format,
                                 void const *const *source_data,
                                 uint32_t const *source_pitch,
                                 VdpRect const *destination_rect,
                                 VdpColorTableFormat color_table_format,
                                 void const *color_table)
{
   vlVdpOutputSurface *vlsurface;
   struct pipe_context *context;
   struct vl_compositor *compositor;

   enum pipe_format index_format;
   enum pipe_format colortbl_format;

   struct pipe_resource *res, res_tmpl;
   struct pipe_sampler_view sv_tmpl;
   struct pipe_sampler_view *sv_idx = NULL, *sv_tbl = NULL;

   struct pipe_box box;
   struct pipe_video_rect dst_rect;

   VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Uploading indexed output surface\n");

   vlsurface = vlGetDataHTAB(surface);
   if (!vlsurface)
      return VDP_STATUS_INVALID_HANDLE;

   context = vlsurface->device->context->pipe;
   compositor = &vlsurface->device->compositor;

   index_format = FormatIndexedToPipe(source_indexed_format);
   if (index_format == PIPE_FORMAT_NONE)
       return VDP_STATUS_INVALID_INDEXED_FORMAT;

   if (!source_data || !source_pitch)
       return VDP_STATUS_INVALID_POINTER;

   colortbl_format = FormatColorTableToPipe(color_table_format);
   if (colortbl_format == PIPE_FORMAT_NONE)
       return VDP_STATUS_INVALID_COLOR_TABLE_FORMAT;

   if (!color_table)
       return VDP_STATUS_INVALID_POINTER;

   memset(&res_tmpl, 0, sizeof(res_tmpl));
   res_tmpl.target = PIPE_TEXTURE_2D;
   res_tmpl.format = index_format;

   if (destination_rect) {
      res_tmpl.width0 = abs(destination_rect->x0-destination_rect->x1);
      res_tmpl.height0 = abs(destination_rect->y0-destination_rect->y1);
   } else {
      res_tmpl.width0 = vlsurface->surface->texture->width0;
      res_tmpl.height0 = vlsurface->surface->texture->height0;
   }
   res_tmpl.depth0 = 1;
   res_tmpl.array_size = 1;
   res_tmpl.usage = PIPE_USAGE_STAGING;
   res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW;

   res = context->screen->resource_create(context->screen, &res_tmpl);
   if (!res)
      goto error_resource;

   box.x = box.y = box.z = 0;
   box.width = res->width0;
   box.height = res->height0;
   box.depth = res->depth0;

   context->transfer_inline_write(context, res, 0, PIPE_TRANSFER_WRITE, &box,
                                  source_data[0], source_pitch[0],
                                  source_pitch[0] * res->height0);

   memset(&sv_tmpl, 0, sizeof(sv_tmpl));
   u_sampler_view_default_template(&sv_tmpl, res, res->format);

   sv_idx = context->create_sampler_view(context, res, &sv_tmpl);
   pipe_resource_reference(&res, NULL);

   if (!sv_idx)
      goto error_resource;

   memset(&res_tmpl, 0, sizeof(res_tmpl));
   res_tmpl.target = PIPE_TEXTURE_1D;
   res_tmpl.format = colortbl_format;
   res_tmpl.width0 = 1 << util_format_get_component_bits(
      index_format, UTIL_FORMAT_COLORSPACE_RGB, 0);
   res_tmpl.height0 = 1;
   res_tmpl.depth0 = 1;
   res_tmpl.array_size = 1;
   res_tmpl.usage = PIPE_USAGE_STAGING;
   res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW;

   res = context->screen->resource_create(context->screen, &res_tmpl);
   if (!res)
      goto error_resource;

   box.x = box.y = box.z = 0;
   box.width = res->width0;
   box.height = res->height0;
   box.depth = res->depth0;

   context->transfer_inline_write(context, res, 0, PIPE_TRANSFER_WRITE, &box, color_table,
                                  util_format_get_stride(colortbl_format, res->width0), 0);

   memset(&sv_tmpl, 0, sizeof(sv_tmpl));
   u_sampler_view_default_template(&sv_tmpl, res, res->format);

   sv_tbl = context->create_sampler_view(context, res, &sv_tmpl);
   pipe_resource_reference(&res, NULL);

   if (!sv_tbl)
      goto error_resource;

   vl_compositor_clear_layers(compositor);
   vl_compositor_set_palette_layer(compositor, 0, sv_idx, sv_tbl, NULL, NULL, false);
   vl_compositor_render(compositor, vlsurface->surface,
                        RectToPipe(destination_rect, &dst_rect), NULL, NULL);

   pipe_sampler_view_reference(&sv_idx, NULL);
   pipe_sampler_view_reference(&sv_tbl, NULL);

   return VDP_STATUS_OK;

error_resource:
   pipe_sampler_view_reference(&sv_idx, NULL);
   pipe_sampler_view_reference(&sv_tbl, NULL);
   return VDP_STATUS_RESOURCES;
}
Beispiel #2
0
void util_blitter_copy_texture(struct blitter_context *blitter,
                               struct pipe_resource *dst,
                               unsigned dstlevel,
                               unsigned dstx, unsigned dsty, unsigned dstz,
                               struct pipe_resource *src,
                               unsigned srclevel,
                               const struct pipe_box *srcbox,
                               boolean ignore_stencil)
{
   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
   struct pipe_context *pipe = ctx->base.pipe;
   struct pipe_screen *screen = pipe->screen;
   struct pipe_surface *dst_view, dst_templ;
   struct pipe_sampler_view src_templ, *src_view;
   unsigned bind;
   boolean is_stencil, is_depth;

   /* Give up if textures are not set. */
   assert(dst && src);
   if (!dst || !src)
      return;

   assert(src->target < PIPE_MAX_TEXTURE_TYPES);

   /* Is this a ZS format? */
   is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0;
   is_stencil = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 1) != 0;

   if (is_depth || is_stencil)
      bind = PIPE_BIND_DEPTH_STENCIL;
   else
      bind = PIPE_BIND_RENDER_TARGET;

   /* Check if we can sample from and render to the surfaces. */
   /* (assuming copying a stencil buffer is not possible) */
   if ((!ignore_stencil && is_stencil) ||
       !screen->is_format_supported(screen, dst->format, dst->target,
                                    dst->nr_samples, bind) ||
       !screen->is_format_supported(screen, src->format, src->target,
                                    src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) {
      blitter_set_running_flag(ctx);
      util_resource_copy_region(pipe, dst, dstlevel, dstx, dsty, dstz,
                                src, srclevel, srcbox);
      blitter_unset_running_flag(ctx);
      return;
   }

   /* Initialize the surface. */
   util_blitter_default_dst_texture(&dst_templ, dst, dstlevel, dstz, srcbox);
   dst_view = pipe->create_surface(pipe, dst, &dst_templ);

   /* Initialize the sampler view. */
   util_blitter_default_src_texture(&src_templ, src, srclevel);
   src_view = pipe->create_sampler_view(pipe, src, &src_templ);

   /* Copy. */
   util_blitter_copy_texture_view(blitter, dst_view, dstx, dsty, src_view,
                                  srcbox, src->width0, src->height0);

   pipe_surface_reference(&dst_view, NULL);
   pipe_sampler_view_reference(&src_view, NULL);
}
Beispiel #3
0
static boolean
st_context_teximage(struct st_context_iface *stctxi,
                    enum st_texture_type target,
                    int level, enum pipe_format internal_format,
                    struct pipe_resource *tex, boolean mipmap)
{
   struct st_context *st = (struct st_context *) stctxi;
   struct gl_context *ctx = st->ctx;
   struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
   struct gl_texture_object *texObj;
   struct gl_texture_image *texImage;
   struct st_texture_object *stObj;
   struct st_texture_image *stImage;
   GLenum internalFormat;
   GLuint width, height, depth;

   switch (target) {
   case ST_TEXTURE_1D:
      target = GL_TEXTURE_1D;
      break;
   case ST_TEXTURE_2D:
      target = GL_TEXTURE_2D;
      break;
   case ST_TEXTURE_3D:
      target = GL_TEXTURE_3D;
      break;
   case ST_TEXTURE_RECT:
      target = GL_TEXTURE_RECTANGLE_ARB;
      break;
   default:
      return FALSE;
      break;
   }

   texObj = _mesa_select_tex_object(ctx, texUnit, target);
   _mesa_lock_texture(ctx, texObj);

   stObj = st_texture_object(texObj);
   /* switch to surface based */
   if (!stObj->surface_based) {
      _mesa_clear_texture_object(ctx, texObj);
      stObj->surface_based = GL_TRUE;
   }

   texImage = _mesa_get_tex_image(ctx, texObj, target, level);
   stImage = st_texture_image(texImage);
   if (tex) {
      gl_format texFormat;

      /*
       * XXX When internal_format and tex->format differ, st_finalize_texture
       * needs to allocate a new texture with internal_format and copy the
       * texture here into the new one.  It will result in surface_copy being
       * called on surfaces whose formats differ.
       *
       * To avoid that, internal_format is (wrongly) ignored here.  A sane fix
       * is to use a sampler view.
       */
      if (!st_sampler_compat_formats(tex->format, internal_format))
	 internal_format = tex->format;
     
      if (util_format_get_component_bits(internal_format,
               UTIL_FORMAT_COLORSPACE_RGB, 3) > 0)
         internalFormat = GL_RGBA;
      else
         internalFormat = GL_RGB;

      texFormat = st_ChooseTextureFormat(ctx, internalFormat,
                                         GL_BGRA, GL_UNSIGNED_BYTE);

      _mesa_init_teximage_fields(ctx, texImage,
                                 tex->width0, tex->height0, 1, 0,
                                 internalFormat, texFormat);

      width = tex->width0;
      height = tex->height0;
      depth = tex->depth0;

      /* grow the image size until we hit level = 0 */
      while (level > 0) {
         if (width != 1)
            width <<= 1;
         if (height != 1)
            height <<= 1;
         if (depth != 1)
            depth <<= 1;
         level--;
      }
   }
   else {
      _mesa_clear_texture_image(ctx, texImage);
      width = height = depth = 0;
   }

   pipe_resource_reference(&stImage->pt, tex);
   stObj->width0 = width;
   stObj->height0 = height;
   stObj->depth0 = depth;

   _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
   _mesa_unlock_texture(ctx, texObj);
   
   return TRUE;
}
Beispiel #4
0
/**
 * Intialize a struct gl_config from a visual.
 */
static void
st_visual_to_context_mode(const struct st_visual *visual,
                          struct gl_config *mode)
{
   memset(mode, 0, sizeof(*mode));

   if (st_visual_have_buffers(visual, ST_ATTACHMENT_BACK_LEFT_MASK))
      mode->doubleBufferMode = GL_TRUE;
   if (st_visual_have_buffers(visual,
            ST_ATTACHMENT_FRONT_RIGHT_MASK | ST_ATTACHMENT_BACK_RIGHT_MASK))
      mode->stereoMode = GL_TRUE;

   if (visual->color_format != PIPE_FORMAT_NONE) {
      mode->rgbMode = GL_TRUE;

      mode->redBits =
         util_format_get_component_bits(visual->color_format,
               UTIL_FORMAT_COLORSPACE_RGB, 0);
      mode->greenBits =
         util_format_get_component_bits(visual->color_format,
               UTIL_FORMAT_COLORSPACE_RGB, 1);
      mode->blueBits =
         util_format_get_component_bits(visual->color_format,
               UTIL_FORMAT_COLORSPACE_RGB, 2);
      mode->alphaBits =
         util_format_get_component_bits(visual->color_format,
               UTIL_FORMAT_COLORSPACE_RGB, 3);

      mode->rgbBits = mode->redBits +
         mode->greenBits + mode->blueBits + mode->alphaBits;
   }

   if (visual->depth_stencil_format != PIPE_FORMAT_NONE) {
      mode->depthBits =
         util_format_get_component_bits(visual->depth_stencil_format,
               UTIL_FORMAT_COLORSPACE_ZS, 0);
      mode->stencilBits =
         util_format_get_component_bits(visual->depth_stencil_format,
               UTIL_FORMAT_COLORSPACE_ZS, 1);

      mode->haveDepthBuffer = mode->depthBits > 0;
      mode->haveStencilBuffer = mode->stencilBits > 0;
   }

   if (visual->accum_format != PIPE_FORMAT_NONE) {
      mode->haveAccumBuffer = GL_TRUE;

      mode->accumRedBits =
         util_format_get_component_bits(visual->accum_format,
               UTIL_FORMAT_COLORSPACE_RGB, 0);
      mode->accumGreenBits =
         util_format_get_component_bits(visual->accum_format,
               UTIL_FORMAT_COLORSPACE_RGB, 1);
      mode->accumBlueBits =
         util_format_get_component_bits(visual->accum_format,
               UTIL_FORMAT_COLORSPACE_RGB, 2);
      mode->accumAlphaBits =
         util_format_get_component_bits(visual->accum_format,
               UTIL_FORMAT_COLORSPACE_RGB, 3);
   }

   if (visual->samples > 1) {
      mode->sampleBuffers = 1;
      mode->samples = visual->samples;
   }
}
Beispiel #5
0
/**
 * Initialize and validate the EGL config attributes.
 */
static EGLBoolean
init_config_attributes(_EGLConfig *conf, const struct native_config *nconf,
                       EGLint api_mask, enum pipe_format depth_stencil_format,
                       EGLint preserve_buffer, EGLint max_swap_interval,
                       EGLBoolean pre_alpha)
{
   uint rgba[4], depth_stencil[2], buffer_size;
   EGLint surface_type;
   EGLint i;

   /* get the color and depth/stencil component sizes */
   assert(nconf->color_format != PIPE_FORMAT_NONE);
   buffer_size = 0;
   for (i = 0; i < 4; i++) {
      rgba[i] = util_format_get_component_bits(nconf->color_format,
            UTIL_FORMAT_COLORSPACE_RGB, i);
      buffer_size += rgba[i];
   }
   for (i = 0; i < 2; i++) {
      if (depth_stencil_format != PIPE_FORMAT_NONE) {
         depth_stencil[i] =
            util_format_get_component_bits(depth_stencil_format,
               UTIL_FORMAT_COLORSPACE_ZS, i);
      }
      else {
         depth_stencil[i] = 0;
      }
   }

   surface_type = 0x0;
   /* pixmap surfaces should be EGL_SINGLE_BUFFER */
   if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_FRONT_LEFT)) {
      if (nconf->pixmap_bit)
         surface_type |= EGL_PIXMAP_BIT;
   }
   /* the others surfaces should be EGL_BACK_BUFFER (or settable) */
   if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT)) {
      if (nconf->window_bit)
         surface_type |= EGL_WINDOW_BIT;
#ifdef EGL_MESA_screen_surface
      if (nconf->scanout_bit)
         surface_type |= EGL_SCREEN_BIT_MESA;
#endif
      surface_type |= EGL_PBUFFER_BIT;
   }

   if (preserve_buffer)
      surface_type |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT;

   if (pre_alpha && rgba[3]) {
      surface_type |= EGL_VG_ALPHA_FORMAT_PRE_BIT;
      /* st/vega does not support premultiplied alpha yet */
      api_mask &= ~EGL_OPENVG_BIT;
   }

   conf->Conformant = api_mask;
   conf->RenderableType = api_mask;

   conf->RedSize = rgba[0];
   conf->GreenSize = rgba[1];
   conf->BlueSize = rgba[2];
   conf->AlphaSize = rgba[3];
   conf->BufferSize = buffer_size;

   conf->DepthSize = depth_stencil[0];
   conf->StencilSize = depth_stencil[1];

   /* st/vega will allocate the mask on demand */
   if (api_mask & EGL_OPENVG_BIT)
      conf->AlphaMaskSize = 8;

   conf->SurfaceType = surface_type;

   conf->NativeRenderable = EGL_TRUE;
   if (surface_type & EGL_WINDOW_BIT) {
      conf->NativeVisualID = nconf->native_visual_id;
      conf->NativeVisualType = nconf->native_visual_type;
   }

   if (surface_type & EGL_PBUFFER_BIT) {
      conf->BindToTextureRGB = EGL_TRUE;
      if (rgba[3])
         conf->BindToTextureRGBA = EGL_TRUE;

      conf->MaxPbufferWidth = 4096;
      conf->MaxPbufferHeight = 4096;
      conf->MaxPbufferPixels = 4096 * 4096;
   }

   conf->Level = nconf->level;

   if (nconf->transparent_rgb) {
      conf->TransparentType = EGL_TRANSPARENT_RGB;
      conf->TransparentRedValue = nconf->transparent_rgb_values[0];
      conf->TransparentGreenValue = nconf->transparent_rgb_values[1];
      conf->TransparentBlueValue = nconf->transparent_rgb_values[2];
   }

   conf->MinSwapInterval = 0;
   conf->MaxSwapInterval = max_swap_interval;

   return _eglValidateConfig(conf, EGL_FALSE);
}