VAStatus vlVaCreateBuffer(VADriverContextP ctx, VAContextID context, VABufferType type, unsigned int size, unsigned int num_elements, void *data, VABufferID *buf_id) { vlVaBuffer *buf; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; buf = CALLOC(1, sizeof(vlVaBuffer)); if (!buf) return VA_STATUS_ERROR_ALLOCATION_FAILED; buf->type = type; buf->size = size; buf->num_elements = num_elements; buf->data = MALLOC(size * num_elements); if (!buf->data) { FREE(buf); return VA_STATUS_ERROR_ALLOCATION_FAILED; } if (data) memcpy(buf->data, data, size * num_elements); *buf_id = handle_table_add(VL_VA_DRIVER(ctx)->htab, buf); return VA_STATUS_SUCCESS; }
DHGLRC APIENTRY DrvCreateLayerContext( HDC hdc, INT iLayerPlane ) { int iPixelFormat; const struct stw_pixelformat_info *pfi; struct st_context_attribs attribs; struct stw_context *ctx = NULL; if(!stw_dev) return 0; if (iLayerPlane != 0) return 0; iPixelFormat = GetPixelFormat(hdc); if(!iPixelFormat) return 0; pfi = stw_pixelformat_get_info( iPixelFormat - 1 ); ctx = CALLOC_STRUCT( stw_context ); if (ctx == NULL) goto no_ctx; ctx->hdc = hdc; ctx->iPixelFormat = iPixelFormat; memset(&attribs, 0, sizeof(attribs)); attribs.profile = ST_PROFILE_DEFAULT; attribs.visual = pfi->stvis; ctx->st = stw_dev->stapi->create_context(stw_dev->stapi, stw_dev->smapi, &attribs, NULL); if (ctx->st == NULL) goto no_st_ctx; ctx->st->st_manager_private = (void *) ctx; pipe_mutex_lock( stw_dev->ctx_mutex ); ctx->dhglrc = handle_table_add(stw_dev->ctx_table, ctx); pipe_mutex_unlock( stw_dev->ctx_mutex ); if (!ctx->dhglrc) goto no_hglrc; return ctx->dhglrc; no_hglrc: ctx->st->destroy(ctx->st); no_st_ctx: FREE(ctx); no_ctx: return 0; }
vlHandle vlAddDataHTAB(void *data) { assert(data); #ifdef VL_HANDLES vlHandle handle = 0; pipe_mutex_lock(htab_lock); if (htab) handle = handle_table_add(htab, data); pipe_mutex_unlock(htab_lock); return handle; #else return (vlHandle)data; #endif }
VAStatus vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width, int picture_height, int flag, VASurfaceID *render_targets, int num_render_targets, VAContextID *context_id) { vlVaDriver *drv; vlVaContext *context; vlVaConfig *config; int is_vpp; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; drv = VL_VA_DRIVER(ctx); pipe_mutex_lock(drv->mutex); config = handle_table_get(drv->htab, config_id); pipe_mutex_unlock(drv->mutex); is_vpp = config->profile == PIPE_VIDEO_PROFILE_UNKNOWN && !picture_width && !picture_height && !flag && !render_targets && !num_render_targets; if (!(picture_width && picture_height) && !is_vpp) return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT; context = CALLOC(1, sizeof(vlVaContext)); if (!context) return VA_STATUS_ERROR_ALLOCATION_FAILED; if (is_vpp) { context->decoder = NULL; } else { context->templat.profile = config->profile; context->templat.entrypoint = config->entrypoint; context->templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420; context->templat.width = picture_width; context->templat.height = picture_height; context->templat.expect_chunked_decode = true; switch (u_reduce_video_profile(context->templat.profile)) { case PIPE_VIDEO_FORMAT_MPEG12: case PIPE_VIDEO_FORMAT_VC1: case PIPE_VIDEO_FORMAT_MPEG4: context->templat.max_references = 2; break; case PIPE_VIDEO_FORMAT_MPEG4_AVC: context->templat.max_references = 0; if (config->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE) { context->desc.h264.pps = CALLOC_STRUCT(pipe_h264_pps); if (!context->desc.h264.pps) { FREE(context); return VA_STATUS_ERROR_ALLOCATION_FAILED; } context->desc.h264.pps->sps = CALLOC_STRUCT(pipe_h264_sps); if (!context->desc.h264.pps->sps) { FREE(context->desc.h264.pps); FREE(context); return VA_STATUS_ERROR_ALLOCATION_FAILED; } } break; case PIPE_VIDEO_FORMAT_HEVC: context->templat.max_references = num_render_targets; context->desc.h265.pps = CALLOC_STRUCT(pipe_h265_pps); if (!context->desc.h265.pps) { FREE(context); return VA_STATUS_ERROR_ALLOCATION_FAILED; } context->desc.h265.pps->sps = CALLOC_STRUCT(pipe_h265_sps); if (!context->desc.h265.pps->sps) { FREE(context->desc.h265.pps); FREE(context); return VA_STATUS_ERROR_ALLOCATION_FAILED; } break; default: break; } } context->desc.base.profile = config->profile; context->desc.base.entry_point = config->entrypoint; if (config->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) context->desc.h264enc.rate_ctrl.rate_ctrl_method = config->rc; pipe_mutex_lock(drv->mutex); *context_id = handle_table_add(drv->htab, context); pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; }
VAStatus vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format, unsigned int width, unsigned int height, VASurfaceID *surfaces, unsigned int num_surfaces, VASurfaceAttrib *attrib_list, unsigned int num_attribs) { vlVaDriver *drv; VASurfaceAttribExternalBuffers *memory_attibute; struct pipe_video_buffer templat; struct pipe_screen *pscreen; int i; int memory_type; int expected_fourcc; VAStatus vaStatus; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; if (!(width && height)) return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT; drv = VL_VA_DRIVER(ctx); if (!drv) return VA_STATUS_ERROR_INVALID_CONTEXT; pscreen = VL_VA_PSCREEN(ctx); if (!pscreen) return VA_STATUS_ERROR_INVALID_CONTEXT; /* Default. */ memory_attibute = NULL; memory_type = VA_SURFACE_ATTRIB_MEM_TYPE_VA; expected_fourcc = 0; for (i = 0; i < num_attribs && attrib_list; i++) { if ((attrib_list[i].type == VASurfaceAttribPixelFormat) && (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) { if (attrib_list[i].value.type != VAGenericValueTypeInteger) return VA_STATUS_ERROR_INVALID_PARAMETER; expected_fourcc = attrib_list[i].value.value.i; } if ((attrib_list[i].type == VASurfaceAttribMemoryType) && (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) { if (attrib_list[i].value.type != VAGenericValueTypeInteger) return VA_STATUS_ERROR_INVALID_PARAMETER; switch (attrib_list[i].value.value.i) { case VA_SURFACE_ATTRIB_MEM_TYPE_VA: case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: memory_type = attrib_list[i].value.value.i; break; default: return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE; } } if ((attrib_list[i].type == VASurfaceAttribExternalBufferDescriptor) && (attrib_list[i].flags == VA_SURFACE_ATTRIB_SETTABLE)) { if (attrib_list[i].value.type != VAGenericValueTypePointer) return VA_STATUS_ERROR_INVALID_PARAMETER; memory_attibute = (VASurfaceAttribExternalBuffers *)attrib_list[i].value.value.p; } } if (VA_RT_FORMAT_YUV420 != format && VA_RT_FORMAT_YUV422 != format && VA_RT_FORMAT_YUV444 != format && VA_RT_FORMAT_RGB32 != format) { return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; } switch (memory_type) { case VA_SURFACE_ATTRIB_MEM_TYPE_VA: break; case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: if (!memory_attibute) return VA_STATUS_ERROR_INVALID_PARAMETER; expected_fourcc = memory_attibute->pixel_format; break; default: assert(0); } memset(&templat, 0, sizeof(templat)); if (expected_fourcc) { templat.buffer_format = VaFourccToPipeFormat(expected_fourcc); templat.interlaced = 0; } else { templat.buffer_format = pscreen->get_video_param ( pscreen, PIPE_VIDEO_PROFILE_UNKNOWN, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_PREFERED_FORMAT ); templat.interlaced = pscreen->get_video_param ( pscreen, PIPE_VIDEO_PROFILE_UNKNOWN, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_PREFERS_INTERLACED ); } templat.chroma_format = ChromaToPipe(format); templat.width = width; templat.height = height; memset(surfaces, VA_INVALID_ID, num_surfaces * sizeof(VASurfaceID)); for (i = 0; i < num_surfaces; i++) { vlVaSurface *surf = CALLOC(1, sizeof(vlVaSurface)); if (!surf) goto no_res; surf->templat = templat; switch (memory_type) { case VA_SURFACE_ATTRIB_MEM_TYPE_VA: surf->buffer = drv->pipe->create_video_buffer(drv->pipe, &templat); if (!surf->buffer) goto no_res; util_dynarray_init(&surf->subpics); surfaces[i] = handle_table_add(drv->htab, surf); break; case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: vaStatus = suface_from_external_memory(ctx, surf, memory_attibute, i, surfaces, &templat); if (vaStatus != VA_STATUS_SUCCESS) goto no_res; break; default: assert(0); } } return VA_STATUS_SUCCESS; no_res: if (i) vlVaDestroySurfaces(ctx, surfaces, i); return VA_STATUS_ERROR_ALLOCATION_FAILED; }
static VAStatus suface_from_external_memory(VADriverContextP ctx, vlVaSurface *surface, VASurfaceAttribExternalBuffers *memory_attibute, int index, VASurfaceID *surfaces, struct pipe_video_buffer *templat) { vlVaDriver *drv; struct pipe_screen *pscreen; struct pipe_resource *resource; struct pipe_resource res_templ; struct winsys_handle whandle; struct pipe_resource *resources[VL_NUM_COMPONENTS]; if (!ctx) return VA_STATUS_ERROR_INVALID_PARAMETER; pscreen = VL_VA_PSCREEN(ctx); drv = VL_VA_DRIVER(ctx); if (!memory_attibute || !memory_attibute->buffers || index > memory_attibute->num_buffers) return VA_STATUS_ERROR_INVALID_PARAMETER; if (surface->templat.width != memory_attibute->width || surface->templat.height != memory_attibute->height || memory_attibute->num_planes < 1) return VA_STATUS_ERROR_INVALID_PARAMETER; switch (memory_attibute->pixel_format) { case VA_FOURCC_RGBA: case VA_FOURCC_RGBX: case VA_FOURCC_BGRA: case VA_FOURCC_BGRX: if (memory_attibute->num_planes != 1) return VA_STATUS_ERROR_INVALID_PARAMETER; break; default: return VA_STATUS_ERROR_INVALID_PARAMETER; } memset(&res_templ, 0, sizeof(res_templ)); res_templ.target = PIPE_TEXTURE_2D; res_templ.last_level = 0; res_templ.depth0 = 1; res_templ.array_size = 1; res_templ.width0 = memory_attibute->width; res_templ.height0 = memory_attibute->height; res_templ.format = surface->templat.buffer_format; res_templ.bind = PIPE_BIND_SAMPLER_VIEW; res_templ.usage = PIPE_USAGE_DEFAULT; memset(&whandle, 0, sizeof(struct winsys_handle)); whandle.type = DRM_API_HANDLE_TYPE_FD; whandle.handle = memory_attibute->buffers[index]; whandle.stride = memory_attibute->pitches[index]; resource = pscreen->resource_from_handle(pscreen, &res_templ, &whandle); if (!resource) return VA_STATUS_ERROR_ALLOCATION_FAILED; memset(resources, 0, sizeof resources); resources[0] = resource; surface->buffer = vl_video_buffer_create_ex2(drv->pipe, templat, resources); if (!surface->buffer) return VA_STATUS_ERROR_ALLOCATION_FAILED; util_dynarray_init(&surface->subpics); surfaces[index] = handle_table_add(drv->htab, surface); if (!surfaces[index]) return VA_STATUS_ERROR_ALLOCATION_FAILED; return VA_STATUS_SUCCESS; }
/** * Called via DrvCreateContext(), DrvCreateLayerContext() and * wglCreateContextAttribsARB() to actually create a rendering context. * \param handle the desired DHGLRC handle to use for the context, or zero * if a new handle should be allocated. * \return the handle for the new context or zero if there was a problem. */ DHGLRC stw_create_context_attribs(HDC hdc, INT iLayerPlane, DHGLRC hShareContext, int majorVersion, int minorVersion, int contextFlags, int profileMask, DHGLRC handle) { int iPixelFormat; struct stw_framebuffer *fb; const struct stw_pixelformat_info *pfi; struct st_context_attribs attribs; struct stw_context *ctx = NULL; struct stw_context *shareCtx = NULL; enum st_context_error ctx_err = 0; if (!stw_dev) return 0; if (iLayerPlane != 0) return 0; iPixelFormat = GetPixelFormat(hdc); if(!iPixelFormat) return 0; /* * GDI only knows about displayable pixel formats, so determine the pixel * format from the framebuffer. * * TODO: Remove the GetPixelFormat() above, and stop relying on GDI. */ fb = stw_framebuffer_from_hdc( hdc ); if (fb) { assert(iPixelFormat == fb->iDisplayablePixelFormat); iPixelFormat = fb->iPixelFormat; stw_framebuffer_release(fb); } pfi = stw_pixelformat_get_info( iPixelFormat ); if (hShareContext != 0) { pipe_mutex_lock( stw_dev->ctx_mutex ); shareCtx = stw_lookup_context_locked( hShareContext ); pipe_mutex_unlock( stw_dev->ctx_mutex ); } ctx = CALLOC_STRUCT( stw_context ); if (ctx == NULL) goto no_ctx; ctx->hdc = hdc; ctx->iPixelFormat = iPixelFormat; memset(&attribs, 0, sizeof(attribs)); attribs.visual = pfi->stvis; attribs.major = majorVersion; attribs.minor = minorVersion; if (contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE; if (contextFlags & WGL_CONTEXT_DEBUG_BIT_ARB) attribs.flags |= ST_CONTEXT_FLAG_DEBUG; switch (profileMask) { case WGL_CONTEXT_CORE_PROFILE_BIT_ARB: /* There are no profiles before OpenGL 3.2. The * WGL_ARB_create_context_profile spec says: * * "If the requested OpenGL version is less than 3.2, * WGL_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality * of the context is determined solely by the requested version." */ if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2)) { attribs.profile = ST_PROFILE_OPENGL_CORE; break; } /* fall-through */ case WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB: /* * The spec also says: * * "If version 3.1 is requested, the context returned may implement * any of the following versions: * * * Version 3.1. The GL_ARB_compatibility extension may or may not * be implemented, as determined by the implementation. * * The core profile of version 3.2 or greater." * * and because Mesa doesn't support GL_ARB_compatibility, the only chance to * honour a 3.1 context is through core profile. */ if (majorVersion == 3 && minorVersion == 1) { attribs.profile = ST_PROFILE_OPENGL_CORE; } else { attribs.profile = ST_PROFILE_DEFAULT; } break; case WGL_CONTEXT_ES_PROFILE_BIT_EXT: if (majorVersion >= 2) { attribs.profile = ST_PROFILE_OPENGL_ES2; } else { attribs.profile = ST_PROFILE_OPENGL_ES1; } break; default: assert(0); goto no_st_ctx; } ctx->st = stw_dev->stapi->create_context(stw_dev->stapi, stw_dev->smapi, &attribs, &ctx_err, shareCtx ? shareCtx->st : NULL); if (ctx->st == NULL) goto no_st_ctx; ctx->st->st_manager_private = (void *) ctx; if (ctx->st->cso_context) { ctx->hud = hud_create(ctx->st->pipe, ctx->st->cso_context); } pipe_mutex_lock( stw_dev->ctx_mutex ); if (handle) { /* We're replacing the context data for this handle. See the * wglCreateContextAttribsARB() function. */ struct stw_context *old_ctx = stw_lookup_context_locked((unsigned) handle); if (old_ctx) { /* free the old context data associated with this handle */ if (old_ctx->hud) { hud_destroy(old_ctx->hud); } ctx->st->destroy(old_ctx->st); FREE(old_ctx); } /* replace table entry */ handle_table_set(stw_dev->ctx_table, (unsigned) handle, ctx); } else { /* create new table entry */ handle = (DHGLRC) handle_table_add(stw_dev->ctx_table, ctx); } ctx->dhglrc = handle; pipe_mutex_unlock( stw_dev->ctx_mutex ); if (!ctx->dhglrc) goto no_hglrc; return ctx->dhglrc; no_hglrc: if (ctx->hud) { hud_destroy(ctx->hud); } ctx->st->destroy(ctx->st); no_st_ctx: FREE(ctx); no_ctx: return 0; }
VAStatus vlVaCreateImage(VADriverContextP ctx, VAImageFormat *format, int width, int height, VAImage *image) { VAStatus status; vlVaDriver *drv; VAImage *img; int w, h; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; if (!(format && image && width && height)) return VA_STATUS_ERROR_INVALID_PARAMETER; drv = VL_VA_DRIVER(ctx); img = CALLOC(1, sizeof(VAImage)); if (!img) return VA_STATUS_ERROR_ALLOCATION_FAILED; pipe_mutex_lock(drv->mutex); img->image_id = handle_table_add(drv->htab, img); pipe_mutex_unlock(drv->mutex); img->format = *format; img->width = width; img->height = height; w = align(width, 2); h = align(height, 2); switch (format->fourcc) { case VA_FOURCC('N','V','1','2'): img->num_planes = 2; img->pitches[0] = w; img->offsets[0] = 0; img->pitches[1] = w; img->offsets[1] = w * h; img->data_size = w * h * 3 / 2; break; case VA_FOURCC('I','4','2','0'): case VA_FOURCC('Y','V','1','2'): img->num_planes = 3; img->pitches[0] = w; img->offsets[0] = 0; img->pitches[1] = w / 2; img->offsets[1] = w * h; img->pitches[2] = w / 2; img->offsets[2] = w * h * 5 / 4; img->data_size = w * h * 3 / 2; break; case VA_FOURCC('U','Y','V','Y'): case VA_FOURCC('Y','U','Y','V'): img->num_planes = 1; img->pitches[0] = w * 2; img->offsets[0] = 0; img->data_size = w * h * 2; break; case VA_FOURCC('B','G','R','A'): case VA_FOURCC('R','G','B','A'): case VA_FOURCC('B','G','R','X'): case VA_FOURCC('R','G','B','X'): img->num_planes = 1; img->pitches[0] = w * 4; img->offsets[0] = 0; img->data_size = w * h * 4; break; default: return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT; } status = vlVaCreateBuffer(ctx, 0, VAImageBufferType, align(img->data_size, 16), 1, NULL, &img->buf); if (status != VA_STATUS_SUCCESS) return status; *image = *img; return status; }
VAStatus vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image) { vlVaDriver *drv; vlVaSurface *surf; vlVaBuffer *img_buf; VAImage *img; struct pipe_surface **surfaces; int w; int h; int i; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; drv = VL_VA_DRIVER(ctx); if (!drv) return VA_STATUS_ERROR_INVALID_CONTEXT; surf = handle_table_get(drv->htab, surface); if (!surf || !surf->buffer || surf->buffer->interlaced) return VA_STATUS_ERROR_INVALID_SURFACE; surfaces = surf->buffer->get_surfaces(surf->buffer); if (!surfaces || !surfaces[0]->texture) return VA_STATUS_ERROR_ALLOCATION_FAILED; img = CALLOC(1, sizeof(VAImage)); if (!img) return VA_STATUS_ERROR_ALLOCATION_FAILED; img->format.fourcc = PipeFormatToVaFourcc(surf->buffer->buffer_format); img->buf = VA_INVALID_ID; img->width = surf->buffer->width; img->height = surf->buffer->height; img->num_palette_entries = 0; img->entry_bytes = 0; w = align(surf->buffer->width, 2); h = align(surf->buffer->height, 2); for (i = 0; i < ARRAY_SIZE(formats); ++i) { if (img->format.fourcc == formats[i].fourcc) { img->format = formats[i]; break; } } switch (img->format.fourcc) { case VA_FOURCC('U','Y','V','Y'): case VA_FOURCC('Y','U','Y','V'): img->num_planes = 1; img->pitches[0] = w * 2; img->offsets[0] = 0; img->data_size = w * h * 2; break; case VA_FOURCC('B','G','R','A'): case VA_FOURCC('R','G','B','A'): case VA_FOURCC('B','G','R','X'): case VA_FOURCC('R','G','B','X'): img->num_planes = 1; img->pitches[0] = w * 4; img->offsets[0] = 0; img->data_size = w * h * 4; break; default: /* VaDeriveImage is designed for contiguous planes. */ FREE(img); return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT; } img_buf = CALLOC(1, sizeof(vlVaBuffer)); if (!img_buf) { FREE(img); return VA_STATUS_ERROR_ALLOCATION_FAILED; } pipe_mutex_lock(drv->mutex); img->image_id = handle_table_add(drv->htab, img); img_buf->type = VAImageBufferType; img_buf->size = img->data_size; img_buf->num_elements = 1; pipe_resource_reference(&img_buf->derived_surface.resource, surfaces[0]->texture); img->buf = handle_table_add(VL_VA_DRIVER(ctx)->htab, img_buf); pipe_mutex_unlock(drv->mutex); *image = *img; return VA_STATUS_SUCCESS; }
DHGLRC stw_create_context_attribs( HDC hdc, INT iLayerPlane, DHGLRC hShareContext, int majorVersion, int minorVersion, int contextFlags, int profileMask) { int iPixelFormat; struct stw_framebuffer *fb; const struct stw_pixelformat_info *pfi; struct st_context_attribs attribs; struct stw_context *ctx = NULL; struct stw_context *shareCtx = NULL; enum st_context_error ctx_err = 0; if (!stw_dev) return 0; if (iLayerPlane != 0) return 0; iPixelFormat = GetPixelFormat(hdc); if(!iPixelFormat) return 0; /* * GDI only knows about displayable pixel formats, so determine the pixel format * from the framebuffer. * * TODO: Remove the GetPixelFormat() above, and stop relying on GDI. */ fb = stw_framebuffer_from_hdc( hdc ); if (fb) { assert(iPixelFormat == fb->iDisplayablePixelFormat); iPixelFormat = fb->iPixelFormat; stw_framebuffer_release(fb); } pfi = stw_pixelformat_get_info( iPixelFormat ); if (hShareContext != 0) { pipe_mutex_lock( stw_dev->ctx_mutex ); shareCtx = stw_lookup_context_locked( hShareContext ); pipe_mutex_unlock( stw_dev->ctx_mutex ); } ctx = CALLOC_STRUCT( stw_context ); if (ctx == NULL) goto no_ctx; ctx->hdc = hdc; ctx->iPixelFormat = iPixelFormat; memset(&attribs, 0, sizeof(attribs)); attribs.visual = pfi->stvis; attribs.major = majorVersion; attribs.minor = minorVersion; if (contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE; if (contextFlags & WGL_CONTEXT_DEBUG_BIT_ARB) attribs.flags |= ST_CONTEXT_FLAG_DEBUG; /* There are no profiles before OpenGL 3.2. The * WGL_ARB_create_context_profile spec says: * * "If the requested OpenGL version is less than 3.2, * WGL_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality of the * context is determined solely by the requested version." * * The spec also says: * * "The default value for WGL_CONTEXT_PROFILE_MASK_ARB is * WGL_CONTEXT_CORE_PROFILE_BIT_ARB." */ attribs.profile = ST_PROFILE_DEFAULT; if ((majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2)) && ((profileMask & WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB) == 0)) attribs.profile = ST_PROFILE_OPENGL_CORE; ctx->st = stw_dev->stapi->create_context(stw_dev->stapi, stw_dev->smapi, &attribs, &ctx_err, shareCtx ? shareCtx->st : NULL); if (ctx->st == NULL) goto no_st_ctx; ctx->st->st_manager_private = (void *) ctx; pipe_mutex_lock( stw_dev->ctx_mutex ); ctx->dhglrc = handle_table_add(stw_dev->ctx_table, ctx); pipe_mutex_unlock( stw_dev->ctx_mutex ); if (!ctx->dhglrc) goto no_hglrc; return ctx->dhglrc; no_hglrc: ctx->st->destroy(ctx->st); no_st_ctx: FREE(ctx); no_ctx: return 0; }
VAStatus vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint, VAConfigAttrib *attrib_list, int num_attribs, VAConfigID *config_id) { vlVaDriver *drv; vlVaConfig *config; struct pipe_screen *pscreen; enum pipe_video_profile p; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; drv = VL_VA_DRIVER(ctx); if (!drv) return VA_STATUS_ERROR_INVALID_CONTEXT; config = CALLOC(1, sizeof(vlVaConfig)); if (!config) return VA_STATUS_ERROR_ALLOCATION_FAILED; if (profile == VAProfileNone && entrypoint == VAEntrypointVideoProc) { config->entrypoint = VAEntrypointVideoProc; config->profile = PIPE_VIDEO_PROFILE_UNKNOWN; for (int i = 0; i < num_attribs; i++) { if (attrib_list[i].type == VAConfigAttribRTFormat) { if (attrib_list[i].value & (VA_RT_FORMAT_YUV420 | VA_RT_FORMAT_RGB32)) { config->rt_format = attrib_list[i].value; } else { FREE(config); return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; } } } /* Default value if not specified in the input attributes. */ if (!config->rt_format) config->rt_format = VA_RT_FORMAT_YUV420 | VA_RT_FORMAT_RGB32; pipe_mutex_lock(drv->mutex); *config_id = handle_table_add(drv->htab, config); pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } p = ProfileToPipe(profile); if (p == PIPE_VIDEO_PROFILE_UNKNOWN) { FREE(config); return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; } pscreen = VL_VA_PSCREEN(ctx); switch (entrypoint) { case VAEntrypointVLD: if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) { FREE(config); return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; } config->entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM; break; case VAEntrypointEncSlice: if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_SUPPORTED)) { FREE(config); return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; } config->entrypoint = PIPE_VIDEO_ENTRYPOINT_ENCODE; break; default: FREE(config); return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; } config->profile = p; for (int i = 0; i <num_attribs ; i++) { if (attrib_list[i].type == VAConfigAttribRateControl) { if (attrib_list[i].value == VA_RC_CBR) config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT; else if (attrib_list[i].value == VA_RC_VBR) config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE; else config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE; } if (attrib_list[i].type == VAConfigAttribRTFormat) { if (attrib_list[i].value == VA_RT_FORMAT_YUV420) { config->rt_format = attrib_list[i].value; } else { FREE(config); return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; } } } /* Default value if not specified in the input attributes. */ if (!config->rt_format) config->rt_format = VA_RT_FORMAT_YUV420; pipe_mutex_lock(drv->mutex); *config_id = handle_table_add(drv->htab, config); pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; }