boolean vl_video_buffer_is_format_supported(struct pipe_screen *screen, enum pipe_format format, enum pipe_video_profile profile) { const enum pipe_format *resource_formats; unsigned i; resource_formats = vl_video_buffer_formats(screen, format); if (!resource_formats) return false; for (i = 0; i < VL_NUM_COMPONENTS; ++i) { enum pipe_format format = resource_formats[i]; if (format == PIPE_FORMAT_NONE) continue; /* we at least need to sample from it */ if (!screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW)) return false; format = vl_video_buffer_surface_format(format); if (!screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET)) return false; } return true; }
struct pipe_video_buffer * vl_video_buffer_create(struct pipe_context *pipe, const struct pipe_video_buffer *tmpl) { const enum pipe_format *resource_formats; struct pipe_video_buffer templat, *result; bool pot_buffers; assert(pipe); assert(tmpl->width > 0 && tmpl->height > 0); pot_buffers = !pipe->screen->get_video_param ( pipe->screen, PIPE_VIDEO_PROFILE_UNKNOWN, PIPE_VIDEO_CAP_NPOT_TEXTURES ); resource_formats = vl_video_buffer_formats(pipe->screen, tmpl->buffer_format); if (!resource_formats) return NULL; templat = *tmpl; templat.width = pot_buffers ? util_next_power_of_two(tmpl->width) : align(tmpl->width, VL_MACROBLOCK_WIDTH); templat.height = pot_buffers ? util_next_power_of_two(tmpl->height) : align(tmpl->height, VL_MACROBLOCK_HEIGHT); if (tmpl->interlaced) templat.height /= 2; result = vl_video_buffer_create_ex ( pipe, &templat, resource_formats, 1, tmpl->interlaced ? 2 : 1, PIPE_USAGE_STATIC ); if (result && tmpl->interlaced) result->height *= 2; return result; }
/** * creates an video buffer with an UVD compatible memory layout */ struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe, const struct pipe_video_buffer *tmpl) { struct r600_context *ctx = (struct r600_context *)pipe; struct r600_texture *resources[VL_NUM_COMPONENTS] = {}; struct radeon_surf* surfaces[VL_NUM_COMPONENTS] = {}; struct pb_buffer **pbs[VL_NUM_COMPONENTS] = {}; const enum pipe_format *resource_formats; struct pipe_video_buffer template; struct pipe_resource templ; unsigned i, array_size; assert(pipe); /* first create the needed resources as "normal" textures */ resource_formats = vl_video_buffer_formats(pipe->screen, tmpl->buffer_format); if (!resource_formats) return NULL; array_size = tmpl->interlaced ? 2 : 1;
boolean vl_video_buffer_is_format_supported(struct pipe_screen *screen, enum pipe_format format, enum pipe_video_profile profile) { const enum pipe_format *resource_formats; unsigned i; resource_formats = vl_video_buffer_formats(screen, format); if (!resource_formats) return false; for(i = 0; i < VL_MAX_PLANES; ++i) { if (!resource_formats[i]) continue; if (!screen->is_format_supported(screen, resource_formats[i], PIPE_TEXTURE_2D, 0, PIPE_USAGE_STATIC)) return false; } return true; }
struct pipe_video_buffer * vl_video_buffer_create(struct pipe_context *pipe, enum pipe_format buffer_format, enum pipe_video_chroma_format chroma_format, unsigned width, unsigned height) { const enum pipe_format *resource_formats; struct pipe_video_buffer *result; unsigned buffer_width, buffer_height; bool pot_buffers; assert(pipe); assert(width > 0 && height > 0); pot_buffers = !pipe->screen->get_video_param ( pipe->screen, PIPE_VIDEO_PROFILE_UNKNOWN, PIPE_VIDEO_CAP_NPOT_TEXTURES ); resource_formats = vl_video_buffer_formats(pipe->screen, buffer_format); if (!resource_formats) return NULL; buffer_width = pot_buffers ? util_next_power_of_two(width) : align(width, MACROBLOCK_WIDTH); buffer_height = pot_buffers ? util_next_power_of_two(height) : align(height, MACROBLOCK_HEIGHT); result = vl_video_buffer_create_ex ( pipe, buffer_width, buffer_height, 1, chroma_format, resource_formats, PIPE_USAGE_STATIC ); if (result) result->buffer_format = buffer_format; return result; }