dri/nouveau: Implement EXT_texture_from_pixmap.
This commit is contained in:
@@ -168,19 +168,19 @@ nouveau_context_destroy(__DRIcontext *dri_ctx)
|
||||
context_drv(ctx)->context_destroy(ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
nouveau_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable,
|
||||
unsigned int *stamp)
|
||||
void
|
||||
nouveau_update_renderbuffers(__DRIcontext *dri_ctx, __DRIdrawable *draw)
|
||||
{
|
||||
struct nouveau_context *nctx = context->driverPrivate;
|
||||
GLcontext *ctx = &nctx->base;
|
||||
__DRIscreen *screen = context->driScreenPriv;
|
||||
struct gl_framebuffer *fb = drawable->driverPrivate;
|
||||
GLcontext *ctx = dri_ctx->driverPrivate;
|
||||
__DRIscreen *screen = dri_ctx->driScreenPriv;
|
||||
struct gl_framebuffer *fb = draw->driverPrivate;
|
||||
unsigned int attachments[10];
|
||||
__DRIbuffer *buffers = NULL;
|
||||
int i = 0, count, ret;
|
||||
|
||||
*stamp = *drawable->pStamp;
|
||||
if (draw->lastStamp == *draw->pStamp)
|
||||
return;
|
||||
draw->lastStamp = *draw->pStamp;
|
||||
|
||||
attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
|
||||
if (fb->Visual.doubleBufferMode)
|
||||
@@ -192,10 +192,9 @@ nouveau_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable,
|
||||
else if (fb->Visual.haveStencilBuffer)
|
||||
attachments[i++] = __DRI_BUFFER_STENCIL;
|
||||
|
||||
buffers = (*screen->dri2.loader->getBuffers)(drawable,
|
||||
&drawable->w, &drawable->h,
|
||||
buffers = (*screen->dri2.loader->getBuffers)(draw, &draw->w, &draw->h,
|
||||
attachments, i, &count,
|
||||
drawable->loaderPrivate);
|
||||
draw->loaderPrivate);
|
||||
if (buffers == NULL)
|
||||
return;
|
||||
|
||||
@@ -227,8 +226,8 @@ nouveau_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable,
|
||||
rb = fb->Attachment[index].Renderbuffer;
|
||||
s = &to_nouveau_renderbuffer(rb)->surface;
|
||||
|
||||
s->width = drawable->w;
|
||||
s->height = drawable->h;
|
||||
s->width = draw->w;
|
||||
s->height = draw->h;
|
||||
s->pitch = buffers[i].pitch;
|
||||
s->cpp = buffers[i].cpp;
|
||||
|
||||
@@ -244,12 +243,25 @@ nouveau_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable,
|
||||
ret = nouveau_bo_handle_ref(context_dev(ctx),
|
||||
buffers[i].name, &s->bo);
|
||||
assert(!ret);
|
||||
|
||||
context_dirty(ctx, FRAMEBUFFER);
|
||||
}
|
||||
}
|
||||
|
||||
_mesa_resize_framebuffer(ctx, fb, drawable->w, drawable->h);
|
||||
_mesa_resize_framebuffer(NULL, fb, draw->w, draw->h);
|
||||
}
|
||||
|
||||
static void
|
||||
update_framebuffer(__DRIcontext *dri_ctx, __DRIdrawable *draw,
|
||||
int *stamp)
|
||||
{
|
||||
GLcontext *ctx = dri_ctx->driverPrivate;
|
||||
struct gl_framebuffer *fb = draw->driverPrivate;
|
||||
|
||||
*stamp = *draw->pStamp;
|
||||
|
||||
nouveau_update_renderbuffers(dri_ctx, draw);
|
||||
_mesa_resize_framebuffer(ctx, fb, draw->w, draw->h);
|
||||
|
||||
context_dirty(ctx, FRAMEBUFFER);
|
||||
}
|
||||
|
||||
GLboolean
|
||||
@@ -260,16 +272,15 @@ nouveau_context_make_current(__DRIcontext *dri_ctx, __DRIdrawable *dri_draw,
|
||||
struct nouveau_context *nctx = dri_ctx->driverPrivate;
|
||||
GLcontext *ctx = &nctx->base;
|
||||
|
||||
if (dri_draw->driverPrivate == ctx->WinSysDrawBuffer &&
|
||||
dri_read->driverPrivate == ctx->WinSysReadBuffer)
|
||||
return GL_TRUE;
|
||||
|
||||
/* Ask the X server for new renderbuffers. */
|
||||
nouveau_update_renderbuffers(dri_ctx, dri_draw,
|
||||
&nctx->drawable.d_stamp);
|
||||
if (dri_draw != dri_read)
|
||||
nouveau_update_renderbuffers(dri_ctx, dri_read,
|
||||
&nctx->drawable.r_stamp);
|
||||
if (dri_draw->driverPrivate != ctx->WinSysDrawBuffer)
|
||||
update_framebuffer(dri_ctx, dri_draw,
|
||||
&dri_ctx->dri2.draw_stamp);
|
||||
|
||||
if (dri_draw != dri_read &&
|
||||
dri_read->driverPrivate != ctx->WinSysReadBuffer)
|
||||
update_framebuffer(dri_ctx, dri_read,
|
||||
&dri_ctx->dri2.read_stamp);
|
||||
|
||||
/* Pass it down to mesa. */
|
||||
_mesa_make_current(ctx, dri_draw->driverPrivate,
|
||||
@@ -307,30 +318,20 @@ nouveau_fallback(GLcontext *ctx, enum nouveau_fallback mode)
|
||||
void
|
||||
nouveau_validate_framebuffer(GLcontext *ctx)
|
||||
{
|
||||
struct nouveau_context *nctx = to_nouveau_context(ctx);
|
||||
__DRIcontext *dri_ctx = to_nouveau_context(ctx)->dri_context;
|
||||
__DRIdrawable *dri_draw = dri_ctx->driDrawablePriv;
|
||||
__DRIdrawable *dri_read = dri_ctx->driReadablePriv;
|
||||
|
||||
if ((ctx->DrawBuffer->Name == 0 &&
|
||||
nctx->drawable.d_stamp != *dri_draw->pStamp) ||
|
||||
(dri_draw != dri_read &&
|
||||
ctx->ReadBuffer->Name == 0 &&
|
||||
nctx->drawable.r_stamp != *dri_read->pStamp)) {
|
||||
if (nctx->drawable.dirty)
|
||||
ctx->Driver.Flush(ctx);
|
||||
if (ctx->DrawBuffer->Name == 0 &&
|
||||
dri_ctx->dri2.draw_stamp != *dri_draw->pStamp)
|
||||
update_framebuffer(dri_ctx, dri_draw,
|
||||
&dri_ctx->dri2.draw_stamp);
|
||||
|
||||
/* Ask the X server for new renderbuffers. */
|
||||
nouveau_update_renderbuffers(dri_ctx, dri_draw,
|
||||
&nctx->drawable.d_stamp);
|
||||
if (dri_draw != dri_read)
|
||||
nouveau_update_renderbuffers(dri_ctx, dri_read,
|
||||
&nctx->drawable.r_stamp);
|
||||
if (ctx->ReadBuffer->Name == 0 && dri_draw != dri_read &&
|
||||
dri_ctx->dri2.read_stamp != *dri_read->pStamp)
|
||||
update_framebuffer(dri_ctx, dri_read,
|
||||
&dri_ctx->dri2.read_stamp);
|
||||
|
||||
if (nouveau_next_dirty_state(ctx) >= 0)
|
||||
FIRE_RING(context_chan(ctx));
|
||||
}
|
||||
|
||||
/* Someone's planning to draw something really soon. */
|
||||
nctx->drawable.dirty = GL_TRUE;
|
||||
if (nouveau_next_dirty_state(ctx) >= 0)
|
||||
FIRE_RING(context_chan(ctx));
|
||||
}
|
||||
|
||||
@@ -56,12 +56,6 @@ struct nouveau_hw_state {
|
||||
struct nouveau_grobj *sifm;
|
||||
};
|
||||
|
||||
struct nouveau_drawable_state {
|
||||
GLboolean dirty;
|
||||
unsigned int d_stamp;
|
||||
unsigned int r_stamp;
|
||||
};
|
||||
|
||||
struct nouveau_context {
|
||||
GLcontext base;
|
||||
__DRIcontext *dri_context;
|
||||
@@ -73,7 +67,6 @@ struct nouveau_context {
|
||||
struct nouveau_hw_state hw;
|
||||
struct nouveau_bo_state bo;
|
||||
struct nouveau_render_state render;
|
||||
struct nouveau_drawable_state drawable;
|
||||
};
|
||||
|
||||
#define to_nouveau_context(ctx) ((struct nouveau_context *)(ctx))
|
||||
@@ -107,9 +100,11 @@ nouveau_context_deinit(GLcontext *ctx);
|
||||
void
|
||||
nouveau_context_destroy(__DRIcontext *dri_ctx);
|
||||
|
||||
void
|
||||
nouveau_update_renderbuffers(__DRIcontext *dri_ctx, __DRIdrawable *draw);
|
||||
|
||||
GLboolean
|
||||
nouveau_context_make_current(__DRIcontext *dri_ctx,
|
||||
__DRIdrawable *ddraw,
|
||||
nouveau_context_make_current(__DRIcontext *dri_ctx, __DRIdrawable *ddraw,
|
||||
__DRIdrawable *rdraw);
|
||||
|
||||
GLboolean
|
||||
|
||||
@@ -67,8 +67,6 @@ nouveau_flush(GLcontext *ctx)
|
||||
|
||||
dri2->flushFrontBuffer(drawable, drawable->loaderPrivate);
|
||||
}
|
||||
|
||||
nctx->drawable.dirty = GL_FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -142,7 +142,6 @@ nouveau_renderbuffer_dri_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
rb->Width = width;
|
||||
rb->Height = height;
|
||||
|
||||
context_dirty(ctx, FRAMEBUFFER);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "nouveau_driver.h"
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_fbo.h"
|
||||
#include "nouveau_texture.h"
|
||||
#include "nouveau_drmif.h"
|
||||
#include "nv04_driver.h"
|
||||
#include "nv10_driver.h"
|
||||
@@ -226,8 +227,15 @@ static const struct __DRI2flushExtensionRec nouveau_flush_extension = {
|
||||
dri2InvalidateDrawable,
|
||||
};
|
||||
|
||||
static const struct __DRItexBufferExtensionRec nouveau_texbuffer_extension = {
|
||||
{ __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
|
||||
NULL,
|
||||
nouveau_set_texbuffer,
|
||||
};
|
||||
|
||||
static const __DRIextension *nouveau_screen_extensions[] = {
|
||||
&nouveau_flush_extension.base,
|
||||
&nouveau_texbuffer_extension.base,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "nouveau_driver.h"
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_texture.h"
|
||||
#include "nouveau_fbo.h"
|
||||
#include "nouveau_util.h"
|
||||
|
||||
#include "main/texobj.h"
|
||||
@@ -36,6 +37,7 @@
|
||||
#include "main/texgetimage.h"
|
||||
#include "main/mipmap.h"
|
||||
#include "main/texfetch.h"
|
||||
#include "main/teximage.h"
|
||||
|
||||
static struct gl_texture_object *
|
||||
nouveau_texture_new(GLcontext *ctx, GLuint name, GLenum target)
|
||||
@@ -489,6 +491,57 @@ nouveau_bind_texture(GLcontext *ctx, GLenum target,
|
||||
context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
|
||||
}
|
||||
|
||||
static gl_format
|
||||
get_texbuffer_format(struct gl_renderbuffer *rb, GLint format)
|
||||
{
|
||||
struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
|
||||
|
||||
if (s->cpp < 4)
|
||||
return s->format;
|
||||
else if (format == __DRI_TEXTURE_FORMAT_RGBA)
|
||||
return MESA_FORMAT_ARGB8888;
|
||||
else
|
||||
return MESA_FORMAT_XRGB8888;
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_set_texbuffer(__DRIcontext *dri_ctx,
|
||||
GLint target, GLint format,
|
||||
__DRIdrawable *draw)
|
||||
{
|
||||
struct nouveau_context *nctx = dri_ctx->driverPrivate;
|
||||
GLcontext *ctx = &nctx->base;
|
||||
struct gl_framebuffer *fb = draw->driverPrivate;
|
||||
struct gl_renderbuffer *rb =
|
||||
fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
|
||||
struct gl_texture_object *t = _mesa_get_current_tex_object(ctx, target);
|
||||
struct gl_texture_image *ti;
|
||||
struct nouveau_surface *s;
|
||||
|
||||
_mesa_lock_texture(ctx, t);
|
||||
ti = _mesa_get_tex_image(ctx, t, target, 0);
|
||||
s = &to_nouveau_teximage(ti)->surface;
|
||||
|
||||
/* Update the texture surface with the given drawable. */
|
||||
nouveau_update_renderbuffers(dri_ctx, draw);
|
||||
nouveau_surface_ref(&to_nouveau_renderbuffer(rb)->surface, s);
|
||||
|
||||
/* Update the image fields. */
|
||||
_mesa_init_teximage_fields(ctx, target, ti, s->width, s->height,
|
||||
1, 0, s->cpp);
|
||||
ti->RowStride = s->pitch / s->cpp;
|
||||
ti->TexFormat = s->format = get_texbuffer_format(rb, format);
|
||||
|
||||
/* Try to validate it. */
|
||||
if (!validate_teximage(ctx, t, 0, 0, 0, 0, s->width, s->height, 1))
|
||||
nouveau_texture_reallocate(ctx, t);
|
||||
|
||||
context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
|
||||
context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
|
||||
|
||||
_mesa_unlock_texture(ctx, t);
|
||||
}
|
||||
|
||||
static void
|
||||
nouveau_texture_map(GLcontext *ctx, struct gl_texture_object *t)
|
||||
{
|
||||
|
||||
@@ -43,6 +43,11 @@ struct nouveau_texture {
|
||||
#define texture_dirty(t) \
|
||||
to_nouveau_texture(t)->dirty = GL_TRUE;
|
||||
|
||||
void
|
||||
nouveau_set_texbuffer(__DRIcontext *dri_ctx,
|
||||
GLint target, GLint format,
|
||||
__DRIdrawable *draw);
|
||||
|
||||
GLboolean
|
||||
nouveau_texture_validate(GLcontext *ctx, struct gl_texture_object *t);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user