mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-21 16:20:39 +02:00
egl,wgl: Support eglCreateImageKHR
Acked-by: Daniel Stone <daniels@collabora.com> Acked-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Acked-by: Sidney Just <justsid@x-plane.com> Acked-by: Jason Ekstrand <jason.ekstrand@collabora.com> Tested-by: Yonggang Luo <luoyonggang@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12964>
This commit is contained in:
parent
76756ea4c6
commit
d57a4abcf8
7 changed files with 367 additions and 12 deletions
|
|
@ -33,6 +33,7 @@
|
|||
#include <stw_pixelformat.h>
|
||||
#include <stw_context.h>
|
||||
#include <stw_framebuffer.h>
|
||||
#include <stw_image.h>
|
||||
|
||||
#include <GL/wglext.h>
|
||||
|
||||
|
|
@ -242,21 +243,12 @@ wgl_initialize_impl(_EGLDisplay *disp, HDC hdc)
|
|||
disp->Extensions.KHR_gl_colorspace = EGL_TRUE;
|
||||
|
||||
disp->Extensions.KHR_create_context = EGL_TRUE;
|
||||
disp->Extensions.KHR_reusable_sync = EGL_TRUE;
|
||||
|
||||
#if 0
|
||||
disp->Extensions.KHR_image_base = EGL_TRUE;
|
||||
disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
|
||||
if (wgl_dpy->image->base.version >= 5 &&
|
||||
wgl_dpy->image->createImageFromTexture) {
|
||||
disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE;
|
||||
disp->Extensions.KHR_gl_texture_cubemap_image = EGL_TRUE;
|
||||
|
||||
if (wgl_renderer_query_integer(wgl_dpy,
|
||||
__wgl_RENDERER_HAS_TEXTURE_3D))
|
||||
disp->Extensions.KHR_gl_texture_3D_image = EGL_TRUE;
|
||||
}
|
||||
#endif
|
||||
disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE;
|
||||
disp->Extensions.KHR_gl_texture_cubemap_image = EGL_TRUE;
|
||||
disp->Extensions.KHR_gl_texture_3D_image = EGL_TRUE;
|
||||
|
||||
if (!wgl_add_configs(disp)) {
|
||||
err = "wgl: failed to add configs";
|
||||
|
|
@ -841,6 +833,161 @@ wgl_wait_native(EGLint engine)
|
|||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
static EGLint
|
||||
egl_error_from_stw_image_error(enum stw_image_error err)
|
||||
{
|
||||
switch (err) {
|
||||
case STW_IMAGE_ERROR_SUCCESS:
|
||||
return EGL_SUCCESS;
|
||||
case STW_IMAGE_ERROR_BAD_ALLOC:
|
||||
return EGL_BAD_ALLOC;
|
||||
case STW_IMAGE_ERROR_BAD_MATCH:
|
||||
return EGL_BAD_MATCH;
|
||||
case STW_IMAGE_ERROR_BAD_PARAMETER:
|
||||
return EGL_BAD_PARAMETER;
|
||||
case STW_IMAGE_ERROR_BAD_ACCESS:
|
||||
return EGL_BAD_ACCESS;
|
||||
default:
|
||||
assert(!"unknown stw_image_error code");
|
||||
return EGL_BAD_ALLOC;
|
||||
}
|
||||
}
|
||||
|
||||
static _EGLImage *
|
||||
wgl_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx,
|
||||
EGLenum target,
|
||||
EGLClientBuffer buffer,
|
||||
const EGLint *attr_list)
|
||||
{
|
||||
struct wgl_egl_context *wgl_ctx = wgl_egl_context(ctx);
|
||||
struct wgl_egl_image *wgl_img;
|
||||
GLuint texture = (GLuint) (uintptr_t) buffer;
|
||||
_EGLImageAttribs attrs;
|
||||
GLuint depth;
|
||||
GLenum gl_target;
|
||||
enum stw_image_error error;
|
||||
|
||||
if (texture == 0) {
|
||||
_eglError(EGL_BAD_PARAMETER, "wgl_create_image_khr");
|
||||
return EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
|
||||
if (!_eglParseImageAttribList(&attrs, disp, attr_list))
|
||||
return EGL_NO_IMAGE_KHR;
|
||||
|
||||
switch (target) {
|
||||
case EGL_GL_TEXTURE_2D_KHR:
|
||||
depth = 0;
|
||||
gl_target = GL_TEXTURE_2D;
|
||||
break;
|
||||
case EGL_GL_TEXTURE_3D_KHR:
|
||||
depth = attrs.GLTextureZOffset;
|
||||
gl_target = GL_TEXTURE_3D;
|
||||
break;
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
|
||||
depth = target - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR;
|
||||
gl_target = GL_TEXTURE_CUBE_MAP;
|
||||
break;
|
||||
default:
|
||||
unreachable("Unexpected target in wgl_create_image_khr_texture()");
|
||||
return EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
|
||||
wgl_img = malloc(sizeof *wgl_img);
|
||||
if (!wgl_img) {
|
||||
_eglError(EGL_BAD_ALLOC, "wgl_create_image_khr");
|
||||
return EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
|
||||
_eglInitImage(&wgl_img->base, disp);
|
||||
|
||||
wgl_img->img = stw_create_image_from_texture(wgl_ctx->ctx,
|
||||
gl_target,
|
||||
texture,
|
||||
depth,
|
||||
attrs.GLTextureLevel,
|
||||
&error);
|
||||
assert(!!wgl_img->img == (error == STW_IMAGE_ERROR_SUCCESS));
|
||||
|
||||
if (!wgl_img->img) {
|
||||
free(wgl_img);
|
||||
_eglError(egl_error_from_stw_image_error(error), "wgl_create_image_khr");
|
||||
return EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
return &wgl_img->base;
|
||||
}
|
||||
|
||||
static _EGLImage *
|
||||
wgl_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx,
|
||||
EGLClientBuffer buffer,
|
||||
const EGLint *attr_list)
|
||||
{
|
||||
struct wgl_egl_context *wgl_ctx = wgl_egl_context(ctx);
|
||||
struct wgl_egl_image *wgl_img;
|
||||
GLuint renderbuffer = (GLuint) (uintptr_t) buffer;
|
||||
enum stw_image_error error;
|
||||
|
||||
if (renderbuffer == 0) {
|
||||
_eglError(EGL_BAD_PARAMETER, "wgl_create_image_khr");
|
||||
return EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
|
||||
wgl_img = malloc(sizeof(*wgl_img));
|
||||
if (!wgl_img) {
|
||||
_eglError(EGL_BAD_ALLOC, "wgl_create_image");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_eglInitImage(&wgl_img->base, disp);
|
||||
|
||||
wgl_img->img = stw_create_image_from_renderbuffer(wgl_ctx->ctx, renderbuffer, &error);
|
||||
assert(!!wgl_img->img == (error == STW_IMAGE_ERROR_SUCCESS));
|
||||
|
||||
if (!wgl_img->img) {
|
||||
free(wgl_img);
|
||||
_eglError(egl_error_from_stw_image_error(error), "wgl_create_image_khr");
|
||||
return EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
|
||||
return &wgl_img->base;
|
||||
}
|
||||
|
||||
static _EGLImage *
|
||||
wgl_create_image_khr(_EGLDisplay *disp, _EGLContext *ctx, EGLenum target,
|
||||
EGLClientBuffer buffer, const EGLint *attr_list)
|
||||
{
|
||||
switch (target) {
|
||||
case EGL_GL_TEXTURE_2D_KHR:
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
|
||||
case EGL_GL_TEXTURE_3D_KHR:
|
||||
return wgl_create_image_khr_texture(disp, ctx, target, buffer, attr_list);
|
||||
case EGL_GL_RENDERBUFFER_KHR:
|
||||
return wgl_create_image_khr_renderbuffer(disp, ctx, buffer, attr_list);
|
||||
default:
|
||||
_eglError(EGL_BAD_PARAMETER, "wgl_create_image_khr");
|
||||
return EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
}
|
||||
|
||||
static EGLBoolean
|
||||
wgl_destroy_image_khr(_EGLDisplay *disp, _EGLImage *img)
|
||||
{
|
||||
struct wgl_egl_image *wgl_img = wgl_egl_image(img);
|
||||
stw_destroy_image(wgl_img->img);
|
||||
free(wgl_img);
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
struct _egl_driver _eglDriver = {
|
||||
.Initialize = wgl_initialize,
|
||||
.Terminate = wgl_terminate,
|
||||
|
|
@ -858,5 +1005,7 @@ struct _egl_driver _eglDriver = {
|
|||
.SwapBuffers = wgl_swap_buffers,
|
||||
.WaitClient = wgl_wait_client,
|
||||
.WaitNative = wgl_wait_native,
|
||||
.CreateImageKHR = wgl_create_image_khr,
|
||||
.DestroyImageKHR = wgl_destroy_image_khr,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include <egldriver.h>
|
||||
#include <egldisplay.h>
|
||||
#include <eglconfig.h>
|
||||
#include <eglimage.h>
|
||||
|
||||
#include <stw_pixelformat.h>
|
||||
#include <windows.h>
|
||||
|
|
@ -54,4 +55,11 @@ struct wgl_egl_surface
|
|||
struct stw_framebuffer *fb;
|
||||
};
|
||||
|
||||
struct wgl_egl_image
|
||||
{
|
||||
_EGLImage base;
|
||||
struct stw_image *img;
|
||||
};
|
||||
|
||||
_EGL_DRIVER_STANDARD_TYPECASTS(wgl_egl)
|
||||
_EGL_DRIVER_TYPECAST(wgl_egl_image, _EGLImage, obj)
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ libwgl = static_library(
|
|||
'stw_ext_swapinterval.c',
|
||||
'stw_framebuffer.c',
|
||||
'stw_getprocaddress.c',
|
||||
'stw_image.c',
|
||||
'stw_nopfuncs.c',
|
||||
'stw_nopfuncs.h',
|
||||
'stw_pixelformat.c',
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
#define STW_CONTEXT_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <GL/gl.h>
|
||||
#include <gldrv.h>
|
||||
|
||||
struct hud_context;
|
||||
struct stw_framebuffer;
|
||||
|
|
|
|||
135
src/gallium/frontends/wgl/stw_image.c
Normal file
135
src/gallium/frontends/wgl/stw_image.c
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright © Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "stw_image.h"
|
||||
#include <pipe/p_state.h>
|
||||
#include <util/u_inlines.h>
|
||||
#include <frontend/api.h>
|
||||
|
||||
#include <main/mtypes.h>
|
||||
#include <main/texobj.h>
|
||||
#include <state_tracker/st_context.h>
|
||||
#include <state_tracker/st_texture.h>
|
||||
|
||||
struct stw_image *
|
||||
stw_create_image_from_texture(struct stw_context *ctx, GLenum gl_target, GLuint texture,
|
||||
GLuint depth, GLint level, enum stw_image_error *error)
|
||||
{
|
||||
struct st_context *st_ctx = (struct st_context *)ctx->st;
|
||||
struct gl_context *gl_ctx = st_ctx->ctx;
|
||||
struct gl_texture_object *obj;
|
||||
struct pipe_resource *tex;
|
||||
GLuint face = 0;
|
||||
|
||||
obj = _mesa_lookup_texture(gl_ctx, texture);
|
||||
if (!obj || obj->Target != gl_target) {
|
||||
*error = STW_IMAGE_ERROR_BAD_PARAMETER;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tex = st_get_texobj_resource(obj);
|
||||
if (!tex) {
|
||||
*error = STW_IMAGE_ERROR_BAD_PARAMETER;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (gl_target == GL_TEXTURE_CUBE_MAP)
|
||||
face = depth;
|
||||
|
||||
_mesa_test_texobj_completeness(gl_ctx, obj);
|
||||
if (!obj->_BaseComplete || (level > 0 && !obj->_MipmapComplete)) {
|
||||
*error = STW_IMAGE_ERROR_BAD_PARAMETER;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (level < obj->Attrib.BaseLevel || level > obj->_MaxLevel) {
|
||||
*error = STW_IMAGE_ERROR_BAD_MATCH;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (gl_target == GL_TEXTURE_3D && obj->Image[face][level]->Depth < depth) {
|
||||
*error = STW_IMAGE_ERROR_BAD_MATCH;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct stw_image *ret = calloc(1, sizeof(struct stw_image));
|
||||
pipe_resource_reference(&ret->pres, tex);
|
||||
ret->level = level;
|
||||
ret->layer = depth;
|
||||
ret->format = tex->format;
|
||||
|
||||
gl_ctx->Shared->HasExternallySharedImages = true;
|
||||
*error = STW_IMAGE_ERROR_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct stw_image *
|
||||
stw_create_image_from_renderbuffer(struct stw_context *ctx, GLuint renderbuffer,
|
||||
enum stw_image_error *error)
|
||||
{
|
||||
struct st_context *st_ctx = (struct st_context *)ctx->st;
|
||||
struct gl_context *gl_ctx = st_ctx->ctx;
|
||||
struct gl_renderbuffer *rb;
|
||||
struct pipe_resource *tex;
|
||||
|
||||
/* Section 3.9 (EGLImage Specification and Management) of the EGL 1.5
|
||||
* specification says:
|
||||
*
|
||||
* "If target is EGL_GL_RENDERBUFFER and buffer is not the name of a
|
||||
* renderbuffer object, or if buffer is the name of a multisampled
|
||||
* renderbuffer object, the error EGL_BAD_PARAMETER is generated."
|
||||
*
|
||||
* "If target is EGL_GL_TEXTURE_2D , EGL_GL_TEXTURE_CUBE_MAP_*,
|
||||
* EGL_GL_RENDERBUFFER or EGL_GL_TEXTURE_3D and buffer refers to the
|
||||
* default GL texture object (0) for the corresponding GL target, the
|
||||
* error EGL_BAD_PARAMETER is generated."
|
||||
* (rely on _mesa_lookup_renderbuffer returning NULL in this case)
|
||||
*/
|
||||
rb = _mesa_lookup_renderbuffer(gl_ctx, renderbuffer);
|
||||
if (!rb || rb->NumSamples > 0) {
|
||||
*error = STW_IMAGE_ERROR_BAD_PARAMETER;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tex = rb->texture;
|
||||
if (!tex) {
|
||||
*error = STW_IMAGE_ERROR_BAD_PARAMETER;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct stw_image *ret = calloc(1, sizeof(struct stw_image));
|
||||
pipe_resource_reference(&ret->pres, tex);
|
||||
ret->format = tex->format;
|
||||
|
||||
gl_ctx->Shared->HasExternallySharedImages = true;
|
||||
*error = STW_IMAGE_ERROR_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
stw_destroy_image(struct stw_image *img)
|
||||
{
|
||||
pipe_resource_reference(&img->pres, NULL);
|
||||
free(img);
|
||||
}
|
||||
|
||||
57
src/gallium/frontends/wgl/stw_image.h
Normal file
57
src/gallium/frontends/wgl/stw_image.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright © Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <pipe/p_state.h>
|
||||
#include "stw_context.h"
|
||||
|
||||
#include <GL/gl.h>
|
||||
|
||||
enum stw_image_error
|
||||
{
|
||||
STW_IMAGE_ERROR_SUCCESS,
|
||||
STW_IMAGE_ERROR_BAD_ALLOC,
|
||||
STW_IMAGE_ERROR_BAD_PARAMETER,
|
||||
STW_IMAGE_ERROR_BAD_MATCH,
|
||||
STW_IMAGE_ERROR_BAD_ACCESS,
|
||||
};
|
||||
|
||||
struct stw_image
|
||||
{
|
||||
struct pipe_resource *pres;
|
||||
unsigned level;
|
||||
unsigned layer;
|
||||
enum pipe_format format;
|
||||
};
|
||||
|
||||
struct stw_image *
|
||||
stw_create_image_from_texture(struct stw_context *ctx, GLenum gl_target, GLuint texture,
|
||||
GLuint depth, GLint level, enum stw_image_error *error);
|
||||
|
||||
struct stw_image *
|
||||
stw_create_image_from_renderbuffer(struct stw_context *ctx, GLuint renderbuffer,
|
||||
enum stw_image_error *error);
|
||||
|
||||
void
|
||||
stw_destroy_image(struct stw_image *img);
|
||||
|
|
@ -39,3 +39,6 @@ stw_framebuffer_unlock
|
|||
stw_framebuffer_swap_locked
|
||||
stw_get_framebuffer_resource
|
||||
stw_pbuffer_create
|
||||
stw_create_image_from_texture
|
||||
stw_create_image_from_renderbuffer
|
||||
stw_destroy_image
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue