radeon: Implement __DRI_IMAGE and EGL_MESA_image_drm

This commit is contained in:
Johann Rudloff 2010-11-08 14:43:55 -05:00 committed by Alex Deucher
parent 4990b771de
commit b42e562a11
2 changed files with 196 additions and 0 deletions

View File

@ -41,12 +41,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "main/mtypes.h"
#include "main/framebuffer.h"
#include "main/renderbuffer.h"
#include "main/fbobject.h"
#define STANDALONE_MMIO
#include "radeon_chipset.h"
#include "radeon_macros.h"
#include "radeon_screen.h"
#include "radeon_common.h"
#include "radeon_common_context.h"
#if defined(RADEON_R100)
#include "radeon_context.h"
#include "radeon_tex.h"
@ -398,6 +400,188 @@ static const struct __DRI2flushExtensionRec radeonFlushExtension = {
dri2InvalidateDrawable,
};
static __DRIimage *
radeon_create_image_from_name(__DRIcontext *context,
int width, int height, int format,
int name, int pitch, void *loaderPrivate)
{
__DRIimage *image;
radeonContextPtr radeon = context->driverPrivate;
if (name == 0)
return NULL;
image = CALLOC(sizeof *image);
if (image == NULL)
return NULL;
switch (format) {
case __DRI_IMAGE_FORMAT_RGB565:
image->format = MESA_FORMAT_RGB565;
image->internal_format = GL_RGB;
image->data_type = GL_UNSIGNED_BYTE;
break;
case __DRI_IMAGE_FORMAT_XRGB8888:
image->format = MESA_FORMAT_XRGB8888;
image->internal_format = GL_RGB;
image->data_type = GL_UNSIGNED_BYTE;
break;
case __DRI_IMAGE_FORMAT_ARGB8888:
image->format = MESA_FORMAT_ARGB8888;
image->internal_format = GL_RGBA;
image->data_type = GL_UNSIGNED_BYTE;
break;
default:
free(image);
return NULL;
}
image->data = loaderPrivate;
image->cpp = _mesa_get_format_bytes(image->format);
image->width = width;
image->pitch = pitch;
image->height = height;
image->bo = radeon_bo_open(radeon->radeonScreen->bom,
(uint32_t)name,
image->pitch * image->height * image->cpp,
0,
RADEON_GEM_DOMAIN_VRAM,
0);
if (image->bo == NULL) {
FREE(image);
return NULL;
}
return image;
}
static __DRIimage *
radeon_create_image_from_renderbuffer(__DRIcontext *context,
int renderbuffer, void *loaderPrivate)
{
__DRIimage *image;
radeonContextPtr radeon = context->driverPrivate;
struct gl_renderbuffer *rb;
struct radeon_renderbuffer *rrb;
rb = _mesa_lookup_renderbuffer(radeon->glCtx, renderbuffer);
if (!rb) {
_mesa_error(radeon->glCtx,
GL_INVALID_OPERATION, "glRenderbufferExternalMESA");
return NULL;
}
rrb = radeon_renderbuffer(rb);
image = CALLOC(sizeof *image);
if (image == NULL)
return NULL;
image->internal_format = rb->InternalFormat;
image->format = rb->Format;
image->cpp = rrb->cpp;
image->data_type = rb->DataType;
image->data = loaderPrivate;
radeon_bo_ref(rrb->bo);
image->bo = rrb->bo;
image->width = rb->Width;
image->height = rb->Height;
image->pitch = rrb->pitch / image->cpp;
return image;
}
static void
radeon_destroy_image(__DRIimage *image)
{
radeon_bo_unref(image->bo);
FREE(image);
}
static __DRIimage *
radeon_create_image(__DRIscreen *screen,
int width, int height, int format,
unsigned int use,
void *loaderPrivate)
{
__DRIimage *image;
radeonScreenPtr radeonScreen = screen->private;
image = CALLOC(sizeof *image);
if (image == NULL)
return NULL;
switch (format) {
case __DRI_IMAGE_FORMAT_RGB565:
image->format = MESA_FORMAT_RGB565;
image->internal_format = GL_RGB;
image->data_type = GL_UNSIGNED_BYTE;
break;
case __DRI_IMAGE_FORMAT_XRGB8888:
image->format = MESA_FORMAT_XRGB8888;
image->internal_format = GL_RGB;
image->data_type = GL_UNSIGNED_BYTE;
break;
case __DRI_IMAGE_FORMAT_ARGB8888:
image->format = MESA_FORMAT_ARGB8888;
image->internal_format = GL_RGBA;
image->data_type = GL_UNSIGNED_BYTE;
break;
default:
free(image);
return NULL;
}
image->data = loaderPrivate;
image->cpp = _mesa_get_format_bytes(image->format);
image->width = width;
image->height = height;
image->pitch = ((image->cpp * image->width + 255) & ~255) / image->cpp;
image->bo = radeon_bo_open(radeonScreen->bom,
0,
image->pitch * image->height * image->cpp,
0,
RADEON_GEM_DOMAIN_VRAM,
0);
if (image->bo == NULL) {
FREE(image);
return NULL;
}
return image;
}
static GLboolean
radeon_query_image(__DRIimage *image, int attrib, int *value)
{
switch (attrib) {
case __DRI_IMAGE_ATTRIB_STRIDE:
*value = image->pitch * image->cpp;
return GL_TRUE;
case __DRI_IMAGE_ATTRIB_HANDLE:
*value = image->bo->handle;
return GL_TRUE;
case __DRI_IMAGE_ATTRIB_NAME:
radeon_gem_get_kernel_name(image->bo, (uint32_t *) value);
return GL_TRUE;
default:
return GL_FALSE;
}
}
static struct __DRIimageExtensionRec radeonImageExtension = {
{ __DRI_IMAGE, __DRI_IMAGE_VERSION },
radeon_create_image_from_name,
radeon_create_image_from_renderbuffer,
radeon_destroy_image,
radeon_create_image,
radeon_query_image
};
static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
{
screen->device_id = device_id;
@ -1510,6 +1694,7 @@ radeonCreateScreen2(__DRIscreen *sPriv)
#endif
screen->extensions[i++] = &radeonFlushExtension.base;
screen->extensions[i++] = &radeonImageExtension.base;
screen->extensions[i++] = NULL;
sPriv->extensions = screen->extensions;

View File

@ -121,6 +121,17 @@ typedef struct radeon_screen {
GLint r7xx_bank_op;
} radeonScreenRec, *radeonScreenPtr;
struct __DRIimageRec {
struct radeon_bo *bo;
GLenum internal_format;
GLuint format;
GLenum data_type;
int width, height; /* in pixels */
int pitch; /* in pixels */
int cpp;
void *data;
};
#define IS_R100_CLASS(screen) \
((screen->chip_flags & RADEON_CLASS_MASK) == RADEON_CLASS_R100)
#define IS_R200_CLASS(screen) \