diff options
author | Chia-I Wu <olvaffe@gmail.com> | 2010-01-12 11:25:02 +0800 |
---|---|---|
committer | Chia-I Wu <olvaffe@gmail.com> | 2010-01-12 11:25:02 +0800 |
commit | 562c127693200822f04a145db50add1be2425d7b (patch) | |
tree | 9441774fb212b17ddf2a364f06abc43f166cc00b /src/mesa/drivers/dri/radeon | |
parent | e5d351dcfde58777162552cf5cd2a9cd8299f4cd (diff) | |
parent | 077d6dd7508af88509dd0499c5dfbdaa186b4015 (diff) |
Merge branch 'master' into opengl-es-v2
Conflicts:
src/mesa/main/dd.h
Diffstat (limited to 'src/mesa/drivers/dri/radeon')
39 files changed, 1656 insertions, 1282 deletions
diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile index ae2e695bfc..2b2f2c4aa7 100644 --- a/src/mesa/drivers/dri/radeon/Makefile +++ b/src/mesa/drivers/dri/radeon/Makefile @@ -11,7 +11,7 @@ LIBNAME = radeon_dri.so MINIGLX_SOURCES = server/radeon_dri.c ifeq ($(RADEON_LDFLAGS),) -CS_SOURCES = radeon_cs_space_drm.c +CS_SOURCES = radeon_cs_space_drm.c radeon_bo.c radeon_cs.c endif RADEON_COMMON_SOURCES = \ diff --git a/src/mesa/drivers/dri/radeon/radeon_bo.c b/src/mesa/drivers/dri/radeon/radeon_bo.c new file mode 100644 index 0000000000..393d156cde --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_bo.c @@ -0,0 +1,110 @@ +#include <radeon_bocs_wrapper.h> +#include <radeon_bo_int_drm.h> + +void radeon_bo_debug(struct radeon_bo *bo, + const char *op) +{ + struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; + + fprintf(stderr, "%s %p 0x%08X 0x%08X 0x%08X\n", + op, bo, bo->handle, boi->size, boi->cref); +} + +struct radeon_bo *radeon_bo_open(struct radeon_bo_manager *bom, + uint32_t handle, + uint32_t size, + uint32_t alignment, + uint32_t domains, + uint32_t flags) +{ + struct radeon_bo *bo; + bo = bom->funcs->bo_open(bom, handle, size, alignment, domains, flags); + return bo; +} + +void radeon_bo_ref(struct radeon_bo *bo) +{ + struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; + boi->cref++; + boi->bom->funcs->bo_ref(boi); +} + +struct radeon_bo *radeon_bo_unref(struct radeon_bo *bo) +{ + struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; + boi->cref--; + return boi->bom->funcs->bo_unref(boi); +} + +int radeon_bo_map(struct radeon_bo *bo, int write) +{ + struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; + return boi->bom->funcs->bo_map(boi, write); +} + +int radeon_bo_unmap(struct radeon_bo *bo) +{ + struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; + return boi->bom->funcs->bo_unmap(boi); +} + +int radeon_bo_wait(struct radeon_bo *bo) +{ + struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; + if (!boi->bom->funcs->bo_wait) + return 0; + return boi->bom->funcs->bo_wait(boi); +} + +int radeon_bo_is_busy(struct radeon_bo *bo, + uint32_t *domain) +{ + struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; + return boi->bom->funcs->bo_is_busy(boi, domain); +} + +int radeon_bo_set_tiling(struct radeon_bo *bo, + uint32_t tiling_flags, uint32_t pitch) +{ + struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; + return boi->bom->funcs->bo_set_tiling(boi, tiling_flags, pitch); +} + +int radeon_bo_get_tiling(struct radeon_bo *bo, + uint32_t *tiling_flags, uint32_t *pitch) +{ + struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; + return boi->bom->funcs->bo_get_tiling(boi, tiling_flags, pitch); +} + +int radeon_bo_is_static(struct radeon_bo *bo) +{ + struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; + if (boi->bom->funcs->bo_is_static) + return boi->bom->funcs->bo_is_static(boi); + return 0; +} + +int radeon_bo_is_referenced_by_cs(struct radeon_bo *bo, + struct radeon_cs *cs) +{ + struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; + return boi->cref > 1; +} + +uint32_t radeon_bo_get_handle(struct radeon_bo *bo) +{ + return bo->handle; +} + +uint32_t radeon_bo_get_src_domain(struct radeon_bo *bo) +{ + struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; + uint32_t src_domain; + + src_domain = boi->space_accounted & 0xffff; + if (!src_domain) + src_domain = boi->space_accounted >> 16; + + return src_domain; +} diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_drm.h b/src/mesa/drivers/dri/radeon/radeon_bo_drm.h index 7141371633..beb2369880 100644 --- a/src/mesa/drivers/dri/radeon/radeon_bo_drm.h +++ b/src/mesa/drivers/dri/radeon/radeon_bo_drm.h @@ -32,188 +32,44 @@ #include <stdio.h> #include <stdint.h> -//#include "radeon_track.h" /* bo object */ #define RADEON_BO_FLAGS_MACRO_TILE 1 #define RADEON_BO_FLAGS_MICRO_TILE 2 struct radeon_bo_manager; +struct radeon_cs; struct radeon_bo { - uint32_t alignment; + void *ptr; + uint32_t flags; uint32_t handle; uint32_t size; - uint32_t domains; - uint32_t flags; - unsigned cref; -#ifdef RADEON_BO_TRACK - struct radeon_track *track; -#endif - void *ptr; - struct radeon_bo_manager *bom; - uint32_t space_accounted; -}; - -/* bo functions */ -struct radeon_bo_funcs { - struct radeon_bo *(*bo_open)(struct radeon_bo_manager *bom, - uint32_t handle, - uint32_t size, - uint32_t alignment, - uint32_t domains, - uint32_t flags); - void (*bo_ref)(struct radeon_bo *bo); - struct radeon_bo *(*bo_unref)(struct radeon_bo *bo); - 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); - int (*bo_set_tiling)(struct radeon_bo *bo, uint32_t tiling_flags, - uint32_t pitch); - int (*bo_get_tiling)(struct radeon_bo *bo, uint32_t *tiling_flags, - uint32_t *pitch); - int (*bo_is_busy)(struct radeon_bo *bo, uint32_t *domain); }; -struct radeon_bo_manager { - struct radeon_bo_funcs *funcs; - int fd; - -#ifdef RADEON_BO_TRACK - struct radeon_tracker tracker; -#endif -}; - -static inline void _radeon_bo_debug(struct radeon_bo *bo, - const char *op, - const char *file, - const char *func, - int line) -{ - fprintf(stderr, "%s %p 0x%08X 0x%08X 0x%08X [%s %s %d]\n", - op, bo, bo->handle, bo->size, bo->cref, file, func, line); -} - -static inline struct radeon_bo *_radeon_bo_open(struct radeon_bo_manager *bom, - uint32_t handle, - uint32_t size, - uint32_t alignment, - uint32_t domains, - uint32_t flags, - const char *file, - const char *func, - int line) -{ - struct radeon_bo *bo; - - bo = bom->funcs->bo_open(bom, handle, size, alignment, domains, flags); - -#ifdef RADEON_BO_TRACK - if (bo) { - bo->track = radeon_tracker_add_track(&bom->tracker, bo->handle); - radeon_track_add_event(bo->track, file, func, "open", line); - } -#endif - return bo; -} - -static inline void _radeon_bo_ref(struct radeon_bo *bo, - const char *file, - const char *func, - int line) -{ - bo->cref++; -#ifdef RADEON_BO_TRACK - radeon_track_add_event(bo->track, file, func, "ref", line); -#endif - bo->bom->funcs->bo_ref(bo); -} - -static inline struct radeon_bo *_radeon_bo_unref(struct radeon_bo *bo, - const char *file, - const char *func, - int line) -{ - bo->cref--; -#ifdef RADEON_BO_TRACK - radeon_track_add_event(bo->track, file, func, "unref", line); - if (bo->cref <= 0) { - radeon_tracker_remove_track(&bo->bom->tracker, bo->track); - bo->track = NULL; - } -#endif - return bo->bom->funcs->bo_unref(bo); -} - -static inline int _radeon_bo_map(struct radeon_bo *bo, - int write, - const char *file, - const char *func, - int line) -{ - return bo->bom->funcs->bo_map(bo, write); -} - -static inline int _radeon_bo_unmap(struct radeon_bo *bo, - const char *file, - const char *func, - int line) -{ - return bo->bom->funcs->bo_unmap(bo); -} - -static inline int _radeon_bo_wait(struct radeon_bo *bo, - const char *file, - const char *func, - int line) -{ - return bo->bom->funcs->bo_wait(bo); -} - -static inline int _radeon_bo_is_busy(struct radeon_bo *bo, - uint32_t *domain, - const char *file, - const char *func, - int line) -{ - return bo->bom->funcs->bo_is_busy(bo, domain); -} - -static inline int radeon_bo_set_tiling(struct radeon_bo *bo, - uint32_t tiling_flags, uint32_t pitch) -{ - return bo->bom->funcs->bo_set_tiling(bo, tiling_flags, pitch); -} - -static inline int radeon_bo_get_tiling(struct radeon_bo *bo, - uint32_t *tiling_flags, uint32_t *pitch) -{ - return bo->bom->funcs->bo_get_tiling(bo, tiling_flags, pitch); -} - -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)\ - _radeon_bo_ref(bo, __FILE__, __FUNCTION__, __LINE__) -#define radeon_bo_unref(bo)\ - _radeon_bo_unref(bo, __FILE__, __FUNCTION__, __LINE__) -#define radeon_bo_map(bo, w)\ - _radeon_bo_map(bo, w, __FILE__, __FUNCTION__, __LINE__) -#define radeon_bo_unmap(bo)\ - _radeon_bo_unmap(bo, __FILE__, __FUNCTION__, __LINE__) -#define radeon_bo_debug(bo, opcode)\ - _radeon_bo_debug(bo, opcode, __FILE__, __FUNCTION__, __LINE__) -#define radeon_bo_wait(bo) \ - _radeon_bo_wait(bo, __FILE__, __func__, __LINE__) -#define radeon_bo_is_busy(bo, domain) \ - _radeon_bo_is_busy(bo, domain, __FILE__, __func__, __LINE__) +struct radeon_bo_manager; +void radeon_bo_debug(struct radeon_bo *bo, + const char *op); + +struct radeon_bo *radeon_bo_open(struct radeon_bo_manager *bom, + uint32_t handle, + uint32_t size, + uint32_t alignment, + uint32_t domains, + uint32_t flags); + +void radeon_bo_ref(struct radeon_bo *bo); +struct radeon_bo *radeon_bo_unref(struct radeon_bo *bo); +int radeon_bo_map(struct radeon_bo *bo, int write); +int radeon_bo_unmap(struct radeon_bo *bo); +int radeon_bo_wait(struct radeon_bo *bo); +int radeon_bo_is_busy(struct radeon_bo *bo, uint32_t *domain); +int radeon_bo_set_tiling(struct radeon_bo *bo, uint32_t tiling_flags, uint32_t pitch); +int radeon_bo_get_tiling(struct radeon_bo *bo, uint32_t *tiling_flags, uint32_t *pitch); +int radeon_bo_is_static(struct radeon_bo *bo); +int radeon_bo_is_referenced_by_cs(struct radeon_bo *bo, + struct radeon_cs *cs); +uint32_t radeon_bo_get_handle(struct radeon_bo *bo); +uint32_t radeon_bo_get_src_domain(struct radeon_bo *bo); #endif diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_int_drm.h b/src/mesa/drivers/dri/radeon/radeon_bo_int_drm.h new file mode 100644 index 0000000000..190c332475 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_bo_int_drm.h @@ -0,0 +1,45 @@ +#ifndef RADEON_BO_INT +#define RADEON_BO_INT + +struct radeon_bo_manager { + struct radeon_bo_funcs *funcs; + int fd; +}; + +struct radeon_bo_int { + void *ptr; + uint32_t flags; + uint32_t handle; + uint32_t size; + /* private members */ + uint32_t alignment; + uint32_t domains; + unsigned cref; + struct radeon_bo_manager *bom; + uint32_t space_accounted; + uint32_t referenced_in_cs; +}; + +/* bo functions */ +struct radeon_bo_funcs { + struct radeon_bo *(*bo_open)(struct radeon_bo_manager *bom, + uint32_t handle, + uint32_t size, + uint32_t alignment, + uint32_t domains, + uint32_t flags); + void (*bo_ref)(struct radeon_bo_int *bo); + struct radeon_bo *(*bo_unref)(struct radeon_bo_int *bo); + int (*bo_map)(struct radeon_bo_int *bo, int write); + int (*bo_unmap)(struct radeon_bo_int *bo); + int (*bo_wait)(struct radeon_bo_int *bo); + int (*bo_is_static)(struct radeon_bo_int *bo); + int (*bo_set_tiling)(struct radeon_bo_int *bo, uint32_t tiling_flags, + uint32_t pitch); + int (*bo_get_tiling)(struct radeon_bo_int *bo, uint32_t *tiling_flags, + uint32_t *pitch); + int (*bo_is_busy)(struct radeon_bo_int *bo, uint32_t *domain); + int (*bo_is_referenced_by_cs)(struct radeon_bo_int *bo, struct radeon_cs *cs); +}; + +#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c index ce60a2f7ea..cf12664bac 100644 --- a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c +++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c @@ -50,6 +50,12 @@ #include "radeon_bocs_wrapper.h" #include "radeon_macros.h" +#ifdef HAVE_LIBDRM_RADEON +#include "radeon_bo_int.h" +#else +#include "radeon_bo_int_drm.h" +#endif + /* no seriously texmem.c is this screwed up */ struct bo_legacy_texture_object { driTextureObject base; @@ -57,7 +63,7 @@ struct bo_legacy_texture_object { }; struct bo_legacy { - struct radeon_bo base; + struct radeon_bo_int base; int map_count; uint32_t pending; int is_pending; @@ -187,10 +193,10 @@ static void legacy_get_current_age(struct bo_manager_legacy *boml) } } -static int legacy_is_pending(struct radeon_bo *bo) +static int legacy_is_pending(struct radeon_bo_int *boi) { - struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom; - struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; + struct bo_manager_legacy *boml = (struct bo_manager_legacy *)boi->bom; + struct bo_legacy *bo_legacy = (struct bo_legacy*)boi; if (bo_legacy->is_pending <= 0) { bo_legacy->is_pending = 0; @@ -204,13 +210,13 @@ static int legacy_is_pending(struct radeon_bo *bo) if (bo_legacy->pnext) { bo_legacy->pnext->pprev = bo_legacy->pprev; } - assert(bo_legacy->is_pending <= bo->cref); + assert(bo_legacy->is_pending <= boi->cref); while (bo_legacy->is_pending--) { - bo = radeon_bo_unref(bo); - if (!bo) + boi = (struct radeon_bo_int *)radeon_bo_unref((struct radeon_bo *)boi); + if (!boi) break; } - if (bo) + if (boi) bo_legacy->is_pending = 0; boml->cpendings--; return 0; @@ -218,7 +224,7 @@ static int legacy_is_pending(struct radeon_bo *bo) return 1; } -static int legacy_wait_pending(struct radeon_bo *bo) +static int legacy_wait_pending(struct radeon_bo_int *bo) { struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom; struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; @@ -323,7 +329,7 @@ static struct bo_legacy *bo_allocate(struct bo_manager_legacy *boml, return bo_legacy; } -static int bo_dma_alloc(struct radeon_bo *bo) +static int bo_dma_alloc(struct radeon_bo_int *bo) { struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom; struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; @@ -333,7 +339,7 @@ static int bo_dma_alloc(struct radeon_bo *bo) int r; /* align size on 4Kb */ - size = (((4 * 1024) - 1) + bo->size) & ~((4 * 1024) - 1); + size = (((4 * 1024) - 1) + bo_legacy->base.size) & ~((4 * 1024) - 1); alloc.region = RADEON_MEM_REGION_GART; alloc.alignment = bo_legacy->base.alignment; alloc.size = size; @@ -355,7 +361,7 @@ static int bo_dma_alloc(struct radeon_bo *bo) return 0; } -static int bo_dma_free(struct radeon_bo *bo) +static int bo_dma_free(struct radeon_bo_int *bo) { struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom; struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; @@ -428,7 +434,7 @@ static struct radeon_bo *bo_open(struct radeon_bo_manager *bom, bo_legacy = boml->bos.next; while (bo_legacy) { if (bo_legacy->base.handle == handle) { - radeon_bo_ref(&(bo_legacy->base)); + radeon_bo_ref((struct radeon_bo *)&(bo_legacy->base)); return (struct radeon_bo*)bo_legacy; } bo_legacy = bo_legacy->next; @@ -468,20 +474,20 @@ retry: return NULL; } } - radeon_bo_ref(&(bo_legacy->base)); + radeon_bo_ref((struct radeon_bo *)&(bo_legacy->base)); return (struct radeon_bo*)bo_legacy; } -static void bo_ref(struct radeon_bo *bo) +static void bo_ref(struct radeon_bo_int *bo) { } -static struct radeon_bo *bo_unref(struct radeon_bo *bo) +static struct radeon_bo *bo_unref(struct radeon_bo_int *boi) { - struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; + struct bo_legacy *bo_legacy = (struct bo_legacy*)boi; - if (bo->cref <= 0) { + if (boi->cref <= 0) { bo_legacy->prev->next = bo_legacy->next; if (bo_legacy->next) { bo_legacy->next->prev = bo_legacy->prev; @@ -491,10 +497,10 @@ static struct radeon_bo *bo_unref(struct radeon_bo *bo) } return NULL; } - return bo; + return (struct radeon_bo *)boi; } -static int bo_map(struct radeon_bo *bo, int write) +static int bo_map(struct radeon_bo_int *bo, int write) { struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom; struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; @@ -528,7 +534,7 @@ static int bo_map(struct radeon_bo *bo, int write) return 0; } -static int bo_unmap(struct radeon_bo *bo) +static int bo_unmap(struct radeon_bo_int *bo) { struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; @@ -542,7 +548,7 @@ static int bo_unmap(struct radeon_bo *bo) return 0; } -static int bo_is_busy(struct radeon_bo *bo, uint32_t *domain) +static int bo_is_busy(struct radeon_bo_int *bo, uint32_t *domain) { *domain = 0; if (bo->domains & RADEON_GEM_DOMAIN_GTT) @@ -555,7 +561,7 @@ static int bo_is_busy(struct radeon_bo *bo, uint32_t *domain) return 0; } -static int bo_is_static(struct radeon_bo *bo) +static int bo_is_static(struct radeon_bo_int *bo) { struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; return bo_legacy->static_bo; @@ -574,7 +580,7 @@ static struct radeon_bo_funcs bo_legacy_funcs = { bo_is_busy }; -static int bo_vram_validate(struct radeon_bo *bo, +static int bo_vram_validate(struct radeon_bo_int *bo, uint32_t *soffset, uint32_t *eoffset) { @@ -700,29 +706,30 @@ int radeon_bo_legacy_validate(struct radeon_bo *bo, uint32_t *soffset, uint32_t *eoffset) { - struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom; + struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; + struct bo_manager_legacy *boml = (struct bo_manager_legacy *)boi->bom; struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; int r; int retries = 0; if (bo_legacy->map_count) { fprintf(stderr, "bo(%p, %d) is mapped (%d) can't valide it.\n", - bo, bo->size, bo_legacy->map_count); + bo, boi->size, bo_legacy->map_count); return -EINVAL; } - if(bo->size == 0) { + if(boi->size == 0) { fprintf(stderr, "bo(%p) has size 0.\n", bo); return -EINVAL; } if (bo_legacy->static_bo || bo_legacy->validated) { *soffset = bo_legacy->offset; - *eoffset = bo_legacy->offset + bo->size; + *eoffset = bo_legacy->offset + boi->size; return 0; } - if (!(bo->domains & RADEON_GEM_DOMAIN_GTT)) { + if (!(boi->domains & RADEON_GEM_DOMAIN_GTT)) { - r = bo_vram_validate(bo, soffset, eoffset); + r = bo_vram_validate(boi, soffset, eoffset); if (r) { legacy_track_pending(&boml->base, 0); legacy_kick_all_buffers(boml); @@ -736,7 +743,7 @@ int radeon_bo_legacy_validate(struct radeon_bo *bo, } } *soffset = bo_legacy->offset; - *eoffset = bo_legacy->offset + bo->size; + *eoffset = bo_legacy->offset + boi->size; bo_legacy->validated = 1; return 0; @@ -744,7 +751,8 @@ int radeon_bo_legacy_validate(struct radeon_bo *bo, void radeon_bo_legacy_pending(struct radeon_bo *bo, uint32_t pending) { - struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom; + struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; + struct bo_manager_legacy *boml = (struct bo_manager_legacy *)boi->bom; struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; bo_legacy->pending = pending; @@ -799,7 +807,7 @@ static struct bo_legacy *radeon_legacy_bo_alloc_static(struct bo_manager_legacy if (bo->base.handle > bom->nhandle) { bom->nhandle = bo->base.handle + 1; } - radeon_bo_ref(&(bo->base)); + radeon_bo_ref((struct radeon_bo *)&(bo->base)); return bo; } @@ -894,12 +902,13 @@ void radeon_bo_legacy_texture_age(struct radeon_bo_manager *bom) unsigned radeon_bo_legacy_relocs_size(struct radeon_bo *bo) { + struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; - if (bo_legacy->static_bo || (bo->domains & RADEON_GEM_DOMAIN_GTT)) { + if (bo_legacy->static_bo || (boi->domains & RADEON_GEM_DOMAIN_GTT)) { return 0; } - return bo->size; + return boi->size; } /* @@ -924,7 +933,7 @@ struct radeon_bo *radeon_legacy_bo_alloc_fake(struct radeon_bo_manager *bom, if (bo->base.handle > boml->nhandle) { boml->nhandle = bo->base.handle + 1; } - radeon_bo_ref(&(bo->base)); - return &(bo->base); + radeon_bo_ref((struct radeon_bo *)&(bo->base)); + return (struct radeon_bo *)&(bo->base); } diff --git a/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h b/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h index 4520a7d7d4..6c2648b6bd 100644 --- a/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h +++ b/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h @@ -18,8 +18,11 @@ #define RADEON_TILING_MACRO 0x1 #define RADEON_TILING_MICRO 0x2 #define RADEON_TILING_SWAP 0x4 + +#ifndef RADEON_TILING_SURFACE #define RADEON_TILING_SURFACE 0x8 /* this object requires a surface * when mapped - i.e. front buffer */ +#endif /* to be used to build locally in mesa with no libdrm bits */ #include "../radeon/radeon_bo_drm.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c b/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c index 8fac5c6c51..99d3ec7005 100644 --- a/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c +++ b/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c @@ -136,8 +136,13 @@ radeonBufferSubData(GLcontext * ctx, const GLvoid * data, struct gl_buffer_object *obj) { + radeonContextPtr radeon = RADEON_CONTEXT(ctx); struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj); + if (radeon_bo_is_referenced_by_cs(radeon_obj->bo, radeon->cmdbuf.cs)) { + radeon_firevertices(radeon); + } + radeon_bo_map(radeon_obj->bo, GL_TRUE); _mesa_memcpy(radeon_obj->bo->ptr + offset, data, size); diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index 097ab7cf61..e0b853bc97 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -137,7 +137,7 @@ void radeon_get_cliprects(radeonContextPtr radeon, unsigned int *num_cliprects, int *x_off, int *y_off) { - __DRIdrawablePrivate *dPriv = radeon_get_drawable(radeon); + __DRIdrawable *dPriv = radeon_get_drawable(radeon); struct radeon_framebuffer *rfb = dPriv->driverPrivate; if (radeon->constant_cliprect) { @@ -169,8 +169,8 @@ void radeon_get_cliprects(radeonContextPtr radeon, */ void radeonSetCliprects(radeonContextPtr radeon) { - __DRIdrawablePrivate *const drawable = radeon_get_drawable(radeon); - __DRIdrawablePrivate *const readable = radeon_get_readable(radeon); + __DRIdrawable *const drawable = radeon_get_drawable(radeon); + __DRIdrawable *const readable = radeon_get_readable(radeon); struct radeon_framebuffer *const draw_rfb = drawable->driverPrivate; struct radeon_framebuffer *const read_rfb = readable->driverPrivate; int x_off, y_off; @@ -229,7 +229,7 @@ void radeonUpdateScissor( GLcontext *ctx ) } if (!rmesa->radeonScreen->kernel_mm) { /* Fix scissors for dri 1 */ - __DRIdrawablePrivate *dPriv = radeon_get_drawable(rmesa); + __DRIdrawable *dPriv = radeon_get_drawable(rmesa); x1 += dPriv->x; x2 += dPriv->x + 1; min_x += dPriv->x; @@ -262,29 +262,6 @@ void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h) } } -void radeonPolygonStipplePreKMS( GLcontext *ctx, const GLubyte *mask ) -{ - radeonContextPtr radeon = RADEON_CONTEXT(ctx); - GLuint i; - drm_radeon_stipple_t stipple; - - /* Must flip pattern upside down. - */ - for ( i = 0 ; i < 32 ; i++ ) { - stipple.mask[31 - i] = ((GLuint *) mask)[i]; - } - - /* TODO: push this into cmd mechanism - */ - radeon_firevertices(radeon); - LOCK_HARDWARE( radeon ); - - drmCommandWrite( radeon->dri.fd, DRM_RADEON_STIPPLE, - &stipple, sizeof(stipple) ); - UNLOCK_HARDWARE( radeon ); -} - - /* ================================================================ * SwapBuffers with client-side throttling */ @@ -451,7 +428,7 @@ static void radeon_flip_renderbuffers(struct radeon_framebuffer *rfb) /* Copy the back color buffer to the front color buffer. */ -void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, +void radeonCopyBuffer( __DRIdrawable *dPriv, const drm_clip_rect_t *rect) { radeonContextPtr rmesa; @@ -519,7 +496,7 @@ void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, UNLOCK_HARDWARE( rmesa ); } -static int radeonScheduleSwap(__DRIdrawablePrivate *dPriv, GLboolean *missed_target) +static int radeonScheduleSwap(__DRIdrawable *dPriv, GLboolean *missed_target) { radeonContextPtr rmesa; @@ -542,11 +519,11 @@ static int radeonScheduleSwap(__DRIdrawablePrivate *dPriv, GLboolean *missed_tar return 0; } -static GLboolean radeonPageFlip( __DRIdrawablePrivate *dPriv ) +static GLboolean radeonPageFlip( __DRIdrawable *dPriv ) { radeonContextPtr radeon; GLint ret; - __DRIscreenPrivate *psp; + __DRIscreen *psp; struct radeon_renderbuffer *rrb; struct radeon_framebuffer *rfb; @@ -594,10 +571,10 @@ static GLboolean radeonPageFlip( __DRIdrawablePrivate *dPriv ) /** * Swap front and back buffer. */ -void radeonSwapBuffers(__DRIdrawablePrivate * dPriv) +void radeonSwapBuffers(__DRIdrawable * dPriv) { int64_t ust; - __DRIscreenPrivate *psp; + __DRIscreen *psp; if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { radeonContextPtr radeon; @@ -638,7 +615,7 @@ void radeonSwapBuffers(__DRIdrawablePrivate * dPriv) } } -void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, +void radeonCopySubBuffer(__DRIdrawable * dPriv, int x, int y, int w, int h ) { if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { @@ -664,6 +641,27 @@ void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, } } +/** + * Check if we're about to draw into the front color buffer. + * If so, set the intel->front_buffer_dirty field to true. + */ +void +radeon_check_front_buffer_rendering(GLcontext *ctx) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + const struct gl_framebuffer *fb = ctx->DrawBuffer; + + if (fb->Name == 0) { + /* drawing to window system buffer */ + if (fb->_NumColorDrawBuffers > 0) { + if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { + radeon->front_buffer_dirty = GL_TRUE; + } + } + } +} + + void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb) { radeonContextPtr radeon = RADEON_CONTEXT(ctx); @@ -840,7 +838,7 @@ void radeonDrawBuffer( GLcontext *ctx, GLenum mode ) */ if (!was_front_buffer_rendering && radeon->is_front_buffer_rendering) { radeon_update_renderbuffers(radeon->dri.context, - radeon->dri.context->driDrawablePriv); + radeon->dri.context->driDrawablePriv, GL_FALSE); } } @@ -857,7 +855,7 @@ void radeonReadBuffer( GLcontext *ctx, GLenum mode ) if (!was_front_buffer_reading && rmesa->is_front_buffer_reading) { radeon_update_renderbuffers(rmesa->dri.context, - rmesa->dri.context->driReadablePriv); + rmesa->dri.context->driReadablePriv, GL_FALSE); } } /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */ @@ -908,9 +906,9 @@ void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei he if (radeon->is_front_buffer_rendering) { ctx->Driver.Flush(ctx); } - radeon_update_renderbuffers(driContext, driContext->driDrawablePriv); + radeon_update_renderbuffers(driContext, driContext->driDrawablePriv, GL_FALSE); if (driContext->driDrawablePriv != driContext->driReadablePriv) - radeon_update_renderbuffers(driContext, driContext->driReadablePriv); + radeon_update_renderbuffers(driContext, driContext->driReadablePriv, GL_FALSE); } old_viewport = ctx->Driver.Viewport; @@ -1118,22 +1116,21 @@ void radeonFlush(GLcontext *ctx) then no point flushing anything at all. */ if (!radeon->dma.flush && !radeon->cmdbuf.cs->cdw && is_empty_list(&radeon->dma.reserved)) - return; + goto flush_front; if (radeon->dma.flush) radeon->dma.flush( ctx ); - radeonEmitState(radeon); - if (radeon->cmdbuf.cs->cdw) rcommonFlushCmdBuf(radeon, __FUNCTION__); +flush_front: if ((ctx->DrawBuffer->Name == 0) && radeon->front_buffer_dirty) { __DRIscreen *const screen = radeon->radeonScreen->driScreen; if (screen->dri2.loader && (screen->dri2.loader->base.version >= 2) && (screen->dri2.loader->flushFrontBuffer != NULL)) { - __DRIdrawablePrivate * drawable = radeon_get_drawable(radeon); + __DRIdrawable * drawable = radeon_get_drawable(radeon); (*screen->dri2.loader->flushFrontBuffer)(drawable, drawable->loaderPrivate); /* Only clear the dirty bit if front-buffer rendering is no longer @@ -1147,9 +1144,6 @@ void radeonFlush(GLcontext *ctx) } } } - - make_empty_list(&radeon->query.not_flushed_head); - } /* Make sure all commands have been sent to the hardware and have @@ -1236,7 +1230,7 @@ int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller) fprintf(stderr, "drmRadeonCmdBuffer: %d. Kernel failed to " "parse or rejected command stream. See dmesg " "for more info.\n", ret); - _mesa_exit(ret); + exit(ret); } return ret; diff --git a/src/mesa/drivers/dri/radeon/radeon_common.h b/src/mesa/drivers/dri/radeon/radeon_common.h index def0cc17a9..f31f08edf3 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.h +++ b/src/mesa/drivers/dri/radeon/radeon_common.h @@ -10,14 +10,13 @@ void radeonRecalcScissorRects(radeonContextPtr radeon); void radeonSetCliprects(radeonContextPtr radeon); void radeonUpdateScissor( GLcontext *ctx ); void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h); -void radeonPolygonStipplePreKMS( GLcontext *ctx, const GLubyte *mask ); void radeonWaitForIdleLocked(radeonContextPtr radeon); extern uint32_t radeonGetAge(radeonContextPtr radeon); -void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, +void radeonCopyBuffer( __DRIdrawable *dPriv, const drm_clip_rect_t *rect); -void radeonSwapBuffers(__DRIdrawablePrivate * dPriv); -void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, +void radeonSwapBuffers(__DRIdrawable * dPriv); +void radeonCopySubBuffer(__DRIdrawable * dPriv, int x, int y, int w, int h ); void radeonUpdatePageFlipping(radeonContextPtr rmesa); @@ -43,7 +42,9 @@ void radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb, struct radeon_bo *bo); struct radeon_renderbuffer * -radeon_create_renderbuffer(gl_format format, __DRIdrawablePrivate *driDrawPriv); +radeon_create_renderbuffer(gl_format format, __DRIdrawable *driDrawPriv); + +void radeon_check_front_buffer_rendering(GLcontext *ctx); static inline struct radeon_renderbuffer *radeon_renderbuffer(struct gl_renderbuffer *rb) { struct radeon_renderbuffer *rrb = (struct radeon_renderbuffer *)rb; diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c index fe99644907..b9c29b937e 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c @@ -181,10 +181,10 @@ static void radeonInitDriverFuncs(struct dd_function_table *functions) GLboolean radeonInitContext(radeonContextPtr radeon, struct dd_function_table* functions, const __GLcontextModes * glVisual, - __DRIcontextPrivate * driContextPriv, + __DRIcontext * driContextPriv, void *sharedContextPrivate) { - __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + __DRIscreen *sPriv = driContextPriv->driScreenPriv; radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private); GLcontext* ctx; GLcontext* shareCtx; @@ -262,10 +262,9 @@ GLboolean radeonInitContext(radeonContextPtr radeon, else radeon->texture_row_align = 32; radeon->texture_rect_row_align = 64; - radeon->texture_compressed_row_align = 64; + radeon->texture_compressed_row_align = 32; } - make_empty_list(&radeon->query.not_flushed_head); radeon_init_dma(radeon); return GL_TRUE; @@ -292,7 +291,7 @@ static void radeon_destroy_atom_list(radeonContextPtr radeon) * Cleanup common context fields. * Called by r200DestroyContext/r300DestroyContext */ -void radeonDestroyContext(__DRIcontextPrivate *driContextPriv ) +void radeonDestroyContext(__DRIcontext *driContextPriv ) { #ifdef RADEON_BO_TRACK FILE *track; @@ -356,7 +355,7 @@ void radeonDestroyContext(__DRIcontextPrivate *driContextPriv ) /* Force the context `c' to be unbound from its buffer. */ -GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv) +GLboolean radeonUnbindContext(__DRIcontext * driContextPriv) { radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate; @@ -500,7 +499,8 @@ radeon_bits_per_pixel(const struct radeon_renderbuffer *rb) } void -radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) +radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable, + GLboolean front_only) { unsigned int attachments[10]; __DRIbuffer *buffers = NULL; @@ -526,7 +526,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) struct radeon_renderbuffer *stencil_rb; i = 0; - if ((radeon->is_front_buffer_rendering || + if ((front_only || radeon->is_front_buffer_rendering || radeon->is_front_buffer_reading || !draw->color_rb[1]) && draw->color_rb[0]) { @@ -534,23 +534,25 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) attachments[i++] = radeon_bits_per_pixel(draw->color_rb[0]); } - if (draw->color_rb[1]) { - attachments[i++] = __DRI_BUFFER_BACK_LEFT; - attachments[i++] = radeon_bits_per_pixel(draw->color_rb[1]); - } + if (!front_only) { + if (draw->color_rb[1]) { + attachments[i++] = __DRI_BUFFER_BACK_LEFT; + attachments[i++] = radeon_bits_per_pixel(draw->color_rb[1]); + } - depth_rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH); - stencil_rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL); - - if ((depth_rb != NULL) && (stencil_rb != NULL)) { - attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL; - attachments[i++] = radeon_bits_per_pixel(depth_rb); - } else if (depth_rb != NULL) { - attachments[i++] = __DRI_BUFFER_DEPTH; - attachments[i++] = radeon_bits_per_pixel(depth_rb); - } else if (stencil_rb != NULL) { - attachments[i++] = __DRI_BUFFER_STENCIL; - attachments[i++] = radeon_bits_per_pixel(stencil_rb); + depth_rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH); + stencil_rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL); + + if ((depth_rb != NULL) && (stencil_rb != NULL)) { + attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL; + attachments[i++] = radeon_bits_per_pixel(depth_rb); + } else if (depth_rb != NULL) { + attachments[i++] = __DRI_BUFFER_DEPTH; + attachments[i++] = radeon_bits_per_pixel(depth_rb); + } else if (stencil_rb != NULL) { + attachments[i++] = __DRI_BUFFER_STENCIL; + attachments[i++] = radeon_bits_per_pixel(stencil_rb); + } } buffers = (*screen->dri2.loader->getBuffersWithFormat)(drawable, @@ -563,12 +565,14 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) i = 0; if (draw->color_rb[0]) attachments[i++] = __DRI_BUFFER_FRONT_LEFT; - if (draw->color_rb[1]) - attachments[i++] = __DRI_BUFFER_BACK_LEFT; - if (radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH)) - attachments[i++] = __DRI_BUFFER_DEPTH; - if (radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL)) - attachments[i++] = __DRI_BUFFER_STENCIL; + if (!front_only) { + if (draw->color_rb[1]) + attachments[i++] = __DRI_BUFFER_BACK_LEFT; + if (radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH)) + attachments[i++] = __DRI_BUFFER_DEPTH; + if (radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL)) + attachments[i++] = __DRI_BUFFER_STENCIL; + } buffers = (*screen->dri2.loader->getBuffers)(drawable, &drawable->w, @@ -716,9 +720,9 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) /* Force the context `c' to be the current context and associate with it * buffer `b'. */ -GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, - __DRIdrawablePrivate * driDrawPriv, - __DRIdrawablePrivate * driReadPriv) +GLboolean radeonMakeCurrent(__DRIcontext * driContextPriv, + __DRIdrawable * driDrawPriv, + __DRIdrawable * driReadPriv) { radeonContextPtr radeon; struct radeon_framebuffer *drfb; @@ -736,9 +740,9 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, readfb = driReadPriv->driverPrivate; if (driContextPriv->driScreenPriv->dri2.enabled) { - radeon_update_renderbuffers(driContextPriv, driDrawPriv); + radeon_update_renderbuffers(driContextPriv, driDrawPriv, GL_FALSE); if (driDrawPriv != driReadPriv) - radeon_update_renderbuffers(driContextPriv, driReadPriv); + radeon_update_renderbuffers(driContextPriv, driReadPriv, GL_FALSE); _mesa_reference_renderbuffer(&radeon->state.color.rb, &(radeon_get_renderbuffer(&drfb->base, BUFFER_BACK_LEFT)->base)); _mesa_reference_renderbuffer(&radeon->state.depth.rb, diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h index 0309345393..ab79d2dc0f 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h @@ -92,7 +92,7 @@ struct radeon_renderbuffer GLuint pf_pending; /**< sequence number of pending flip */ GLuint vbl_pending; /**< vblank sequence number of pending flip */ - __DRIdrawablePrivate *dPriv; + __DRIdrawable *dPriv; }; struct radeon_framebuffer @@ -208,6 +208,10 @@ struct radeon_tex_obj { * and so on. */ GLboolean validated; + /* Minimum LOD to be used during rendering */ + unsigned minLod; + /* Miximum LOD to be used during rendering */ + unsigned maxLod; GLuint override_offset; GLboolean image_override; /* Image overridden by GLX_EXT_tfp */ @@ -324,6 +328,7 @@ struct radeon_swtcl_info { GLuint vertex_attr_count; GLuint emit_prediction; + struct radeon_bo *bo; }; #define RADEON_MAX_AOS_ARRAYS 16 @@ -376,8 +381,8 @@ struct radeon_store { }; struct radeon_dri_mirror { - __DRIcontextPrivate *context; /* DRI context */ - __DRIscreenPrivate *screen; /* DRI screen */ + __DRIcontext *context; /* DRI context */ + __DRIscreen *screen; /* DRI screen */ drm_context_t hwContext; drm_hw_lock_t *hwLock; @@ -401,9 +406,6 @@ struct radeon_state { struct radeon_depthbuffer_state depth; struct radeon_scissor_state scissor; struct radeon_stencilbuffer_state stencil; - - struct radeon_cs_space_check bos[RADEON_MAX_BOS]; - int validated_bo_count; }; /** @@ -502,7 +504,6 @@ struct radeon_context { struct { struct radeon_query_object *current; - struct radeon_query_object not_flushed_head; struct radeon_state_atom queryobj; } query; @@ -522,12 +523,12 @@ struct radeon_context { #define RADEON_CONTEXT(glctx) ((radeonContextPtr)(ctx->DriverCtx)) -static inline __DRIdrawablePrivate* radeon_get_drawable(radeonContextPtr radeon) +static inline __DRIdrawable* radeon_get_drawable(radeonContextPtr radeon) { return radeon->dri.context->driDrawablePriv; } -static inline __DRIdrawablePrivate* radeon_get_readable(radeonContextPtr radeon) +static inline __DRIdrawable* radeon_get_readable(radeonContextPtr radeon) { return radeon->dri.context->driReadablePriv; } @@ -580,15 +581,16 @@ static INLINE uint32_t radeonPackFloat24(float f) GLboolean radeonInitContext(radeonContextPtr radeon, struct dd_function_table* functions, const __GLcontextModes * glVisual, - __DRIcontextPrivate * driContextPriv, + __DRIcontext * driContextPriv, void *sharedContextPrivate); void radeonCleanupContext(radeonContextPtr radeon); -GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv); -void radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable); -GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, - __DRIdrawablePrivate * driDrawPriv, - __DRIdrawablePrivate * driReadPriv); -extern void radeonDestroyContext(__DRIcontextPrivate * driContextPriv); +GLboolean radeonUnbindContext(__DRIcontext * driContextPriv); +void radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable, + GLboolean front_only); +GLboolean radeonMakeCurrent(__DRIcontext * driContextPriv, + __DRIdrawable * driDrawPriv, + __DRIdrawable * driReadPriv); +extern void radeonDestroyContext(__DRIcontext * driContextPriv); #endif diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index 5e700be4a5..3cd305b0a2 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -208,10 +208,10 @@ static void r100_init_vtbl(radeonContextPtr radeon) */ GLboolean r100CreateContext( const __GLcontextModes *glVisual, - __DRIcontextPrivate *driContextPriv, + __DRIcontext *driContextPriv, void *sharedContextPrivate) { - __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + __DRIscreen *sPriv = driContextPriv->driScreenPriv; radeonScreenPtr screen = (radeonScreenPtr)(sPriv->private); struct dd_function_table functions; r100ContextPtr rmesa; diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h index 4e2c52c835..dfedc38bfd 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_context.h @@ -331,8 +331,12 @@ struct r100_hw_state { struct radeon_state_atom stp; }; +struct radeon_stipple_state { + GLuint mask[32]; +}; struct r100_state { + struct radeon_stipple_state stipple; struct radeon_texture_state texture; }; @@ -447,7 +451,7 @@ struct r100_context { #define RADEON_OLD_PACKETS 1 extern GLboolean r100CreateContext( const __GLcontextModes *glVisual, - __DRIcontextPrivate *driContextPriv, + __DRIcontext *driContextPriv, void *sharedContextPrivate); diff --git a/src/mesa/drivers/dri/radeon/radeon_cs.c b/src/mesa/drivers/dri/radeon/radeon_cs.c new file mode 100644 index 0000000000..17e7433369 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_cs.c @@ -0,0 +1,95 @@ + +#include <stdio.h> +#include <stdint.h> +#include "drm.h" +#include "radeon_drm.h" +#include "radeon_bocs_wrapper.h" +#include "radeon_cs_int_drm.h" + +struct radeon_cs *radeon_cs_create(struct radeon_cs_manager *csm, + uint32_t ndw) +{ + struct radeon_cs_int *csi = csm->funcs->cs_create(csm, ndw); + return (struct radeon_cs *)csi; +} + +int radeon_cs_write_reloc(struct radeon_cs *cs, + struct radeon_bo *bo, + uint32_t read_domain, + uint32_t write_domain, + uint32_t flags) +{ + struct radeon_cs_int *csi = (struct radeon_cs_int *)cs; + + return csi->csm->funcs->cs_write_reloc(csi, + bo, + read_domain, + write_domain, + flags); +} + +int radeon_cs_begin(struct radeon_cs *cs, + uint32_t ndw, + const char *file, + const char *func, + int line) +{ + struct radeon_cs_int *csi = (struct radeon_cs_int *)cs; + return csi->csm->funcs->cs_begin(csi, ndw, file, func, line); +} + +int radeon_cs_end(struct radeon_cs *cs, + const char *file, + const char *func, + int line) +{ + struct radeon_cs_int *csi = (struct radeon_cs_int *)cs; + return csi->csm->funcs->cs_end(csi, file, func, line); +} + +int radeon_cs_emit(struct radeon_cs *cs) +{ + struct radeon_cs_int *csi = (struct radeon_cs_int *)cs; + return csi->csm->funcs->cs_emit(csi); +} + +int radeon_cs_destroy(struct radeon_cs *cs) +{ + struct radeon_cs_int *csi = (struct radeon_cs_int *)cs; + return csi->csm->funcs->cs_destroy(csi); +} + +int radeon_cs_erase(struct radeon_cs *cs) +{ + struct radeon_cs_int *csi = (struct radeon_cs_int *)cs; + return csi->csm->funcs->cs_erase(csi); +} + +int radeon_cs_need_flush(struct radeon_cs *cs) +{ + struct radeon_cs_int *csi = (struct radeon_cs_int *)cs; + return csi->csm->funcs->cs_need_flush(csi); +} + +void radeon_cs_print(struct radeon_cs *cs, FILE *file) +{ + struct radeon_cs_int *csi = (struct radeon_cs_int *)cs; + csi->csm->funcs->cs_print(csi, file); +} + +void radeon_cs_set_limit(struct radeon_cs *cs, uint32_t domain, uint32_t limit) +{ + struct radeon_cs_int *csi = (struct radeon_cs_int *)cs; + if (domain == RADEON_GEM_DOMAIN_VRAM) + csi->csm->vram_limit = limit; + else + csi->csm->gart_limit = limit; +} + +void radeon_cs_space_set_flush(struct radeon_cs *cs, void (*fn)(void *), void *data) +{ + struct radeon_cs_int *csi = (struct radeon_cs_int *)cs; + csi->space_flush_fn = fn; + csi->space_flush_data = data; +} + diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_drm.h b/src/mesa/drivers/dri/radeon/radeon_cs_drm.h index ab4eca31a3..a3f1750c6e 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cs_drm.h +++ b/src/mesa/drivers/dri/radeon/radeon_cs_drm.h @@ -36,6 +36,7 @@ #include <string.h> #include "drm.h" #include "radeon_drm.h" +#include "radeon_bo_drm.h" struct radeon_cs_reloc { struct radeon_bo *bo; @@ -49,173 +50,41 @@ struct radeon_cs_reloc { #define RADEON_CS_SPACE_OP_TO_BIG 1 #define RADEON_CS_SPACE_FLUSH 2 -struct radeon_cs_space_check { - struct radeon_bo *bo; - uint32_t read_domains; - uint32_t write_domain; - uint32_t new_accounted; -}; - -#define MAX_SPACE_BOS (32) - -struct radeon_cs_manager; - struct radeon_cs { - struct radeon_cs_manager *csm; - void *relocs; - uint32_t *packets; - unsigned crelocs; - unsigned relocs_total_size; - unsigned cdw; - unsigned ndw; - int section; + uint32_t *packets; + unsigned cdw; + unsigned ndw; unsigned section_ndw; unsigned section_cdw; - 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 */ -struct radeon_cs_funcs { - struct radeon_cs *(*cs_create)(struct radeon_cs_manager *csm, - uint32_t ndw); - int (*cs_write_reloc)(struct radeon_cs *cs, - struct radeon_bo *bo, - uint32_t read_domain, - uint32_t write_domain, - uint32_t flags); - int (*cs_begin)(struct radeon_cs *cs, - uint32_t ndw, - const char *file, - const char *func, - int line); - int (*cs_end)(struct radeon_cs *cs, - const char *file, - const char *func, - int line); - int (*cs_emit)(struct radeon_cs *cs); - int (*cs_destroy)(struct radeon_cs *cs); - int (*cs_erase)(struct radeon_cs *cs); - int (*cs_need_flush)(struct radeon_cs *cs); - void (*cs_print)(struct radeon_cs *cs, FILE *file); -}; - -struct radeon_cs_manager { - struct radeon_cs_funcs *funcs; - int fd; - 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, - uint32_t ndw) -{ - return csm->funcs->cs_create(csm, ndw); -} - -static inline int radeon_cs_write_reloc(struct radeon_cs *cs, - struct radeon_bo *bo, - uint32_t read_domain, - uint32_t write_domain, - uint32_t flags) -{ - return cs->csm->funcs->cs_write_reloc(cs, - bo, - read_domain, - write_domain, - flags); -} - -static inline int radeon_cs_begin(struct radeon_cs *cs, - uint32_t ndw, - const char *file, - const char *func, - int line) -{ - return cs->csm->funcs->cs_begin(cs, ndw, file, func, line); -} - -static inline int radeon_cs_end(struct radeon_cs *cs, - const char *file, - const char *func, - int line) -{ - return cs->csm->funcs->cs_end(cs, file, func, line); -} - -static inline int radeon_cs_emit(struct radeon_cs *cs) -{ - return cs->csm->funcs->cs_emit(cs); -} - -static inline int radeon_cs_destroy(struct radeon_cs *cs) -{ - return cs->csm->funcs->cs_destroy(cs); -} - -static inline int radeon_cs_erase(struct radeon_cs *cs) -{ - return cs->csm->funcs->cs_erase(cs); -} - -static inline int radeon_cs_need_flush(struct radeon_cs *cs) -{ - return cs->csm->funcs->cs_need_flush(cs); -} - -static inline void radeon_cs_print(struct radeon_cs *cs, FILE *file) -{ - cs->csm->funcs->cs_print(cs, file); -} - -static inline void radeon_cs_set_limit(struct radeon_cs *cs, uint32_t domain, uint32_t limit) -{ - - if (domain == RADEON_GEM_DOMAIN_VRAM) - cs->csm->vram_limit = limit; - else - cs->csm->gart_limit = limit; -} - -static inline void radeon_cs_write_dword(struct radeon_cs *cs, uint32_t dword) -{ - cs->packets[cs->cdw++] = dword; - if (cs->section) { - cs->section_cdw++; - } -} - -static inline void radeon_cs_write_qword(struct radeon_cs *cs, uint64_t qword) -{ - - memcpy(cs->packets + cs->cdw, &qword, sizeof(qword)); - cs->cdw+=2; - if (cs->section) { - cs->section_cdw+=2; - } -} - -static inline void radeon_cs_write_table(struct radeon_cs *cs, void *data, uint32_t size) -{ - memcpy(cs->packets + cs->cdw, data, size * 4); - cs->cdw += size; - if (cs->section) { - cs->section_cdw += size; - } -} +#define MAX_SPACE_BOS (32) -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; -} +struct radeon_cs_manager; +extern struct radeon_cs *radeon_cs_create(struct radeon_cs_manager *csm, + uint32_t ndw); + +extern int radeon_cs_begin(struct radeon_cs *cs, + uint32_t ndw, + const char *file, + const char *func, int line); +extern int radeon_cs_end(struct radeon_cs *cs, + const char *file, + const char *func, + int line); +extern int radeon_cs_emit(struct radeon_cs *cs); +extern int radeon_cs_destroy(struct radeon_cs *cs); +extern int radeon_cs_erase(struct radeon_cs *cs); +extern int radeon_cs_need_flush(struct radeon_cs *cs); +extern void radeon_cs_print(struct radeon_cs *cs, FILE *file); +extern void radeon_cs_set_limit(struct radeon_cs *cs, uint32_t domain, uint32_t limit); +extern void radeon_cs_space_set_flush(struct radeon_cs *cs, void (*fn)(void *), void *data); +extern int radeon_cs_write_reloc(struct radeon_cs *cs, + struct radeon_bo *bo, + uint32_t read_domain, + uint32_t write_domain, + uint32_t flags); /* * add a persistent BO to the list @@ -243,4 +112,30 @@ int radeon_cs_space_check_with_bo(struct radeon_cs *cs, uint32_t read_domains, uint32_t write_domain); +static inline void radeon_cs_write_dword(struct radeon_cs *cs, uint32_t dword) +{ + cs->packets[cs->cdw++] = dword; + if (cs->section_ndw) { + cs->section_cdw++; + } +} + +static inline void radeon_cs_write_qword(struct radeon_cs *cs, uint64_t qword) +{ + memcpy(cs->packets + cs->cdw, &qword, sizeof(uint64_t)); + cs->cdw += 2; + if (cs->section_ndw) { + cs->section_cdw += 2; + } +} + +static inline void radeon_cs_write_table(struct radeon_cs *cs, + void *data, uint32_t size) +{ + memcpy(cs->packets + cs->cdw, data, size * 4); + cs->cdw += size; + if (cs->section_ndw) { + cs->section_cdw += size; + } +} #endif diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_int_drm.h b/src/mesa/drivers/dri/radeon/radeon_cs_int_drm.h new file mode 100644 index 0000000000..8ba76bf951 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_cs_int_drm.h @@ -0,0 +1,66 @@ + +#ifndef _RADEON_CS_INT_H_ +#define _RADEON_CS_INT_H_ + +struct radeon_cs_space_check { + struct radeon_bo_int *bo; + uint32_t read_domains; + uint32_t write_domain; + uint32_t new_accounted; +}; + +struct radeon_cs_int { + /* keep first two in same place */ + uint32_t *packets; + unsigned cdw; + unsigned ndw; + unsigned section_ndw; + unsigned section_cdw; + /* private members */ + struct radeon_cs_manager *csm; + void *relocs; + unsigned crelocs; + unsigned relocs_total_size; + 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 */ +struct radeon_cs_funcs { + struct radeon_cs_int *(*cs_create)(struct radeon_cs_manager *csm, + uint32_t ndw); + int (*cs_write_reloc)(struct radeon_cs_int *cs, + struct radeon_bo *bo, + uint32_t read_domain, + uint32_t write_domain, + uint32_t flags); + int (*cs_begin)(struct radeon_cs_int *cs, + uint32_t ndw, + const char *file, + const char *func, + int line); + int (*cs_end)(struct radeon_cs_int *cs, + const char *file, const char *func, + int line); + + + int (*cs_emit)(struct radeon_cs_int *cs); + int (*cs_destroy)(struct radeon_cs_int *cs); + int (*cs_erase)(struct radeon_cs_int *cs); + int (*cs_need_flush)(struct radeon_cs_int *cs); + void (*cs_print)(struct radeon_cs_int *cs, FILE *file); +}; + +struct radeon_cs_manager { + struct radeon_cs_funcs *funcs; + int fd; + int32_t vram_limit, gart_limit; + int32_t vram_write_used, gart_write_used; + int32_t read_used; +}; +#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c index f1addb299e..bf46eb8aab 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c +++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c @@ -30,10 +30,18 @@ * Jérôme Glisse <glisse@freedesktop.org> */ #include <errno.h> +#include <unistd.h> +#include <stdint.h> +#include "drm.h" +#include "radeon_drm.h" #include "radeon_bocs_wrapper.h" #include "radeon_common.h" - +#ifdef HAVE_LIBDRM_RADEON +#include "radeon_cs_int.h" +#else +#include "radeon_cs_int_drm.h" +#endif struct cs_manager_legacy { struct radeon_cs_manager base; struct radeon_context *ctx; @@ -51,27 +59,27 @@ struct cs_reloc_legacy { }; -static struct radeon_cs *cs_create(struct radeon_cs_manager *csm, - uint32_t ndw) +static struct radeon_cs_int *cs_create(struct radeon_cs_manager *csm, + uint32_t ndw) { - struct radeon_cs *cs; + struct radeon_cs_int *csi; - cs = (struct radeon_cs*)calloc(1, sizeof(struct radeon_cs)); - if (cs == NULL) { + csi = (struct radeon_cs_int*)calloc(1, sizeof(struct radeon_cs_int)); + if (csi == NULL) { return NULL; } - cs->csm = csm; - cs->ndw = (ndw + 0x3FF) & (~0x3FF); - cs->packets = (uint32_t*)malloc(4*cs->ndw); - if (cs->packets == NULL) { - free(cs); + csi->csm = csm; + csi->ndw = (ndw + 0x3FF) & (~0x3FF); + csi->packets = (uint32_t*)malloc(4*csi->ndw); + if (csi->packets == NULL) { + free(csi); return NULL; } - cs->relocs_total_size = 0; - return cs; + csi->relocs_total_size = 0; + return csi; } -static int cs_write_reloc(struct radeon_cs *cs, +static int cs_write_reloc(struct radeon_cs_int *cs, struct radeon_bo *bo, uint32_t read_domain, uint32_t write_domain, @@ -150,20 +158,19 @@ static int cs_write_reloc(struct radeon_cs *cs, return 0; } -static int cs_begin(struct radeon_cs *cs, +static int cs_begin(struct radeon_cs_int *cs, uint32_t ndw, const char *file, const char *func, int line) { - if (cs->section) { + if (cs->section_ndw) { fprintf(stderr, "CS already in a section(%s,%s,%d)\n", cs->section_file, cs->section_func, cs->section_line); fprintf(stderr, "CS can't start section(%s,%s,%d)\n", file, func, line); return -EPIPE; } - cs->section = 1; cs->section_ndw = ndw; cs->section_cdw = 0; cs->section_file = file; @@ -175,7 +182,7 @@ static int cs_begin(struct radeon_cs *cs, uint32_t tmp, *ptr; int num = (ndw > 0x3FF) ? ndw : 0x3FF; - tmp = (cs->cdw + 1 + num) & (~num); + tmp = (cs->cdw + ndw + 0x3ff) & (~0x3ff); ptr = (uint32_t*)realloc(cs->packets, 4 * tmp); if (ptr == NULL) { return -ENOMEM; @@ -187,18 +194,17 @@ static int cs_begin(struct radeon_cs *cs, return 0; } -static int cs_end(struct radeon_cs *cs, +static int cs_end(struct radeon_cs_int *cs, const char *file, const char *func, int line) { - if (!cs->section) { + if (!cs->section_ndw) { fprintf(stderr, "CS no section to end at (%s,%s,%d)\n", file, func, line); return -EPIPE; } - cs->section = 0; if (cs->section_ndw != cs->section_cdw) { fprintf(stderr, "CS section size missmatch start at (%s,%s,%d) %d vs %d\n", cs->section_file, cs->section_func, cs->section_line, cs->section_ndw, cs->section_cdw); @@ -206,10 +212,12 @@ static int cs_end(struct radeon_cs *cs, file, func, line); return -EPIPE; } + cs->section_ndw = 0; + return 0; } -static int cs_process_relocs(struct radeon_cs *cs) +static int cs_process_relocs(struct radeon_cs_int *cs) { struct cs_manager_legacy *csm = (struct cs_manager_legacy*)cs->csm; struct cs_reloc_legacy *relocs; @@ -254,7 +262,7 @@ restart: return 0; } -static int cs_set_age(struct radeon_cs *cs) +static int cs_set_age(struct radeon_cs_int *cs) { struct cs_manager_legacy *csm = (struct cs_manager_legacy*)cs->csm; struct cs_reloc_legacy *relocs; @@ -268,7 +276,7 @@ static int cs_set_age(struct radeon_cs *cs) return 0; } -static int cs_emit(struct radeon_cs *cs) +static int cs_emit(struct radeon_cs_int *cs) { struct cs_manager_legacy *csm = (struct cs_manager_legacy*)cs->csm; drm_radeon_cmd_buffer_t cmd; @@ -276,7 +284,7 @@ static int cs_emit(struct radeon_cs *cs) uint64_t ull; int r; - csm->ctx->vtbl.emit_cs_header(cs, csm->ctx); + csm->ctx->vtbl.emit_cs_header((struct radeon_cs *)cs, csm->ctx); /* append buffer age */ if ( IS_R300_CLASS(csm->ctx->radeonScreen) ) @@ -289,9 +297,9 @@ static int cs_emit(struct radeon_cs *cs) age.scratch.reg = 2; age.scratch.n_bufs = 1; age.scratch.flags = 0; - radeon_cs_write_dword(cs, age.u); - radeon_cs_write_qword(cs, ull); - radeon_cs_write_dword(cs, 0); + radeon_cs_write_dword((struct radeon_cs *)cs, age.u); + radeon_cs_write_qword((struct radeon_cs *)cs, ull); + radeon_cs_write_dword((struct radeon_cs *)cs, 0); } r = cs_process_relocs(cs); @@ -342,7 +350,7 @@ static void inline cs_free_reloc(void *relocs_p, int crelocs) free(relocs[i].indices); } -static int cs_destroy(struct radeon_cs *cs) +static int cs_destroy(struct radeon_cs_int *cs) { cs_free_reloc(cs->relocs, cs->crelocs); free(cs->relocs); @@ -351,7 +359,7 @@ static int cs_destroy(struct radeon_cs *cs) return 0; } -static int cs_erase(struct radeon_cs *cs) +static int cs_erase(struct radeon_cs_int *cs) { cs_free_reloc(cs->relocs, cs->crelocs); free(cs->relocs); @@ -359,18 +367,18 @@ static int cs_erase(struct radeon_cs *cs) cs->relocs = NULL; cs->crelocs = 0; cs->cdw = 0; - cs->section = 0; + cs->section_ndw = 0; return 0; } -static int cs_need_flush(struct radeon_cs *cs) +static int cs_need_flush(struct radeon_cs_int *cs) { /* this function used to flush when the BO usage got to * a certain size, now the higher levels handle this better */ return 0; } -static void cs_print(struct radeon_cs *cs, FILE *file) +static void cs_print(struct radeon_cs_int *cs, FILE *file) { } diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c b/src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c index 89cbbb5a6b..e22b437d56 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c +++ b/src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c @@ -29,6 +29,8 @@ #include <errno.h> #include <stdlib.h> #include "radeon_bocs_wrapper.h" +#include "radeon_bo_int_drm.h" +#include "radeon_cs_int_drm.h" struct rad_sizes { int32_t op_read; @@ -39,7 +41,7 @@ struct rad_sizes { 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; + struct radeon_bo_int *bo; bo = sc->bo; sc->new_accounted = 0; @@ -47,7 +49,7 @@ static inline int radeon_cs_setup_bo(struct radeon_cs_space_check *sc, struct ra write_domain = sc->write_domain; /* legacy needs a static check */ - if (radeon_bo_is_static(bo)) { + if (radeon_bo_is_static((struct radeon_bo *)sc->bo)) { bo->space_accounted = sc->new_accounted = (read_domains << 16) | write_domain; return 0; } @@ -100,11 +102,11 @@ static inline int radeon_cs_setup_bo(struct radeon_cs_space_check *sc, struct ra return 0; } -static int radeon_cs_do_space_check(struct radeon_cs *cs, struct radeon_cs_space_check *new_tmp) +static int radeon_cs_do_space_check(struct radeon_cs_int *cs, struct radeon_cs_space_check *new_tmp) { struct radeon_cs_manager *csm = cs->csm; int i; - struct radeon_bo *bo; + struct radeon_bo_int *bo; struct rad_sizes sizes; int ret; @@ -158,25 +160,28 @@ static int radeon_cs_do_space_check(struct radeon_cs *cs, struct radeon_cs_space void radeon_cs_space_add_persistent_bo(struct radeon_cs *cs, struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain) { + struct radeon_cs_int *csi = (struct radeon_cs_int *)cs; + struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; 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) + for (i = 0; i < csi->bo_count; i++) { + if (csi->bos[i].bo == boi && + csi->bos[i].read_domains == read_domains && + csi->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); + i = csi->bo_count; + csi->bos[i].bo = boi; + csi->bos[i].read_domains = read_domains; + csi->bos[i].write_domain = write_domain; + csi->bos[i].new_accounted = 0; + csi->bo_count++; + + assert(csi->bo_count < MAX_SPACE_BOS); } -static int radeon_cs_check_space_internal(struct radeon_cs *cs, struct radeon_cs_space_check *tmp_bo) +static int radeon_cs_check_space_internal(struct radeon_cs_int *cs, + struct radeon_cs_space_check *tmp_bo) { int ret; int flushed = 0; @@ -198,37 +203,42 @@ again: 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_int *csi = (struct radeon_cs_int *)cs; + struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; struct radeon_cs_space_check temp_bo; + int ret = 0; if (bo) { - temp_bo.bo = bo; + temp_bo.bo = boi; 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); + ret = radeon_cs_check_space_internal(csi, bo ? &temp_bo : NULL); return ret; } int radeon_cs_space_check(struct radeon_cs *cs) { - return radeon_cs_check_space_internal(cs, NULL); + struct radeon_cs_int *csi = (struct radeon_cs_int *)cs; + return radeon_cs_check_space_internal(csi, NULL); } void radeon_cs_space_reset_bos(struct radeon_cs *cs) { + struct radeon_cs_int *csi = (struct radeon_cs_int *)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; + for (i = 0; i < csi->bo_count; i++) { + radeon_bo_unref((struct radeon_bo *)csi->bos[i].bo); + csi->bos[i].bo = NULL; + csi->bos[i].read_domains = 0; + csi->bos[i].write_domain = 0; + csi->bos[i].new_accounted = 0; } - cs->bo_count = 0; + csi->bo_count = 0; } diff --git a/src/mesa/drivers/dri/radeon/radeon_dma.c b/src/mesa/drivers/dri/radeon/radeon_dma.c index c6edbae9a1..d31e4e47dd 100644 --- a/src/mesa/drivers/dri/radeon/radeon_dma.c +++ b/src/mesa/drivers/dri/radeon/radeon_dma.c @@ -151,6 +151,7 @@ void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos, aos->components = size; aos->count = count; + radeon_bo_map(aos->bo, 1); out = (uint32_t*)((char*)aos->bo->ptr + aos->offset); switch (size) { case 1: radeonEmitVec4(out, data, stride, count); break; @@ -161,6 +162,7 @@ void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos, assert(0); break; } + radeon_bo_unmap(aos->bo); } void radeon_init_dma(radeonContextPtr rmesa) @@ -183,10 +185,6 @@ void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size) __FUNCTION__, size, rmesa->dma.minimum_size); - /* unmap old reserved bo */ - if (!is_empty_list(&rmesa->dma.reserved)) - radeon_bo_unmap(first_elem(&rmesa->dma.reserved)->bo); - if (is_empty_list(&rmesa->dma.free) || last_elem(&rmesa->dma.free)->bo->size < size) { dma_bo = CALLOC_STRUCT(radeon_dma_bo); @@ -223,8 +221,6 @@ again_alloc: /* Cmd buff have been flushed in radeon_revalidate_bos */ goto again_alloc; } - - radeon_bo_map(first_elem(&rmesa->dma.reserved)->bo, 1); } /* Allocates a region from rmesa->dma.current. If there isn't enough @@ -281,7 +277,6 @@ void radeonFreeDmaRegions(radeonContextPtr rmesa) foreach_s(dma_bo, temp, &rmesa->dma.reserved) { remove_from_list(dma_bo); - radeon_bo_unmap(dma_bo->bo); radeon_bo_unref(dma_bo->bo); FREE(dma_bo); } @@ -306,10 +301,6 @@ static int radeon_bo_is_idle(struct radeon_bo* bo) WARN_ONCE("Your libdrm or kernel doesn't have support for busy query.\n" "This may cause small performance drop for you.\n"); } - /* Protect against bug in legacy bo handling that causes bos stay - * referenced even after they should be freed */ - if (bo->cref != 1) - return 0; return ret != -EBUSY; } @@ -346,9 +337,7 @@ void radeonReleaseDmaRegions(radeonContextPtr rmesa) foreach_s(dma_bo, temp, &rmesa->dma.wait) { if (dma_bo->expire_counter == time) { WARN_ONCE("Leaking dma buffer object!\n"); - /* force free of buffer so we don't realy start - * leaking stuff now*/ - while ((dma_bo->bo = radeon_bo_unref(dma_bo->bo))) {} + radeon_bo_unref(dma_bo->bo); remove_from_list(dma_bo); FREE(dma_bo); continue; @@ -367,9 +356,6 @@ void radeonReleaseDmaRegions(radeonContextPtr rmesa) insert_at_tail(&rmesa->dma.free, dma_bo); } - /* unmap the last dma region */ - if (!is_empty_list(&rmesa->dma.reserved)) - radeon_bo_unmap(first_elem(&rmesa->dma.reserved)->bo); /* move reserved to wait list */ foreach_s(dma_bo, temp, &rmesa->dma.reserved) { /* free objects that are too small to be used because of large request */ @@ -403,11 +389,12 @@ void rcommon_flush_last_swtcl_prim( GLcontext *ctx ) radeonContextPtr rmesa = RADEON_CONTEXT(ctx); struct radeon_dma *dma = &rmesa->dma; - if (RADEON_DEBUG & RADEON_IOCTL) fprintf(stderr, "%s\n", __FUNCTION__); dma->flush = NULL; + radeon_bo_unmap(rmesa->swtcl.bo); + if (!is_empty_list(&dma->reserved)) { GLuint current_offset = dma->current_used; @@ -422,6 +409,8 @@ void rcommon_flush_last_swtcl_prim( GLcontext *ctx ) } rmesa->swtcl.numverts = 0; } + radeon_bo_unref(rmesa->swtcl.bo); + rmesa->swtcl.bo = NULL; } /* Alloc space in the current dma region. */ @@ -432,6 +421,7 @@ rcommonAllocDmaLowVerts( radeonContextPtr rmesa, int nverts, int vsize ) void *head; if (RADEON_DEBUG & RADEON_IOCTL) fprintf(stderr, "%s\n", __FUNCTION__); + if(is_empty_list(&rmesa->dma.reserved) ||rmesa->dma.current_vertexptr + bytes > first_elem(&rmesa->dma.reserved)->bo->size) { if (rmesa->dma.flush) { @@ -455,7 +445,13 @@ rcommonAllocDmaLowVerts( radeonContextPtr rmesa, int nverts, int vsize ) rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == rmesa->dma.current_vertexptr ); - head = (first_elem(&rmesa->dma.reserved)->bo->ptr + rmesa->dma.current_vertexptr); + if (!rmesa->swtcl.bo) { + rmesa->swtcl.bo = first_elem(&rmesa->dma.reserved)->bo; + radeon_bo_ref(rmesa->swtcl.bo); + radeon_bo_map(rmesa->swtcl.bo, 1); + } + + head = (rmesa->swtcl.bo->ptr + rmesa->dma.current_vertexptr); rmesa->dma.current_vertexptr += bytes; rmesa->swtcl.numverts += nverts; return head; diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c index bf69cd9337..7b1f84a715 100644 --- a/src/mesa/drivers/dri/radeon/radeon_fbo.c +++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c @@ -90,7 +90,7 @@ radeon_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, case GL_R3_G3_B2: case GL_RGB4: case GL_RGB5: - rb->Format = MESA_FORMAT_RGB565; + rb->Format = _dri_texformat_rgb565; rb->DataType = GL_UNSIGNED_BYTE; cpp = 2; break; @@ -99,7 +99,7 @@ radeon_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, case GL_RGB10: case GL_RGB12: case GL_RGB16: - rb->Format = MESA_FORMAT_ARGB8888; + rb->Format = _dri_texformat_argb8888; rb->DataType = GL_UNSIGNED_BYTE; cpp = 4; break; @@ -111,7 +111,7 @@ radeon_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, case GL_RGB10_A2: case GL_RGBA12: case GL_RGBA16: - rb->Format = MESA_FORMAT_ARGB8888; + rb->Format = _dri_texformat_argb8888; rb->DataType = GL_UNSIGNED_BYTE; cpp = 4; break; @@ -166,8 +166,9 @@ radeon_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, uint32_t size; uint32_t pitch = ((cpp * width + 63) & ~63) / cpp; - fprintf(stderr,"Allocating %d x %d radeon RBO (pitch %d)\n", width, - height, pitch); + if (RADEON_DEBUG & RADEON_MEMORY) + fprintf(stderr,"Allocating %d x %d radeon RBO (pitch %d)\n", width, + height, pitch); size = pitch * height * cpp; rrb->pitch = pitch * cpp; @@ -246,7 +247,7 @@ radeon_nop_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, * Not used for user-created renderbuffers. */ struct radeon_renderbuffer * -radeon_create_renderbuffer(gl_format format, __DRIdrawablePrivate *driDrawPriv) +radeon_create_renderbuffer(gl_format format, __DRIdrawable *driDrawPriv) { struct radeon_renderbuffer *rrb; @@ -261,14 +262,32 @@ radeon_create_renderbuffer(gl_format format, __DRIdrawablePrivate *driDrawPriv) switch (format) { case MESA_FORMAT_RGB565: + assert(_mesa_little_endian()); + rrb->base.DataType = GL_UNSIGNED_BYTE; + rrb->base._BaseFormat = GL_RGB; + break; + case MESA_FORMAT_RGB565_REV: + assert(!_mesa_little_endian()); rrb->base.DataType = GL_UNSIGNED_BYTE; rrb->base._BaseFormat = GL_RGB; break; case MESA_FORMAT_XRGB8888: + assert(_mesa_little_endian()); + rrb->base.DataType = GL_UNSIGNED_BYTE; + rrb->base._BaseFormat = GL_RGB; + break; + case MESA_FORMAT_XRGB8888_REV: + assert(!_mesa_little_endian()); rrb->base.DataType = GL_UNSIGNED_BYTE; rrb->base._BaseFormat = GL_RGB; break; case MESA_FORMAT_ARGB8888: + assert(_mesa_little_endian()); + rrb->base.DataType = GL_UNSIGNED_BYTE; + rrb->base._BaseFormat = GL_RGBA; + break; + case MESA_FORMAT_ARGB8888_REV: + assert(!_mesa_little_endian()); rrb->base.DataType = GL_UNSIGNED_BYTE; rrb->base._BaseFormat = GL_RGBA; break; @@ -351,6 +370,12 @@ radeon_framebuffer_renderbuffer(GLcontext * ctx, } +/* TODO: According to EXT_fbo spec internal format of texture image + * once set during glTexImage call, should be preserved when + * attaching image to renderbuffer. When HW doesn't support + * rendering to format of attached image, set framebuffer + * completeness accordingly in radeon_validate_framebuffer (issue #79). + */ static GLboolean radeon_update_wrapper(GLcontext *ctx, struct radeon_renderbuffer *rrb, struct gl_texture_image *texImage) @@ -359,21 +384,21 @@ radeon_update_wrapper(GLcontext *ctx, struct radeon_renderbuffer *rrb, gl_format texFormat; restart: - if (texImage->TexFormat == MESA_FORMAT_ARGB8888) { + if (texImage->TexFormat == _dri_texformat_argb8888) { rrb->base.DataType = GL_UNSIGNED_BYTE; DBG("Render to RGBA8 texture OK\n"); } - else if (texImage->TexFormat == MESA_FORMAT_RGB565) { + else if (texImage->TexFormat == _dri_texformat_rgb565) { rrb->base.DataType = GL_UNSIGNED_BYTE; DBG("Render to RGB5 texture OK\n"); } - else if (texImage->TexFormat == MESA_FORMAT_ARGB1555) { + else if (texImage->TexFormat == _dri_texformat_argb1555) { rrb->base.DataType = GL_UNSIGNED_BYTE; DBG("Render to ARGB1555 texture OK\n"); } - else if (texImage->TexFormat == MESA_FORMAT_ARGB4444) { + else if (texImage->TexFormat == _dri_texformat_argb4444) { rrb->base.DataType = GL_UNSIGNED_BYTE; - DBG("Render to ARGB1555 texture OK\n"); + DBG("Render to ARGB4444 texture OK\n"); } else if (texImage->TexFormat == MESA_FORMAT_Z16) { rrb->base.DataType = GL_UNSIGNED_SHORT; diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index a0106d00fa..a9d50c5d07 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -449,7 +449,7 @@ void radeonEmitAOS( r100ContextPtr rmesa, static void radeonKernelClear(GLcontext *ctx, GLuint flags) { r100ContextPtr rmesa = R100_CONTEXT(ctx); - __DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon); + __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon); drm_radeon_sarea_t *sarea = rmesa->radeon.sarea; uint32_t clear; GLint ret, i; @@ -570,11 +570,15 @@ static void radeonKernelClear(GLcontext *ctx, GLuint flags) static void radeonClear( GLcontext *ctx, GLbitfield mask ) { r100ContextPtr rmesa = R100_CONTEXT(ctx); - __DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon); + __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon); GLuint flags = 0; GLuint color_mask = 0; GLuint orig_mask = mask; + if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT)) { + rmesa->radeon.front_buffer_dirty = GL_TRUE; + } + if ( RADEON_DEBUG & RADEON_IOCTL ) { fprintf( stderr, "radeonClear\n"); } diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.c b/src/mesa/drivers/dri/radeon/radeon_lock.c index 02de8e5fd1..9dee691938 100644 --- a/src/mesa/drivers/dri/radeon/radeon_lock.c +++ b/src/mesa/drivers/dri/radeon/radeon_lock.c @@ -58,11 +58,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ void radeonGetLock(radeonContextPtr rmesa, GLuint flags) { - __DRIdrawablePrivate *const drawable = radeon_get_drawable(rmesa); - __DRIdrawablePrivate *const readable = radeon_get_readable(rmesa); - __DRIscreenPrivate *sPriv = rmesa->dri.screen; - - assert(drawable != NULL); + __DRIdrawable *const drawable = radeon_get_drawable(rmesa); + __DRIdrawable *const readable = radeon_get_readable(rmesa); + __DRIscreen *sPriv = rmesa->dri.screen; drmGetLock(rmesa->dri.fd, rmesa->dri.hwContext, flags); @@ -74,12 +72,13 @@ void radeonGetLock(radeonContextPtr rmesa, GLuint flags) * Since the hardware state depends on having the latest drawable * clip rects, all state checking must be done _after_ this call. */ - DRI_VALIDATE_DRAWABLE_INFO(sPriv, drawable); - if (drawable != readable) { + if (drawable) + DRI_VALIDATE_DRAWABLE_INFO(sPriv, drawable); + if (readable && drawable != readable) { DRI_VALIDATE_DRAWABLE_INFO(sPriv, readable); } - if (rmesa->lastStamp != drawable->lastStamp) { + if (drawable && (rmesa->lastStamp != drawable->lastStamp)) { radeon_window_moved(rmesa); rmesa->lastStamp = drawable->lastStamp; } diff --git a/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c b/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c index 08e1c5d00d..d810e6080e 100644 --- a/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c +++ b/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c @@ -76,12 +76,14 @@ static void emit_vecfog(GLcontext *ctx, struct radeon_aos *aos, /* Emit the data */ + radeon_bo_map(aos->bo, 1); out = (uint32_t*)((char*)aos->bo->ptr + aos->offset); for (i = 0; i < count; i++) { out[0] = radeonComputeFogBlendFactor( ctx, *(GLfloat *)data ); out++; data += stride; } + radeon_bo_unmap(aos->bo); } static void emit_s0_vec(uint32_t *out, GLvoid *data, int stride, int count) @@ -151,6 +153,7 @@ static void emit_tex_vector(GLcontext *ctx, struct radeon_aos *aos, /* Emit the data */ + radeon_bo_map(aos->bo, 1); out = (uint32_t*)((char*)aos->bo->ptr + aos->offset); switch (size) { case 1: @@ -170,6 +173,7 @@ static void emit_tex_vector(GLcontext *ctx, struct radeon_aos *aos, exit(1); break; } + radeon_bo_unmap(aos->bo); } @@ -196,12 +200,12 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) if (!rmesa->tcl.obj.buf) rcommon_emit_vector( ctx, &(rmesa->tcl.aos[nr]), - (char *)VB->ObjPtr->data, - VB->ObjPtr->size, - VB->ObjPtr->stride, + (char *)VB->AttribPtr[_TNL_ATTRIB_POS]->data, + VB->AttribPtr[_TNL_ATTRIB_POS]->size, + VB->AttribPtr[_TNL_ATTRIB_POS]->stride, count); - switch( VB->ObjPtr->size ) { + switch( VB->AttribPtr[_TNL_ATTRIB_POS]->size ) { case 4: vfmt |= RADEON_CP_VC_FRMT_W0; case 3: vfmt |= RADEON_CP_VC_FRMT_Z; case 2: vfmt |= RADEON_CP_VC_FRMT_XY; @@ -216,9 +220,9 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) if (!rmesa->tcl.norm.buf) rcommon_emit_vector( ctx, &(rmesa->tcl.aos[nr]), - (char *)VB->NormalPtr->data, + (char *)VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data, 3, - VB->NormalPtr->stride, + VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride, count); vfmt |= RADEON_CP_VC_FRMT_N0; @@ -227,9 +231,9 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) if (inputs & VERT_BIT_COLOR0) { int emitsize; - if (VB->ColorPtr[0]->size == 4 && - (VB->ColorPtr[0]->stride != 0 || - VB->ColorPtr[0]->data[0][3] != 1.0)) { + if (VB->AttribPtr[_TNL_ATTRIB_COLOR0]->size == 4 && + (VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride != 0 || + VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data[0][3] != 1.0)) { vfmt |= RADEON_CP_VC_FRMT_FPCOLOR | RADEON_CP_VC_FRMT_FPALPHA; emitsize = 4; } @@ -242,9 +246,9 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) if (!rmesa->tcl.rgba.buf) rcommon_emit_vector( ctx, &(rmesa->tcl.aos[nr]), - (char *)VB->ColorPtr[0]->data, + (char *)VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data, emitsize, - VB->ColorPtr[0]->stride, + VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride, count); nr++; @@ -256,9 +260,9 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) rcommon_emit_vector( ctx, &(rmesa->tcl.aos[nr]), - (char *)VB->SecondaryColorPtr[0]->data, + (char *)VB->AttribPtr[_TNL_ATTRIB_COLOR1]->data, 3, - VB->SecondaryColorPtr[0]->stride, + VB->AttribPtr[_TNL_ATTRIB_COLOR1]->stride, count); } @@ -273,8 +277,8 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) if (!rmesa->tcl.fog.buf) emit_vecfog( ctx, &(rmesa->tcl.aos[nr]), - (char *)VB->FogCoordPtr->data, - VB->FogCoordPtr->stride, + (char *)VB->AttribPtr[_TNL_ATTRIB_FOG]->data, + VB->AttribPtr[_TNL_ATTRIB_FOG]->stride, count); vfmt |= RADEON_CP_VC_FRMT_FPFOG; @@ -290,24 +294,24 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) if (!rmesa->tcl.tex[unit].buf) emit_tex_vector( ctx, &(rmesa->tcl.aos[nr]), - (char *)VB->TexCoordPtr[unit]->data, - VB->TexCoordPtr[unit]->size, - VB->TexCoordPtr[unit]->stride, + (char *)VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->data, + VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->size, + VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->stride, count ); nr++; vfmt |= RADEON_ST_BIT(unit); /* assume we need the 3rd coord if texgen is active for r/q OR at least 3 coords are submitted. This may not be 100% correct */ - if (VB->TexCoordPtr[unit]->size >= 3) { + if (VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->size >= 3) { vtx |= RADEON_Q_BIT(unit); vfmt |= RADEON_Q_BIT(unit); } if ( (ctx->Texture.Unit[unit].TexGenEnabled & (R_BIT | Q_BIT)) ) vtx |= RADEON_Q_BIT(unit); - else if ((VB->TexCoordPtr[unit]->size >= 3) && + else if ((VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->size >= 3) && ((ctx->Texture.Unit[unit]._ReallyEnabled & (TEXTURE_CUBE_BIT)) == 0)) { - GLuint swaptexmatcol = (VB->TexCoordPtr[unit]->size - 3); + GLuint swaptexmatcol = (VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->size - 3); if (((rmesa->NeedTexMatrix >> unit) & 1) && (swaptexmatcol != ((rmesa->TexMatColSwap >> unit) & 1))) radeonUploadTexMatrix( rmesa, unit, swaptexmatcol ) ; diff --git a/src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h b/src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h index 515783135d..d764ccb982 100644 --- a/src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h +++ b/src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h @@ -56,18 +56,18 @@ static void TAG(emit)( GLcontext *ctx, radeon_print(RADEON_SWRENDER, RADEON_VERBOSE, "%s\n", __FUNCTION__); - coord = (GLuint (*)[4])VB->ObjPtr->data; - coord_stride = VB->ObjPtr->stride; + coord = (GLuint (*)[4])VB->AttribPtr[_TNL_ATTRIB_POS]->data; + coord_stride = VB->AttribPtr[_TNL_ATTRIB_POS]->stride; if (DO_TEX2) { - if (VB->TexCoordPtr[2]) { + if (VB->AttribPtr[_TNL_ATTRIB_TEX2]) { const GLuint t2 = GET_TEXSOURCE(2); - tc2 = (GLuint (*)[4])VB->TexCoordPtr[t2]->data; - tc2_stride = VB->TexCoordPtr[t2]->stride; - if (DO_PTEX && VB->TexCoordPtr[t2]->size < 3) { + tc2 = (GLuint (*)[4])VB->AttribPtr[_TNL_ATTRIB_TEX0 + t2]->data; + tc2_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t2]->stride; + if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t2]->size < 3) { fill_tex |= (1<<2); } - else if (DO_PTEX && VB->TexCoordPtr[t2]->size < 4) { + else if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t2]->size < 4) { rqcoordsnoswap |= (1<<2); } } else { @@ -77,14 +77,14 @@ static void TAG(emit)( GLcontext *ctx, } if (DO_TEX1) { - if (VB->TexCoordPtr[1]) { + if (VB->AttribPtr[_TNL_ATTRIB_TEX1]) { const GLuint t1 = GET_TEXSOURCE(1); - tc1 = (GLuint (*)[4])VB->TexCoordPtr[t1]->data; - tc1_stride = VB->TexCoordPtr[t1]->stride; - if (DO_PTEX && VB->TexCoordPtr[t1]->size < 3) { + tc1 = (GLuint (*)[4])VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->data; + tc1_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->stride; + if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->size < 3) { fill_tex |= (1<<1); } - else if (DO_PTEX && VB->TexCoordPtr[t1]->size < 4) { + else if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->size < 4) { rqcoordsnoswap |= (1<<1); } } else { @@ -94,14 +94,14 @@ static void TAG(emit)( GLcontext *ctx, } if (DO_TEX0) { - if (VB->TexCoordPtr[0]) { + if (VB->AttribPtr[_TNL_ATTRIB_TEX0]) { const GLuint t0 = GET_TEXSOURCE(0); - tc0_stride = VB->TexCoordPtr[t0]->stride; - tc0 = (GLuint (*)[4])VB->TexCoordPtr[t0]->data; - if (DO_PTEX && VB->TexCoordPtr[t0]->size < 3) { + tc0_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->stride; + tc0 = (GLuint (*)[4])VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->data; + if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->size < 3) { fill_tex |= (1<<0); } - else if (DO_PTEX && VB->TexCoordPtr[t0]->size < 4) { + else if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->size < 4) { rqcoordsnoswap |= (1<<0); } } else { @@ -112,9 +112,9 @@ static void TAG(emit)( GLcontext *ctx, } if (DO_NORM) { - if (VB->NormalPtr) { - norm_stride = VB->NormalPtr->stride; - norm = (GLuint (*)[4])VB->NormalPtr->data; + if (VB->AttribPtr[_TNL_ATTRIB_NORMAL]) { + norm_stride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride; + norm = (GLuint (*)[4])VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data; } else { norm_stride = 0; norm = (GLuint (*)[4])&ctx->Current.Attrib[VERT_ATTRIB_NORMAL]; @@ -122,9 +122,9 @@ static void TAG(emit)( GLcontext *ctx, } if (DO_RGBA) { - if (VB->ColorPtr[0]) { - col = VB->ColorPtr[0]->data; - col_stride = VB->ColorPtr[0]->stride; + if (VB->AttribPtr[_TNL_ATTRIB_COLOR0]) { + col = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data; + col_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride; } else { col = (GLfloat (*)[4])ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; col_stride = 0; @@ -132,9 +132,9 @@ static void TAG(emit)( GLcontext *ctx, } if (DO_SPEC_OR_FOG) { - if (VB->SecondaryColorPtr[0]) { - spec = VB->SecondaryColorPtr[0]->data; - spec_stride = VB->SecondaryColorPtr[0]->stride; + if (VB->AttribPtr[_TNL_ATTRIB_COLOR1]) { + spec = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->data; + spec_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->stride; } else { spec = (GLfloat (*)[4])ctx->Current.Attrib[VERT_ATTRIB_COLOR1]; spec_stride = 0; @@ -142,9 +142,9 @@ static void TAG(emit)( GLcontext *ctx, } if (DO_SPEC_OR_FOG) { - if (VB->FogCoordPtr) { - fog = VB->FogCoordPtr->data; - fog_stride = VB->FogCoordPtr->stride; + if (VB->AttribPtr[_TNL_ATTRIB_FOG]) { + fog = VB->AttribPtr[_TNL_ATTRIB_FOG]->data; + fog_stride = VB->AttribPtr[_TNL_ATTRIB_FOG]->stride; } else { fog = (GLfloat (*)[4])ctx->Current.Attrib[VERT_ATTRIB_FOG]; fog_stride = 0; diff --git a/src/mesa/drivers/dri/radeon/radeon_maos_verts.c b/src/mesa/drivers/dri/radeon/radeon_maos_verts.c index 78ec119302..98f96ff2a7 100644 --- a/src/mesa/drivers/dri/radeon/radeon_maos_verts.c +++ b/src/mesa/drivers/dri/radeon/radeon_maos_verts.c @@ -326,7 +326,7 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) if (1) { req |= RADEON_CP_VC_FRMT_Z; - if (VB->ObjPtr->size == 4) { + if (VB->AttribPtr[_TNL_ATTRIB_POS]->size == 4) { req |= RADEON_CP_VC_FRMT_W0; } } @@ -348,15 +348,15 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) req |= RADEON_ST_BIT(unit); /* assume we need the 3rd coord if texgen is active for r/q OR at least 3 coords are submitted. This may not be 100% correct */ - if (VB->TexCoordPtr[unit]->size >= 3) { + if (VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->size >= 3) { req |= RADEON_Q_BIT(unit); vtx |= RADEON_Q_BIT(unit); } if ( (ctx->Texture.Unit[unit].TexGenEnabled & (R_BIT | Q_BIT)) ) vtx |= RADEON_Q_BIT(unit); - else if ((VB->TexCoordPtr[unit]->size >= 3) && + else if ((VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->size >= 3) && ((ctx->Texture.Unit[unit]._ReallyEnabled & (TEXTURE_CUBE_BIT)) == 0)) { - GLuint swaptexmatcol = (VB->TexCoordPtr[unit]->size - 3); + GLuint swaptexmatcol = (VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->size - 3); if (((rmesa->NeedTexMatrix >> unit) & 1) && (swaptexmatcol != ((rmesa->TexMatColSwap >> unit) & 1))) radeonUploadTexMatrix( rmesa, unit, swaptexmatcol ) ; @@ -390,19 +390,19 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) * this, add more vertex code (for obj-2, obj-3) or preferably move * to maos. */ - if (VB->ObjPtr->size < 3 || - (VB->ObjPtr->size == 3 && + if (VB->AttribPtr[_TNL_ATTRIB_POS]->size < 3 || + (VB->AttribPtr[_TNL_ATTRIB_POS]->size == 3 && (setup_tab[i].vertex_format & RADEON_CP_VC_FRMT_W0))) { _math_trans_4f( rmesa->tcl.ObjClean.data, - VB->ObjPtr->data, - VB->ObjPtr->stride, + VB->AttribPtr[_TNL_ATTRIB_POS]->data, + VB->AttribPtr[_TNL_ATTRIB_POS]->stride, GL_FLOAT, - VB->ObjPtr->size, + VB->AttribPtr[_TNL_ATTRIB_POS]->size, 0, VB->Count ); - switch (VB->ObjPtr->size) { + switch (VB->AttribPtr[_TNL_ATTRIB_POS]->size) { case 1: _mesa_vector4f_clean_elem(&rmesa->tcl.ObjClean, VB->Count, 1); case 2: @@ -416,14 +416,14 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) break; } - VB->ObjPtr = &rmesa->tcl.ObjClean; + VB->AttribPtr[_TNL_ATTRIB_POS] = &rmesa->tcl.ObjClean; } - + radeon_bo_map(rmesa->radeon.tcl.aos[0].bo, 1); setup_tab[i].emit( ctx, 0, VB->Count, rmesa->radeon.tcl.aos[0].bo->ptr + rmesa->radeon.tcl.aos[0].offset); - + radeon_bo_unmap(rmesa->radeon.tcl.aos[0].bo); // rmesa->radeon.tcl.aos[0].size = setup_tab[i].vertex_size; rmesa->radeon.tcl.aos[0].stride = setup_tab[i].vertex_size; rmesa->tcl.vertex_format = setup_tab[i].vertex_format; diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c index dadc72f4c1..033f26db2a 100644 --- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2009 Maciej Cencora. * Copyright (C) 2008 Nicolai Haehnle. * * All Rights Reserved. @@ -32,50 +33,52 @@ #include "main/simple_list.h" #include "main/texcompress.h" - -static GLuint radeon_compressed_texture_size(GLcontext *ctx, - GLsizei width, GLsizei height, GLsizei depth, - GLuint mesaFormat) +#include "main/teximage.h" +#include "main/texobj.h" +#include "radeon_texture.h" + +static unsigned get_aligned_compressed_row_stride( + gl_format format, + unsigned width, + unsigned minStride) { - GLuint size = _mesa_format_image_size(mesaFormat, width, height, depth); - - if (mesaFormat == MESA_FORMAT_RGB_DXT1 || - mesaFormat == MESA_FORMAT_RGBA_DXT1) { - if (width + 3 < 8) /* width one block */ - size = size * 4; - else if (width + 3 < 16) - size = size * 2; - } else { - /* DXT3/5, 16 bytes per block */ - // WARN_ONCE("DXT 3/5 suffers from multitexturing problems!\n"); - if (width + 3 < 8) - size = size * 2; + const unsigned blockSize = _mesa_get_format_bytes(format); + unsigned blockWidth, blockHeight, numXBlocks; + + _mesa_get_format_block_size(format, &blockWidth, &blockHeight); + numXBlocks = (width + blockWidth - 1) / blockWidth; + + while (numXBlocks * blockSize < minStride) + { + ++numXBlocks; } - return size; + return numXBlocks * blockSize; } +static unsigned get_compressed_image_size( + gl_format format, + unsigned rowStride, + unsigned height) +{ + unsigned blockWidth, blockHeight; + + _mesa_get_format_block_size(format, &blockWidth, &blockHeight); + + return rowStride * ((height + blockHeight - 1) / blockHeight); +} -static int radeon_compressed_num_bytes(GLuint mesaFormat) +static int find_next_power_of_two(GLuint value) { - int bytes = 0; - switch(mesaFormat) { - - case MESA_FORMAT_RGB_FXT1: - case MESA_FORMAT_RGBA_FXT1: - case MESA_FORMAT_RGB_DXT1: - case MESA_FORMAT_RGBA_DXT1: - bytes = 2; - break; - - case MESA_FORMAT_RGBA_DXT3: - case MESA_FORMAT_RGBA_DXT5: - bytes = 4; - default: - break; - } - - return bytes; + int i, tmp; + + i = 0; + tmp = value - 1; + while (tmp) { + tmp >>= 1; + i++; + } + return (1 << i); } /** @@ -90,28 +93,28 @@ static void compute_tex_image_offset(radeonContextPtr rmesa, radeon_mipmap_tree { radeon_mipmap_level *lvl = &mt->levels[level]; uint32_t row_align; + GLuint height; + + height = find_next_power_of_two(lvl->height); /* Find image size in bytes */ - if (mt->compressed) { - /* TODO: Is this correct? Need test cases for compressed textures! */ - row_align = rmesa->texture_compressed_row_align - 1; - lvl->rowstride = (lvl->width * mt->bpp + row_align) & ~row_align; - lvl->size = radeon_compressed_texture_size(mt->radeon->glCtx, - lvl->width, lvl->height, lvl->depth, mt->compressed); + if (_mesa_is_format_compressed(mt->mesaFormat)) { + lvl->rowstride = get_aligned_compressed_row_stride(mt->mesaFormat, lvl->width, rmesa->texture_compressed_row_align); + lvl->size = get_compressed_image_size(mt->mesaFormat, lvl->rowstride, height); } else if (mt->target == GL_TEXTURE_RECTANGLE_NV) { row_align = rmesa->texture_rect_row_align - 1; - lvl->rowstride = (lvl->width * mt->bpp + row_align) & ~row_align; - lvl->size = lvl->rowstride * lvl->height; + lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) + row_align) & ~row_align; + lvl->size = lvl->rowstride * height; } else if (mt->tilebits & RADEON_TXO_MICRO_TILE) { /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned, * though the actual offset may be different (if texture is less than * 32 bytes width) to the untiled case */ - lvl->rowstride = (lvl->width * mt->bpp * 2 + 31) & ~31; - lvl->size = lvl->rowstride * ((lvl->height + 1) / 2) * lvl->depth; + lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) * 2 + 31) & ~31; + lvl->size = lvl->rowstride * ((height + 1) / 2) * lvl->depth; } else { row_align = rmesa->texture_row_align - 1; - lvl->rowstride = (lvl->width * mt->bpp + row_align) & ~row_align; - lvl->size = lvl->rowstride * lvl->height * lvl->depth; + lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) + row_align) & ~row_align; + lvl->size = lvl->rowstride * height * lvl->depth; } assert(lvl->size > 0); @@ -123,7 +126,7 @@ static void compute_tex_image_offset(radeonContextPtr rmesa, radeon_mipmap_tree if (RADEON_DEBUG & RADEON_TEXTURE) fprintf(stderr, "level %d, face %d: rs:%d %dx%d at %d\n", - level, face, lvl->rowstride, lvl->width, lvl->height, lvl->faces[face].offset); + level, face, lvl->rowstride, lvl->width, height, lvl->faces[face].offset); } static GLuint minify(GLuint size, GLuint levels) @@ -137,22 +140,19 @@ static GLuint minify(GLuint size, GLuint levels) static void calculate_miptree_layout_r100(radeonContextPtr rmesa, radeon_mipmap_tree *mt) { - GLuint curOffset; - GLuint numLevels; - GLuint i; - GLuint face; + GLuint curOffset, i, face, level; - numLevels = mt->lastLevel - mt->firstLevel + 1; - assert(numLevels <= rmesa->glCtx->Const.MaxTextureLevels); + assert(mt->numLevels <= rmesa->glCtx->Const.MaxTextureLevels); curOffset = 0; for(face = 0; face < mt->faces; face++) { - for(i = 0; i < numLevels; i++) { - mt->levels[i].width = minify(mt->width0, i); - mt->levels[i].height = minify(mt->height0, i); - mt->levels[i].depth = minify(mt->depth0, i); - compute_tex_image_offset(rmesa, mt, face, i, &curOffset); + for(i = 0, level = mt->baseLevel; i < mt->numLevels; i++, level++) { + mt->levels[level].valid = 1; + mt->levels[level].width = minify(mt->width0, i); + mt->levels[level].height = minify(mt->height0, i); + mt->levels[level].depth = minify(mt->depth0, i); + compute_tex_image_offset(rmesa, mt, face, level, &curOffset); } } @@ -162,23 +162,21 @@ static void calculate_miptree_layout_r100(radeonContextPtr rmesa, radeon_mipmap_ static void calculate_miptree_layout_r300(radeonContextPtr rmesa, radeon_mipmap_tree *mt) { - GLuint curOffset; - GLuint numLevels; - GLuint i; + GLuint curOffset, i, level; - numLevels = mt->lastLevel - mt->firstLevel + 1; - assert(numLevels <= rmesa->glCtx->Const.MaxTextureLevels); + assert(mt->numLevels <= rmesa->glCtx->Const.MaxTextureLevels); curOffset = 0; - for(i = 0; i < numLevels; i++) { + for(i = 0, level = mt->baseLevel; i < mt->numLevels; i++, level++) { GLuint face; - mt->levels[i].width = minify(mt->width0, i); - mt->levels[i].height = minify(mt->height0, i); - mt->levels[i].depth = minify(mt->depth0, i); + mt->levels[level].valid = 1; + mt->levels[level].width = minify(mt->width0, i); + mt->levels[level].height = minify(mt->height0, i); + mt->levels[level].depth = minify(mt->depth0, i); for(face = 0; face < mt->faces; face++) - compute_tex_image_offset(rmesa, mt, face, i, &curOffset); + compute_tex_image_offset(rmesa, mt, face, level, &curOffset); } /* Note the required size in memory */ @@ -188,27 +186,22 @@ static void calculate_miptree_layout_r300(radeonContextPtr rmesa, radeon_mipmap_ /** * Create a new mipmap tree, calculate its layout and allocate memory. */ -radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, radeonTexObj *t, - GLenum target, GLenum internal_format, GLuint firstLevel, GLuint lastLevel, - GLuint width0, GLuint height0, GLuint depth0, - GLuint bpp, GLuint tilebits, GLuint compressed) +static radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, + GLenum target, gl_format mesaFormat, GLuint baseLevel, GLuint numLevels, + GLuint width0, GLuint height0, GLuint depth0, GLuint tilebits) { radeon_mipmap_tree *mt = CALLOC_STRUCT(_radeon_mipmap_tree); - mt->radeon = rmesa; - mt->internal_format = internal_format; + mt->mesaFormat = mesaFormat; mt->refcount = 1; - mt->t = t; mt->target = target; mt->faces = (target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; - mt->firstLevel = firstLevel; - mt->lastLevel = lastLevel; + mt->baseLevel = baseLevel; + mt->numLevels = numLevels; mt->width0 = width0; mt->height0 = height0; mt->depth0 = depth0; - mt->bpp = compressed ? radeon_compressed_num_bytes(compressed) : bpp; mt->tilebits = tilebits; - mt->compressed = compressed; if (rmesa->radeonScreen->chip_family >= CHIP_FAMILY_R300) calculate_miptree_layout_r300(rmesa, mt); @@ -223,53 +216,43 @@ radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, radeonTexObj * return mt; } -void radeon_miptree_reference(radeon_mipmap_tree *mt) +void radeon_miptree_reference(radeon_mipmap_tree *mt, radeon_mipmap_tree **ptr) { + assert(!*ptr); + mt->refcount++; assert(mt->refcount > 0); + + *ptr = mt; } -void radeon_miptree_unreference(radeon_mipmap_tree *mt) +void radeon_miptree_unreference(radeon_mipmap_tree **ptr) { + radeon_mipmap_tree *mt = *ptr; if (!mt) return; assert(mt->refcount > 0); + mt->refcount--; if (!mt->refcount) { radeon_bo_unref(mt->bo); free(mt); } -} + *ptr = 0; +} /** - * Calculate first and last mip levels for the given texture object, - * where the dimensions are taken from the given texture image at - * the given level. - * - * Note: level is the OpenGL level number, which is not necessarily the same - * as the first level that is actually present. - * - * The base level image of the given texture face must be non-null, - * or this will fail. + * Calculate min and max LOD for the given texture object. + * @param[in] tObj texture object whose LOD values to calculate + * @param[out] pminLod minimal LOD + * @param[out] pmaxLod maximal LOD */ -static void calculate_first_last_level(struct gl_texture_object *tObj, - GLuint *pfirstLevel, GLuint *plastLevel, - GLuint face, GLuint level) +static void calculate_min_max_lod(struct gl_texture_object *tObj, + unsigned *pminLod, unsigned *pmaxLod) { - const struct gl_texture_image * const baseImage = - tObj->Image[face][level]; - - assert(baseImage); - - /* These must be signed values. MinLod and MaxLod can be negative numbers, - * and having firstLevel and lastLevel as signed prevents the need for - * extra sign checks. - */ - int firstLevel; - int lastLevel; - + int minLod, maxLod; /* Yes, this looks overly complicated, but it's all needed. */ switch (tObj->Target) { @@ -280,32 +263,30 @@ static void calculate_first_last_level(struct gl_texture_object *tObj, if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) { /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL. */ - firstLevel = lastLevel = tObj->BaseLevel; + minLod = maxLod = tObj->BaseLevel; } else { - firstLevel = tObj->BaseLevel + (GLint)(tObj->MinLod + 0.5); - firstLevel = MAX2(firstLevel, tObj->BaseLevel); - firstLevel = MIN2(firstLevel, level + baseImage->MaxLog2); - lastLevel = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5); - lastLevel = MAX2(lastLevel, tObj->BaseLevel); - lastLevel = MIN2(lastLevel, level + baseImage->MaxLog2); - lastLevel = MIN2(lastLevel, tObj->MaxLevel); - lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ + minLod = tObj->BaseLevel + (GLint)(tObj->MinLod); + minLod = MAX2(minLod, tObj->BaseLevel); + minLod = MIN2(minLod, tObj->MaxLevel); + maxLod = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5); + maxLod = MIN2(maxLod, tObj->MaxLevel); + maxLod = MIN2(maxLod, tObj->Image[0][minLod]->MaxLog2 + minLod); + maxLod = MAX2(maxLod, minLod); /* need at least one level */ } break; case GL_TEXTURE_RECTANGLE_NV: case GL_TEXTURE_4D_SGIS: - firstLevel = lastLevel = 0; + minLod = maxLod = 0; break; default: return; } /* save these values */ - *pfirstLevel = firstLevel; - *plastLevel = lastLevel; + *pminLod = minLod; + *pmaxLod = maxLod; } - /** * Checks whether the given miptree can hold the given texture image at the * given face and level. @@ -313,23 +294,17 @@ static void calculate_first_last_level(struct gl_texture_object *tObj, GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt, struct gl_texture_image *texImage, GLuint face, GLuint level) { - GLboolean isCompressed = _mesa_is_format_compressed(texImage->TexFormat); radeon_mipmap_level *lvl; - if (face >= mt->faces || level < mt->firstLevel || level > mt->lastLevel) + if (face >= mt->faces) return GL_FALSE; - if (texImage->InternalFormat != mt->internal_format || - isCompressed != mt->compressed) + if (texImage->TexFormat != mt->mesaFormat) return GL_FALSE; - if (!isCompressed && - !mt->compressed && - _mesa_get_format_bytes(texImage->TexFormat) != mt->bpp) - return GL_FALSE; - - lvl = &mt->levels[level - mt->firstLevel]; - if (lvl->width != texImage->Width || + lvl = &mt->levels[level]; + if (!lvl->valid || + lvl->width != texImage->Width || lvl->height != texImage->Height || lvl->depth != texImage->Depth) return GL_FALSE; @@ -337,64 +312,72 @@ GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt, return GL_TRUE; } - /** * Checks whether the given miptree has the right format to store the given texture object. */ -GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct gl_texture_object *texObj) +static GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct gl_texture_object *texObj) { struct gl_texture_image *firstImage; - GLuint compressed; - GLuint numfaces = 1; - GLuint firstLevel, lastLevel; - GLuint texelBytes; - - calculate_first_last_level(texObj, &firstLevel, &lastLevel, 0, texObj->BaseLevel); - if (texObj->Target == GL_TEXTURE_CUBE_MAP) - numfaces = 6; - - firstImage = texObj->Image[0][firstLevel]; - compressed = _mesa_is_format_compressed(firstImage->TexFormat) ? firstImage->TexFormat : 0; - texelBytes = _mesa_get_format_bytes(firstImage->TexFormat); - - return (mt->firstLevel == firstLevel && - mt->lastLevel == lastLevel && - mt->width0 == firstImage->Width && - mt->height0 == firstImage->Height && - mt->depth0 == firstImage->Depth && - mt->compressed == compressed && - (!mt->compressed ? (mt->bpp == texelBytes) : 1)); -} + unsigned numLevels; + radeon_mipmap_level *mtBaseLevel; + + if (texObj->BaseLevel < mt->baseLevel) + return GL_FALSE; + mtBaseLevel = &mt->levels[texObj->BaseLevel - mt->baseLevel]; + firstImage = texObj->Image[0][texObj->BaseLevel]; + numLevels = MIN2(texObj->MaxLevel - texObj->BaseLevel + 1, firstImage->MaxLog2 + 1); + + if (RADEON_DEBUG & RADEON_TEXTURE) { + fprintf(stderr, "Checking if miptree %p matches texObj %p\n", mt, texObj); + fprintf(stderr, "target %d vs %d\n", mt->target, texObj->Target); + fprintf(stderr, "format %d vs %d\n", mt->mesaFormat, firstImage->TexFormat); + fprintf(stderr, "numLevels %d vs %d\n", mt->numLevels, numLevels); + fprintf(stderr, "width0 %d vs %d\n", mtBaseLevel->width, firstImage->Width); + fprintf(stderr, "height0 %d vs %d\n", mtBaseLevel->height, firstImage->Height); + fprintf(stderr, "depth0 %d vs %d\n", mtBaseLevel->depth, firstImage->Depth); + if (mt->target == texObj->Target && + mt->mesaFormat == firstImage->TexFormat && + mt->numLevels >= numLevels && + mtBaseLevel->width == firstImage->Width && + mtBaseLevel->height == firstImage->Height && + mtBaseLevel->depth == firstImage->Depth) { + fprintf(stderr, "MATCHED\n"); + } else { + fprintf(stderr, "NOT MATCHED\n"); + } + } + + return (mt->target == texObj->Target && + mt->mesaFormat == firstImage->TexFormat && + mt->numLevels >= numLevels && + mtBaseLevel->width == firstImage->Width && + mtBaseLevel->height == firstImage->Height && + mtBaseLevel->depth == firstImage->Depth); +} /** - * Try to allocate a mipmap tree for the given texture that will fit the - * given image in the given position. + * Try to allocate a mipmap tree for the given texture object. + * @param[in] rmesa radeon context + * @param[in] t radeon texture object */ -void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t, - radeon_texture_image *image, GLuint face, GLuint level) +void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t) { - GLuint compressed = _mesa_is_format_compressed(image->base.TexFormat) ? image->base.TexFormat : 0; - GLuint numfaces = 1; - GLuint firstLevel, lastLevel; - GLuint texelBytes; + struct gl_texture_object *texObj = &t->base; + struct gl_texture_image *texImg = texObj->Image[0][texObj->BaseLevel]; + GLuint numLevels; assert(!t->mt); - calculate_first_last_level(&t->base, &firstLevel, &lastLevel, face, level); - if (t->base.Target == GL_TEXTURE_CUBE_MAP) - numfaces = 6; - - if (level != firstLevel || face >= numfaces) + if (!texImg) return; - texelBytes = _mesa_get_format_bytes(image->base.TexFormat); + numLevels = MIN2(texObj->MaxLevel - texObj->BaseLevel + 1, texImg->MaxLog2 + 1); - t->mt = radeon_miptree_create(rmesa, t, t->base.Target, - image->base.InternalFormat, - firstLevel, lastLevel, - image->base.Width, image->base.Height, image->base.Depth, - texelBytes, t->tile_bits, compressed); + t->mt = radeon_miptree_create(rmesa, t->base.Target, + texImg->TexFormat, texObj->BaseLevel, + numLevels, texImg->Width, texImg->Height, + texImg->Depth, t->tile_bits); } /* Although we use the image_offset[] array to store relative offsets @@ -406,21 +389,234 @@ void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t, void radeon_miptree_depth_offsets(radeon_mipmap_tree *mt, GLuint level, GLuint *offsets) { - if (mt->target != GL_TEXTURE_3D || mt->faces == 1) - offsets[0] = 0; - else { - int i; - for (i = 0; i < 6; i++) - offsets[i] = mt->levels[level].faces[i].offset; - } + if (mt->target != GL_TEXTURE_3D || mt->faces == 1) { + offsets[0] = 0; + } else { + int i; + for (i = 0; i < 6; i++) { + offsets[i] = mt->levels[level].faces[i].offset; + } + } } GLuint radeon_miptree_image_offset(radeon_mipmap_tree *mt, GLuint face, GLuint level) { - if (mt->target == GL_TEXTURE_CUBE_MAP_ARB) - return (mt->levels[level].faces[face].offset); - else - return mt->levels[level].faces[0].offset; + if (mt->target == GL_TEXTURE_CUBE_MAP_ARB) + return (mt->levels[level].faces[face].offset); + else + return mt->levels[level].faces[0].offset; } + +/** + * Ensure that the given image is stored in the given miptree from now on. + */ +static void migrate_image_to_miptree(radeon_mipmap_tree *mt, + radeon_texture_image *image, + int face, int level) +{ + radeon_mipmap_level *dstlvl = &mt->levels[level]; + unsigned char *dest; + + assert(image->mt != mt); + assert(dstlvl->valid); + assert(dstlvl->width == image->base.Width); + assert(dstlvl->height == image->base.Height); + assert(dstlvl->depth == image->base.Depth); + + radeon_bo_map(mt->bo, GL_TRUE); + dest = mt->bo->ptr + dstlvl->faces[face].offset; + + if (image->mt) { + /* Format etc. should match, so we really just need a memcpy(). + * In fact, that memcpy() could be done by the hardware in many + * cases, provided that we have a proper memory manager. + */ + assert(mt->mesaFormat == image->base.TexFormat); + + radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel]; + + /* TODO: bring back these assertions once the FBOs are fixed */ +#if 0 + assert(image->mtlevel == level); + assert(srclvl->size == dstlvl->size); + assert(srclvl->rowstride == dstlvl->rowstride); +#endif + + radeon_bo_map(image->mt->bo, GL_FALSE); + + memcpy(dest, + image->mt->bo->ptr + srclvl->faces[face].offset, + dstlvl->size); + radeon_bo_unmap(image->mt->bo); + + radeon_miptree_unreference(&image->mt); + } else if (image->base.Data) { + /* This condition should be removed, it's here to workaround + * a segfault when mapping textures during software fallbacks. + */ + const uint32_t srcrowstride = _mesa_format_row_stride(image->base.TexFormat, image->base.Width); + uint32_t rows = image->base.Height * image->base.Depth; + + if (_mesa_is_format_compressed(image->base.TexFormat)) { + uint32_t blockWidth, blockHeight; + _mesa_get_format_block_size(image->base.TexFormat, &blockWidth, &blockHeight); + rows = (rows + blockHeight - 1) / blockHeight; + } + + copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride, + rows, srcrowstride); + + _mesa_free_texmemory(image->base.Data); + image->base.Data = 0; + } + + radeon_bo_unmap(mt->bo); + + radeon_miptree_reference(mt, &image->mt); + image->mtface = face; + image->mtlevel = level; +} + +/** + * Filter matching miptrees, and select one with the most of data. + * @param[in] texObj radeon texture object + * @param[in] firstLevel first texture level to check + * @param[in] lastLevel last texture level to check + */ +static radeon_mipmap_tree * get_biggest_matching_miptree(radeonTexObj *texObj, + unsigned firstLevel, + unsigned lastLevel) +{ + const unsigned numLevels = lastLevel - firstLevel + 1; + unsigned *mtSizes = calloc(numLevels, sizeof(unsigned)); + radeon_mipmap_tree **mts = calloc(numLevels, sizeof(radeon_mipmap_tree *)); + unsigned mtCount = 0; + unsigned maxMtIndex = 0; + radeon_mipmap_tree *tmp; + + for (unsigned level = firstLevel; level <= lastLevel; ++level) { + radeon_texture_image *img = get_radeon_texture_image(texObj->base.Image[0][level]); + unsigned found = 0; + // TODO: why this hack?? + if (!img) + break; + + if (!img->mt) + continue; + + for (int i = 0; i < mtCount; ++i) { + if (mts[i] == img->mt) { + found = 1; + mtSizes[i] += img->mt->levels[img->mtlevel].size; + break; + } + } + + if (!found && radeon_miptree_matches_texture(img->mt, &texObj->base)) { + mtSizes[mtCount] = img->mt->levels[img->mtlevel].size; + mts[mtCount] = img->mt; + mtCount++; + } + } + + if (mtCount == 0) { + return NULL; + } + + for (int i = 1; i < mtCount; ++i) { + if (mtSizes[i] > mtSizes[maxMtIndex]) { + maxMtIndex = i; + } + } + + tmp = mts[maxMtIndex]; + free(mtSizes); + free(mts); + + return tmp; +} + +/** + * Validate texture mipmap tree. + * If individual images are stored in different mipmap trees + * use the mipmap tree that has the most of the correct data. + */ +int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObj *t = radeon_tex_obj(texObj); + + if (t->validated || t->image_override) { + return GL_TRUE; + } + + if (texObj->Image[0][texObj->BaseLevel]->Border > 0) + return GL_FALSE; + + _mesa_test_texobj_completeness(rmesa->glCtx, texObj); + if (!texObj->_Complete) { + return GL_FALSE; + } + + calculate_min_max_lod(&t->base, &t->minLod, &t->maxLod); + + if (RADEON_DEBUG & RADEON_TEXTURE) + fprintf(stderr, "%s: Validating texture %p now, minLod = %d, maxLod = %d\n", + __FUNCTION__, texObj ,t->minLod, t->maxLod); + + radeon_mipmap_tree *dst_miptree; + dst_miptree = get_biggest_matching_miptree(t, t->minLod, t->maxLod); + + if (!dst_miptree) { + radeon_miptree_unreference(&t->mt); + radeon_try_alloc_miptree(rmesa, t); + dst_miptree = t->mt; + if (RADEON_DEBUG & RADEON_TEXTURE) { + fprintf(stderr, "%s: No matching miptree found, allocated new one %p\n", __FUNCTION__, t->mt); + } + } else if (RADEON_DEBUG & RADEON_TEXTURE) { + fprintf(stderr, "%s: Using miptree %p\n", __FUNCTION__, t->mt); + } + + const unsigned faces = texObj->Target == GL_TEXTURE_CUBE_MAP ? 6 : 1; + unsigned face, level; + radeon_texture_image *img; + /* Validate only the levels that will actually be used during rendering */ + for (face = 0; face < faces; ++face) { + for (level = t->minLod; level <= t->maxLod; ++level) { + img = get_radeon_texture_image(texObj->Image[face][level]); + + if (RADEON_DEBUG & RADEON_TEXTURE) { + fprintf(stderr, "Checking image level %d, face %d, mt %p ... ", level, face, img->mt); + } + + if (img->mt != dst_miptree) { + if (RADEON_DEBUG & RADEON_TEXTURE) { + fprintf(stderr, "MIGRATING\n"); + } + struct radeon_bo *src_bo = (img->mt) ? img->mt->bo : img->bo; + if (src_bo && radeon_bo_is_referenced_by_cs(src_bo, rmesa->cmdbuf.cs)) { + radeon_firevertices(rmesa); + } + migrate_image_to_miptree(dst_miptree, img, face, level); + } else if (RADEON_DEBUG & RADEON_TEXTURE) { + fprintf(stderr, "OK\n"); + } + } + } + + t->validated = GL_TRUE; + + return GL_TRUE; +} + +uint32_t get_base_teximage_offset(radeonTexObj *texObj) +{ + if (!texObj->mt) { + return 0; + } else { + return radeon_miptree_image_offset(texObj->mt, 0, texObj->minLod); + } +}
\ No newline at end of file diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h index db28252da3..a10649b5ae 100644 --- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h @@ -44,6 +44,7 @@ struct _radeon_mipmap_level { GLuint depth; GLuint size; /** Size of each image, in bytes */ GLuint rowstride; /** in bytes */ + GLuint valid; radeon_mipmap_image faces[6]; }; @@ -59,43 +60,35 @@ struct _radeon_mipmap_level { * changed. */ struct _radeon_mipmap_tree { - radeonContextPtr radeon; - radeonTexObj *t; struct radeon_bo *bo; GLuint refcount; GLuint totalsize; /** total size of the miptree, in bytes */ GLenum target; /** GL_TEXTURE_xxx */ - GLenum internal_format; + GLenum mesaFormat; /** MESA_FORMAT_xxx */ GLuint faces; /** # of faces: 6 for cubemaps, 1 otherwise */ - GLuint firstLevel; /** First mip level stored in this mipmap tree */ - GLuint lastLevel; /** Last mip level stored in this mipmap tree */ + GLuint baseLevel; /** gl_texture_object->baseLevel it was created for */ + GLuint numLevels; /** Number of mip levels stored in this mipmap tree */ - GLuint width0; /** Width of firstLevel image */ - GLuint height0; /** Height of firstLevel image */ - GLuint depth0; /** Depth of firstLevel image */ + GLuint width0; /** Width of baseLevel image */ + GLuint height0; /** Height of baseLevel image */ + GLuint depth0; /** Depth of baseLevel image */ - GLuint bpp; /** Bytes per texel */ GLuint tilebits; /** RADEON_TXO_xxx_TILE */ - GLuint compressed; /** MESA_FORMAT_xxx indicating a compressed format, or 0 if uncompressed */ radeon_mipmap_level levels[RADEON_MIPTREE_MAX_TEXTURE_LEVELS]; }; -radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, radeonTexObj *t, - GLenum target, GLenum internal_format, GLuint firstLevel, GLuint lastLevel, - GLuint width0, GLuint height0, GLuint depth0, - GLuint bpp, GLuint tilebits, GLuint compressed); -void radeon_miptree_reference(radeon_mipmap_tree *mt); -void radeon_miptree_unreference(radeon_mipmap_tree *mt); +void radeon_miptree_reference(radeon_mipmap_tree *mt, radeon_mipmap_tree **ptr); +void radeon_miptree_unreference(radeon_mipmap_tree **ptr); GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt, struct gl_texture_image *texImage, GLuint face, GLuint level); -GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct gl_texture_object *texObj); -void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t, - radeon_texture_image *texImage, GLuint face, GLuint level); +void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t); GLuint radeon_miptree_image_offset(radeon_mipmap_tree *mt, GLuint face, GLuint level); void radeon_miptree_depth_offsets(radeon_mipmap_tree *mt, GLuint level, GLuint *offsets); + +uint32_t get_base_teximage_offset(radeonTexObj *texObj); #endif /* __RADEON_MIPMAP_TREE_H_ */ diff --git a/src/mesa/drivers/dri/radeon/radeon_queryobj.c b/src/mesa/drivers/dri/radeon/radeon_queryobj.c index 6539c36268..98117cdfc1 100644 --- a/src/mesa/drivers/dri/radeon/radeon_queryobj.c +++ b/src/mesa/drivers/dri/radeon/radeon_queryobj.c @@ -31,24 +31,11 @@ #include "main/imports.h" #include "main/simple_list.h" -static int radeonQueryIsFlushed(GLcontext *ctx, struct gl_query_object *q) -{ - radeonContextPtr radeon = RADEON_CONTEXT(ctx); - struct radeon_query_object *tmp, *query = (struct radeon_query_object *)q; - - foreach(tmp, &radeon->query.not_flushed_head) { - if (tmp == query) { - return 0; - } - } - - return 1; -} - static void radeonQueryGetResult(GLcontext *ctx, struct gl_query_object *q) { radeonContextPtr radeon = RADEON_CONTEXT(ctx); struct radeon_query_object *query = (struct radeon_query_object *)q; + uint32_t *result; int i; radeon_print(RADEON_STATE, RADEON_VERBOSE, @@ -56,6 +43,7 @@ static void radeonQueryGetResult(GLcontext *ctx, struct gl_query_object *q) __FUNCTION__, query->Base.Id, (int) query->Base.Result); radeon_bo_map(query->bo, GL_FALSE); + result = query->bo->ptr; query->Base.Result = 0; if (IS_R600_CLASS(radeon->radeonScreen)) { @@ -66,10 +54,11 @@ static void radeonQueryGetResult(GLcontext *ctx, struct gl_query_object *q) * hw writes zpass end counts to qwords 1, 3, 5, 7. * then we substract. MSB is the valid bit. */ - uint64_t *result = query->bo->ptr; - for (i = 0; i < 8; i += 2) { - uint64_t start = result[i]; - uint64_t end = result[i + 1]; + for (i = 0; i < 16; i += 4) { + uint64_t start = (uint64_t)LE32_TO_CPU(result[i]) | + (uint64_t)LE32_TO_CPU(result[i + 1]) << 32; + uint64_t end = (uint64_t)LE32_TO_CPU(result[i + 2]) | + (uint64_t)LE32_TO_CPU(result[i + 3]) << 32; if ((start & 0x8000000000000000) && (end & 0x8000000000000000)) { uint64_t query_count = end - start; query->Base.Result += query_count; @@ -79,10 +68,9 @@ static void radeonQueryGetResult(GLcontext *ctx, struct gl_query_object *q) "%d start: %lx, end: %lx %ld\n", i, start, end, end - start); } } else { - uint32_t *result = query->bo->ptr; for (i = 0; i < query->curr_offset/sizeof(uint32_t); ++i) { - query->Base.Result += result[i]; - radeon_print(RADEON_STATE, RADEON_TRACE, "result[%d] = %d\n", i, result[i]); + query->Base.Result += LE32_TO_CPU(result[i]); + radeon_print(RADEON_STATE, RADEON_TRACE, "result[%d] = %d\n", i, LE32_TO_CPU(result[i])); } } @@ -120,10 +108,11 @@ static void radeonDeleteQuery(GLcontext *ctx, struct gl_query_object *q) static void radeonWaitQuery(GLcontext *ctx, struct gl_query_object *q) { + radeonContextPtr radeon = RADEON_CONTEXT(ctx); struct radeon_query_object *query = (struct radeon_query_object *)q; /* If the cmdbuf with packets for this query hasn't been flushed yet, do it now */ - if (!radeonQueryIsFlushed(ctx, q)) + if (radeon_bo_is_referenced_by_cs(query->bo, radeon->cmdbuf.cs)) ctx->Driver.Flush(ctx); radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s: query id %d, bo %p, offset %d\n", __FUNCTION__, q->Id, query->bo, query->curr_offset); @@ -155,8 +144,6 @@ static void radeonBeginQuery(GLcontext *ctx, struct gl_query_object *q) radeon->query.queryobj.dirty = GL_TRUE; radeon->hw.is_dirty = GL_TRUE; - insert_at_tail(&radeon->query.not_flushed_head, query); - } void radeonEmitQueryEnd(GLcontext *ctx) @@ -204,7 +191,7 @@ static void radeonCheckQuery(GLcontext *ctx, struct gl_query_object *q) uint32_t domain; /* Need to perform a flush, as per ARB_occlusion_query spec */ - if (!radeonQueryIsFlushed(ctx, q)) { + if (radeon_bo_is_referenced_by_cs(query->bo, radeon->cmdbuf.cs)) { ctx->Driver.Flush(ctx); } diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 7a124a8be6..3080a0fcd0 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -214,10 +214,10 @@ static const GLuint __driNConfigOptions = 17; #endif -static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo ); +static int getSwapInfo( __DRIdrawable *dPriv, __DRIswapInfo * sInfo ); static int -radeonGetParam(__DRIscreenPrivate *sPriv, int param, void *value) +radeonGetParam(__DRIscreen *sPriv, int param, void *value) { int ret; drm_radeon_getparam_t gp = { 0 }; @@ -249,7 +249,7 @@ radeonGetParam(__DRIscreenPrivate *sPriv, int param, void *value) } static const __DRIconfig ** -radeonFillInModes( __DRIscreenPrivate *psp, +radeonFillInModes( __DRIscreen *psp, unsigned pixel_bits, unsigned depth_bits, unsigned stencil_bits, GLboolean have_back_buffer ) { @@ -390,12 +390,14 @@ static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id) screen->device_id = device_id; screen->chip_flags = 0; switch ( device_id ) { + case PCI_CHIP_RN50_515E: + case PCI_CHIP_RN50_5969: + return -1; + case PCI_CHIP_RADEON_LY: case PCI_CHIP_RADEON_LZ: case PCI_CHIP_RADEON_QY: case PCI_CHIP_RADEON_QZ: - case PCI_CHIP_RN50_515E: - case PCI_CHIP_RN50_5969: screen->chip_family = CHIP_FAMILY_RV100; break; @@ -909,7 +911,7 @@ static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id) /* Create the device specific screen private data struct. */ static radeonScreenPtr -radeonCreateScreen( __DRIscreenPrivate *sPriv ) +radeonCreateScreen( __DRIscreen *sPriv ) { radeonScreenPtr screen; RADEONDRIPtr dri_priv = (RADEONDRIPtr)sPriv->pDevPriv; @@ -1248,7 +1250,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) } static radeonScreenPtr -radeonCreateScreen2(__DRIscreenPrivate *sPriv) +radeonCreateScreen2(__DRIscreen *sPriv) { radeonScreenPtr screen; int i; @@ -1399,7 +1401,7 @@ radeonCreateScreen2(__DRIscreenPrivate *sPriv) /* Destroy the device specific screen private data struct. */ static void -radeonDestroyScreen( __DRIscreenPrivate *sPriv ) +radeonDestroyScreen( __DRIscreen *sPriv ) { radeonScreenPtr screen = (radeonScreenPtr)sPriv->private; @@ -1433,7 +1435,7 @@ radeonDestroyScreen( __DRIscreenPrivate *sPriv ) /* Initialize the driver specific screen private data. */ static GLboolean -radeonInitDriver( __DRIscreenPrivate *sPriv ) +radeonInitDriver( __DRIscreen *sPriv ) { if (sPriv->dri2.enabled) { sPriv->private = (void *) radeonCreateScreen2( sPriv ); @@ -1457,8 +1459,8 @@ radeonInitDriver( __DRIscreenPrivate *sPriv ) * pbuffers. */ static GLboolean -radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, - __DRIdrawablePrivate *driDrawPriv, +radeonCreateBuffer( __DRIscreen *driScrnPriv, + __DRIdrawable *driDrawPriv, const __GLcontextModes *mesaVis, GLboolean isPixmap ) { @@ -1482,11 +1484,11 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, _mesa_initialize_framebuffer(&rfb->base, mesaVis); if (mesaVis->redBits == 5) - rgbFormat = MESA_FORMAT_RGB565; + rgbFormat = _mesa_little_endian() ? MESA_FORMAT_RGB565 : MESA_FORMAT_RGB565_REV; else if (mesaVis->alphaBits == 0) - rgbFormat = MESA_FORMAT_XRGB8888; + rgbFormat = _mesa_little_endian() ? MESA_FORMAT_XRGB8888 : MESA_FORMAT_XRGB8888_REV; else - rgbFormat = MESA_FORMAT_ARGB8888; + rgbFormat = _mesa_little_endian() ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB8888_REV; /* front color renderbuffer */ rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv); @@ -1557,7 +1559,7 @@ static void radeon_cleanup_renderbuffers(struct radeon_framebuffer *rfb) } void -radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) +radeonDestroyBuffer(__DRIdrawable *driDrawPriv) { struct radeon_framebuffer *rfb; if (!driDrawPriv) @@ -1579,7 +1581,7 @@ radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) * \return the __GLcontextModes supported by this driver */ static const __DRIconfig ** -radeonInitScreen(__DRIscreenPrivate *psp) +radeonInitScreen(__DRIscreen *psp) { #if defined(RADEON_R100) static const char *driver_name = "Radeon"; @@ -1629,7 +1631,7 @@ radeonInitScreen(__DRIscreenPrivate *psp) * \return the __GLcontextModes supported by this driver */ static const -__DRIconfig **radeonInitScreen2(__DRIscreenPrivate *psp) +__DRIconfig **radeonInitScreen2(__DRIscreen *psp) { GLenum fb_format[3]; GLenum fb_type[3]; @@ -1696,7 +1698,7 @@ __DRIconfig **radeonInitScreen2(__DRIscreenPrivate *psp) * Get information about previous buffer swaps. */ static int -getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo ) +getSwapInfo( __DRIdrawable *dPriv, __DRIswapInfo * sInfo ) { struct radeon_framebuffer *rfb; @@ -1749,3 +1751,10 @@ const struct __DriverAPIRec driDriverAPI = { .InitScreen2 = radeonInitScreen2, }; +/* This is the table of extensions that the loader will dlsym() for. */ +PUBLIC const __DRIextension *__driDriverExtensions[] = { + &driCoreExtension.base, + &driLegacyExtension.base, + &driDRI2Extension.base, + NULL +}; diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.h b/src/mesa/drivers/dri/radeon/radeon_screen.h index 15744e8828..5e6d432e11 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.h +++ b/src/mesa/drivers/dri/radeon/radeon_screen.h @@ -86,7 +86,7 @@ typedef struct radeon_screen { __volatile__ uint32_t *scratch; - __DRIscreenPrivate *driScreen; + __DRIscreen *driScreen; unsigned int sarea_priv_offset; unsigned int gart_buffer_offset; /* offset in card memory space */ unsigned int gart_texture_offset; /* offset in card memory space */ @@ -123,5 +123,5 @@ typedef struct radeon_screen { #define IS_R600_CLASS(screen) \ ((screen->chip_flags & RADEON_CLASS_MASK) == RADEON_CLASS_R600) -extern void radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv); +extern void radeonDestroyBuffer(__DRIdrawable *driDrawPriv); #endif /* __RADEON_SCREEN_H__ */ diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c index 2bc7d31254..8db3d2b143 100644 --- a/src/mesa/drivers/dri/radeon/radeon_span.c +++ b/src/mesa/drivers/dri/radeon/radeon_span.c @@ -41,6 +41,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "main/glheader.h" +#include "main/texformat.h" #include "swrast/swrast.h" #include "radeon_common.h" @@ -400,6 +401,18 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb, #endif #include "spantmp2.h" +#define SPANTMP_PIXEL_FMT GL_RGB +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5_REV + +#define TAG(x) radeon##x##_RGB565_REV +#define TAG2(x,y) radeon##x##_RGB565_REV##y +#if defined(RADEON_R600) +#define GET_PTR(X,Y) r600_ptr_color(rrb, (X) + x_off, (Y) + y_off) +#else +#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off) +#endif +#include "spantmp2.h" + /* 16 bit, ARGB1555 color spanline and pixel functions */ #define SPANTMP_PIXEL_FMT GL_BGRA @@ -414,6 +427,18 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb, #endif #include "spantmp2.h" +#define SPANTMP_PIXEL_FMT GL_BGRA +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5 + +#define TAG(x) radeon##x##_ARGB1555_REV +#define TAG2(x,y) radeon##x##_ARGB1555_REV##y +#if defined(RADEON_R600) +#define GET_PTR(X,Y) r600_ptr_color(rrb, (X) + x_off, (Y) + y_off) +#else +#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off) +#endif +#include "spantmp2.h" + /* 16 bit, RGBA4 color spanline and pixel functions */ #define SPANTMP_PIXEL_FMT GL_BGRA @@ -428,6 +453,18 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb, #endif #include "spantmp2.h" +#define SPANTMP_PIXEL_FMT GL_BGRA +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4 + +#define TAG(x) radeon##x##_ARGB4444_REV +#define TAG2(x,y) radeon##x##_ARGB4444_REV##y +#if defined(RADEON_R600) +#define GET_PTR(X,Y) r600_ptr_color(rrb, (X) + x_off, (Y) + y_off) +#else +#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off) +#endif +#include "spantmp2.h" + /* 32 bit, xRGB8888 color spanline and pixel functions */ #define SPANTMP_PIXEL_FMT GL_BGRA @@ -472,6 +509,42 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb, #endif #include "spantmp2.h" +/* 32 bit, BGRx8888 color spanline and pixel functions + */ +#define SPANTMP_PIXEL_FMT GL_BGRA +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8 + +#define TAG(x) radeon##x##_BGRx8888 +#define TAG2(x,y) radeon##x##_BGRx8888##y +#if defined(RADEON_R600) +#define GET_VALUE(_x, _y) ((*(GLuint*)(r600_ptr_color(rrb, _x + x_off, _y + y_off)) | 0x000000ff)) +#define PUT_VALUE(_x, _y, d) { \ + GLuint *_ptr = (GLuint*)r600_ptr_color( rrb, _x + x_off, _y + y_off ); \ + *_ptr = d; \ +} while (0) +#else +#define GET_VALUE(_x, _y) ((*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)) | 0x000000ff)) +#define PUT_VALUE(_x, _y, d) { \ + GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \ + *_ptr = d; \ +} while (0) +#endif +#include "spantmp2.h" + +/* 32 bit, BGRA8888 color spanline and pixel functions + */ +#define SPANTMP_PIXEL_FMT GL_BGRA +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8 + +#define TAG(x) radeon##x##_BGRA8888 +#define TAG2(x,y) radeon##x##_BGRA8888##y +#if defined(RADEON_R600) +#define GET_PTR(X,Y) r600_ptr_color(rrb, (X) + x_off, (Y) + y_off) +#else +#define GET_PTR(X,Y) radeon_ptr_4byte(rrb, (X) + x_off, (Y) + y_off) +#endif +#include "spantmp2.h" + /* ================================================================ * Depth buffer */ @@ -526,10 +599,10 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb, #define WRITE_DEPTH( _x, _y, d ) \ do { \ GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \ - GLuint tmp = *_ptr; \ + GLuint tmp = LE32_TO_CPU(*_ptr); \ tmp &= 0x000000ff; \ tmp |= ((d << 8) & 0xffffff00); \ - *_ptr = tmp; \ + *_ptr = CPU_TO_LE32(tmp); \ } while (0) #elif defined(RADEON_R600) #define WRITE_DEPTH( _x, _y, d ) \ @@ -544,26 +617,26 @@ do { \ #define WRITE_DEPTH( _x, _y, d ) \ do { \ GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x + x_off, _y + y_off ); \ - GLuint tmp = *_ptr; \ + GLuint tmp = LE32_TO_CPU(*_ptr); \ tmp &= 0xff000000; \ tmp |= ((d) & 0x00ffffff); \ - *_ptr = tmp; \ + *_ptr = CPU_TO_LE32(tmp); \ } while (0) #else #define WRITE_DEPTH( _x, _y, d ) \ do { \ GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \ - GLuint tmp = *_ptr; \ + GLuint tmp = LE32_TO_CPU(*_ptr); \ tmp &= 0xff000000; \ tmp |= ((d) & 0x00ffffff); \ - *_ptr = tmp; \ + *_ptr = CPU_TO_LE32(tmp); \ } while (0) #endif #if defined(RADEON_R300) #define READ_DEPTH( d, _x, _y ) \ do { \ - d = (*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)) & 0xffffff00) >> 8; \ + d = (LE32_TO_CPU(*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off))) & 0xffffff00) >> 8; \ }while(0) #elif defined(RADEON_R600) #define READ_DEPTH( d, _x, _y ) \ @@ -573,11 +646,11 @@ do { \ #elif defined(RADEON_R200) #define READ_DEPTH( d, _x, _y ) \ do { \ - d = *(GLuint*)(r200_depth_4byte(rrb, _x + x_off, _y + y_off)) & 0x00ffffff; \ + d = LE32_TO_CPU(*(GLuint*)(r200_depth_4byte(rrb, _x + x_off, _y + y_off))) & 0x00ffffff; \ }while(0) #else #define READ_DEPTH( d, _x, _y ) \ - d = *(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)) & 0x00ffffff; + d = LE32_TO_CPU(*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off))) & 0x00ffffff; #endif #define TAG(x) radeon##x##_z24 @@ -595,7 +668,7 @@ do { \ #define WRITE_DEPTH( _x, _y, d ) \ do { \ GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \ - *_ptr = d; \ + *_ptr = CPU_TO_LE32((((d) & 0xff000000) >> 24) | (((d) & 0x00ffffff) << 8)); \ } while (0) #elif defined(RADEON_R600) #define WRITE_DEPTH( _x, _y, d ) \ @@ -615,20 +688,21 @@ do { \ #define WRITE_DEPTH( _x, _y, d ) \ do { \ GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x + x_off, _y + y_off ); \ - *_ptr = d; \ + *_ptr = CPU_TO_LE32(d); \ } while (0) #else #define WRITE_DEPTH( _x, _y, d ) \ do { \ GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \ - *_ptr = d; \ + *_ptr = CPU_TO_LE32(d); \ } while (0) #endif #if defined(RADEON_R300) #define READ_DEPTH( d, _x, _y ) \ do { \ - d = (*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off))); \ + GLuint tmp = (*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off))); \ + d = LE32_TO_CPU(((tmp & 0x000000ff) << 24) | ((tmp & 0xffffff00) >> 8)); \ }while(0) #elif defined(RADEON_R600) #define READ_DEPTH( d, _x, _y ) \ @@ -639,11 +713,11 @@ do { \ #elif defined(RADEON_R200) #define READ_DEPTH( d, _x, _y ) \ do { \ - d = *(GLuint*)(r200_depth_4byte(rrb, _x + x_off, _y + y_off)); \ + d = LE32_TO_CPU(*(GLuint*)(r200_depth_4byte(rrb, _x + x_off, _y + y_off))); \ }while(0) #else #define READ_DEPTH( d, _x, _y ) do { \ - d = *(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off )); \ + d = LE32_TO_CPU(*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off))); \ } while (0) #endif @@ -660,10 +734,10 @@ do { \ #define WRITE_STENCIL( _x, _y, d ) \ do { \ GLuint *_ptr = (GLuint*)radeon_ptr_4byte(rrb, _x + x_off, _y + y_off); \ - GLuint tmp = *_ptr; \ + GLuint tmp = LE32_TO_CPU(*_ptr); \ tmp &= 0xffffff00; \ tmp |= (d) & 0xff; \ - *_ptr = tmp; \ + *_ptr = CPU_TO_LE32(tmp); \ } while (0) #elif defined(RADEON_R600) #define WRITE_STENCIL( _x, _y, d ) \ @@ -678,19 +752,19 @@ do { \ #define WRITE_STENCIL( _x, _y, d ) \ do { \ GLuint *_ptr = (GLuint*)r200_depth_4byte(rrb, _x + x_off, _y + y_off); \ - GLuint tmp = *_ptr; \ + GLuint tmp = LE32_TO_CPU(*_ptr); \ tmp &= 0x00ffffff; \ tmp |= (((d) & 0xff) << 24); \ - *_ptr = tmp; \ + *_ptr = CPU_TO_LE32(tmp); \ } while (0) #else #define WRITE_STENCIL( _x, _y, d ) \ do { \ GLuint *_ptr = (GLuint*)radeon_ptr_4byte(rrb, _x + x_off, _y + y_off); \ - GLuint tmp = *_ptr; \ + GLuint tmp = LE32_TO_CPU(*_ptr); \ tmp &= 0x00ffffff; \ tmp |= (((d) & 0xff) << 24); \ - *_ptr = tmp; \ + *_ptr = CPU_TO_LE32(tmp); \ } while (0) #endif @@ -698,7 +772,7 @@ do { \ #define READ_STENCIL( d, _x, _y ) \ do { \ GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \ - GLuint tmp = *_ptr; \ + GLuint tmp = LE32_TO_CPU(*_ptr); \ d = tmp & 0x000000ff; \ } while (0) #elif defined(RADEON_R600) @@ -712,14 +786,14 @@ do { \ #define READ_STENCIL( d, _x, _y ) \ do { \ GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x + x_off, _y + y_off ); \ - GLuint tmp = *_ptr; \ + GLuint tmp = LE32_TO_CPU(*_ptr); \ d = (tmp & 0xff000000) >> 24; \ } while (0) #else #define READ_STENCIL( d, _x, _y ) \ do { \ GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \ - GLuint tmp = *_ptr; \ + GLuint tmp = LE32_TO_CPU(*_ptr); \ d = (tmp & 0xff000000) >> 24; \ } while (0) #endif @@ -737,8 +811,7 @@ static void map_unmap_rb(struct gl_renderbuffer *rb, int flag) return; if (flag) { - if (rrb->bo->bom->funcs->bo_wait) - radeon_bo_wait(rrb->bo); + radeon_bo_wait(rrb->bo); r = radeon_bo_map(rrb->bo, 1); if (r) { fprintf(stderr, "(%s) error(%d) mapping buffer.\n", @@ -754,18 +827,21 @@ static void map_unmap_rb(struct gl_renderbuffer *rb, int flag) } static void -radeon_map_unmap_buffers(GLcontext *ctx, GLboolean map) +radeon_map_unmap_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb, + GLboolean map) { GLuint i, j; /* color draw buffers */ for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers; j++) - map_unmap_rb(ctx->DrawBuffer->_ColorDrawBuffers[j], map); + map_unmap_rb(fb->_ColorDrawBuffers[j], map); + + map_unmap_rb(fb->_ColorReadBuffer, map); /* check for render to textures */ for (i = 0; i < BUFFER_COUNT; i++) { struct gl_renderbuffer_attachment *att = - ctx->DrawBuffer->Attachment + i; + fb->Attachment + i; struct gl_texture_object *tex = att->Texture; if (tex) { /* Render to texture. Note that a mipmapped texture need not @@ -781,15 +857,15 @@ radeon_map_unmap_buffers(GLcontext *ctx, GLboolean map) radeon_teximage_unmap(image); } } - - map_unmap_rb(ctx->ReadBuffer->_ColorReadBuffer, map); - + /* depth buffer (Note wrapper!) */ - if (ctx->DrawBuffer->_DepthBuffer) - map_unmap_rb(ctx->DrawBuffer->_DepthBuffer->Wrapped, map); + if (fb->_DepthBuffer) + map_unmap_rb(fb->_DepthBuffer->Wrapped, map); - if (ctx->DrawBuffer->_StencilBuffer) - map_unmap_rb(ctx->DrawBuffer->_StencilBuffer->Wrapped, map); + if (fb->_StencilBuffer) + map_unmap_rb(fb->_StencilBuffer->Wrapped, map); + + radeon_check_front_buffer_rendering(ctx); } static void radeonSpanRenderStart(GLcontext * ctx) @@ -814,23 +890,30 @@ static void radeonSpanRenderStart(GLcontext * ctx) ctx->Driver.MapTexture(ctx, ctx->Texture.Unit[i]._Current); } - radeon_map_unmap_buffers(ctx, 1); + radeon_map_unmap_framebuffer(ctx, ctx->DrawBuffer, GL_TRUE); + if (ctx->ReadBuffer != ctx->DrawBuffer) + radeon_map_unmap_framebuffer(ctx, ctx->ReadBuffer, GL_TRUE); } static void radeonSpanRenderFinish(GLcontext * ctx) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); int i; + _swrast_flush(ctx); - if (!rmesa->radeonScreen->driScreen->dri2.enabled) { - UNLOCK_HARDWARE(rmesa); - } + for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { if (ctx->Texture.Unit[i]._ReallyEnabled) ctx->Driver.UnmapTexture(ctx, ctx->Texture.Unit[i]._Current); } - radeon_map_unmap_buffers(ctx, 0); + radeon_map_unmap_framebuffer(ctx, ctx->DrawBuffer, GL_FALSE); + if (ctx->ReadBuffer != ctx->DrawBuffer) + radeon_map_unmap_framebuffer(ctx, ctx->ReadBuffer, GL_FALSE); + + if (!rmesa->radeonScreen->driScreen->dri2.enabled) { + UNLOCK_HARDWARE(rmesa); + } } void radeonInitSpanFuncs(GLcontext * ctx) @@ -848,14 +931,24 @@ static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb) { if (rrb->base.Format == MESA_FORMAT_RGB565) { radeonInitPointers_RGB565(&rrb->base); + } else if (rrb->base.Format == MESA_FORMAT_RGB565_REV) { + radeonInitPointers_RGB565_REV(&rrb->base); } else if (rrb->base.Format == MESA_FORMAT_XRGB8888) { radeonInitPointers_xRGB8888(&rrb->base); + } else if (rrb->base.Format == MESA_FORMAT_XRGB8888_REV) { + radeonInitPointers_BGRx8888(&rrb->base); } else if (rrb->base.Format == MESA_FORMAT_ARGB8888) { radeonInitPointers_ARGB8888(&rrb->base); + } else if (rrb->base.Format == MESA_FORMAT_ARGB8888_REV) { + radeonInitPointers_BGRA8888(&rrb->base); } else if (rrb->base.Format == MESA_FORMAT_ARGB4444) { radeonInitPointers_ARGB4444(&rrb->base); + } else if (rrb->base.Format == MESA_FORMAT_ARGB4444_REV) { + radeonInitPointers_ARGB4444_REV(&rrb->base); } else if (rrb->base.Format == MESA_FORMAT_ARGB1555) { radeonInitPointers_ARGB1555(&rrb->base); + } else if (rrb->base.Format == MESA_FORMAT_ARGB1555_REV) { + radeonInitPointers_ARGB1555_REV(&rrb->base); } else if (rrb->base.Format == MESA_FORMAT_Z16) { radeonInitDepthPointers_z16(&rrb->base); } else if (rrb->base.Format == MESA_FORMAT_X8_Z24) { diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index 4d0d35ee0c..1c9ec36dae 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -521,10 +521,10 @@ static void radeonColorMask( GLcontext *ctx, return; mask = radeonPackColor( rrb->cpp, - ctx->Color.ColorMask[RCOMP], - ctx->Color.ColorMask[GCOMP], - ctx->Color.ColorMask[BCOMP], - ctx->Color.ColorMask[ACOMP] ); + ctx->Color.ColorMask[0][RCOMP], + ctx->Color.ColorMask[0][GCOMP], + ctx->Color.ColorMask[0][BCOMP], + ctx->Color.ColorMask[0][ACOMP] ); if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) { RADEON_STATECHANGE( rmesa, msk ); @@ -550,6 +550,31 @@ static void radeonPolygonOffset( GLcontext *ctx, rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = constant.ui32; } +static void radeonPolygonStipplePreKMS( GLcontext *ctx, const GLubyte *mask ) +{ + r100ContextPtr rmesa = R100_CONTEXT(ctx); + GLuint i; + drm_radeon_stipple_t stipple; + + /* Must flip pattern upside down. + */ + for ( i = 0 ; i < 32 ; i++ ) { + rmesa->state.stipple.mask[31 - i] = ((GLuint *) mask)[i]; + } + + /* TODO: push this into cmd mechanism + */ + radeon_firevertices(&rmesa->radeon); + LOCK_HARDWARE( &rmesa->radeon ); + + /* FIXME: Use window x,y offsets into stipple RAM. + */ + stipple.mask = rmesa->state.stipple.mask; + drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_STIPPLE, + &stipple, sizeof(drm_radeon_stipple_t) ); + UNLOCK_HARDWARE( &rmesa->radeon ); +} + static void radeonPolygonMode( GLcontext *ctx, GLenum face, GLenum mode ) { r100ContextPtr rmesa = R100_CONTEXT(ctx); @@ -1375,7 +1400,7 @@ static void radeonClearStencil( GLcontext *ctx, GLint s ) void radeonUpdateWindow( GLcontext *ctx ) { r100ContextPtr rmesa = R100_CONTEXT(ctx); - __DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon); + __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon); GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0; GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0; const GLfloat *v = ctx->Viewport._WindowMap.m; @@ -1430,7 +1455,7 @@ static void radeonDepthRange( GLcontext *ctx, GLclampd nearval, void radeonUpdateViewportOffset( GLcontext *ctx ) { r100ContextPtr rmesa = R100_CONTEXT(ctx); - __DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon); + __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon); GLfloat xoffset = (GLfloat)dPriv->x; GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h; const GLfloat *v = ctx->Viewport._WindowMap.m; diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c index 2d19220d8a..dd82888254 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state_init.c +++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c @@ -645,11 +645,11 @@ static void tex_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom) OUT_BATCH(CP_PACKET0(RADEON_PP_TXOFFSET_0 + (24 * i), 0)); if (t->mt && !t->image_override) { if ((ctx->Texture.Unit[i]._ReallyEnabled & TEXTURE_CUBE_BIT)) { - lvl = &t->mt->levels[0]; + lvl = &t->mt->levels[t->minLod]; OUT_BATCH_RELOC(lvl->faces[5].offset, t->mt->bo, lvl->faces[5].offset, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); } else { - OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0, + OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, get_base_teximage_offset(t), RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); } } else { diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.c b/src/mesa/drivers/dri/radeon/radeon_swtcl.c index e61f59eaea..8bf1bfbc57 100644 --- a/src/mesa/drivers/dri/radeon/radeon_swtcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.c @@ -179,7 +179,7 @@ static void radeonSetVertexFormat( GLcontext *ctx ) for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) { - GLuint sz = VB->TexCoordPtr[i]->size; + GLuint sz = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]->size; switch (sz) { case 1: @@ -309,7 +309,7 @@ void r100_swtcl_flush(GLcontext *ctx, uint32_t current_offset) radeonEmitState(&rmesa->radeon); radeonEmitVertexAOS( rmesa, rmesa->radeon.swtcl.vertex_size, - first_elem(&rmesa->radeon.dma.reserved)->bo, + rmesa->radeon.swtcl.bo, current_offset); diff --git a/src/mesa/drivers/dri/radeon/radeon_tcl.c b/src/mesa/drivers/dri/radeon/radeon_tcl.c index b334ea05e5..cd02bfbcf5 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_tcl.c @@ -412,6 +412,7 @@ static GLuint radeonEnsureEmitSize( GLcontext * ctx , GLuint inputs ) space_required += vbuf; else space_required += index + elts; + space_required += VB->Primitive[i].count * 3; space_required += AOS_BUFSZ(nr_aos); } space_required += SCISSOR_BUFSZ; diff --git a/src/mesa/drivers/dri/radeon/radeon_tex.c b/src/mesa/drivers/dri/radeon/radeon_tex.c index 60981aada2..14163f13af 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tex.c +++ b/src/mesa/drivers/dri/radeon/radeon_tex.c @@ -341,24 +341,14 @@ static void radeonTexParameter( GLcontext *ctx, GLenum target, break; case GL_TEXTURE_BORDER_COLOR: - radeonSetTexBorderColor( t, texObj->BorderColor ); + radeonSetTexBorderColor( t, texObj->BorderColor.f ); break; case GL_TEXTURE_BASE_LEVEL: case GL_TEXTURE_MAX_LEVEL: case GL_TEXTURE_MIN_LOD: case GL_TEXTURE_MAX_LOD: - - /* This isn't the most efficient solution but there doesn't appear to - * be a nice alternative. Since there's no LOD clamping, - * we just have to rely on loading the right subset of mipmap levels - * to simulate a clamped LOD. - */ - if (t->mt) { - radeon_miptree_unreference(t->mt); - t->mt = 0; - t->validated = GL_FALSE; - } + t->validated = GL_FALSE; break; default: @@ -388,10 +378,8 @@ static void radeonDeleteTexture( GLcontext *ctx, } } - if (t->mt) { - radeon_miptree_unreference(t->mt); - t->mt = 0; - } + radeon_miptree_unreference(&t->mt); + /* Free mipmap images and the texture object itself */ _mesa_delete_texture_object(ctx, texObj); } @@ -440,7 +428,7 @@ radeonNewTextureObject( GLcontext *ctx, GLuint name, GLenum target ) radeonSetTexWrap( t, t->base.WrapS, t->base.WrapT ); radeonSetTexMaxAnisotropy( t, t->base.MaxAnisotropy ); radeonSetTexFilter( t, t->base.MinFilter, t->base.MagFilter ); - radeonSetTexBorderColor( t, t->base.BorderColor ); + radeonSetTexBorderColor( t, t->base.BorderColor.f ); return &t->base; } diff --git a/src/mesa/drivers/dri/radeon/radeon_texstate.c b/src/mesa/drivers/dri/radeon/radeon_texstate.c index 429977a8bc..84ddcfd4fd 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texstate.c +++ b/src/mesa/drivers/dri/radeon/radeon_texstate.c @@ -672,24 +672,13 @@ void radeonSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_ return; } - radeon_update_renderbuffers(pDRICtx, dPriv); - /* back & depth buffer are useless free them right away */ - rb = (void*)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer; - if (rb && rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; - } - rb = (void*)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; - if (rb && rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; - } + radeon_update_renderbuffers(pDRICtx, dPriv, GL_TRUE); rb = rfb->color_rb[0]; if (rb->bo == NULL) { /* Failed to BO for the buffer */ return; } - + _mesa_lock_texture(radeon->glCtx, texObj); if (t->bo) { radeon_bo_unref(t->bo); @@ -699,14 +688,10 @@ void radeonSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_ radeon_bo_unref(rImage->bo); rImage->bo = NULL; } - if (t->mt) { - radeon_miptree_unreference(t->mt); - t->mt = NULL; - } - if (rImage->mt) { - radeon_miptree_unreference(rImage->mt); - rImage->mt = NULL; - } + + radeon_miptree_unreference(&t->mt); + radeon_miptree_unreference(&rImage->mt); + _mesa_init_teximage_fields(radeon->glCtx, target, texImage, rb->base.Width, rb->base.Height, 1, 0, rb->cpp); texImage->RowStride = rb->pitch / rb->cpp; @@ -718,8 +703,6 @@ void radeonSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_ t->tile_bits = 0; t->image_override = GL_TRUE; t->override_offset = 0; - t->pp_txpitch &= (1 << 13) -1; - pitch_val = rb->pitch; switch (rb->cpp) { case 4: if (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT) @@ -738,12 +721,17 @@ void radeonSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_ t->pp_txfilter |= tx_table[MESA_FORMAT_RGB565].filter; break; } - t->pp_txsize = ((rb->base.Width - 1) << RADEON_TEX_USIZE_SHIFT) - | ((rb->base.Height - 1) << RADEON_TEX_VSIZE_SHIFT); - t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2; - t->pp_txpitch = pitch_val; - t->pp_txpitch -= 32; + t->pp_txpitch &= (1 << 13) -1; + pitch_val = rb->pitch; + + t->pp_txsize = ((rb->base.Width - 1) << RADEON_TEX_USIZE_SHIFT) + | ((rb->base.Height - 1) << RADEON_TEX_VSIZE_SHIFT); + if (target == GL_TEXTURE_RECTANGLE_NV) { + t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2; + t->pp_txpitch = pitch_val; + t->pp_txpitch -= 32; + } t->validated = GL_TRUE; _mesa_unlock_texture(radeon->glCtx, texObj); return; @@ -1021,7 +1009,7 @@ static GLboolean setup_hardware_state(r100ContextPtr rmesa, radeonTexObj *t, int return GL_TRUE; } - firstImage = t->base.Image[0][t->mt->firstLevel]; + firstImage = t->base.Image[0][t->minLod]; if (firstImage->Border > 0) { fprintf(stderr, "%s: border\n", __FUNCTION__); @@ -1049,9 +1037,9 @@ static GLboolean setup_hardware_state(r100ContextPtr rmesa, radeonTexObj *t, int return GL_FALSE; } } - + t->pp_txfilter &= ~RADEON_MAX_MIP_LEVEL_MASK; - t->pp_txfilter |= (t->mt->lastLevel - t->mt->firstLevel) << RADEON_MAX_MIP_LEVEL_SHIFT; + t->pp_txfilter |= (t->maxLod - t->minLod) << RADEON_MAX_MIP_LEVEL_SHIFT; t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK | RADEON_TXFORMAT_HEIGHT_MASK | @@ -1060,9 +1048,9 @@ static GLboolean setup_hardware_state(r100ContextPtr rmesa, radeonTexObj *t, int RADEON_TXFORMAT_F5_HEIGHT_MASK); t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) | (log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT)); - + t->tile_bits = 0; - + if (t->base.Target == GL_TEXTURE_CUBE_MAP) { ASSERT(log2Width == log2Height); t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_F5_WIDTH_SHIFT) | diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c index baa99b752b..03178116c1 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.c +++ b/src/mesa/drivers/dri/radeon/radeon_texture.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2009 Maciej Cencora. * Copyright (C) 2008 Nicolai Haehnle. * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. * @@ -46,7 +47,7 @@ #include "radeon_mipmap_tree.h" -static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride, +void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride, GLuint numrows, GLuint rowsize) { assert(rowsize <= dststride); @@ -81,8 +82,7 @@ void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage) radeon_texture_image* image = get_radeon_texture_image(timage); if (image->mt) { - radeon_miptree_unreference(image->mt); - image->mt = 0; + radeon_miptree_unreference(&image->mt); assert(!image->base.Data); } else { _mesa_free_texture_image_data(ctx, timage); @@ -108,7 +108,7 @@ static void teximage_set_map_data(radeon_texture_image *image) lvl = &image->mt->levels[image->mtlevel]; image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset; - image->base.RowStride = lvl->rowstride / image->mt->bpp; + image->base.RowStride = lvl->rowstride / _mesa_get_format_bytes(image->base.TexFormat); } @@ -174,7 +174,7 @@ void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj) radeon_bo_map(t->mt->bo, GL_FALSE); for(face = 0; face < t->mt->faces; ++face) { - for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) + for(level = t->minLod; level <= t->maxLod; ++level) teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level])); } } @@ -191,7 +191,7 @@ void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj) return; for(face = 0; face < t->mt->faces; ++face) { - for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) + for(level = t->minLod; level <= t->maxLod; ++level) texObj->Image[face][level]->Data = 0; } radeon_bo_unmap(t->mt->bo); @@ -240,8 +240,7 @@ static void radeon_generate_mipmap(GLcontext *ctx, GLenum target, image->mtlevel = i; image->mtface = face; - radeon_miptree_unreference(image->mt); - image->mt = NULL; + radeon_miptree_unreference(&image->mt); } } @@ -473,6 +472,19 @@ gl_format radeonChooseTextureFormat(GLcontext * ctx, case GL_RGBA32F_ARB: return MESA_FORMAT_RGBA_FLOAT32; +#ifdef RADEON_R300 + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16: + return MESA_FORMAT_Z16; + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: + case GL_DEPTH_STENCIL_EXT: + case GL_DEPTH24_STENCIL8_EXT: + if (rmesa->radeonScreen->chip_family >= CHIP_FAMILY_RV515) + return MESA_FORMAT_S8_Z24; + else + return MESA_FORMAT_Z16; +#else case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT16: case GL_DEPTH_COMPONENT24: @@ -480,6 +492,7 @@ gl_format radeonChooseTextureFormat(GLcontext * ctx, case GL_DEPTH_STENCIL_EXT: case GL_DEPTH24_STENCIL8_EXT: return MESA_FORMAT_S8_Z24; +#endif /* EXT_texture_sRGB */ case GL_SRGB: @@ -510,6 +523,173 @@ gl_format radeonChooseTextureFormat(GLcontext * ctx, return MESA_FORMAT_NONE; /* never get here */ } +/** Check if given image is valid within current texture object. + */ +static int image_matches_texture_obj(struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + unsigned level) +{ + const struct gl_texture_image *baseImage = texObj->Image[0][texObj->BaseLevel]; + + if (!baseImage) + return 0; + + if (level < texObj->BaseLevel || level > texObj->MaxLevel) + return 0; + + const unsigned levelDiff = level - texObj->BaseLevel; + const unsigned refWidth = MAX2(baseImage->Width >> levelDiff, 1); + const unsigned refHeight = MAX2(baseImage->Height >> levelDiff, 1); + const unsigned refDepth = MAX2(baseImage->Depth >> levelDiff, 1); + + return (texImage->Width == refWidth && + texImage->Height == refHeight && + texImage->Depth == refDepth); +} + +static void teximage_assign_miptree(radeonContextPtr rmesa, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + unsigned face, + unsigned level) +{ + radeonTexObj *t = radeon_tex_obj(texObj); + radeon_texture_image* image = get_radeon_texture_image(texImage); + + /* Since miptree holds only images for levels <BaseLevel..MaxLevel> + * don't allocate the miptree if the teximage won't fit. + */ + if (!image_matches_texture_obj(texObj, texImage, level)) + return; + + /* Try using current miptree, or create new if there isn't any */ + if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, level)) { + radeon_miptree_unreference(&t->mt); + radeon_try_alloc_miptree(rmesa, t); + if (RADEON_DEBUG & RADEON_TEXTURE) { + fprintf(stderr, "%s: texObj %p, texImage %p, face %d, level %d, " + "texObj miptree doesn't match, allocated new miptree %p\n", + __FUNCTION__, texObj, texImage, face, level, t->mt); + } + } + + /* Miptree alocation may have failed, + * when there was no image for baselevel specified */ + if (t->mt) { + image->mtface = face; + image->mtlevel = level; + radeon_miptree_reference(t->mt, &image->mt); + } +} + +static GLuint * allocate_image_offsets(GLcontext *ctx, + unsigned alignedWidth, + unsigned height, + unsigned depth) +{ + int i; + GLuint *offsets; + + offsets = _mesa_malloc(depth * sizeof(GLuint)) ; + if (!offsets) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex[Sub]Image"); + return NULL; + } + + for (i = 0; i < depth; ++i) { + offsets[i] = alignedWidth * height * i; + } + + return offsets; +} + +/** + * Update a subregion of the given texture image. + */ +static void radeon_store_teximage(GLcontext* ctx, int dims, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLsizei imageSize, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + int compressed) +{ + radeonTexObj *t = radeon_tex_obj(texObj); + radeon_texture_image* image = get_radeon_texture_image(texImage); + + GLuint dstRowStride; + GLuint *dstImageOffsets; + + if (image->mt) { + dstRowStride = image->mt->levels[image->mtlevel].rowstride; + } else if (t->bo) { + /* TFP case */ + /* TODO */ + assert(0); + } else { + dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width); + } + + assert(dstRowStride); + + if (dims == 3) { + unsigned alignedWidth = dstRowStride/_mesa_get_format_bytes(texImage->TexFormat); + dstImageOffsets = allocate_image_offsets(ctx, alignedWidth, texImage->Height, texImage->Depth); + if (!dstImageOffsets) { + return; + } + } else { + dstImageOffsets = texImage->ImageOffsets; + } + + radeon_teximage_map(image, GL_TRUE); + + if (compressed) { + uint32_t srcRowStride, bytesPerRow, rows, block_width, block_height; + GLubyte *img_start; + + _mesa_get_format_block_size(texImage->TexFormat, &block_width, &block_height); + + if (!image->mt) { + dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width); + img_start = _mesa_compressed_image_address(xoffset, yoffset, 0, + texImage->TexFormat, + texImage->Width, texImage->Data); + } + else { + uint32_t offset; + offset = dstRowStride / _mesa_get_format_bytes(texImage->TexFormat) * yoffset / block_height + xoffset / block_width; + offset *= _mesa_get_format_bytes(texImage->TexFormat); + img_start = texImage->Data + offset; + } + srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width); + bytesPerRow = srcRowStride; + rows = (height + block_height - 1) / block_height; + + copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow); + } + else { + if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat, + texImage->TexFormat, texImage->Data, + xoffset, yoffset, zoffset, + dstRowStride, + dstImageOffsets, + width, height, depth, + format, type, pixels, packing)) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); + } + } + + if (dims == 3) { + _mesa_free(dstImageOffsets); + } + + radeon_teximage_unmap(image); +} + /** * All glTexImage calls go through this function. */ @@ -528,13 +708,22 @@ static void radeon_teximage( radeonContextPtr rmesa = RADEON_CONTEXT(ctx); radeonTexObj* t = radeon_tex_obj(texObj); radeon_texture_image* image = get_radeon_texture_image(texImage); - GLuint dstRowStride; GLint postConvWidth = width; GLint postConvHeight = height; - GLuint texelBytes; GLuint face = radeon_face_for_target(target); - radeon_firevertices(rmesa); + { + struct radeon_bo *bo; + bo = !image->mt ? image->bo : image->mt->bo; + if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { + radeon_firevertices(rmesa); + } + } + + if (RADEON_DEBUG & RADEON_TEXTURE) { + fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, face %d, level %d\n", + dims, texObj, texImage, face, level); + } t->validated = GL_FALSE; @@ -543,53 +732,35 @@ static void radeon_teximage( &postConvHeight); } - if (_mesa_is_format_compressed(texImage->TexFormat)) { - texelBytes = 0; - } else { - texelBytes = _mesa_get_format_bytes(texImage->TexFormat); + if (!_mesa_is_format_compressed(texImage->TexFormat)) { + GLuint texelBytes = _mesa_get_format_bytes(texImage->TexFormat); /* Minimum pitch of 32 bytes */ if (postConvWidth * texelBytes < 32) { - postConvWidth = 32 / texelBytes; - texImage->RowStride = postConvWidth; + postConvWidth = 32 / texelBytes; + texImage->RowStride = postConvWidth; } - if (!image->mt) { + if (!image->mt) { assert(texImage->RowStride == postConvWidth); } } - /* Allocate memory for image */ - radeonFreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */ - - if (t->mt && - t->mt->firstLevel == level && - t->mt->lastLevel == level && - t->mt->target != GL_TEXTURE_CUBE_MAP_ARB && - !radeon_miptree_matches_image(t->mt, texImage, face, level)) { - radeon_miptree_unreference(t->mt); - t->mt = NULL; - } - - if (!t->mt) - radeon_try_alloc_miptree(rmesa, t, image, face, level); - if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) { - radeon_mipmap_level *lvl; - image->mt = t->mt; - image->mtlevel = level - t->mt->firstLevel; - image->mtface = face; - radeon_miptree_reference(t->mt); - lvl = &image->mt->levels[image->mtlevel]; - dstRowStride = lvl->rowstride; - } else { - int size; - if (_mesa_is_format_compressed(texImage->TexFormat)) { - size = _mesa_format_image_size(texImage->TexFormat, - texImage->Width, - texImage->Height, - texImage->Depth); - } else { - size = texImage->Width * texImage->Height * texImage->Depth * _mesa_get_format_bytes(texImage->TexFormat); + /* Mesa core only clears texImage->Data but not image->mt */ + radeonFreeTexImageData(ctx, texImage); + + if (!t->bo) { + teximage_assign_miptree(rmesa, texObj, texImage, face, level); + if (!image->mt) { + int size = _mesa_format_image_size(texImage->TexFormat, + texImage->Width, + texImage->Height, + texImage->Depth); + texImage->Data = _mesa_alloc_texmemory(size); + if (RADEON_DEBUG & RADEON_TEXTURE) { + fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, " + " no miptree assigned, using local memory %p\n", + dims, texObj, texImage, texImage->Data); + } } - texImage->Data = _mesa_alloc_texmemory(size); } /* Upload texture image; note that the spec allows pixels to be NULL */ @@ -603,65 +774,16 @@ static void radeon_teximage( } if (pixels) { - radeon_teximage_map(image, GL_TRUE); - if (compressed) { - if (image->mt) { - uint32_t srcRowStride, bytesPerRow, rows; - srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width); - bytesPerRow = srcRowStride; - rows = (height + 3) / 4; - copy_rows(texImage->Data, image->mt->levels[level].rowstride, - pixels, srcRowStride, rows, bytesPerRow); - } else { - memcpy(texImage->Data, pixels, imageSize); - } - } else { - GLuint dstRowStride; - GLuint *dstImageOffsets; - - if (image->mt) { - radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; - dstRowStride = lvl->rowstride; - } else { - dstRowStride = texImage->Width * _mesa_get_format_bytes(texImage->TexFormat); - } - - if (dims == 3) { - int i; - - dstImageOffsets = _mesa_malloc(depth * sizeof(GLuint)) ; - if (!dstImageOffsets) - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); - - for (i = 0; i < depth; ++i) { - dstImageOffsets[i] = dstRowStride/_mesa_get_format_bytes(texImage->TexFormat) * height * i; - } - } else { - dstImageOffsets = texImage->ImageOffsets; - } - - if (!_mesa_texstore(ctx, dims, - texImage->_BaseFormat, - texImage->TexFormat, - texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */ - dstRowStride, - dstImageOffsets, - width, height, depth, - format, type, pixels, packing)) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); - } - - if (dims == 3) - _mesa_free(dstImageOffsets); - } + radeon_store_teximage(ctx, dims, + 0, 0, 0, + width, height, depth, + imageSize, format, type, + pixels, packing, + texObj, texImage, + compressed); } _mesa_unmap_teximage_pbo(ctx, packing); - - if (pixels) - radeon_teximage_unmap(image); - - } void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level, @@ -714,7 +836,7 @@ void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level, } /** - * Update a subregion of the given texture image. + * All glTexSubImage calls go through this function. */ static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int level, GLint xoffset, GLint yoffset, GLint zoffset, @@ -731,66 +853,39 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int leve radeonTexObj* t = radeon_tex_obj(texObj); radeon_texture_image* image = get_radeon_texture_image(texImage); - radeon_firevertices(rmesa); + { + struct radeon_bo *bo; + bo = !image->mt ? image->bo : image->mt->bo; + if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { + radeon_firevertices(rmesa); + } + } + + if (RADEON_DEBUG & RADEON_TEXTURE) { + fprintf(stderr, "radeon_texsubimage%dd: texObj %p, texImage %p, face %d, level %d\n", + dims, texObj, texImage, radeon_face_for_target(target), level); + } t->validated = GL_FALSE; if (compressed) { pixels = _mesa_validate_pbo_compressed_teximage( - ctx, imageSize, pixels, packing, "glCompressedTexImage"); + ctx, imageSize, pixels, packing, "glCompressedTexSubImage"); } else { pixels = _mesa_validate_pbo_teximage(ctx, dims, - width, height, depth, format, type, pixels, packing, "glTexSubImage1D"); + width, height, depth, format, type, pixels, packing, "glTexSubImage"); } if (pixels) { - GLint dstRowStride; - radeon_teximage_map(image, GL_TRUE); - - if (image->mt) { - radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; - dstRowStride = lvl->rowstride; - } else { - dstRowStride = texImage->RowStride * _mesa_get_format_bytes(texImage->TexFormat); - } - - if (compressed) { - uint32_t srcRowStride, bytesPerRow, rows; - GLubyte *img_start; - if (!image->mt) { - dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width); - img_start = _mesa_compressed_image_address(xoffset, yoffset, 0, - texImage->TexFormat, - texImage->Width, texImage->Data); - } - else { - uint32_t blocks_x = dstRowStride / (image->mt->bpp * 4); - img_start = texImage->Data + image->mt->bpp * 4 * (blocks_x * (yoffset / 4) + xoffset / 4); - } - srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width); - bytesPerRow = srcRowStride; - rows = (height + 3) / 4; - - copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow); - - } - else { - if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat, - texImage->TexFormat, texImage->Data, - xoffset, yoffset, zoffset, - dstRowStride, - texImage->ImageOffsets, - width, height, depth, - format, type, pixels, packing)) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); - } - } + radeon_store_teximage(ctx, dims, + xoffset, yoffset, zoffset, + width, height, depth, + imageSize, format, type, + pixels, packing, + texObj, texImage, + compressed); } - radeon_teximage_unmap(image); - _mesa_unmap_teximage_pbo(ctx, packing); - - } void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, @@ -846,143 +941,6 @@ void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, format, type, pixels, packing, texObj, texImage, 0); } - - -/** - * Ensure that the given image is stored in the given miptree from now on. - */ -static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_image *image, int face, int level) -{ - radeon_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel]; - unsigned char *dest; - - assert(image->mt != mt); - assert(dstlvl->width == image->base.Width); - assert(dstlvl->height == image->base.Height); - assert(dstlvl->depth == image->base.Depth); - - - radeon_bo_map(mt->bo, GL_TRUE); - dest = mt->bo->ptr + dstlvl->faces[face].offset; - - if (image->mt) { - /* Format etc. should match, so we really just need a memcpy(). - * In fact, that memcpy() could be done by the hardware in many - * cases, provided that we have a proper memory manager. - */ - radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel-image->mt->firstLevel]; - - assert(srclvl->size == dstlvl->size); - assert(srclvl->rowstride == dstlvl->rowstride); - - radeon_bo_map(image->mt->bo, GL_FALSE); - - memcpy(dest, - image->mt->bo->ptr + srclvl->faces[face].offset, - dstlvl->size); - radeon_bo_unmap(image->mt->bo); - - radeon_miptree_unreference(image->mt); - } else { - uint32_t srcrowstride; - uint32_t height; - /* need to confirm this value is correct */ - if (mt->compressed) { - height = (image->base.Height + 3) / 4; - srcrowstride = _mesa_format_row_stride(image->base.TexFormat, image->base.Width); - } else { - height = image->base.Height * image->base.Depth; - srcrowstride = image->base.Width * _mesa_get_format_bytes(image->base.TexFormat); - } - -// if (mt->tilebits) -// WARN_ONCE("%s: tiling not supported yet", __FUNCTION__); - - copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride, - height, srcrowstride); - - _mesa_free_texmemory(image->base.Data); - image->base.Data = 0; - } - - radeon_bo_unmap(mt->bo); - - image->mt = mt; - image->mtface = face; - image->mtlevel = level; - radeon_miptree_reference(image->mt); -} - -int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonTexObj *t = radeon_tex_obj(texObj); - radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[0][texObj->BaseLevel]); - int face, level; - - if (t->validated || t->image_override) - return GL_TRUE; - - if (RADEON_DEBUG & RADEON_TEXTURE) - fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj); - - if (baseimage->base.Border > 0) - return GL_FALSE; - - /* Ensure a matching miptree exists. - * - * Differing mipmap trees can result when the app uses TexImage to - * change texture dimensions. - * - * Prefer to use base image's miptree if it - * exists, since that most likely contains more valid data (remember - * that the base level is usually significantly larger than the rest - * of the miptree, so cubemaps are the only possible exception). - */ - if (baseimage->mt && - baseimage->mt != t->mt && - radeon_miptree_matches_texture(baseimage->mt, &t->base)) { - radeon_miptree_unreference(t->mt); - t->mt = baseimage->mt; - radeon_miptree_reference(t->mt); - } else if (t->mt && !radeon_miptree_matches_texture(t->mt, &t->base)) { - radeon_miptree_unreference(t->mt); - t->mt = 0; - } - - if (!t->mt) { - if (RADEON_DEBUG & RADEON_TEXTURE) - fprintf(stderr, " Allocate new miptree\n"); - radeon_try_alloc_miptree(rmesa, t, baseimage, 0, texObj->BaseLevel); - if (!t->mt) { - _mesa_problem(ctx, "radeon_validate_texture failed to alloc miptree"); - return GL_FALSE; - } - } - - /* Ensure all images are stored in the single main miptree */ - for(face = 0; face < t->mt->faces; ++face) { - for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) { - radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][level]); - if (RADEON_DEBUG & RADEON_TEXTURE) - fprintf(stderr, " face %i, level %i... %p vs %p ", face, level, t->mt, image->mt); - if (t->mt == image->mt || (!image->mt && !image->base.Data)) { - if (RADEON_DEBUG & RADEON_TEXTURE) - fprintf(stderr, "OK\n"); - - continue; - } - - if (RADEON_DEBUG & RADEON_TEXTURE) - fprintf(stderr, "migrating\n"); - migrate_image_to_miptree(t->mt, image, face, level); - } - } - - return GL_TRUE; -} - - /** * Need to map texture image into memory before copying image data, * then unmap it. diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.h b/src/mesa/drivers/dri/radeon/radeon_texture.h index 8995546d77..906daf12d0 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.h +++ b/src/mesa/drivers/dri/radeon/radeon_texture.h @@ -33,7 +33,8 @@ #include "main/formats.h" - +void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride, + GLuint numrows, GLuint rowsize); struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx); void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage); |