From f806a0336153ec211441a23da0eb8e763e001b02 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Wed, 17 Jun 2009 16:33:14 +0200 Subject: radeon: Flush command buffer on viewport change We flush the command buffer so we don't emit mixed state (with new and previous buffer size) command buffer, this is especialy affecting zbuffer states. --- src/mesa/drivers/dri/radeon/radeon_common.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/mesa/drivers/dri/radeon/radeon_common.c') diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index 466eda784e..32fe4d5645 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -861,6 +861,7 @@ void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei he if (!driContext->driScreenPriv->dri2.enabled) return; + radeonFlush(ctx); radeon_update_renderbuffers(driContext, driContext->driDrawablePriv); if (driContext->driDrawablePriv != driContext->driReadablePriv) radeon_update_renderbuffers(driContext, driContext->driReadablePriv); -- cgit v1.2.3 From b165fa7d45e230f9e61fcf3a09babf0c61c67319 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 18 Jun 2009 13:12:21 +1000 Subject: radeon: don't re-add BOs to validate list if its on the list its on the list don't go readding it. multitexturing from the same texture could cause this. --- src/mesa/drivers/dri/radeon/radeon_common.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/mesa/drivers/dri/radeon/radeon_common.c') diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index 32fe4d5645..7bd4a6f14f 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -999,6 +999,13 @@ void radeon_validate_reset_bos(radeonContextPtr radeon) void radeon_validate_bo(radeonContextPtr radeon, struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain) { + int i; + for (i = 0; i < radeon->state.validated_bo_count; i++) { + if (radeon->state.bos[i].bo == bo && + radeon->state.bos[i].read_domains == read_domains && + radeon->state.bos[i].write_domain == write_domain) + return; + } radeon_bo_ref(bo); radeon->state.bos[radeon->state.validated_bo_count].bo = bo; radeon->state.bos[radeon->state.validated_bo_count].read_domains = read_domains; -- cgit v1.2.3 From c27f21f92d2cf9d23a9edb15d144eceb9ff383bc Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 6 Jul 2009 14:15:00 +1000 Subject: radeon/r200/r300: port to new space checking code in libdrm This moves a big chunk of the space checking code into libdrm so it can be shared by the DDX. --- src/mesa/drivers/dri/r200/Makefile | 8 +- src/mesa/drivers/dri/r200/r200_cmdbuf.c | 8 +- src/mesa/drivers/dri/r200/r200_state.c | 24 +-- src/mesa/drivers/dri/r300/Makefile | 10 +- src/mesa/drivers/dri/r300/r300_ioctl.c | 48 ++++- src/mesa/drivers/dri/r300/r300_texstate.c | 31 +-- src/mesa/drivers/dri/radeon/Makefile | 7 +- src/mesa/drivers/dri/radeon/radeon_bo_drm.h | 8 + src/mesa/drivers/dri/radeon/radeon_bo_legacy.c | 17 +- src/mesa/drivers/dri/radeon/radeon_common.c | 52 +---- src/mesa/drivers/dri/radeon/radeon_common.h | 4 - src/mesa/drivers/dri/radeon/radeon_cs_drm.h | 56 ++++-- src/mesa/drivers/dri/radeon/radeon_cs_legacy.c | 100 --------- src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c | 234 ++++++++++++++++++++++ src/mesa/drivers/dri/radeon/radeon_dma.c | 8 +- src/mesa/drivers/dri/radeon/radeon_state.c | 25 ++- 16 files changed, 417 insertions(+), 223 deletions(-) create mode 100644 src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c (limited to 'src/mesa/drivers/dri/radeon/radeon_common.c') diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile index 6a246edf7c..4605f72a61 100644 --- a/src/mesa/drivers/dri/r200/Makefile +++ b/src/mesa/drivers/dri/r200/Makefile @@ -13,6 +13,10 @@ ifeq ($(USING_EGL), 1) EGL_SOURCES = server/radeon_egl.c endif +ifeq ($(RADEON_LDFLAGS),) +CS_SOURCES = radeon_cs_space_drm.c +endif + RADEON_COMMON_SOURCES = \ radeon_texture.c \ radeon_common_context.c \ @@ -43,6 +47,7 @@ DRIVER_SOURCES = r200_context.c \ radeon_screen.c \ $(EGL_SOURCES) \ $(RADEON_COMMON_SOURCES) + $(CS_SOURCES) C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) @@ -82,7 +87,8 @@ COMMON_SYMLINKS = \ radeon_texture.h \ radeon_dma.c \ radeon_dma.h \ - radeon_fbo.c + radeon_fbo.c \ + $(CS_SOURCES) DRI_LIB_DEPS += $(RADEON_LDFLAGS) diff --git a/src/mesa/drivers/dri/r200/r200_cmdbuf.c b/src/mesa/drivers/dri/r200/r200_cmdbuf.c index df9dd83344..25e30eda52 100644 --- a/src/mesa/drivers/dri/r200/r200_cmdbuf.c +++ b/src/mesa/drivers/dri/r200/r200_cmdbuf.c @@ -225,6 +225,7 @@ GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa, GLuint min_nr ) { GLushort *retval; + int ret; if (R200_DEBUG & DEBUG_IOCTL) fprintf(stderr, "%s %d prim %x\n", __FUNCTION__, min_nr, primitive); @@ -239,10 +240,11 @@ GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa, rmesa->radeon.tcl.elt_dma_offset = 0; rmesa->tcl.elt_used = min_nr * 2; - radeon_validate_bo(&rmesa->radeon, rmesa->radeon.tcl.elt_dma_bo, - RADEON_GEM_DOMAIN_GTT, 0); - if (radeon_revalidate_bos(rmesa->radeon.glCtx) == GL_FALSE) + ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.tcl.elt_dma_bo, + RADEON_GEM_DOMAIN_GTT, 0); + if (ret) { fprintf(stderr,"failure to revalidate BOs - badness\n"); + } radeon_bo_map(rmesa->radeon.tcl.elt_dma_bo, 1); retval = rmesa->radeon.tcl.elt_dma_bo->ptr + rmesa->radeon.tcl.elt_dma_offset; diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index f8ebe0df57..4426f3c3ec 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -2274,23 +2274,23 @@ static GLboolean r200ValidateBuffers(GLcontext *ctx) { r200ContextPtr rmesa = R200_CONTEXT(ctx); struct radeon_renderbuffer *rrb; - int i; + int i, ret; - radeon_validate_reset_bos(&rmesa->radeon); + radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs); rrb = radeon_get_colorbuffer(&rmesa->radeon); /* color buffer */ if (rrb && rrb->bo) { - radeon_validate_bo(&rmesa->radeon, rrb->bo, - 0, RADEON_GEM_DOMAIN_VRAM); + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo, + 0, RADEON_GEM_DOMAIN_VRAM); } /* depth buffer */ rrb = radeon_get_depthbuffer(&rmesa->radeon); /* color buffer */ if (rrb && rrb->bo) { - radeon_validate_bo(&rmesa->radeon, rrb->bo, - 0, RADEON_GEM_DOMAIN_VRAM); + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo, + 0, RADEON_GEM_DOMAIN_VRAM); } for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) { @@ -2301,17 +2301,17 @@ static GLboolean r200ValidateBuffers(GLcontext *ctx) t = radeon_tex_obj(ctx->Texture.Unit[i]._Current); if (t->image_override && t->bo) - radeon_validate_bo(&rmesa->radeon, t->bo, + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); else if (t->mt->bo) - radeon_validate_bo(&rmesa->radeon, t->mt->bo, + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); } - if (rmesa->radeon.dma.current) - radeon_validate_bo(&rmesa->radeon, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0); - - return radeon_revalidate_bos(ctx); + ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0); + if (ret) + return GL_FALSE; + return GL_TRUE; } GLboolean r200ValidateState( GLcontext *ctx ) diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile index bdb09624be..a77209074a 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile @@ -13,6 +13,10 @@ ifeq ($(USING_EGL), 1) EGL_SOURCES = server/radeon_egl.c endif +ifeq ($(RADEON_LDFLAGS),) +CS_SOURCES = radeon_cs_space_drm.c +endif + COMMON_SOURCES = \ ../../common/driverfuncs.c \ ../common/mm.c \ @@ -59,7 +63,8 @@ DRIVER_SOURCES = \ r300_emit.c \ r300_swtcl.c \ $(RADEON_COMMON_SOURCES) \ - $(EGL_SOURCES) + $(EGL_SOURCES) \ + $(CS_SOURCES) C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) @@ -100,7 +105,8 @@ COMMON_SYMLINKS = \ radeon_mipmap_tree.h \ radeon_texture.c \ radeon_texture.h \ - radeon_fbo.c + radeon_fbo.c \ + $(CS_SOURCES) DRI_LIB_DEPS += $(RADEON_LDFLAGS) diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index 104079b4db..4ae0b4504c 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -540,19 +540,50 @@ static void r300EmitClearState(GLcontext * ctx) } } -static void r300KernelClear(GLcontext *ctx, GLuint flags) +static int r300KernelClear(GLcontext *ctx, GLuint flags) { r300ContextPtr r300 = R300_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon); struct radeon_framebuffer *rfb = dPriv->driverPrivate; struct radeon_renderbuffer *rrb; struct radeon_renderbuffer *rrbd; - int bits = 0; + int bits = 0, ret; /* Make sure it fits there. */ + radeon_cs_space_reset_bos(r300->radeon.cmdbuf.cs); + + if (flags & BUFFER_BIT_COLOR0) { + rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_COLOR0); + radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs, + rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM); + } + + if (flags & BUFFER_BIT_FRONT_LEFT) { + rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT); + radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs, + rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM); + } + + if (flags & BUFFER_BIT_BACK_LEFT) { + rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_BACK_LEFT); + radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs, + rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM); + } + + rrbd = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH); + if (rrbd) { + radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs, + rrbd->bo, 0, RADEON_GEM_DOMAIN_VRAM); + } + + ret = radeon_cs_space_check(r300->radeon.cmdbuf.cs); + if (ret) + return -1; + rcommonEnsureCmdBufSpace(&r300->radeon, 421 * 3, __FUNCTION__); if (flags || bits) r300EmitClearState(ctx); + rrbd = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH); if (rrbd && (flags & BUFFER_BIT_DEPTH)) bits |= CLEARBUFFER_DEPTH; @@ -582,6 +613,7 @@ static void r300KernelClear(GLcontext *ctx, GLuint flags) r300ClearBuffer(r300, bits, NULL, rrbd); COMMIT_BATCH(); + return 0; } /** @@ -593,7 +625,7 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) __DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon); const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask); GLbitfield swrast_mask = 0, tri_mask = 0; - int i; + int i, ret; struct gl_framebuffer *fb = ctx->DrawBuffer; if (RADEON_DEBUG & DEBUG_IOCTL) @@ -643,12 +675,18 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) /* SW fallback clearing */ swrast_mask = mask & ~tri_mask; + ret = 0; if (tri_mask) { if (r300->radeon.radeonScreen->kernel_mm) r300UserClear(ctx, tri_mask); - else - r300KernelClear(ctx, tri_mask); + else { + /* if kernel clear fails due to size restraints fallback */ + ret = r300KernelClear(ctx, tri_mask); + if (ret < 0) + swrast_mask |= tri_mask; + } } + if (swrast_mask) { if (RADEON_DEBUG & DEBUG_FALLBACKS) fprintf(stderr, "%s: swrast clear, mask: %x\n", diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c index c380840a00..6f489ace7b 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c @@ -281,21 +281,24 @@ GLboolean r300ValidateBuffers(GLcontext * ctx) r300ContextPtr rmesa = R300_CONTEXT(ctx); struct radeon_renderbuffer *rrb; int i; + int ret; - radeon_validate_reset_bos(&rmesa->radeon); + radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs); rrb = radeon_get_colorbuffer(&rmesa->radeon); /* color buffer */ if (rrb && rrb->bo) { - radeon_validate_bo(&rmesa->radeon, rrb->bo, - 0, RADEON_GEM_DOMAIN_VRAM); + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, + rrb->bo, 0, + RADEON_GEM_DOMAIN_VRAM); } /* depth buffer */ rrb = radeon_get_depthbuffer(&rmesa->radeon); if (rrb && rrb->bo) { - radeon_validate_bo(&rmesa->radeon, rrb->bo, - 0, RADEON_GEM_DOMAIN_VRAM); + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, + rrb->bo, 0, + RADEON_GEM_DOMAIN_VRAM); } for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) { @@ -311,17 +314,19 @@ GLboolean r300ValidateBuffers(GLcontext * ctx) } t = radeon_tex_obj(ctx->Texture.Unit[i]._Current); if (t->image_override && t->bo) - radeon_validate_bo(&rmesa->radeon, t->bo, - RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); - + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, + t->bo, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); else if (t->mt->bo) - radeon_validate_bo(&rmesa->radeon, t->mt->bo, - RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, + t->mt->bo, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); } - if (rmesa->radeon.dma.current) - radeon_validate_bo(&rmesa->radeon, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0); - return radeon_revalidate_bos(ctx); + ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0); + if (ret) + return GL_FALSE; + return GL_TRUE; } void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname, diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile index ba409ba813..b59ad68f44 100644 --- a/src/mesa/drivers/dri/radeon/Makefile +++ b/src/mesa/drivers/dri/radeon/Makefile @@ -10,6 +10,10 @@ LIBNAME = radeon_dri.so MINIGLX_SOURCES = server/radeon_dri.c +ifeq ($(RADEON_LDFLAGS),) +CS_SOURCES = radeon_cs_space_drm.c +endif + RADEON_COMMON_SOURCES = \ radeon_texture.c \ radeon_common_context.c \ @@ -38,7 +42,8 @@ DRIVER_SOURCES = \ C_SOURCES = \ $(COMMON_SOURCES) \ - $(DRIVER_SOURCES) + $(DRIVER_SOURCES) \ + $(CS_SOURCES) DRIVER_DEFINES = -DRADEON_COMMON=0 diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_drm.h b/src/mesa/drivers/dri/radeon/radeon_bo_drm.h index 1ed13f1795..c5c28ed066 100644 --- a/src/mesa/drivers/dri/radeon/radeon_bo_drm.h +++ b/src/mesa/drivers/dri/radeon/radeon_bo_drm.h @@ -68,6 +68,7 @@ struct radeon_bo_funcs { int (*bo_map)(struct radeon_bo *bo, int write); int (*bo_unmap)(struct radeon_bo *bo); int (*bo_wait)(struct radeon_bo *bo); + int (*bo_is_static)(struct radeon_bo *bo); }; struct radeon_bo_manager { @@ -164,6 +165,13 @@ static inline int _radeon_bo_wait(struct radeon_bo *bo, return bo->bom->funcs->bo_wait(bo); } +static inline int radeon_bo_is_static(struct radeon_bo *bo) +{ + if (bo->bom->funcs->bo_is_static) + return bo->bom->funcs->bo_is_static(bo); + return 0; +} + #define radeon_bo_open(bom, h, s, a, d, f)\ _radeon_bo_open(bom, h, s, a, d, f, __FILE__, __FUNCTION__, __LINE__) #define radeon_bo_ref(bo)\ diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c index 6a8da402b1..1fec7444cd 100644 --- a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c +++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c @@ -528,12 +528,21 @@ static int bo_unmap(struct radeon_bo *bo) return 0; } + +static int bo_is_static(struct radeon_bo *bo) +{ + struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; + return bo_legacy->static_bo; +} + static struct radeon_bo_funcs bo_legacy_funcs = { bo_open, bo_ref, bo_unref, bo_map, - bo_unmap + bo_unmap, + NULL, + bo_is_static, }; static int bo_vram_validate(struct radeon_bo *bo, @@ -822,9 +831,3 @@ unsigned radeon_bo_legacy_relocs_size(struct radeon_bo *bo) return bo->size; } -int radeon_legacy_bo_is_static(struct radeon_bo *bo) -{ - struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; - return bo_legacy->static_bo; -} - diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index 7bd4a6f14f..bac72fbdfa 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -964,58 +964,17 @@ static INLINE void radeonEmitAtoms(radeonContextPtr radeon, GLboolean dirty) COMMIT_BATCH(); } -GLboolean radeon_revalidate_bos(GLcontext *ctx) +static GLboolean radeon_revalidate_bos(GLcontext *ctx) { radeonContextPtr radeon = RADEON_CONTEXT(ctx); - int flushed = 0; int ret; -again: - ret = radeon_cs_space_check(radeon->cmdbuf.cs, radeon->state.bos, radeon->state.validated_bo_count); - if (ret == RADEON_CS_SPACE_OP_TO_BIG) + + ret = radeon_cs_space_check(radeon->cmdbuf.cs); + if (ret == RADEON_CS_SPACE_FLUSH) return GL_FALSE; - if (ret == RADEON_CS_SPACE_FLUSH) { - radeonFlush(ctx); - if (flushed) - return GL_FALSE; - flushed = 1; - goto again; - } return GL_TRUE; } -void radeon_validate_reset_bos(radeonContextPtr radeon) -{ - int i; - - for (i = 0; i < radeon->state.validated_bo_count; i++) { - radeon_bo_unref(radeon->state.bos[i].bo); - radeon->state.bos[i].bo = NULL; - radeon->state.bos[i].read_domains = 0; - radeon->state.bos[i].write_domain = 0; - radeon->state.bos[i].new_accounted = 0; - } - radeon->state.validated_bo_count = 0; -} - -void radeon_validate_bo(radeonContextPtr radeon, struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain) -{ - int i; - for (i = 0; i < radeon->state.validated_bo_count; i++) { - if (radeon->state.bos[i].bo == bo && - radeon->state.bos[i].read_domains == read_domains && - radeon->state.bos[i].write_domain == write_domain) - return; - } - radeon_bo_ref(bo); - radeon->state.bos[radeon->state.validated_bo_count].bo = bo; - radeon->state.bos[radeon->state.validated_bo_count].read_domains = read_domains; - radeon->state.bos[radeon->state.validated_bo_count].write_domain = write_domain; - radeon->state.bos[radeon->state.validated_bo_count].new_accounted = 0; - radeon->state.validated_bo_count++; - - assert(radeon->state.validated_bo_count < RADEON_MAX_BOS); -} - void radeonEmitState(radeonContextPtr radeon) { if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS)) @@ -1229,6 +1188,9 @@ void rcommonInitCmdBuf(radeonContextPtr rmesa) assert(rmesa->cmdbuf.cs != NULL); rmesa->cmdbuf.size = size; + radeon_cs_space_set_flush(rmesa->cmdbuf.cs, + (void (*)(void *))radeonFlush, rmesa->glCtx); + if (!rmesa->radeonScreen->kernel_mm) { radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, rmesa->radeonScreen->texSize[0]); radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, rmesa->radeonScreen->gartTextures.size); diff --git a/src/mesa/drivers/dri/radeon/radeon_common.h b/src/mesa/drivers/dri/radeon/radeon_common.h index b60792df0b..ba6c7c5773 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.h +++ b/src/mesa/drivers/dri/radeon/radeon_common.h @@ -47,10 +47,6 @@ void radeon_get_cliprects(radeonContextPtr radeon, struct drm_clip_rect **cliprects, unsigned int *num_cliprects, int *x_off, int *y_off); -GLboolean radeon_revalidate_bos(GLcontext *ctx); -void radeon_validate_bo(radeonContextPtr radeon, struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain); -void radeon_validate_reset_bos(radeonContextPtr radeon); - void radeon_fbo_init(struct radeon_context *radeon); void radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb, diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_drm.h b/src/mesa/drivers/dri/radeon/radeon_cs_drm.h index 984725a6c9..ee403d173c 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cs_drm.h +++ b/src/mesa/drivers/dri/radeon/radeon_cs_drm.h @@ -56,6 +56,8 @@ struct radeon_cs_space_check { uint32_t new_accounted; }; +#define MAX_SPACE_BOS (32) + struct radeon_cs_manager; struct radeon_cs { @@ -72,7 +74,10 @@ struct radeon_cs { const char *section_file; const char *section_func; int section_line; - + struct radeon_cs_space_check bos[MAX_SPACE_BOS]; + int bo_count; + void (*space_flush_fn)(void *); + void *space_flush_data; }; /* cs functions */ @@ -98,16 +103,14 @@ struct radeon_cs_funcs { int (*cs_erase)(struct radeon_cs *cs); int (*cs_need_flush)(struct radeon_cs *cs); void (*cs_print)(struct radeon_cs *cs, FILE *file); - int (*cs_space_check)(struct radeon_cs *cs, struct radeon_cs_space_check *bos, - int num_bo); }; struct radeon_cs_manager { struct radeon_cs_funcs *funcs; int fd; - uint32_t vram_limit, gart_limit; - uint32_t vram_write_used, gart_write_used; - uint32_t read_used; + int32_t vram_limit, gart_limit; + int32_t vram_write_used, gart_write_used; + int32_t read_used; }; static inline struct radeon_cs *radeon_cs_create(struct radeon_cs_manager *csm, @@ -171,13 +174,6 @@ static inline void radeon_cs_print(struct radeon_cs *cs, FILE *file) cs->csm->funcs->cs_print(cs, file); } -static inline int radeon_cs_space_check(struct radeon_cs *cs, - struct radeon_cs_space_check *bos, - int num_bo) -{ - return cs->csm->funcs->cs_space_check(cs, bos, num_bo); -} - static inline void radeon_cs_set_limit(struct radeon_cs *cs, uint32_t domain, uint32_t limit) { @@ -204,4 +200,38 @@ static inline void radeon_cs_write_qword(struct radeon_cs *cs, uint64_t qword) cs->section_cdw+=2; } } + +static inline void radeon_cs_space_set_flush(struct radeon_cs *cs, void (*fn)(void *), void *data) +{ + cs->space_flush_fn = fn; + cs->space_flush_data = data; +} + + +/* + * add a persistent BO to the list + * a persistent BO is one that will be referenced across flushes, + * i.e. colorbuffer, textures etc. + * They get reset when a new "operation" happens, where an operation + * is a state emission with a color/textures etc followed by a bunch of vertices. + */ +void radeon_cs_space_add_persistent_bo(struct radeon_cs *cs, + struct radeon_bo *bo, + uint32_t read_domains, + uint32_t write_domain); + +/* reset the persistent BO list */ +void radeon_cs_space_reset_bos(struct radeon_cs *cs); + +/* do a space check with the current persistent BO list */ +int radeon_cs_space_check(struct radeon_cs *cs); + +/* do a space check with the current persistent BO list and a temporary BO + * a temporary BO is like a DMA buffer, which gets flushed with the + * command buffer */ +int radeon_cs_space_check_with_bo(struct radeon_cs *cs, + struct radeon_bo *bo, + uint32_t read_domains, + uint32_t write_domain); + #endif diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c index ac94789417..f77e22c437 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c +++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c @@ -365,105 +365,6 @@ static void cs_print(struct radeon_cs *cs, FILE *file) { } -static int cs_check_space(struct radeon_cs *cs, struct radeon_cs_space_check *bos, int num_bo) -{ - struct radeon_cs_manager *csm = cs->csm; - int this_op_read = 0, this_op_gart_write = 0, this_op_vram_write = 0; - uint32_t read_domains, write_domain; - int i; - struct radeon_bo *bo; - - /* check the totals for this operation */ - - if (num_bo == 0) - return 0; - - /* prepare */ - for (i = 0; i < num_bo; i++) { - bo = bos[i].bo; - - bos[i].new_accounted = 0; - read_domains = bos[i].read_domains; - write_domain = bos[i].write_domain; - - /* pinned bos don't count */ - if (radeon_legacy_bo_is_static(bo)) - continue; - - /* already accounted this bo */ - if (write_domain && (write_domain == bo->space_accounted)) { - bos[i].new_accounted = bo->space_accounted; - continue; - } - - if (read_domains && ((read_domains << 16) == bo->space_accounted)) { - bos[i].new_accounted = bo->space_accounted; - continue; - } - - if (bo->space_accounted == 0) { - if (write_domain == RADEON_GEM_DOMAIN_VRAM) - this_op_vram_write += bo->size; - else if (write_domain == RADEON_GEM_DOMAIN_GTT) - this_op_gart_write += bo->size; - else - this_op_read += bo->size; - bos[i].new_accounted = (read_domains << 16) | write_domain; - } else { - uint16_t old_read, old_write; - - old_read = bo->space_accounted >> 16; - old_write = bo->space_accounted & 0xffff; - - if (write_domain && (old_read & write_domain)) { - bos[i].new_accounted = write_domain; - /* moving from read to a write domain */ - if (write_domain == RADEON_GEM_DOMAIN_VRAM) { - this_op_read -= bo->size; - this_op_vram_write += bo->size; - } else if (write_domain == RADEON_GEM_DOMAIN_VRAM) { - this_op_read -= bo->size; - this_op_gart_write += bo->size; - } - } else if (read_domains & old_write) { - bos[i].new_accounted = bo->space_accounted & 0xffff; - } else { - /* rewrite the domains */ - if (write_domain != old_write) - fprintf(stderr,"WRITE DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, write_domain, old_write); - if (read_domains != old_read) - fprintf(stderr,"READ DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, read_domains, old_read); - return RADEON_CS_SPACE_FLUSH; - } - } - } - - if (this_op_read < 0) - this_op_read = 0; - - /* check sizes - operation first */ - if ((this_op_read + this_op_gart_write > csm->gart_limit) || - (this_op_vram_write > csm->vram_limit)) { - return RADEON_CS_SPACE_OP_TO_BIG; - } - - if (((csm->vram_write_used + this_op_vram_write) > csm->vram_limit) || - ((csm->read_used + csm->gart_write_used + this_op_gart_write + this_op_read) > csm->gart_limit)) { - return RADEON_CS_SPACE_FLUSH; - } - - csm->gart_write_used += this_op_gart_write; - csm->vram_write_used += this_op_vram_write; - csm->read_used += this_op_read; - /* commit */ - for (i = 0; i < num_bo; i++) { - bo = bos[i].bo; - bo->space_accounted = bos[i].new_accounted; - } - - return RADEON_CS_SPACE_OK; -} - static struct radeon_cs_funcs radeon_cs_legacy_funcs = { cs_create, cs_write_reloc, @@ -474,7 +375,6 @@ static struct radeon_cs_funcs radeon_cs_legacy_funcs = { cs_erase, cs_need_flush, cs_print, - cs_check_space }; struct radeon_cs_manager *radeon_cs_manager_legacy_ctor(struct radeon_context *ctx) diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c b/src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c new file mode 100644 index 0000000000..5a8df7bb8c --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c @@ -0,0 +1,234 @@ +/* + * Copyright © 2009 Red Hat Inc. + * All Rights Reserved. + * + * 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, sub license, 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 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 + * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS + * AND/OR ITS SUPPLIERS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + */ +#include +#include +#include +#include "radeon_bocs_wrapper.h" + +struct rad_sizes { + int32_t op_read; + int32_t op_gart_write; + int32_t op_vram_write; +}; + +static inline int radeon_cs_setup_bo(struct radeon_cs_space_check *sc, struct rad_sizes *sizes) +{ + uint32_t read_domains, write_domain; + struct radeon_bo *bo; + + bo = sc->bo; + sc->new_accounted = 0; + read_domains = sc->read_domains; + write_domain = sc->write_domain; + + /* legacy needs a static check */ + if (radeon_bo_is_static(bo)) { + bo->space_accounted = sc->new_accounted = (read_domains << 16) | write_domain; + return 0; + } + + /* already accounted this bo */ + if (write_domain && (write_domain == bo->space_accounted)) { + sc->new_accounted = bo->space_accounted; + return 0; + } + if (read_domains && ((read_domains << 16) == bo->space_accounted)) { + sc->new_accounted = bo->space_accounted; + return 0; + } + + if (bo->space_accounted == 0) { + if (write_domain == RADEON_GEM_DOMAIN_VRAM) + sizes->op_vram_write += bo->size; + else if (write_domain == RADEON_GEM_DOMAIN_GTT) + sizes->op_gart_write += bo->size; + else + sizes->op_read += bo->size; + sc->new_accounted = (read_domains << 16) | write_domain; + } else { + uint16_t old_read, old_write; + + old_read = bo->space_accounted >> 16; + old_write = bo->space_accounted & 0xffff; + + if (write_domain && (old_read & write_domain)) { + sc->new_accounted = write_domain; + /* moving from read to a write domain */ + if (write_domain == RADEON_GEM_DOMAIN_VRAM) { + sizes->op_read -= bo->size; + sizes->op_vram_write += bo->size; + } else if (write_domain == RADEON_GEM_DOMAIN_VRAM) { + sizes->op_read -= bo->size; + sizes->op_gart_write += bo->size; + } + } else if (read_domains & old_write) { + sc->new_accounted = bo->space_accounted & 0xffff; + } else { + /* rewrite the domains */ + if (write_domain != old_write) + fprintf(stderr,"WRITE DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, write_domain, old_write); + if (read_domains != old_read) + fprintf(stderr,"READ DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, read_domains, old_read); + return RADEON_CS_SPACE_FLUSH; + } + } + return 0; +} + +static int radeon_cs_do_space_check(struct radeon_cs *cs, struct radeon_cs_space_check *new_tmp) +{ + struct radeon_cs_manager *csm = cs->csm; + int i; + struct radeon_bo *bo; + struct rad_sizes sizes; + int ret; + + /* check the totals for this operation */ + + if (cs->bo_count == 0 && !new_tmp) + return 0; + + memset(&sizes, 0, sizeof(struct rad_sizes)); + + /* prepare */ + for (i = 0; i < cs->bo_count; i++) { + ret = radeon_cs_setup_bo(&cs->bos[i], &sizes); + if (ret) + return ret; + } + + if (new_tmp) { + ret = radeon_cs_setup_bo(new_tmp, &sizes); + if (ret) + return ret; + } + + if (sizes.op_read < 0) + sizes.op_read = 0; + + /* check sizes - operation first */ + if ((sizes.op_read + sizes.op_gart_write > csm->gart_limit) || + (sizes.op_vram_write > csm->vram_limit)) { + return RADEON_CS_SPACE_OP_TO_BIG; + } + + if (((csm->vram_write_used + sizes.op_vram_write) > csm->vram_limit) || + ((csm->read_used + csm->gart_write_used + sizes.op_gart_write + sizes.op_read) > csm->gart_limit)) { + return RADEON_CS_SPACE_FLUSH; + } + + csm->gart_write_used += sizes.op_gart_write; + csm->vram_write_used += sizes.op_vram_write; + csm->read_used += sizes.op_read; + /* commit */ + for (i = 0; i < cs->bo_count; i++) { + bo = cs->bos[i].bo; + bo->space_accounted = cs->bos[i].new_accounted; + } + if (new_tmp) + new_tmp->bo->space_accounted = new_tmp->new_accounted; + + return RADEON_CS_SPACE_OK; +} + +void radeon_cs_space_add_persistent_bo(struct radeon_cs *cs, struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain) +{ + int i; + for (i = 0; i < cs->bo_count; i++) { + if (cs->bos[i].bo == bo && + cs->bos[i].read_domains == read_domains && + cs->bos[i].write_domain == write_domain) + return; + } + radeon_bo_ref(bo); + i = cs->bo_count; + cs->bos[i].bo = bo; + cs->bos[i].read_domains = read_domains; + cs->bos[i].write_domain = write_domain; + cs->bos[i].new_accounted = 0; + cs->bo_count++; + + assert(cs->bo_count < MAX_SPACE_BOS); +} + +static int radeon_cs_check_space_internal(struct radeon_cs *cs, struct radeon_cs_space_check *tmp_bo) +{ + int ret; + int flushed = 0; + +again: + ret = radeon_cs_do_space_check(cs, tmp_bo); + if (ret == RADEON_CS_SPACE_OP_TO_BIG) + return -1; + if (ret == RADEON_CS_SPACE_FLUSH) { + (*cs->space_flush_fn)(cs->space_flush_data); + if (flushed) + return -1; + flushed = 1; + goto again; + } + return 0; +} + +int radeon_cs_space_check_with_bo(struct radeon_cs *cs, + struct radeon_bo *bo, + uint32_t read_domains, uint32_t write_domain) +{ + struct radeon_cs_space_check temp_bo; + int ret = 0; + + if (bo) { + temp_bo.bo = bo; + temp_bo.read_domains = read_domains; + temp_bo.write_domain = write_domain; + temp_bo.new_accounted = 0; + } + + ret = radeon_cs_check_space_internal(cs, bo ? &temp_bo : NULL); + return ret; +} + +int radeon_cs_space_check(struct radeon_cs *cs) +{ + return radeon_cs_check_space_internal(cs, NULL); +} + +void radeon_cs_space_reset_bos(struct radeon_cs *cs) +{ + int i; + for (i = 0; i < cs->bo_count; i++) { + radeon_bo_unref(cs->bos[i].bo); + cs->bos[i].bo = NULL; + cs->bos[i].read_domains = 0; + cs->bos[i].write_domain = 0; + cs->bos[i].new_accounted = 0; + } + cs->bo_count = 0; +} + + diff --git a/src/mesa/drivers/dri/radeon/radeon_dma.c b/src/mesa/drivers/dri/radeon/radeon_dma.c index 48b0d63818..dc9a0157f7 100644 --- a/src/mesa/drivers/dri/radeon/radeon_dma.c +++ b/src/mesa/drivers/dri/radeon/radeon_dma.c @@ -198,10 +198,10 @@ again_alloc: rmesa->dma.current_used = 0; rmesa->dma.current_vertexptr = 0; - radeon_validate_bo(rmesa, rmesa->dma.current, RADEON_GEM_DOMAIN_GTT, 0); - - if (radeon_revalidate_bos(rmesa->glCtx) == GL_FALSE) - fprintf(stderr,"failure to revalidate BOs - badness\n"); + if (radeon_cs_space_check_with_bo(rmesa->cmdbuf.cs, + rmesa->dma.current, + RADEON_GEM_DOMAIN_GTT, 0)) + fprintf(stderr,"failure to revalidate BOs - badness\n"); if (!rmesa->dma.current) { /* Cmd buff have been flushed in radeon_revalidate_bos */ diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index 06b8c29936..528348a300 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -2048,23 +2048,23 @@ static GLboolean r100ValidateBuffers(GLcontext *ctx) { r100ContextPtr rmesa = R100_CONTEXT(ctx); struct radeon_renderbuffer *rrb; - int i; + int i, ret; - radeon_validate_reset_bos(&rmesa->radeon); + radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs); rrb = radeon_get_colorbuffer(&rmesa->radeon); /* color buffer */ if (rrb && rrb->bo) { - radeon_validate_bo(&rmesa->radeon, rrb->bo, - 0, RADEON_GEM_DOMAIN_VRAM); + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo, + 0, RADEON_GEM_DOMAIN_VRAM); } /* depth buffer */ rrb = radeon_get_depthbuffer(&rmesa->radeon); /* color buffer */ if (rrb && rrb->bo) { - radeon_validate_bo(&rmesa->radeon, rrb->bo, - 0, RADEON_GEM_DOMAIN_VRAM); + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo, + 0, RADEON_GEM_DOMAIN_VRAM); } for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) { @@ -2075,18 +2075,17 @@ static GLboolean r100ValidateBuffers(GLcontext *ctx) t = radeon_tex_obj(ctx->Texture.Unit[i]._Current); if (t->image_override && t->bo) - radeon_validate_bo(&rmesa->radeon, t->bo, + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); else if (t->mt->bo) - radeon_validate_bo(&rmesa->radeon, t->mt->bo, + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); } - if (rmesa->radeon.dma.current) - radeon_validate_bo(&rmesa->radeon, rmesa->radeon.dma.current, - RADEON_GEM_DOMAIN_GTT, 0); - - return radeon_revalidate_bos(ctx); + ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0); + if (ret) + return GL_FALSE; + return GL_TRUE; } GLboolean radeonValidateState( GLcontext *ctx ) -- cgit v1.2.3 From 95df7bfc03fc63152b241e65bce1f7c73bbf007b Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sun, 5 Jul 2009 16:17:12 +0200 Subject: radeon: fix copy and paste typo --- src/mesa/drivers/dri/radeon/radeon_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/radeon/radeon_common.c') diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index bac72fbdfa..42922732ec 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -713,7 +713,7 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb) } if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) { - rrbStencil = radeon_renderbuffer(fb->_DepthBuffer->Wrapped); + rrbStencil = radeon_renderbuffer(fb->_StencilBuffer->Wrapped); if (rrbStencil && rrbStencil->bo) { radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE); /* need to re-compute stencil hw state */ -- cgit v1.2.3 From 65059606e9a0039fc962869857c5f00a11d6b7cc Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Sat, 11 Jul 2009 20:25:09 +0200 Subject: radeon: Fix scissor rectangle calculation when rendering to FBO. fgl_glxgears -fbo runs, though the gears don't look right yet. --- src/mesa/drivers/dri/radeon/radeon_common.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri/radeon/radeon_common.c') diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index 42922732ec..e9559cc25a 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -221,7 +221,7 @@ void radeonUpdateScissor( GLcontext *ctx ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - if ( radeon_get_drawable(rmesa) ) { + if ( !ctx->DrawBuffer->Name ) { __DRIdrawablePrivate *dPriv = radeon_get_drawable(rmesa); int x = ctx->Scissor.X; @@ -233,9 +233,14 @@ void radeonUpdateScissor( GLcontext *ctx ) rmesa->state.scissor.rect.y1 = y + dPriv->y; rmesa->state.scissor.rect.x2 = w + dPriv->x + 1; rmesa->state.scissor.rect.y2 = h + dPriv->y + 1; - - radeonRecalcScissorRects( rmesa ); + } else { + rmesa->state.scissor.rect.x1 = ctx->Scissor.X; + rmesa->state.scissor.rect.y1 = ctx->Scissor.Y; + rmesa->state.scissor.rect.x2 = ctx->Scissor.X + ctx->Scissor.Width; + rmesa->state.scissor.rect.y2 = ctx->Scissor.Y + ctx->Scissor.Height; } + + radeonRecalcScissorRects( rmesa ); } /* ============================================================= -- cgit v1.2.3 From a10244453c24d62cd87f8c4d85cbe103b62db311 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 12 Jul 2009 17:28:14 +1000 Subject: radeon: update clear code from Intel codebase. This updates some of the clear code from Intel gives a 5x clearspd perf for me here. played openarena also, not sure if the viewport changes broke anything, --- src/mesa/drivers/dri/radeon/radeon_common.c | 101 ++++++++++++++------- .../drivers/dri/radeon/radeon_common_context.h | 8 ++ 2 files changed, 74 insertions(+), 35 deletions(-) (limited to 'src/mesa/drivers/dri/radeon/radeon_common.c') diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index e9559cc25a..f721c630a2 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -45,6 +45,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/glheader.h" #include "main/imports.h" #include "main/context.h" +#include "main/arrayobj.h" #include "main/api_arrayelt.h" #include "main/enums.h" #include "main/colormac.h" @@ -866,10 +867,14 @@ void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei he if (!driContext->driScreenPriv->dri2.enabled) return; - radeonFlush(ctx); - radeon_update_renderbuffers(driContext, driContext->driDrawablePriv); - if (driContext->driDrawablePriv != driContext->driReadablePriv) - radeon_update_renderbuffers(driContext, driContext->driReadablePriv); + if (!radeon->internal_viewport_call && ctx->DrawBuffer->Name == 0) { + if (radeon->is_front_buffer_rendering) { + radeonFlush(ctx); + } + radeon_update_renderbuffers(driContext, driContext->driDrawablePriv); + if (driContext->driDrawablePriv != driContext->driReadablePriv) + radeon_update_renderbuffers(driContext, driContext->driReadablePriv); + } old_viewport = ctx->Driver.Viewport; ctx->Driver.Viewport = NULL; @@ -1256,7 +1261,9 @@ radeon_meta_set_passthrough_transform(radeonContextPtr radeon) radeon->meta.saved_vp_height = ctx->Viewport.Height; radeon->meta.saved_matrix_mode = ctx->Transform.MatrixMode; + radeon->internal_viewport_call = GL_TRUE; _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); + radeon->internal_viewport_call = GL_FALSE; _mesa_MatrixMode(GL_PROJECTION); _mesa_PushMatrix(); @@ -1278,8 +1285,10 @@ radeon_meta_restore_transform(radeonContextPtr radeon) _mesa_MatrixMode(radeon->meta.saved_matrix_mode); + radeon->internal_viewport_call = GL_TRUE; _mesa_Viewport(radeon->meta.saved_vp_x, radeon->meta.saved_vp_y, radeon->meta.saved_vp_width, radeon->meta.saved_vp_height); + radeon->internal_viewport_call = GL_FALSE; } @@ -1292,31 +1301,60 @@ radeon_meta_restore_transform(radeonContextPtr radeon) * it. */ +static void radeon_clear_init(GLcontext *ctx) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct gl_array_object *arraySave = NULL; + const GLuint arrayBuffer = ctx->Array.ArrayBufferObj->Name; + const GLuint elementBuffer = ctx->Array.ElementArrayBufferObj->Name; + + /* create new array object */ + rmesa->clear.arrayObj = _mesa_new_array_object(ctx, ~0); + _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj); + _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, rmesa->clear.arrayObj); + + /* one time setup of vertex arrays (pos, color) */ + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), rmesa->clear.color); + _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), rmesa->clear.vertices); + _mesa_Enable(GL_COLOR_ARRAY); + _mesa_Enable(GL_VERTEX_ARRAY); + + /* restore original array object */ + _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave); + _mesa_reference_array_object(ctx, &arraySave, NULL); + + /* restore original buffer objects */ + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, arrayBuffer); + _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, elementBuffer); +} + void radeon_clear_tris(GLcontext *ctx, GLbitfield mask) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat vertices[4][3]; - GLfloat color[4][4]; GLfloat dst_z; struct gl_framebuffer *fb = ctx->DrawBuffer; int i; GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE; GLboolean saved_shader_program = 0; unsigned int saved_active_texture; + struct gl_array_object *arraySave = NULL; + + if (!rmesa->clear.arrayObj) + radeon_clear_init(ctx); assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) == 0); _mesa_PushAttrib(GL_COLOR_BUFFER_BIT | - GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT | GL_STENCIL_BUFFER_BIT | GL_TRANSFORM_BIT | GL_CURRENT_BIT); - _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); saved_active_texture = ctx->Texture.CurrentUnit; /* Disable existing GL state we don't want to apply to a clear. */ @@ -1367,18 +1405,14 @@ void radeon_clear_tris(GLcontext *ctx, GLbitfield mask) } } -#if FEATURE_ARB_vertex_buffer_object - _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); -#endif + /* save current array object, bind our private one */ + _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj); + _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, rmesa->clear.arrayObj); radeon_meta_set_passthrough_transform(rmesa); for (i = 0; i < 4; i++) { - color[i][0] = ctx->Color.ClearColor[0]; - color[i][1] = ctx->Color.ClearColor[1]; - color[i][2] = ctx->Color.ClearColor[2]; - color[i][3] = ctx->Color.ClearColor[3]; + COPY_4FV(rmesa->clear.color[i], ctx->Color.ClearColor); } /* convert clear Z from [0,1] to NDC coord in [-1,1] */ @@ -1387,23 +1421,18 @@ void radeon_clear_tris(GLcontext *ctx, GLbitfield mask) /* Prepare the vertices, which are the same regardless of which buffer we're * drawing to. */ - vertices[0][0] = fb->_Xmin; - vertices[0][1] = fb->_Ymin; - vertices[0][2] = dst_z; - vertices[1][0] = fb->_Xmax; - vertices[1][1] = fb->_Ymin; - vertices[1][2] = dst_z; - vertices[2][0] = fb->_Xmax; - vertices[2][1] = fb->_Ymax; - vertices[2][2] = dst_z; - vertices[3][0] = fb->_Xmin; - vertices[3][1] = fb->_Ymax; - vertices[3][2] = dst_z; - - _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &color); - _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), &vertices); - _mesa_Enable(GL_COLOR_ARRAY); - _mesa_Enable(GL_VERTEX_ARRAY); + rmesa->clear.vertices[0][0] = fb->_Xmin; + rmesa->clear.vertices[0][1] = fb->_Ymin; + rmesa->clear.vertices[0][2] = dst_z; + rmesa->clear.vertices[1][0] = fb->_Xmax; + rmesa->clear.vertices[1][1] = fb->_Ymin; + rmesa->clear.vertices[1][2] = dst_z; + rmesa->clear.vertices[2][0] = fb->_Xmax; + rmesa->clear.vertices[2][1] = fb->_Ymax; + rmesa->clear.vertices[2][2] = dst_z; + rmesa->clear.vertices[3][0] = fb->_Xmin; + rmesa->clear.vertices[3][1] = fb->_Ymax; + rmesa->clear.vertices[3][2] = dst_z; while (mask != 0) { GLuint this_mask = 0; @@ -1449,7 +1478,7 @@ void radeon_clear_tris(GLcontext *ctx, GLbitfield mask) _mesa_Disable(GL_STENCIL_TEST); } - CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); mask &= ~this_mask; } @@ -1465,6 +1494,8 @@ void radeon_clear_tris(GLcontext *ctx, GLbitfield mask) if (saved_shader_program) _mesa_UseProgramObjectARB(saved_shader_program); - _mesa_PopClientAttrib(); _mesa_PopAttrib(); + /* restore current array object */ + _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave); + _mesa_reference_array_object(ctx, &arraySave, NULL); } diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h index b607fad87b..8781715af0 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h @@ -467,6 +467,14 @@ struct radeon_context { */ GLboolean is_front_buffer_rendering; + /* info for radeon_clear_tris() */ + struct { + struct gl_array_object *arrayObj; + GLfloat vertices[4][3]; + GLfloat color[4][4]; + } clear; + GLboolean internal_viewport_call; + struct { struct gl_fragment_program *bitmap_fp; struct gl_vertex_program *passthrough_vp; -- cgit v1.2.3 From a79aefb1775ce6eaf0fd0cf9a1f72150f631c90f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 13 Jul 2009 23:09:17 +1000 Subject: radeon: Use Stencil.Enabled instead of Stencil._Enabled in DrawBuffers. The _Enabled field isn't updated at the point that DrawBuffers is called, and the Driver.Enable() function does the testing for stencil buffer presence anyway. --- src/mesa/drivers/dri/radeon/radeon_common.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri/radeon/radeon_common.c') diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index f721c630a2..3b8541a74a 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -751,9 +751,8 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb) ctx->Driver.Enable(ctx, GL_DEPTH_TEST, (ctx->Depth.Test && fb->Visual.depthBits > 0)); /* Need to update the derived ctx->Stencil._Enabled first */ - _mesa_update_stencil(ctx); ctx->Driver.Enable(ctx, GL_STENCIL_TEST, - (ctx->Stencil._Enabled && fb->Visual.stencilBits > 0)); + (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0)); } else { ctx->NewState |= (_NEW_DEPTH | _NEW_STENCIL); } -- cgit v1.2.3 From bb4c70358778f28f644ae493b5d8163e76e9fddb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 14 Jul 2009 01:22:17 +1000 Subject: radeon: port more front fixes from intel. Port fixes to read buffer from front. --- src/mesa/drivers/dri/radeon/radeon_common.c | 11 +++++++++++ src/mesa/drivers/dri/radeon/radeon_common_context.c | 5 ++++- src/mesa/drivers/dri/radeon/radeon_common_context.h | 9 +++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/radeon/radeon_common.c') diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index 3b8541a74a..08535180b8 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -823,6 +823,17 @@ void radeonDrawBuffer( GLcontext *ctx, GLenum mode ) void radeonReadBuffer( GLcontext *ctx, GLenum mode ) { + if ((ctx->DrawBuffer != NULL) && (ctx->DrawBuffer->Name == 0)) { + struct radeon_context *const rmesa = RADEON_CONTEXT(ctx); + const GLboolean was_front_buffer_reading = rmesa->is_front_buffer_reading; + rmesa->is_front_buffer_reading = (mode == GL_FRONT_LEFT) + || (mode == GL_FRONT); + + if (!was_front_buffer_reading && rmesa->is_front_buffer_reading) { + radeon_update_renderbuffers(rmesa->dri.context, + rmesa->dri.context->driReadablePriv); + } + } /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */ if (ctx->ReadBuffer == ctx->DrawBuffer) { /* This will update FBO completeness status. diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c index 94bda78ce3..828d6477f0 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c @@ -487,7 +487,10 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) struct radeon_renderbuffer *stencil_rb; i = 0; - if (draw->color_rb[0]) { + if ((radeon->is_front_buffer_rendering || + radeon->is_front_buffer_reading || + !draw->color_rb[1]) + && draw->color_rb[0]) { attachments[i++] = __DRI_BUFFER_FRONT_LEFT; attachments[i++] = radeon_bits_per_pixel(draw->color_rb[0]); } diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h index 8781715af0..036d2658d9 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h @@ -467,6 +467,15 @@ struct radeon_context { */ GLboolean is_front_buffer_rendering; + /** + * Track whether front-buffer is the current read target. + * + * This is closely associated with is_front_buffer_rendering, but may + * be set separately. The DRI2 fake front buffer must be referenced + * either way. + */ + GLboolean is_front_buffer_reading; + /* info for radeon_clear_tris() */ struct { struct gl_array_object *arrayObj; -- cgit v1.2.3 From 681ede8836746735fbb904edf89b076343507a8b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 15 Jul 2009 07:10:45 +1000 Subject: radeon: fix unsigned vs signed comparison in stencil code. This function takes a GLint not a GLuint, passing in -1 breaks internally. --- src/mesa/drivers/dri/radeon/radeon_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/radeon/radeon_common.c') diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index 08535180b8..0a8d8b03e8 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -1482,7 +1482,7 @@ void radeon_clear_tris(GLcontext *ctx, GLbitfield mask) if (this_mask & BUFFER_BIT_STENCIL) { _mesa_Enable(GL_STENCIL_TEST); _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); - _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, ctx->Stencil.Clear, + _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, (GLint)ctx->Stencil.Clear, ctx->Stencil.WriteMask[0]); } else { _mesa_Disable(GL_STENCIL_TEST); -- cgit v1.2.3 From f6f0e117a45a64464e49290ebc9f75b9a976070a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 15 Jul 2009 09:35:09 +1000 Subject: intel/radeon: add common metaops code. Move all the metaops to a dri_metaops file and port radeon/intel to use the new common meta ops code. --- src/mesa/drivers/dri/Makefile.template | 3 +- src/mesa/drivers/dri/common/dri_metaops.c | 541 +++++++++++++++++++++ src/mesa/drivers/dri/common/dri_metaops.h | 99 ++++ src/mesa/drivers/dri/intel/intel_clear.c | 247 +--------- src/mesa/drivers/dri/intel/intel_context.c | 6 +- src/mesa/drivers/dri/intel/intel_context.h | 33 +- src/mesa/drivers/dri/intel/intel_generatemipmap.c | 18 +- src/mesa/drivers/dri/intel/intel_pixel.c | 251 ---------- src/mesa/drivers/dri/intel/intel_pixel.h | 15 - src/mesa/drivers/dri/intel/intel_pixel_bitmap.c | 16 +- src/mesa/drivers/dri/intel/intel_pixel_draw.c | 16 +- src/mesa/drivers/dri/r200/r200_ioctl.c | 7 +- src/mesa/drivers/dri/r300/r300_ioctl.c | 7 +- src/mesa/drivers/dri/radeon/radeon_common.c | 252 +--------- src/mesa/drivers/dri/radeon/radeon_common.h | 13 +- .../drivers/dri/radeon/radeon_common_context.c | 3 +- .../drivers/dri/radeon/radeon_common_context.h | 23 +- src/mesa/drivers/dri/radeon/radeon_ioctl.c | 5 - 18 files changed, 684 insertions(+), 871 deletions(-) create mode 100644 src/mesa/drivers/dri/common/dri_metaops.c create mode 100644 src/mesa/drivers/dri/common/dri_metaops.h (limited to 'src/mesa/drivers/dri/radeon/radeon_common.c') diff --git a/src/mesa/drivers/dri/Makefile.template b/src/mesa/drivers/dri/Makefile.template index bd38e3be47..18dbeba24a 100644 --- a/src/mesa/drivers/dri/Makefile.template +++ b/src/mesa/drivers/dri/Makefile.template @@ -11,7 +11,8 @@ COMMON_GALLIUM_SOURCES = \ COMMON_SOURCES = $(COMMON_GALLIUM_SOURCES) \ ../../common/driverfuncs.c \ ../common/texmem.c \ - ../common/drirenderbuffer.c + ../common/drirenderbuffer.c \ + ../common/dri_metaops.c ifeq ($(WINDOW_SYSTEM),dri) WINOBJ= diff --git a/src/mesa/drivers/dri/common/dri_metaops.c b/src/mesa/drivers/dri/common/dri_metaops.c new file mode 100644 index 0000000000..fe183c2e87 --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_metaops.c @@ -0,0 +1,541 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009 Intel Corporation. + * All Rights Reserved. + * + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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 "main/arrayobj.h" +#include "main/attrib.h" +#include "main/blend.h" +#include "main/bufferobj.h" +#include "main/buffers.h" +#include "main/depth.h" +#include "main/enable.h" +#include "main/matrix.h" +#include "main/macros.h" +#include "main/polygon.h" +#include "main/shaders.h" +#include "main/stencil.h" +#include "main/texstate.h" +#include "main/varray.h" +#include "main/viewport.h" +#include "shader/arbprogram.h" +#include "shader/program.h" +#include "dri_metaops.h" + +void +meta_set_passthrough_transform(struct dri_metaops *meta) +{ + GLcontext *ctx = meta->ctx; + + meta->saved_vp_x = ctx->Viewport.X; + meta->saved_vp_y = ctx->Viewport.Y; + meta->saved_vp_width = ctx->Viewport.Width; + meta->saved_vp_height = ctx->Viewport.Height; + meta->saved_matrix_mode = ctx->Transform.MatrixMode; + + meta->internal_viewport_call = GL_TRUE; + _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); + meta->internal_viewport_call = GL_FALSE; + + _mesa_MatrixMode(GL_PROJECTION); + _mesa_PushMatrix(); + _mesa_LoadIdentity(); + _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1); + + _mesa_MatrixMode(GL_MODELVIEW); + _mesa_PushMatrix(); + _mesa_LoadIdentity(); +} + +void +meta_restore_transform(struct dri_metaops *meta) +{ + _mesa_MatrixMode(GL_PROJECTION); + _mesa_PopMatrix(); + _mesa_MatrixMode(GL_MODELVIEW); + _mesa_PopMatrix(); + + _mesa_MatrixMode(meta->saved_matrix_mode); + + meta->internal_viewport_call = GL_TRUE; + _mesa_Viewport(meta->saved_vp_x, meta->saved_vp_y, + meta->saved_vp_width, meta->saved_vp_height); + meta->internal_viewport_call = GL_FALSE; +} + + +/** + * Set up a vertex program to pass through the position and first texcoord + * for pixel path. + */ +void +meta_set_passthrough_vertex_program(struct dri_metaops *meta) +{ + GLcontext *ctx = meta->ctx; + static const char *vp = + "!!ARBvp1.0\n" + "TEMP vertexClip;\n" + "DP4 vertexClip.x, state.matrix.mvp.row[0], vertex.position;\n" + "DP4 vertexClip.y, state.matrix.mvp.row[1], vertex.position;\n" + "DP4 vertexClip.z, state.matrix.mvp.row[2], vertex.position;\n" + "DP4 vertexClip.w, state.matrix.mvp.row[3], vertex.position;\n" + "MOV result.position, vertexClip;\n" + "MOV result.texcoord[0], vertex.texcoord[0];\n" + "MOV result.color, vertex.color;\n" + "END\n"; + + assert(meta->saved_vp == NULL); + + _mesa_reference_vertprog(ctx, &meta->saved_vp, + ctx->VertexProgram.Current); + if (meta->passthrough_vp == NULL) { + GLuint prog_name; + _mesa_GenPrograms(1, &prog_name); + _mesa_BindProgram(GL_VERTEX_PROGRAM_ARB, prog_name); + _mesa_ProgramStringARB(GL_VERTEX_PROGRAM_ARB, + GL_PROGRAM_FORMAT_ASCII_ARB, + strlen(vp), (const GLubyte *)vp); + _mesa_reference_vertprog(ctx, &meta->passthrough_vp, + ctx->VertexProgram.Current); + _mesa_DeletePrograms(1, &prog_name); + } + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, + meta->passthrough_vp); + ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, + &meta->passthrough_vp->Base); + + meta->saved_vp_enable = ctx->VertexProgram.Enabled; + _mesa_Enable(GL_VERTEX_PROGRAM_ARB); +} + +/** + * Restores the previous vertex program after + * meta_set_passthrough_vertex_program() + */ +void +meta_restore_vertex_program(struct dri_metaops *meta) +{ + GLcontext *ctx = meta->ctx; + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, + meta->saved_vp); + _mesa_reference_vertprog(ctx, &meta->saved_vp, NULL); + ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, + &ctx->VertexProgram.Current->Base); + + if (!meta->saved_vp_enable) + _mesa_Disable(GL_VERTEX_PROGRAM_ARB); +} + +/** + * Binds the given program string to GL_FRAGMENT_PROGRAM_ARB, caching the + * program object. + */ +void +meta_set_fragment_program(struct dri_metaops *meta, + struct gl_fragment_program **prog, + const char *prog_string) +{ + GLcontext *ctx = meta->ctx; + assert(meta->saved_fp == NULL); + + _mesa_reference_fragprog(ctx, &meta->saved_fp, + ctx->FragmentProgram.Current); + if (*prog == NULL) { + GLuint prog_name; + _mesa_GenPrograms(1, &prog_name); + _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, prog_name); + _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, + GL_PROGRAM_FORMAT_ASCII_ARB, + strlen(prog_string), (const GLubyte *)prog_string); + _mesa_reference_fragprog(ctx, prog, ctx->FragmentProgram.Current); + /* Note that DeletePrograms unbinds the program on us */ + _mesa_DeletePrograms(1, &prog_name); + } + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, *prog); + ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, &((*prog)->Base)); + + meta->saved_fp_enable = ctx->FragmentProgram.Enabled; + _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); +} + +/** + * Restores the previous fragment program after + * meta_set_fragment_program() + */ +void +meta_restore_fragment_program(struct dri_metaops *meta) +{ + GLcontext *ctx = meta->ctx; + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, + meta->saved_fp); + _mesa_reference_fragprog(ctx, &meta->saved_fp, NULL); + ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, + &ctx->FragmentProgram.Current->Base); + + if (!meta->saved_fp_enable) + _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); +} + +static const float default_texcoords[4][2] = { { 0.0, 0.0 }, + { 1.0, 0.0 }, + { 1.0, 1.0 }, + { 0.0, 1.0 } }; + +void +meta_set_default_texrect(struct dri_metaops *meta) +{ + GLcontext *ctx = meta->ctx; + struct gl_client_array *old_texcoord_array; + + meta->saved_active_texture = ctx->Texture.CurrentUnit; + if (meta->saved_array_vbo == NULL) { + _mesa_reference_buffer_object(ctx, &meta->saved_array_vbo, + ctx->Array.ArrayBufferObj); + } + + old_texcoord_array = &ctx->Array.ArrayObj->TexCoord[0]; + meta->saved_texcoord_type = old_texcoord_array->Type; + meta->saved_texcoord_size = old_texcoord_array->Size; + meta->saved_texcoord_stride = old_texcoord_array->Stride; + meta->saved_texcoord_enable = old_texcoord_array->Enabled; + meta->saved_texcoord_ptr = old_texcoord_array->Ptr; + _mesa_reference_buffer_object(ctx, &meta->saved_texcoord_vbo, + old_texcoord_array->BufferObj); + + _mesa_ClientActiveTextureARB(GL_TEXTURE0); + + if (meta->texcoord_vbo == NULL) { + GLuint vbo_name; + + _mesa_GenBuffersARB(1, &vbo_name); + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_name); + _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(default_texcoords), + default_texcoords, GL_STATIC_DRAW_ARB); + _mesa_reference_buffer_object(ctx, &meta->texcoord_vbo, + ctx->Array.ArrayBufferObj); + } else { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, + meta->texcoord_vbo->Name); + } + _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), NULL); + + _mesa_Enable(GL_TEXTURE_COORD_ARRAY); +} + +void +meta_restore_texcoords(struct dri_metaops *meta) +{ + GLcontext *ctx = meta->ctx; + + /* Restore the old TexCoordPointer */ + if (meta->saved_texcoord_vbo) { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, + meta->saved_texcoord_vbo->Name); + _mesa_reference_buffer_object(ctx, &meta->saved_texcoord_vbo, NULL); + } else { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + } + + _mesa_TexCoordPointer(meta->saved_texcoord_size, + meta->saved_texcoord_type, + meta->saved_texcoord_stride, + meta->saved_texcoord_ptr); + if (!meta->saved_texcoord_enable) + _mesa_Disable(GL_TEXTURE_COORD_ARRAY); + + _mesa_ClientActiveTextureARB(GL_TEXTURE0 + + meta->saved_active_texture); + + if (meta->saved_array_vbo) { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, + meta->saved_array_vbo->Name); + _mesa_reference_buffer_object(ctx, &meta->saved_array_vbo, NULL); + } else { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + } +} + + +/** + * Perform glClear where mask contains only color, depth, and/or stencil. + * + * The implementation is based on calling into Mesa to set GL state and + * performing normal triangle rendering. The intent of this path is to + * have as generic a path as possible, so that any driver could make use of + * it. + */ + +/** + * Per-context one-time init of things for intl_clear_tris(). + * Basically set up a private array object for vertex/color arrays. + */ +static void +meta_init_clear(struct dri_metaops *meta) +{ + GLcontext *ctx = meta->ctx; + struct gl_array_object *arraySave = NULL; + const GLuint arrayBuffer = ctx->Array.ArrayBufferObj->Name; + const GLuint elementBuffer = ctx->Array.ElementArrayBufferObj->Name; + + /* create new array object */ + meta->clear.arrayObj = _mesa_new_array_object(ctx, ~0); + + /* save current array object, bind new one */ + _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj); + ctx->NewState |= _NEW_ARRAY; + ctx->Array.NewState |= _NEW_ARRAY_ALL; + _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, meta->clear.arrayObj); + + /* one-time setup of vertex arrays (pos, color) */ + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), meta->clear.color); + _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), meta->clear.vertices); + _mesa_Enable(GL_COLOR_ARRAY); + _mesa_Enable(GL_VERTEX_ARRAY); + + /* restore original array object */ + ctx->NewState |= _NEW_ARRAY; + ctx->Array.NewState |= _NEW_ARRAY_ALL; + _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave); + _mesa_reference_array_object(ctx, &arraySave, NULL); + + /* restore original buffer objects */ + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, arrayBuffer); + _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, elementBuffer); +} + + + +/** + * Perform glClear where mask contains only color, depth, and/or stencil. + * + * The implementation is based on calling into Mesa to set GL state and + * performing normal triangle rendering. The intent of this path is to + * have as generic a path as possible, so that any driver could make use of + * it. + */ +void +meta_clear_tris(struct dri_metaops *meta, GLbitfield mask) +{ + GLcontext *ctx = meta->ctx; + GLfloat dst_z; + struct gl_framebuffer *fb = ctx->DrawBuffer; + int i; + GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE; + GLuint saved_shader_program = 0; + unsigned int saved_active_texture; + struct gl_array_object *arraySave = NULL; + + if (!meta->clear.arrayObj) + meta_init_clear(meta); + + assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH | + BUFFER_BIT_STENCIL)) == 0); + + _mesa_PushAttrib(GL_COLOR_BUFFER_BIT | + GL_DEPTH_BUFFER_BIT | + GL_ENABLE_BIT | + GL_POLYGON_BIT | + GL_STENCIL_BUFFER_BIT | + GL_TRANSFORM_BIT | + GL_CURRENT_BIT | + GL_VIEWPORT_BIT); + saved_active_texture = ctx->Texture.CurrentUnit; + + /* Disable existing GL state we don't want to apply to a clear. */ + _mesa_Disable(GL_ALPHA_TEST); + _mesa_Disable(GL_BLEND); + _mesa_Disable(GL_CULL_FACE); + _mesa_Disable(GL_FOG); + _mesa_Disable(GL_POLYGON_SMOOTH); + _mesa_Disable(GL_POLYGON_STIPPLE); + _mesa_Disable(GL_POLYGON_OFFSET_FILL); + _mesa_Disable(GL_LIGHTING); + _mesa_Disable(GL_CLIP_PLANE0); + _mesa_Disable(GL_CLIP_PLANE1); + _mesa_Disable(GL_CLIP_PLANE2); + _mesa_Disable(GL_CLIP_PLANE3); + _mesa_Disable(GL_CLIP_PLANE4); + _mesa_Disable(GL_CLIP_PLANE5); + _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL); + if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) { + saved_fp_enable = GL_TRUE; + _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); + } + if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) { + saved_vp_enable = GL_TRUE; + _mesa_Disable(GL_VERTEX_PROGRAM_ARB); + } + if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) { + saved_shader_program = ctx->Shader.CurrentProgram->Name; + _mesa_UseProgramObjectARB(0); + } + + if (ctx->Texture._EnabledUnits != 0) { + int i; + + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { + _mesa_ActiveTextureARB(GL_TEXTURE0 + i); + _mesa_Disable(GL_TEXTURE_1D); + _mesa_Disable(GL_TEXTURE_2D); + _mesa_Disable(GL_TEXTURE_3D); + if (ctx->Extensions.ARB_texture_cube_map) + _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB); + if (ctx->Extensions.NV_texture_rectangle) + _mesa_Disable(GL_TEXTURE_RECTANGLE_NV); + if (ctx->Extensions.MESA_texture_array) { + _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT); + _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT); + } + } + } + + /* save current array object, bind our private one */ + _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj); + ctx->NewState |= _NEW_ARRAY; + ctx->Array.NewState |= _NEW_ARRAY_ALL; + _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, meta->clear.arrayObj); + + meta_set_passthrough_transform(meta); + + for (i = 0; i < 4; i++) { + COPY_4FV(meta->clear.color[i], ctx->Color.ClearColor); + } + + /* convert clear Z from [0,1] to NDC coord in [-1,1] */ + dst_z = -1.0 + 2.0 * ctx->Depth.Clear; + + /* The ClearDepth value is unaffected by DepthRange, so do a default + * mapping. + */ + _mesa_DepthRange(0.0, 1.0); + + /* Prepare the vertices, which are the same regardless of which buffer we're + * drawing to. + */ + meta->clear.vertices[0][0] = fb->_Xmin; + meta->clear.vertices[0][1] = fb->_Ymin; + meta->clear.vertices[0][2] = dst_z; + meta->clear.vertices[1][0] = fb->_Xmax; + meta->clear.vertices[1][1] = fb->_Ymin; + meta->clear.vertices[1][2] = dst_z; + meta->clear.vertices[2][0] = fb->_Xmax; + meta->clear.vertices[2][1] = fb->_Ymax; + meta->clear.vertices[2][2] = dst_z; + meta->clear.vertices[3][0] = fb->_Xmin; + meta->clear.vertices[3][1] = fb->_Ymax; + meta->clear.vertices[3][2] = dst_z; + + while (mask != 0) { + GLuint this_mask = 0; + GLuint color_bit; + + color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS); + if (color_bit != 0) + this_mask |= (1 << (color_bit - 1)); + + /* Clear depth/stencil in the same pass as color. */ + this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)); + + /* Select the current color buffer and use the color write mask if + * we have one, otherwise don't write any color channels. + */ + if (this_mask & BUFFER_BIT_FRONT_LEFT) + _mesa_DrawBuffer(GL_FRONT_LEFT); + else if (this_mask & BUFFER_BIT_BACK_LEFT) + _mesa_DrawBuffer(GL_BACK_LEFT); + else if (color_bit != 0) + _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 + + (color_bit - BUFFER_COLOR0 - 1)); + else + _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + + /* Control writing of the depth clear value to depth. */ + if (this_mask & BUFFER_BIT_DEPTH) { + _mesa_DepthFunc(GL_ALWAYS); + _mesa_Enable(GL_DEPTH_TEST); + } else { + _mesa_Disable(GL_DEPTH_TEST); + _mesa_DepthMask(GL_FALSE); + } + + /* Control writing of the stencil clear value to stencil. */ + if (this_mask & BUFFER_BIT_STENCIL) { + _mesa_Enable(GL_STENCIL_TEST); + _mesa_StencilOpSeparate(GL_FRONT_AND_BACK, + GL_REPLACE, GL_REPLACE, GL_REPLACE); + _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, + ctx->Stencil.Clear & 0x7fffffff, + ctx->Stencil.WriteMask[0]); + } else { + _mesa_Disable(GL_STENCIL_TEST); + } + + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); + + mask &= ~this_mask; + } + + meta_restore_transform(meta); + + _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture); + if (saved_fp_enable) + _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); + if (saved_vp_enable) + _mesa_Enable(GL_VERTEX_PROGRAM_ARB); + + if (saved_shader_program) + _mesa_UseProgramObjectARB(saved_shader_program); + + _mesa_PopAttrib(); + + /* restore current array object */ + ctx->NewState |= _NEW_ARRAY; + ctx->Array.NewState |= _NEW_ARRAY_ALL; + _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave); + _mesa_reference_array_object(ctx, &arraySave, NULL); +} + +void meta_init_metaops(GLcontext *ctx, struct dri_metaops *meta) +{ + meta->ctx = ctx; +} + +void meta_destroy_metaops(struct dri_metaops *meta) +{ + if (meta->clear.arrayObj) + _mesa_delete_array_object(meta->ctx, meta->clear.arrayObj); + +} diff --git a/src/mesa/drivers/dri/common/dri_metaops.h b/src/mesa/drivers/dri/common/dri_metaops.h new file mode 100644 index 0000000000..bb4079d535 --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_metaops.h @@ -0,0 +1,99 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009 Intel Corporation. + * All Rights Reserved. + * + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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. + * + **************************************************************************/ +#ifndef DRI_METAOPS_H +#define DRI_METAOPS_H + +#define TRI_CLEAR_COLOR_BITS (BUFFER_BIT_BACK_LEFT | \ + BUFFER_BIT_FRONT_LEFT | \ + BUFFER_BIT_COLOR0 | \ + BUFFER_BIT_COLOR1 | \ + BUFFER_BIT_COLOR2 | \ + BUFFER_BIT_COLOR3 | \ + BUFFER_BIT_COLOR4 | \ + BUFFER_BIT_COLOR5 | \ + BUFFER_BIT_COLOR6 | \ + BUFFER_BIT_COLOR7) + +struct dri_meta_clear { + struct gl_array_object *arrayObj; + GLfloat vertices[4][3]; + GLfloat color[4][4]; +}; + +struct dri_metaops { + GLcontext *ctx; + GLboolean internal_viewport_call; + struct gl_fragment_program *bitmap_fp; + struct gl_vertex_program *passthrough_vp; + struct gl_buffer_object *texcoord_vbo; + + struct gl_fragment_program *saved_fp; + GLboolean saved_fp_enable; + struct gl_vertex_program *saved_vp; + GLboolean saved_vp_enable; + + struct gl_fragment_program *tex2d_fp; + + GLboolean saved_texcoord_enable; + struct gl_buffer_object *saved_array_vbo, *saved_texcoord_vbo; + GLenum saved_texcoord_type; + GLsizei saved_texcoord_size, saved_texcoord_stride; + const void *saved_texcoord_ptr; + int saved_active_texture; + + GLint saved_vp_x, saved_vp_y; + GLsizei saved_vp_width, saved_vp_height; + GLenum saved_matrix_mode; + + struct dri_meta_clear clear; +}; + + +void meta_set_passthrough_transform(struct dri_metaops *meta); + +void meta_restore_transform(struct dri_metaops *meta); + +void meta_set_passthrough_vertex_program(struct dri_metaops *meta); + +void meta_restore_vertex_program(struct dri_metaops *meta); + +void meta_set_fragment_program(struct dri_metaops *meta, + struct gl_fragment_program **prog, + const char *prog_string); + +void meta_restore_fragment_program(struct dri_metaops *meta); + +void meta_set_default_texrect(struct dri_metaops *meta); + +void meta_restore_texcoords(struct dri_metaops *meta); +void meta_clear_tris(struct dri_metaops *meta, GLbitfield mask); + +void meta_init_metaops(GLcontext *ctx, struct dri_metaops *meta); +void meta_destroy_metaops(struct dri_metaops *meta); +#endif + diff --git a/src/mesa/drivers/dri/intel/intel_clear.c b/src/mesa/drivers/dri/intel/intel_clear.c index 13b433dd17..cfddabd318 100644 --- a/src/mesa/drivers/dri/intel/intel_clear.c +++ b/src/mesa/drivers/dri/intel/intel_clear.c @@ -57,250 +57,6 @@ #define FILE_DEBUG_FLAG DEBUG_BLIT -#define TRI_CLEAR_COLOR_BITS (BUFFER_BIT_BACK_LEFT | \ - BUFFER_BIT_FRONT_LEFT | \ - BUFFER_BIT_COLOR0 | \ - BUFFER_BIT_COLOR1 | \ - BUFFER_BIT_COLOR2 | \ - BUFFER_BIT_COLOR3 | \ - BUFFER_BIT_COLOR4 | \ - BUFFER_BIT_COLOR5 | \ - BUFFER_BIT_COLOR6 | \ - BUFFER_BIT_COLOR7) - - -/** - * Per-context one-time init of things for intl_clear_tris(). - * Basically set up a private array object for vertex/color arrays. - */ -static void -init_clear(GLcontext *ctx) -{ - struct intel_context *intel = intel_context(ctx); - struct gl_array_object *arraySave = NULL; - const GLuint arrayBuffer = ctx->Array.ArrayBufferObj->Name; - const GLuint elementBuffer = ctx->Array.ElementArrayBufferObj->Name; - - /* create new array object */ - intel->clear.arrayObj = _mesa_new_array_object(ctx, ~0); - - /* save current array object, bind new one */ - _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj); - ctx->NewState |= _NEW_ARRAY; - ctx->Array.NewState |= _NEW_ARRAY_ALL; - _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, intel->clear.arrayObj); - - /* one-time setup of vertex arrays (pos, color) */ - _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); - _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), intel->clear.color); - _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), intel->clear.vertices); - _mesa_Enable(GL_COLOR_ARRAY); - _mesa_Enable(GL_VERTEX_ARRAY); - - /* restore original array object */ - ctx->NewState |= _NEW_ARRAY; - ctx->Array.NewState |= _NEW_ARRAY_ALL; - _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave); - _mesa_reference_array_object(ctx, &arraySave, NULL); - - /* restore original buffer objects */ - _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, arrayBuffer); - _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, elementBuffer); -} - - - -/** - * Perform glClear where mask contains only color, depth, and/or stencil. - * - * The implementation is based on calling into Mesa to set GL state and - * performing normal triangle rendering. The intent of this path is to - * have as generic a path as possible, so that any driver could make use of - * it. - */ -void -intel_clear_tris(GLcontext *ctx, GLbitfield mask) -{ - struct intel_context *intel = intel_context(ctx); - GLfloat dst_z; - struct gl_framebuffer *fb = ctx->DrawBuffer; - int i; - GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE; - GLuint saved_shader_program = 0; - unsigned int saved_active_texture; - struct gl_array_object *arraySave = NULL; - - if (!intel->clear.arrayObj) - init_clear(ctx); - - assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH | - BUFFER_BIT_STENCIL)) == 0); - - _mesa_PushAttrib(GL_COLOR_BUFFER_BIT | - GL_DEPTH_BUFFER_BIT | - GL_ENABLE_BIT | - GL_POLYGON_BIT | - GL_STENCIL_BUFFER_BIT | - GL_TRANSFORM_BIT | - GL_CURRENT_BIT | - GL_VIEWPORT_BIT); - saved_active_texture = ctx->Texture.CurrentUnit; - - /* Disable existing GL state we don't want to apply to a clear. */ - _mesa_Disable(GL_ALPHA_TEST); - _mesa_Disable(GL_BLEND); - _mesa_Disable(GL_CULL_FACE); - _mesa_Disable(GL_FOG); - _mesa_Disable(GL_POLYGON_SMOOTH); - _mesa_Disable(GL_POLYGON_STIPPLE); - _mesa_Disable(GL_POLYGON_OFFSET_FILL); - _mesa_Disable(GL_LIGHTING); - _mesa_Disable(GL_CLIP_PLANE0); - _mesa_Disable(GL_CLIP_PLANE1); - _mesa_Disable(GL_CLIP_PLANE2); - _mesa_Disable(GL_CLIP_PLANE3); - _mesa_Disable(GL_CLIP_PLANE4); - _mesa_Disable(GL_CLIP_PLANE5); - _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL); - if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) { - saved_fp_enable = GL_TRUE; - _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); - } - if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) { - saved_vp_enable = GL_TRUE; - _mesa_Disable(GL_VERTEX_PROGRAM_ARB); - } - if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) { - saved_shader_program = ctx->Shader.CurrentProgram->Name; - _mesa_UseProgramObjectARB(0); - } - - if (ctx->Texture._EnabledUnits != 0) { - int i; - - for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - _mesa_ActiveTextureARB(GL_TEXTURE0 + i); - _mesa_Disable(GL_TEXTURE_1D); - _mesa_Disable(GL_TEXTURE_2D); - _mesa_Disable(GL_TEXTURE_3D); - if (ctx->Extensions.ARB_texture_cube_map) - _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB); - if (ctx->Extensions.NV_texture_rectangle) - _mesa_Disable(GL_TEXTURE_RECTANGLE_NV); - if (ctx->Extensions.MESA_texture_array) { - _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT); - _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT); - } - } - } - - /* save current array object, bind our private one */ - _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj); - ctx->NewState |= _NEW_ARRAY; - ctx->Array.NewState |= _NEW_ARRAY_ALL; - _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, intel->clear.arrayObj); - - intel_meta_set_passthrough_transform(intel); - - for (i = 0; i < 4; i++) { - COPY_4FV(intel->clear.color[i], ctx->Color.ClearColor); - } - - /* convert clear Z from [0,1] to NDC coord in [-1,1] */ - dst_z = -1.0 + 2.0 * ctx->Depth.Clear; - - /* The ClearDepth value is unaffected by DepthRange, so do a default - * mapping. - */ - _mesa_DepthRange(0.0, 1.0); - - /* Prepare the vertices, which are the same regardless of which buffer we're - * drawing to. - */ - intel->clear.vertices[0][0] = fb->_Xmin; - intel->clear.vertices[0][1] = fb->_Ymin; - intel->clear.vertices[0][2] = dst_z; - intel->clear.vertices[1][0] = fb->_Xmax; - intel->clear.vertices[1][1] = fb->_Ymin; - intel->clear.vertices[1][2] = dst_z; - intel->clear.vertices[2][0] = fb->_Xmax; - intel->clear.vertices[2][1] = fb->_Ymax; - intel->clear.vertices[2][2] = dst_z; - intel->clear.vertices[3][0] = fb->_Xmin; - intel->clear.vertices[3][1] = fb->_Ymax; - intel->clear.vertices[3][2] = dst_z; - - while (mask != 0) { - GLuint this_mask = 0; - GLuint color_bit; - - color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS); - if (color_bit != 0) - this_mask |= (1 << (color_bit - 1)); - - /* Clear depth/stencil in the same pass as color. */ - this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)); - - /* Select the current color buffer and use the color write mask if - * we have one, otherwise don't write any color channels. - */ - if (this_mask & BUFFER_BIT_FRONT_LEFT) - _mesa_DrawBuffer(GL_FRONT_LEFT); - else if (this_mask & BUFFER_BIT_BACK_LEFT) - _mesa_DrawBuffer(GL_BACK_LEFT); - else if (color_bit != 0) - _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 + - (color_bit - BUFFER_COLOR0 - 1)); - else - _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - - /* Control writing of the depth clear value to depth. */ - if (this_mask & BUFFER_BIT_DEPTH) { - _mesa_DepthFunc(GL_ALWAYS); - _mesa_Enable(GL_DEPTH_TEST); - } else { - _mesa_Disable(GL_DEPTH_TEST); - _mesa_DepthMask(GL_FALSE); - } - - /* Control writing of the stencil clear value to stencil. */ - if (this_mask & BUFFER_BIT_STENCIL) { - _mesa_Enable(GL_STENCIL_TEST); - _mesa_StencilOpSeparate(GL_FRONT_AND_BACK, - GL_REPLACE, GL_REPLACE, GL_REPLACE); - _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, - ctx->Stencil.Clear, - ctx->Stencil.WriteMask[0]); - } else { - _mesa_Disable(GL_STENCIL_TEST); - } - - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - - mask &= ~this_mask; - } - - intel_meta_restore_transform(intel); - - _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture); - if (saved_fp_enable) - _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); - if (saved_vp_enable) - _mesa_Enable(GL_VERTEX_PROGRAM_ARB); - - if (saved_shader_program) - _mesa_UseProgramObjectARB(saved_shader_program); - - _mesa_PopAttrib(); - - /* restore current array object */ - ctx->NewState |= _NEW_ARRAY; - ctx->Array.NewState |= _NEW_ARRAY_ALL; - _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave); - _mesa_reference_array_object(ctx, &arraySave, NULL); -} - static const char *buffer_names[] = { [BUFFER_FRONT_LEFT] = "front", [BUFFER_BACK_LEFT] = "back", @@ -326,6 +82,7 @@ static const char *buffer_names[] = { static void intelClear(GLcontext *ctx, GLbitfield mask) { + struct intel_context *intel = intel_context(ctx); const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask); GLbitfield tri_mask = 0; GLbitfield blit_mask = 0; @@ -425,7 +182,7 @@ intelClear(GLcontext *ctx, GLbitfield mask) } DBG("\n"); } - intel_clear_tris(ctx, tri_mask); + meta_clear_tris(&intel->meta, tri_mask); } if (swrast_mask) { diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index edf422c1bd..4abb525f78 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -404,7 +404,7 @@ intel_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) if (!driContext->driScreenPriv->dri2.enabled) return; - if (!intel->internal_viewport_call && ctx->DrawBuffer->Name == 0) { + if (!intel->meta.internal_viewport_call && ctx->DrawBuffer->Name == 0) { /* If we're rendering to the fake front buffer, make sure all the pending * drawing has landed on the real front buffer. Otherwise when we * eventually get to DRI2GetBuffersWithFormat the stale real front @@ -672,6 +672,7 @@ intelInitContext(struct intel_context *intel, */ _mesa_init_point(ctx); + meta_init_metaops(ctx, &intel->meta); ctx->Const.MaxColorAttachments = 4; /* XXX FBO: review this */ if (IS_965(intelScreen->deviceID)) { if (MAX_WIDTH > 8192) @@ -794,8 +795,7 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) INTEL_FIREVERTICES(intel); - if (intel->clear.arrayObj) - _mesa_delete_array_object(&intel->ctx, intel->clear.arrayObj); + meta_destroy_metaops(&intel->meta); intel->vtbl.destroy(intel); diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h index 6761193f8c..08bea88c95 100644 --- a/src/mesa/drivers/dri/intel/intel_context.h +++ b/src/mesa/drivers/dri/intel/intel_context.h @@ -33,6 +33,7 @@ #include "main/mtypes.h" #include "main/mm.h" #include "texmem.h" +#include "dri_metaops.h" #include "drm.h" #include "intel_bufmgr.h" @@ -157,29 +158,7 @@ struct intel_context void (*debug_batch)(struct intel_context *intel); } vtbl; - struct { - struct gl_fragment_program *bitmap_fp; - struct gl_vertex_program *passthrough_vp; - struct gl_buffer_object *texcoord_vbo; - - struct gl_fragment_program *saved_fp; - GLboolean saved_fp_enable; - struct gl_vertex_program *saved_vp; - GLboolean saved_vp_enable; - - struct gl_fragment_program *tex2d_fp; - - GLboolean saved_texcoord_enable; - struct gl_buffer_object *saved_array_vbo, *saved_texcoord_vbo; - GLenum saved_texcoord_type; - GLsizei saved_texcoord_size, saved_texcoord_stride; - const void *saved_texcoord_ptr; - int saved_active_texture; - - GLint saved_vp_x, saved_vp_y; - GLsizei saved_vp_width, saved_vp_height; - GLenum saved_matrix_mode; - } meta; + struct dri_metaops meta; GLint refcount; GLuint Fallback; @@ -191,7 +170,6 @@ struct intel_context struct intel_region *front_region; struct intel_region *back_region; struct intel_region *depth_region; - GLboolean internal_viewport_call; /** * This value indicates that the kernel memory manager is being used @@ -224,13 +202,6 @@ struct intel_context GLuint ClearColor565; GLuint ClearColor8888; - /* info for intel_clear_tris() */ - struct - { - struct gl_array_object *arrayObj; - GLfloat vertices[4][3]; - GLfloat color[4][4]; - } clear; /* Offsets of fields within the current vertex: */ diff --git a/src/mesa/drivers/dri/intel/intel_generatemipmap.c b/src/mesa/drivers/dri/intel/intel_generatemipmap.c index b00f8019dd..fe986092db 100644 --- a/src/mesa/drivers/dri/intel/intel_generatemipmap.c +++ b/src/mesa/drivers/dri/intel/intel_generatemipmap.c @@ -88,7 +88,7 @@ intel_generate_mipmap_level(GLcontext *ctx, GLuint tex_name, if (status != GL_FRAMEBUFFER_COMPLETE_EXT) return GL_FALSE; - intel_meta_set_passthrough_transform(intel); + meta_set_passthrough_transform(&intel->meta); /* XXX: Doing it right would involve setting up the transformation to do * 0-1 mapping or something, and not changing the vertex data. @@ -104,12 +104,12 @@ intel_generate_mipmap_level(GLcontext *ctx, GLuint tex_name, _mesa_VertexPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &vertices); _mesa_Enable(GL_VERTEX_ARRAY); - intel_meta_set_default_texrect(intel); + meta_set_default_texrect(&intel->meta); _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - intel_meta_restore_texcoords(intel); - intel_meta_restore_transform(intel); + meta_restore_texcoords(&intel->meta); + meta_restore_transform(&intel->meta); return GL_TRUE; } @@ -153,9 +153,9 @@ intel_generate_mipmap_2d(GLcontext *ctx, _mesa_GenFramebuffersEXT(1, &fb_name); _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb_name); - intel_meta_set_fragment_program(intel, &intel->meta.tex2d_fp, - intel_fp_tex2d); - intel_meta_set_passthrough_vertex_program(intel); + meta_set_fragment_program(&intel->meta, &intel->meta.tex2d_fp, + intel_fp_tex2d); + meta_set_passthrough_vertex_program(&intel->meta); max_levels = _mesa_max_texture_levels(ctx, texObj->Target); start_level = texObj->BaseLevel; @@ -202,8 +202,8 @@ intel_generate_mipmap_2d(GLcontext *ctx, success = GL_TRUE; fail: - intel_meta_restore_fragment_program(intel); - intel_meta_restore_vertex_program(intel); + meta_restore_fragment_program(&intel->meta); + meta_restore_vertex_program(&intel->meta); _mesa_DeleteFramebuffersEXT(1, &fb_name); _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture); diff --git a/src/mesa/drivers/dri/intel/intel_pixel.c b/src/mesa/drivers/dri/intel/intel_pixel.c index da9ccb23f1..a300141655 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel.c +++ b/src/mesa/drivers/dri/intel/intel_pixel.c @@ -176,246 +176,6 @@ intel_check_blit_format(struct intel_region * region, return GL_FALSE; } -void -intel_meta_set_passthrough_transform(struct intel_context *intel) -{ - GLcontext *ctx = &intel->ctx; - - intel->meta.saved_vp_x = ctx->Viewport.X; - intel->meta.saved_vp_y = ctx->Viewport.Y; - intel->meta.saved_vp_width = ctx->Viewport.Width; - intel->meta.saved_vp_height = ctx->Viewport.Height; - intel->meta.saved_matrix_mode = ctx->Transform.MatrixMode; - - intel->internal_viewport_call = GL_TRUE; - _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); - intel->internal_viewport_call = GL_FALSE; - - _mesa_MatrixMode(GL_PROJECTION); - _mesa_PushMatrix(); - _mesa_LoadIdentity(); - _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1); - - _mesa_MatrixMode(GL_MODELVIEW); - _mesa_PushMatrix(); - _mesa_LoadIdentity(); -} - -void -intel_meta_restore_transform(struct intel_context *intel) -{ - _mesa_MatrixMode(GL_PROJECTION); - _mesa_PopMatrix(); - _mesa_MatrixMode(GL_MODELVIEW); - _mesa_PopMatrix(); - - _mesa_MatrixMode(intel->meta.saved_matrix_mode); - - intel->internal_viewport_call = GL_TRUE; - _mesa_Viewport(intel->meta.saved_vp_x, intel->meta.saved_vp_y, - intel->meta.saved_vp_width, intel->meta.saved_vp_height); - intel->internal_viewport_call = GL_FALSE; -} - -/** - * Set up a vertex program to pass through the position and first texcoord - * for pixel path. - */ -void -intel_meta_set_passthrough_vertex_program(struct intel_context *intel) -{ - GLcontext *ctx = &intel->ctx; - static const char *vp = - "!!ARBvp1.0\n" - "TEMP vertexClip;\n" - "DP4 vertexClip.x, state.matrix.mvp.row[0], vertex.position;\n" - "DP4 vertexClip.y, state.matrix.mvp.row[1], vertex.position;\n" - "DP4 vertexClip.z, state.matrix.mvp.row[2], vertex.position;\n" - "DP4 vertexClip.w, state.matrix.mvp.row[3], vertex.position;\n" - "MOV result.position, vertexClip;\n" - "MOV result.texcoord[0], vertex.texcoord[0];\n" - "MOV result.color, vertex.color;\n" - "END\n"; - - assert(intel->meta.saved_vp == NULL); - - _mesa_reference_vertprog(ctx, &intel->meta.saved_vp, - ctx->VertexProgram.Current); - if (intel->meta.passthrough_vp == NULL) { - GLuint prog_name; - _mesa_GenPrograms(1, &prog_name); - _mesa_BindProgram(GL_VERTEX_PROGRAM_ARB, prog_name); - _mesa_ProgramStringARB(GL_VERTEX_PROGRAM_ARB, - GL_PROGRAM_FORMAT_ASCII_ARB, - strlen(vp), (const GLubyte *)vp); - _mesa_reference_vertprog(ctx, &intel->meta.passthrough_vp, - ctx->VertexProgram.Current); - _mesa_DeletePrograms(1, &prog_name); - } - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, - intel->meta.passthrough_vp); - ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, - &intel->meta.passthrough_vp->Base); - - intel->meta.saved_vp_enable = ctx->VertexProgram.Enabled; - _mesa_Enable(GL_VERTEX_PROGRAM_ARB); -} - -/** - * Restores the previous vertex program after - * intel_meta_set_passthrough_vertex_program() - */ -void -intel_meta_restore_vertex_program(struct intel_context *intel) -{ - GLcontext *ctx = &intel->ctx; - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, - intel->meta.saved_vp); - _mesa_reference_vertprog(ctx, &intel->meta.saved_vp, NULL); - ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, - &ctx->VertexProgram.Current->Base); - - if (!intel->meta.saved_vp_enable) - _mesa_Disable(GL_VERTEX_PROGRAM_ARB); -} - -/** - * Binds the given program string to GL_FRAGMENT_PROGRAM_ARB, caching the - * program object. - */ -void -intel_meta_set_fragment_program(struct intel_context *intel, - struct gl_fragment_program **prog, - const char *prog_string) -{ - GLcontext *ctx = &intel->ctx; - assert(intel->meta.saved_fp == NULL); - - _mesa_reference_fragprog(ctx, &intel->meta.saved_fp, - ctx->FragmentProgram.Current); - if (*prog == NULL) { - GLuint prog_name; - _mesa_GenPrograms(1, &prog_name); - _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, prog_name); - _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, - GL_PROGRAM_FORMAT_ASCII_ARB, - strlen(prog_string), (const GLubyte *)prog_string); - _mesa_reference_fragprog(ctx, prog, ctx->FragmentProgram.Current); - /* Note that DeletePrograms unbinds the program on us */ - _mesa_DeletePrograms(1, &prog_name); - } - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, *prog); - ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, &((*prog)->Base)); - - intel->meta.saved_fp_enable = ctx->FragmentProgram.Enabled; - _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); -} - -/** - * Restores the previous fragment program after - * intel_meta_set_fragment_program() - */ -void -intel_meta_restore_fragment_program(struct intel_context *intel) -{ - GLcontext *ctx = &intel->ctx; - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, - intel->meta.saved_fp); - _mesa_reference_fragprog(ctx, &intel->meta.saved_fp, NULL); - ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, - &ctx->FragmentProgram.Current->Base); - - if (!intel->meta.saved_fp_enable) - _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); -} - -static const float default_texcoords[4][2] = { { 0.0, 0.0 }, - { 1.0, 0.0 }, - { 1.0, 1.0 }, - { 0.0, 1.0 } }; - -void -intel_meta_set_default_texrect(struct intel_context *intel) -{ - GLcontext *ctx = &intel->ctx; - struct gl_client_array *old_texcoord_array; - - intel->meta.saved_active_texture = ctx->Texture.CurrentUnit; - if (intel->meta.saved_array_vbo == NULL) { - _mesa_reference_buffer_object(ctx, &intel->meta.saved_array_vbo, - ctx->Array.ArrayBufferObj); - } - - old_texcoord_array = &ctx->Array.ArrayObj->TexCoord[0]; - intel->meta.saved_texcoord_type = old_texcoord_array->Type; - intel->meta.saved_texcoord_size = old_texcoord_array->Size; - intel->meta.saved_texcoord_stride = old_texcoord_array->Stride; - intel->meta.saved_texcoord_enable = old_texcoord_array->Enabled; - intel->meta.saved_texcoord_ptr = old_texcoord_array->Ptr; - _mesa_reference_buffer_object(ctx, &intel->meta.saved_texcoord_vbo, - old_texcoord_array->BufferObj); - - _mesa_ClientActiveTextureARB(GL_TEXTURE0); - - if (intel->meta.texcoord_vbo == NULL) { - GLuint vbo_name; - - _mesa_GenBuffersARB(1, &vbo_name); - _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_name); - _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(default_texcoords), - default_texcoords, GL_STATIC_DRAW_ARB); - _mesa_reference_buffer_object(ctx, &intel->meta.texcoord_vbo, - ctx->Array.ArrayBufferObj); - } else { - _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, - intel->meta.texcoord_vbo->Name); - } - _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), NULL); - - _mesa_Enable(GL_TEXTURE_COORD_ARRAY); -} - -void -intel_meta_restore_texcoords(struct intel_context *intel) -{ - GLcontext *ctx = &intel->ctx; - - /* Restore the old TexCoordPointer */ - if (intel->meta.saved_texcoord_vbo) { - _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, - intel->meta.saved_texcoord_vbo->Name); - _mesa_reference_buffer_object(ctx, &intel->meta.saved_texcoord_vbo, NULL); - } else { - _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - } - - _mesa_TexCoordPointer(intel->meta.saved_texcoord_size, - intel->meta.saved_texcoord_type, - intel->meta.saved_texcoord_stride, - intel->meta.saved_texcoord_ptr); - if (!intel->meta.saved_texcoord_enable) - _mesa_Disable(GL_TEXTURE_COORD_ARRAY); - - _mesa_ClientActiveTextureARB(GL_TEXTURE0 + - intel->meta.saved_active_texture); - - if (intel->meta.saved_array_vbo) { - _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, - intel->meta.saved_array_vbo->Name); - _mesa_reference_buffer_object(ctx, &intel->meta.saved_array_vbo, NULL); - } else { - _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - } -} - void intelInitPixelFuncs(struct dd_function_table *functions) { @@ -428,14 +188,3 @@ intelInitPixelFuncs(struct dd_function_table *functions) functions->ReadPixels = intelReadPixels; } -void -intel_free_pixel_state(struct intel_context *intel) -{ - GLcontext *ctx = &intel->ctx; - - _mesa_reference_vertprog(ctx, &intel->meta.passthrough_vp, NULL); - _mesa_reference_fragprog(ctx, &intel->meta.bitmap_fp, NULL); - _mesa_reference_fragprog(ctx, &intel->meta.tex2d_fp, NULL); - _mesa_reference_buffer_object(ctx, &intel->meta.texcoord_vbo, NULL); -} - diff --git a/src/mesa/drivers/dri/intel/intel_pixel.h b/src/mesa/drivers/dri/intel/intel_pixel.h index 6acf0813c8..96a6dd17b2 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel.h +++ b/src/mesa/drivers/dri/intel/intel_pixel.h @@ -31,19 +31,6 @@ #include "main/mtypes.h" void intelInitPixelFuncs(struct dd_function_table *functions); -void intel_meta_set_passthrough_transform(struct intel_context *intel); -void intel_meta_restore_transform(struct intel_context *intel); -void intel_meta_set_passthrough_vertex_program(struct intel_context *intel); -void intel_meta_restore_vertex_program(struct intel_context *intel); -void intel_meta_set_fragment_program(struct intel_context *intel, - struct gl_fragment_program **prog, - const char *prog_string); -void intel_meta_restore_fragment_program(struct intel_context *intel); -void intel_free_pixel_state(struct intel_context *intel); -void intel_meta_set_default_texrect(struct intel_context *intel); -void intel_meta_set_default_texrect(struct intel_context *intel); -void intel_meta_restore_texcoords(struct intel_context *intel); - GLboolean intel_check_blit_fragment_ops(GLcontext * ctx, GLboolean src_alpha_is_one); @@ -79,6 +66,4 @@ void intelBitmap(GLcontext * ctx, const struct gl_pixelstore_attrib *unpack, const GLubyte * pixels); -void intel_clear_tris(GLcontext *ctx, GLbitfield mask); - #endif diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c index ebba6aafad..540e7620a9 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c @@ -476,11 +476,11 @@ intel_texture_bitmap(GLcontext * ctx, GL_ALPHA, GL_UNSIGNED_BYTE, a8_bitmap); _mesa_free(a8_bitmap); - intel_meta_set_fragment_program(intel, &intel->meta.bitmap_fp, fp); + meta_set_fragment_program(&intel->meta, &intel->meta.bitmap_fp, fp); _mesa_ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0, ctx->Current.RasterColor); - intel_meta_set_passthrough_vertex_program(intel); - intel_meta_set_passthrough_transform(intel); + meta_set_passthrough_vertex_program(&intel->meta); + meta_set_passthrough_transform(&intel->meta); /* convert rasterpos Z from [0,1] to NDC coord in [-1,1] */ dst_z = -1.0 + 2.0 * ctx->Current.RasterPos[2]; @@ -507,13 +507,13 @@ intel_texture_bitmap(GLcontext * ctx, _mesa_VertexPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &vertices); _mesa_Enable(GL_VERTEX_ARRAY); - intel_meta_set_default_texrect(intel); + meta_set_default_texrect(&intel->meta); _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - intel_meta_restore_texcoords(intel); - intel_meta_restore_transform(intel); - intel_meta_restore_fragment_program(intel); - intel_meta_restore_vertex_program(intel); + meta_restore_texcoords(&intel->meta); + meta_restore_transform(&intel->meta); + meta_restore_fragment_program(&intel->meta); + meta_restore_vertex_program(&intel->meta); _mesa_PopClientAttrib(); _mesa_Disable(GL_TEXTURE_2D); /* asserted that it was disabled at entry */ diff --git a/src/mesa/drivers/dri/intel/intel_pixel_draw.c b/src/mesa/drivers/dri/intel/intel_pixel_draw.c index dfc9e1539f..a6b6824164 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_draw.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_draw.c @@ -150,7 +150,7 @@ intel_texture_drawpixels(GLcontext * ctx, _mesa_TexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, pixels); - intel_meta_set_passthrough_transform(intel); + meta_set_passthrough_transform(&intel->meta); /* convert rasterpos Z from [0,1] to NDC coord in [-1,1] */ z = -1.0 + 2.0 * ctx->Current.RasterPos[2]; @@ -182,12 +182,12 @@ intel_texture_drawpixels(GLcontext * ctx, _mesa_VertexPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &vertices); _mesa_Enable(GL_VERTEX_ARRAY); - intel_meta_set_default_texrect(intel); + meta_set_default_texrect(&intel->meta); _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - intel_meta_restore_texcoords(intel); - intel_meta_restore_transform(intel); + meta_restore_texcoords(&intel->meta); + meta_restore_transform(&intel->meta); _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture); _mesa_PopClientAttrib(); @@ -352,7 +352,7 @@ intel_stencil_drawpixels(GLcontext * ctx, ctx->Unpack = old_unpack; _mesa_free(stencil_pixels); - intel_meta_set_passthrough_transform(intel); + meta_set_passthrough_transform(&intel->meta); /* Since we're rendering to the framebuffer as if it was an FBO, * if it's the window system we have to flip the coordinates. @@ -375,12 +375,12 @@ intel_stencil_drawpixels(GLcontext * ctx, _mesa_VertexPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &vertices); _mesa_Enable(GL_VERTEX_ARRAY); - intel_meta_set_default_texrect(intel); + meta_set_default_texrect(&intel->meta); _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - intel_meta_restore_texcoords(intel); - intel_meta_restore_transform(intel); + meta_restore_texcoords(&intel->meta); + meta_restore_transform(&intel->meta); _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture); _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, old_fb_name); diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c index 6560efdca3..4dbda39eb9 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.c +++ b/src/mesa/drivers/dri/r200/r200_ioctl.c @@ -58,11 +58,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define R200_TIMEOUT 512 #define R200_IDLE_RETRY 16 -static void r200UserClear(GLcontext *ctx, GLuint mask) -{ - radeon_clear_tris(ctx, mask); -} - static void r200KernelClear(GLcontext *ctx, GLuint flags) { r200ContextPtr rmesa = R200_CONTEXT(ctx); @@ -253,7 +248,7 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask ) } if (rmesa->radeon.radeonScreen->kernel_mm) - r200UserClear(ctx, orig_mask); + radeonUserClear(ctx, orig_mask); else { r200KernelClear(ctx, flags); rmesa->radeon.hw.all_dirty = GL_TRUE; diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index 4e913dba29..ddabd53992 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -68,11 +68,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. static void r300EmitClearState(GLcontext * ctx); -static void r300UserClear(GLcontext *ctx, GLuint mask) -{ - radeon_clear_tris(ctx, mask); -} - static void r300ClearBuffer(r300ContextPtr r300, int flags, struct radeon_renderbuffer *rrb, struct radeon_renderbuffer *rrbd) @@ -680,7 +675,7 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) ret = 0; if (tri_mask) { if (r300->radeon.radeonScreen->kernel_mm) - r300UserClear(ctx, tri_mask); + radeonUserClear(ctx, tri_mask); else { /* if kernel clear fails due to size restraints fallback */ ret = r300KernelClear(ctx, tri_mask); diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index 0a8d8b03e8..3bf42e9bb0 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -877,7 +877,7 @@ void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei he if (!driContext->driScreenPriv->dri2.enabled) return; - if (!radeon->internal_viewport_call && ctx->DrawBuffer->Name == 0) { + if (!radeon->meta.internal_viewport_call && ctx->DrawBuffer->Name == 0) { if (radeon->is_front_buffer_rendering) { radeonFlush(ctx); } @@ -1258,254 +1258,8 @@ void rcommonBeginBatch(radeonContextPtr rmesa, int n, } - - -static void -radeon_meta_set_passthrough_transform(radeonContextPtr radeon) -{ - GLcontext *ctx = radeon->glCtx; - - radeon->meta.saved_vp_x = ctx->Viewport.X; - radeon->meta.saved_vp_y = ctx->Viewport.Y; - radeon->meta.saved_vp_width = ctx->Viewport.Width; - radeon->meta.saved_vp_height = ctx->Viewport.Height; - radeon->meta.saved_matrix_mode = ctx->Transform.MatrixMode; - - radeon->internal_viewport_call = GL_TRUE; - _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); - radeon->internal_viewport_call = GL_FALSE; - - _mesa_MatrixMode(GL_PROJECTION); - _mesa_PushMatrix(); - _mesa_LoadIdentity(); - _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1); - - _mesa_MatrixMode(GL_MODELVIEW); - _mesa_PushMatrix(); - _mesa_LoadIdentity(); -} - -static void -radeon_meta_restore_transform(radeonContextPtr radeon) -{ - _mesa_MatrixMode(GL_PROJECTION); - _mesa_PopMatrix(); - _mesa_MatrixMode(GL_MODELVIEW); - _mesa_PopMatrix(); - - _mesa_MatrixMode(radeon->meta.saved_matrix_mode); - - radeon->internal_viewport_call = GL_TRUE; - _mesa_Viewport(radeon->meta.saved_vp_x, radeon->meta.saved_vp_y, - radeon->meta.saved_vp_width, radeon->meta.saved_vp_height); - radeon->internal_viewport_call = GL_FALSE; -} - - -/** - * Perform glClear where mask contains only color, depth, and/or stencil. - * - * The implementation is based on calling into Mesa to set GL state and - * performing normal triangle rendering. The intent of this path is to - * have as generic a path as possible, so that any driver could make use of - * it. - */ - -static void radeon_clear_init(GLcontext *ctx) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - struct gl_array_object *arraySave = NULL; - const GLuint arrayBuffer = ctx->Array.ArrayBufferObj->Name; - const GLuint elementBuffer = ctx->Array.ElementArrayBufferObj->Name; - - /* create new array object */ - rmesa->clear.arrayObj = _mesa_new_array_object(ctx, ~0); - _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj); - _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, rmesa->clear.arrayObj); - - /* one time setup of vertex arrays (pos, color) */ - _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); - _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), rmesa->clear.color); - _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), rmesa->clear.vertices); - _mesa_Enable(GL_COLOR_ARRAY); - _mesa_Enable(GL_VERTEX_ARRAY); - - /* restore original array object */ - _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave); - _mesa_reference_array_object(ctx, &arraySave, NULL); - - /* restore original buffer objects */ - _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, arrayBuffer); - _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, elementBuffer); -} - - -void radeon_clear_tris(GLcontext *ctx, GLbitfield mask) +void radeonUserClear(GLcontext *ctx, GLuint mask) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat dst_z; - struct gl_framebuffer *fb = ctx->DrawBuffer; - int i; - GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE; - GLboolean saved_shader_program = 0; - unsigned int saved_active_texture; - struct gl_array_object *arraySave = NULL; - - if (!rmesa->clear.arrayObj) - radeon_clear_init(ctx); - - assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH | - BUFFER_BIT_STENCIL)) == 0); - - _mesa_PushAttrib(GL_COLOR_BUFFER_BIT | - GL_DEPTH_BUFFER_BIT | - GL_ENABLE_BIT | - GL_POLYGON_BIT | - GL_STENCIL_BUFFER_BIT | - GL_TRANSFORM_BIT | - GL_CURRENT_BIT); - saved_active_texture = ctx->Texture.CurrentUnit; - - /* Disable existing GL state we don't want to apply to a clear. */ - _mesa_Disable(GL_ALPHA_TEST); - _mesa_Disable(GL_BLEND); - _mesa_Disable(GL_CULL_FACE); - _mesa_Disable(GL_FOG); - _mesa_Disable(GL_POLYGON_SMOOTH); - _mesa_Disable(GL_POLYGON_STIPPLE); - _mesa_Disable(GL_POLYGON_OFFSET_FILL); - _mesa_Disable(GL_LIGHTING); - _mesa_Disable(GL_CLIP_PLANE0); - _mesa_Disable(GL_CLIP_PLANE1); - _mesa_Disable(GL_CLIP_PLANE2); - _mesa_Disable(GL_CLIP_PLANE3); - _mesa_Disable(GL_CLIP_PLANE4); - _mesa_Disable(GL_CLIP_PLANE5); - _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL); - if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) { - saved_fp_enable = GL_TRUE; - _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); - } - if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) { - saved_vp_enable = GL_TRUE; - _mesa_Disable(GL_VERTEX_PROGRAM_ARB); - } - if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) { - saved_shader_program = ctx->Shader.CurrentProgram->Name; - _mesa_UseProgramObjectARB(0); - } - - if (ctx->Texture._EnabledUnits != 0) { - int i; - - for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - _mesa_ActiveTextureARB(GL_TEXTURE0 + i); - _mesa_Disable(GL_TEXTURE_1D); - _mesa_Disable(GL_TEXTURE_2D); - _mesa_Disable(GL_TEXTURE_3D); - if (ctx->Extensions.ARB_texture_cube_map) - _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB); - if (ctx->Extensions.NV_texture_rectangle) - _mesa_Disable(GL_TEXTURE_RECTANGLE_NV); - if (ctx->Extensions.MESA_texture_array) { - _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT); - _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT); - } - } - } - - /* save current array object, bind our private one */ - _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj); - _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, rmesa->clear.arrayObj); - - radeon_meta_set_passthrough_transform(rmesa); - - for (i = 0; i < 4; i++) { - COPY_4FV(rmesa->clear.color[i], ctx->Color.ClearColor); - } - - /* convert clear Z from [0,1] to NDC coord in [-1,1] */ - - dst_z = -1.0 + 2.0 * ctx->Depth.Clear; - /* Prepare the vertices, which are the same regardless of which buffer we're - * drawing to. - */ - rmesa->clear.vertices[0][0] = fb->_Xmin; - rmesa->clear.vertices[0][1] = fb->_Ymin; - rmesa->clear.vertices[0][2] = dst_z; - rmesa->clear.vertices[1][0] = fb->_Xmax; - rmesa->clear.vertices[1][1] = fb->_Ymin; - rmesa->clear.vertices[1][2] = dst_z; - rmesa->clear.vertices[2][0] = fb->_Xmax; - rmesa->clear.vertices[2][1] = fb->_Ymax; - rmesa->clear.vertices[2][2] = dst_z; - rmesa->clear.vertices[3][0] = fb->_Xmin; - rmesa->clear.vertices[3][1] = fb->_Ymax; - rmesa->clear.vertices[3][2] = dst_z; - - while (mask != 0) { - GLuint this_mask = 0; - GLuint color_bit; - - color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS); - if (color_bit != 0) - this_mask |= (1 << (color_bit - 1)); - - /* Clear depth/stencil in the same pass as color. */ - this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)); - - /* Select the current color buffer and use the color write mask if - * we have one, otherwise don't write any color channels. - */ - if (this_mask & BUFFER_BIT_FRONT_LEFT) - _mesa_DrawBuffer(GL_FRONT_LEFT); - else if (this_mask & BUFFER_BIT_BACK_LEFT) - _mesa_DrawBuffer(GL_BACK_LEFT); - else if (color_bit != 0) - _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 + - (color_bit - BUFFER_COLOR0 - 1)); - else - _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - - /* Control writing of the depth clear value to depth. */ - if (this_mask & BUFFER_BIT_DEPTH) { - _mesa_DepthFunc(GL_ALWAYS); - _mesa_DepthMask(GL_TRUE); - _mesa_Enable(GL_DEPTH_TEST); - } else { - _mesa_Disable(GL_DEPTH_TEST); - _mesa_DepthMask(GL_FALSE); - } - - /* Control writing of the stencil clear value to stencil. */ - if (this_mask & BUFFER_BIT_STENCIL) { - _mesa_Enable(GL_STENCIL_TEST); - _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); - _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, (GLint)ctx->Stencil.Clear, - ctx->Stencil.WriteMask[0]); - } else { - _mesa_Disable(GL_STENCIL_TEST); - } - - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - - mask &= ~this_mask; - } - - radeon_meta_restore_transform(rmesa); - - _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture); - if (saved_fp_enable) - _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); - if (saved_vp_enable) - _mesa_Enable(GL_VERTEX_PROGRAM_ARB); - - if (saved_shader_program) - _mesa_UseProgramObjectARB(saved_shader_program); - - _mesa_PopAttrib(); - /* restore current array object */ - _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave); - _mesa_reference_array_object(ctx, &arraySave, NULL); + meta_clear_tris(&rmesa->meta, mask); } diff --git a/src/mesa/drivers/dri/radeon/radeon_common.h b/src/mesa/drivers/dri/radeon/radeon_common.h index ba6c7c5773..cebae18b2d 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.h +++ b/src/mesa/drivers/dri/radeon/radeon_common.h @@ -5,18 +5,7 @@ #include "radeon_dma.h" #include "radeon_texture.h" - -#define TRI_CLEAR_COLOR_BITS (BUFFER_BIT_BACK_LEFT | \ - BUFFER_BIT_FRONT_LEFT | \ - BUFFER_BIT_COLOR0 | \ - BUFFER_BIT_COLOR1 | \ - BUFFER_BIT_COLOR2 | \ - BUFFER_BIT_COLOR3 | \ - BUFFER_BIT_COLOR4 | \ - BUFFER_BIT_COLOR5 | \ - BUFFER_BIT_COLOR6 | \ - BUFFER_BIT_COLOR7) - +void radeonUserClear(GLcontext *ctx, GLuint mask); void radeonRecalcScissorRects(radeonContextPtr radeon); void radeonSetCliprects(radeonContextPtr radeon); void radeonUpdateScissor( GLcontext *ctx ); diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c index 828d6477f0..9add50b4cc 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c @@ -184,6 +184,7 @@ GLboolean radeonInitContext(radeonContextPtr radeon, ctx = radeon->glCtx; driContextPriv->driverPrivate = radeon; + meta_init_metaops(ctx, &radeon->meta); /* DRI fields */ radeon->dri.context = driContextPriv; radeon->dri.screen = sPriv; @@ -264,7 +265,7 @@ void radeonDestroyContext(__DRIcontextPrivate *driContextPriv ) } radeonReleaseArrays(radeon->glCtx, ~0); - + meta_destroy_metaops(&radeon->meta); if (radeon->vtbl.free_context) radeon->vtbl.free_context(radeon->glCtx); _swsetup_DestroyContext( radeon->glCtx ); diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h index 036d2658d9..07ac85fb52 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h @@ -13,6 +13,7 @@ #include "dri_util.h" #include "tnl/t_vertex.h" +#include "dri_metaops.h" struct radeon_context; #include "radeon_bocs_wrapper.h" @@ -476,27 +477,7 @@ struct radeon_context { */ GLboolean is_front_buffer_reading; - /* info for radeon_clear_tris() */ - struct { - struct gl_array_object *arrayObj; - GLfloat vertices[4][3]; - GLfloat color[4][4]; - } clear; - GLboolean internal_viewport_call; - - struct { - struct gl_fragment_program *bitmap_fp; - struct gl_vertex_program *passthrough_vp; - - struct gl_fragment_program *saved_fp; - GLboolean saved_fp_enable; - struct gl_vertex_program *saved_vp; - GLboolean saved_vp_enable; - - GLint saved_vp_x, saved_vp_y; - GLsizei saved_vp_width, saved_vp_height; - GLenum saved_matrix_mode; - } meta; + struct dri_metaops meta; struct { void (*get_lock)(radeonContextPtr radeon); diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index 01c45df2df..a5e4df7941 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -445,11 +445,6 @@ void radeonEmitAOS( r100ContextPtr rmesa, */ #define RADEON_MAX_CLEARS 256 -static void radeonUserClear(GLcontext *ctx, GLuint mask) -{ - radeon_clear_tris(ctx, mask); -} - static void radeonKernelClear(GLcontext *ctx, GLuint flags) { r100ContextPtr rmesa = R100_CONTEXT(ctx); -- cgit v1.2.3