summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.c185
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.h11
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) \