diff options
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_screen.c | 185 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_screen.h | 11 |
2 files changed, 196 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 450e33ef134..1ea52f96d7e 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -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; diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.h b/src/mesa/drivers/dri/radeon/radeon_screen.h index 2b33201a538..417ebf3b067 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.h +++ b/src/mesa/drivers/dri/radeon/radeon_screen.h @@ -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) \ |