/** * Query the implementation's capability to perform a PutBits operation using * application data in a specific indexed format. */ VdpStatus vlVdpOutputSurfaceQueryPutBitsIndexedCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format, VdpIndexedFormat bits_indexed_format, VdpColorTableFormat color_table_format, VdpBool *is_supported) { vlVdpDevice *dev; struct pipe_screen *pscreen; enum pipe_format rgba_format, index_format, colortbl_format; dev = vlGetDataHTAB(device); if (!dev) return VDP_STATUS_INVALID_HANDLE; pscreen = dev->vscreen->pscreen; if (!pscreen) return VDP_STATUS_ERROR; rgba_format = VdpFormatRGBAToPipe(surface_rgba_format); if (rgba_format == PIPE_FORMAT_NONE || rgba_format == PIPE_FORMAT_A8_UNORM) return VDP_STATUS_INVALID_RGBA_FORMAT; index_format = FormatIndexedToPipe(bits_indexed_format); if (index_format == PIPE_FORMAT_NONE) return VDP_STATUS_INVALID_INDEXED_FORMAT; colortbl_format = FormatColorTableToPipe(color_table_format); if (colortbl_format == PIPE_FORMAT_NONE) return VDP_STATUS_INVALID_COLOR_TABLE_FORMAT; if (!is_supported) return VDP_STATUS_INVALID_POINTER; pipe_mutex_lock(dev->mutex); *is_supported = pscreen->is_format_supported ( pscreen, rgba_format, PIPE_TEXTURE_2D, 1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET ); *is_supported &= pscreen->is_format_supported ( pscreen, index_format, PIPE_TEXTURE_2D, 1, PIPE_BIND_SAMPLER_VIEW ); *is_supported &= pscreen->is_format_supported ( pscreen, colortbl_format, PIPE_TEXTURE_1D, 1, PIPE_BIND_SAMPLER_VIEW ); pipe_mutex_unlock(dev->mutex); return VDP_STATUS_OK; }
/** * 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; struct vl_compositor_state *cstate; 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 u_rect dst_rect; vlsurface = vlGetDataHTAB(surface); if (!vlsurface) return VDP_STATUS_INVALID_HANDLE; context = vlsurface->device->context; compositor = &vlsurface->device->compositor; cstate = &vlsurface->cstate; 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; pipe_mutex_lock(vlsurface->device->mutex); vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL); 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(cstate); vl_compositor_set_palette_layer(cstate, compositor, 0, sv_idx, sv_tbl, NULL, NULL, false); vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect)); vl_compositor_render(cstate, compositor, vlsurface->surface, NULL); pipe_sampler_view_reference(&sv_idx, NULL); pipe_sampler_view_reference(&sv_tbl, NULL); pipe_mutex_unlock(vlsurface->device->mutex); return VDP_STATUS_OK; error_resource: pipe_sampler_view_reference(&sv_idx, NULL); pipe_sampler_view_reference(&sv_tbl, NULL); pipe_mutex_unlock(vlsurface->device->mutex); return VDP_STATUS_RESOURCES; }