/** * 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; }
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); }
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; }
/** * 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; } }
/** * 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); }