**************************************************************************/
-/*
- * Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
- * Nicolai Haehnle <prefect_@gmx.net>
+/**
+ * \file
+ *
+ * \author Keith Whitwell <keith@tungstengraphics.com>
+ *
+ * \author Nicolai Haehnle <prefect_@gmx.net>
*/
+
#include "glheader.h"
#include "api_arrayelt.h"
#include "context.h"
#include "matrix.h"
#include "extensions.h"
#include "state.h"
+#include "bufferobj.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
+#include "tnl/t_vp_build.h"
#include "drivers/common/driverfuncs.h"
#include "r300_state.h"
#include "r300_ioctl.h"
#include "r300_tex.h"
+#include "r300_emit.h"
+#include "r300_swtcl.h"
+
+#ifdef USER_BUFFERS
+#include "r300_mem.h"
+#endif
#include "vblank.h"
#include "utils.h"
#include "xmlpool.h" /* for symbolic values of enum-type options */
/* hw_tcl_on derives from future_hw_tcl_on when its safe to change it. */
-int future_hw_tcl_on=0;
-int hw_tcl_on=0;
+int future_hw_tcl_on = 1;
+int hw_tcl_on = 1;
-#if 1
+#define need_GL_EXT_stencil_two_side
#define need_GL_ARB_multisample
+#define need_GL_ARB_point_parameters
#define need_GL_ARB_texture_compression
+#define need_GL_ARB_vertex_buffer_object
+#define need_GL_ARB_vertex_program
#define need_GL_EXT_blend_minmax
+//#define need_GL_EXT_fog_coord
+#define need_GL_EXT_multi_draw_arrays
+#define need_GL_EXT_secondary_color
+#define need_GL_EXT_blend_equation_separate
+#define need_GL_EXT_blend_func_separate
+#define need_GL_EXT_gpu_program_parameters
+#define need_GL_NV_vertex_program
#include "extension_helper.h"
-static const struct dri_extension card_extensions[] = {
+const struct dri_extension card_extensions[] = {
+ /* *INDENT-OFF* */
+ {"GL_ARB_depth_texture", NULL},
+ {"GL_ARB_fragment_program", NULL},
{"GL_ARB_multisample", GL_ARB_multisample_functions},
{"GL_ARB_multitexture", NULL},
+ {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions},
+ {"GL_ARB_shadow", NULL},
+ {"GL_ARB_shadow_ambient", NULL},
{"GL_ARB_texture_border_clamp", NULL},
{"GL_ARB_texture_compression", GL_ARB_texture_compression_functions},
-/* disable until we support it, fixes a few things in ut2004 */
-/* {"GL_ARB_texture_cube_map", NULL}, */
+ {"GL_ARB_texture_cube_map", NULL},
{"GL_ARB_texture_env_add", NULL},
{"GL_ARB_texture_env_combine", NULL},
{"GL_ARB_texture_env_crossbar", NULL},
{"GL_ARB_texture_env_dot3", NULL},
{"GL_ARB_texture_mirrored_repeat", NULL},
- {"GL_ARB_vertex_buffer_object", NULL},
- {"GL_ARB_vertex_program", NULL},
-#if USE_ARB_F_P == 1
- {"GL_ARB_fragment_program", NULL},
-#endif
- {"GL_EXT_blend_equation_separate", NULL},
- {"GL_EXT_blend_func_separate", NULL},
+ {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions},
+ {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions},
+ {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions},
+ {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions},
{"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions},
{"GL_EXT_blend_subtract", NULL},
- {"GL_EXT_secondary_color", NULL},
+// {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
+ {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions},
+ {"GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions},
+ {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions},
+ {"GL_EXT_shadow_funcs", NULL},
+ {"GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions},
{"GL_EXT_stencil_wrap", NULL},
{"GL_EXT_texture_edge_clamp", NULL},
{"GL_EXT_texture_env_combine", NULL},
{"GL_ATI_texture_mirror_once", NULL},
{"GL_MESA_pack_invert", NULL},
{"GL_MESA_ycbcr_texture", NULL},
+ {"GL_MESAX_texture_float", NULL},
{"GL_NV_blend_square", NULL},
- {"GL_NV_vertex_program", NULL},
+ {"GL_NV_vertex_program", GL_NV_vertex_program_functions},
{"GL_SGIS_generate_mipmap", NULL},
+ {"GL_SGIX_depth_texture", NULL},
{NULL, NULL}
+ /* *INDENT-ON* */
};
-#else
-/* Extension strings exported by the R300 driver.
- */
-static const char *const card_extensions[] = {
- "GL_ARB_multisample",
- "GL_ARB_multitexture",
- "GL_ARB_texture_border_clamp",
- "GL_ARB_texture_compression",
-/* disable until we support it, fixes a few things in ut2004 */
-/* "GL_ARB_texture_cube_map", */
- "GL_ARB_texture_env_add",
- "GL_ARB_texture_env_combine",
- "GL_ARB_texture_env_crossbar",
- "GL_ARB_texture_env_dot3",
- "GL_ARB_texture_mirrored_repeat",
- "GL_ARB_vertex_buffer_object",
- "GL_ARB_vertex_program",
-#if USE_ARB_F_P == 1
- "GL_ARB_fragment_program",
-#endif
- "GL_EXT_blend_equation_separate",
- "GL_EXT_blend_func_separate",
- "GL_EXT_blend_minmax",
- "GL_EXT_blend_subtract",
- "GL_EXT_secondary_color",
- "GL_EXT_stencil_wrap",
- "GL_EXT_texture_edge_clamp",
- "GL_EXT_texture_env_combine",
- "GL_EXT_texture_env_dot3",
- "GL_EXT_texture_filter_anisotropic",
- "GL_EXT_texture_lod_bias",
- "GL_EXT_texture_mirror_clamp",
- "GL_EXT_texture_rectangle",
- "GL_ATI_texture_env_combine3",
- "GL_ATI_texture_mirror_once",
- "GL_MESA_pack_invert",
- "GL_MESA_ycbcr_texture",
- "GL_NV_blend_square",
- "GL_NV_vertex_program",
- "GL_SGIS_generate_mipmap",
- NULL
-};
-#endif
extern struct tnl_pipeline_stage _r300_render_stage;
-extern struct tnl_pipeline_stage _r300_tcl_stage;
+extern const struct tnl_pipeline_stage _r300_tcl_stage;
static const struct tnl_pipeline_stage *r300_pipeline[] = {
0,
};
-void r300BufferData(GLcontext *ctx, GLenum target, GLsizeiptrARB size,
- const GLvoid *data, GLenum usage, struct gl_buffer_object *obj)
-{
- r300ContextPtr rmesa = R300_CONTEXT(ctx);
- drm_radeon_mem_alloc_t alloc;
- int offset, ret;
-
- /* Free previous buffer */
- if (obj->OnCard) {
- drm_radeon_mem_free_t memfree;
-
- memfree.region = RADEON_MEM_REGION_GART;
- memfree.region_offset = (char *)obj->Data - (char *)rmesa->radeon.radeonScreen->gartTextures.map;
-
- ret = drmCommandWrite(rmesa->radeon.radeonScreen->driScreen->fd,
- DRM_RADEON_FREE, &memfree, sizeof(memfree));
-
- if (ret) {
- WARN_ONCE("Failed to free GART memroy!\n");
- }
- obj->OnCard = GL_FALSE;
- }
-
- alloc.region = RADEON_MEM_REGION_GART;
- alloc.alignment = 4;
- alloc.size = size;
- alloc.region_offset = &offset;
-
- ret = drmCommandWriteRead( rmesa->radeon.dri.fd, DRM_RADEON_ALLOC, &alloc, sizeof(alloc));
- if (ret) {
- WARN_ONCE("Ran out of GART memory!\n");
- obj->Data = NULL;
- _mesa_buffer_data(ctx, target, size, data, usage, obj);
- return ;
- }
- obj->Data = ((char *)rmesa->radeon.radeonScreen->gartTextures.map) + offset;
-
- if (data)
- memcpy(obj->Data, data, size);
-
- obj->Size = size;
- obj->Usage = usage;
- obj->OnCard = GL_TRUE;
-#if 0
- fprintf(stderr, "allocated %d bytes at %p, offset=%d\n", size, obj->Data, offset);
-#endif
-}
-
-void r300DeleteBuffer(GLcontext *ctx, struct gl_buffer_object *obj)
-{
- r300ContextPtr rmesa = R300_CONTEXT(ctx);
-
- if(r300IsGartMemory(rmesa, obj->Data, obj->Size)){
- drm_radeon_mem_free_t memfree;
- int ret;
-
- memfree.region = RADEON_MEM_REGION_GART;
- memfree.region_offset = (char *)obj->Data - (char *)rmesa->radeon.radeonScreen->gartTextures.map;
-
- ret = drmCommandWrite(rmesa->radeon.radeonScreen->driScreen->fd,
- DRM_RADEON_FREE, &memfree, sizeof(memfree));
-
- if(ret){
- WARN_ONCE("Failed to free GART memroy!\n");
- }
- obj->Data = NULL;
- }
- _mesa_delete_buffer_object(ctx, obj);
-}
-
/* Create the device specific rendering context.
*/
GLboolean r300CreateContext(const __GLcontextModes * glVisual,
assert(screen);
/* Allocate the R300 context */
- r300 = (r300ContextPtr)CALLOC(sizeof(*r300));
+ r300 = (r300ContextPtr) CALLOC(sizeof(*r300));
if (!r300)
return GL_FALSE;
+ if (!(screen->chip_flags & RADEON_CHIPSET_TCL))
+ hw_tcl_on = future_hw_tcl_on = 0;
+
/* Parse configuration files.
* Do this here so that initialMaxAnisotropy is set before we create
* the default textures.
*/
driParseConfigFiles(&r300->radeon.optionCache, &screen->optionCache,
screen->driScreen->myNum, "r300");
+ r300->initialMaxAnisotropy = driQueryOptionf(&r300->radeon.optionCache,
+ "def_max_anisotropy");
/* Init default driver functions then plug in our R300-specific functions
* (the texture functions are especially important)
r300InitStateFuncs(&functions);
r300InitTextureFuncs(&functions);
r300InitShaderFuncs(&functions);
-
-#if 0 /* Needs various Mesa changes... */
- if (hw_tcl_on) {
- functions.BufferData = r300BufferData;
- functions.DeleteBuffer = r300DeleteBuffer;
- }
+
+#ifdef USER_BUFFERS
+ r300_mem_init(r300);
#endif
-
+
if (!radeonInitContext(&r300->radeon, &functions,
- glVisual, driContextPriv, sharedContextPrivate)) {
+ glVisual, driContextPriv,
+ sharedContextPrivate)) {
FREE(r300);
return GL_FALSE;
}
/* Init r300 context data */
- r300->dma.buf0_address = r300->radeon.radeonScreen->buffers->list[0].address;
+ r300->dma.buf0_address =
+ r300->radeon.radeonScreen->buffers->list[0].address;
(void)memset(r300->texture_heaps, 0, sizeof(r300->texture_heaps));
make_empty_list(&r300->swapped);
r300->nr_heaps = 1 /* screen->numTexHeaps */ ;
- assert(r300->nr_heaps < R200_NR_TEX_HEAPS);
+ assert(r300->nr_heaps < RADEON_NR_TEX_HEAPS);
for (i = 0; i < r300->nr_heaps; i++) {
+ /* *INDENT-OFF* */
r300->texture_heaps[i] = driCreateTextureHeap(i, r300,
screen->
texSize[i], 12,
(destroy_texture_object_t
*)
r300DestroyTexObj);
+ /* *INDENT-ON* */
}
r300->texture_depth = driQueryOptioni(&r300->radeon.optionCache,
- "texture_depth");
+ "texture_depth");
if (r300->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
r300->texture_depth = (screen->cpp == 4) ?
DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
* texturable memory at once.
*/
- ctx = r300->radeon.glCtx;
-
- ctx->Const.MaxTextureImageUnits = driQueryOptioni(&r300->radeon.optionCache,
- "texture_image_units");
- ctx->Const.MaxTextureCoordUnits = driQueryOptioni(&r300->radeon.optionCache,
- "texture_coord_units");
- ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureImageUnits,
- ctx->Const.MaxTextureCoordUnits);
+ ctx = r300->radeon.glCtx;
+
+ ctx->Const.MaxTextureImageUnits =
+ driQueryOptioni(&r300->radeon.optionCache, "texture_image_units");
+ ctx->Const.MaxTextureCoordUnits =
+ driQueryOptioni(&r300->radeon.optionCache, "texture_coord_units");
+ ctx->Const.MaxTextureUnits =
+ MIN2(ctx->Const.MaxTextureImageUnits,
+ ctx->Const.MaxTextureCoordUnits);
ctx->Const.MaxTextureMaxAnisotropy = 16.0;
+ ctx->Const.MaxTextureLodBias = 16.0;
+
+ if (screen->chip_family >= CHIP_FAMILY_RV515) {
+ ctx->Const.MaxTextureLevels = 13;
+ ctx->Const.MaxTextureRectSize = 4096;
+ }
ctx->Const.MinPointSize = 1.0;
ctx->Const.MinPointSizeAA = 1.0;
ctx->Const.MaxLineWidth = R300_LINESIZE_MAX;
ctx->Const.MaxLineWidthAA = R300_LINESIZE_MAX;
+#ifdef USER_BUFFERS
+ /* Needs further modifications */
+#if 0
+ ctx->Const.MaxArrayLockSize =
+ ( /*512 */ RADEON_BUFFER_SIZE * 16 * 1024) / (4 * 4);
+#endif
+#endif
+
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext(ctx);
- _ac_CreateContext(ctx);
+ _vbo_CreateContext(ctx);
_tnl_CreateContext(ctx);
_swsetup_CreateContext(ctx);
_swsetup_Wakeup(ctx);
/* Try and keep materials and vertices separate:
*/
- _tnl_isolate_materials(ctx, GL_TRUE);
+/* _tnl_isolate_materials(ctx, GL_TRUE); */
/* Configure swrast and TNL to match hardware characteristics:
*/
_tnl_allow_vertex_fog(ctx, GL_TRUE);
/* currently bogus data */
- ctx->Const.MaxVertexProgramInstructions=VSF_MAX_FRAGMENT_LENGTH;
- ctx->Const.MaxVertexProgramAttribs=16; // r420
- ctx->Const.MaxVertexProgramTemps=VSF_MAX_FRAGMENT_TEMPS;
- ctx->Const.MaxVertexProgramLocalParams=256; // r420
- ctx->Const.MaxVertexProgramEnvParams=256; // r420
- ctx->Const.MaxVertexProgramAddressRegs=1;
-
-#if USE_ARB_F_P
- ctx->Const.MaxFragmentProgramTemps = PFS_NUM_TEMP_REGS;
- ctx->Const.MaxFragmentProgramAttribs = 11; /* copy i915... */
- ctx->Const.MaxFragmentProgramLocalParams = PFS_NUM_CONST_REGS;
- ctx->Const.MaxFragmentProgramEnvParams = PFS_NUM_CONST_REGS;
- ctx->Const.MaxFragmentProgramAluInstructions = PFS_MAX_ALU_INST;
- ctx->Const.MaxFragmentProgramTexInstructions = PFS_MAX_TEX_INST;
- ctx->Const.MaxFragmentProgramInstructions = PFS_MAX_ALU_INST+PFS_MAX_TEX_INST;
- ctx->Const.MaxFragmentProgramTexIndirections = PFS_MAX_TEX_INDIRECT;
- ctx->Const.MaxFragmentProgramAddressRegs = 0; /* and these are?? */
- ctx->_MaintainTexEnvProgram = GL_TRUE;
-#endif
+ if (screen->chip_flags & RADEON_CHIPSET_TCL) {
+ ctx->Const.VertexProgram.MaxInstructions = VSF_MAX_FRAGMENT_LENGTH / 4;
+ ctx->Const.VertexProgram.MaxNativeInstructions =
+ VSF_MAX_FRAGMENT_LENGTH / 4;
+ ctx->Const.VertexProgram.MaxNativeAttribs = 16; /* r420 */
+ ctx->Const.VertexProgram.MaxTemps = 32;
+ ctx->Const.VertexProgram.MaxNativeTemps =
+ /*VSF_MAX_FRAGMENT_TEMPS */ 32;
+ ctx->Const.VertexProgram.MaxNativeParameters = 256; /* r420 */
+ ctx->Const.VertexProgram.MaxNativeAddressRegs = 1;
+ }
+
+ ctx->Const.FragmentProgram.MaxNativeTemps = PFS_NUM_TEMP_REGS;
+ ctx->Const.FragmentProgram.MaxNativeAttribs = 11; /* copy i915... */
+ ctx->Const.FragmentProgram.MaxNativeParameters = PFS_NUM_CONST_REGS;
+ ctx->Const.FragmentProgram.MaxNativeAluInstructions = PFS_MAX_ALU_INST;
+ ctx->Const.FragmentProgram.MaxNativeTexInstructions = PFS_MAX_TEX_INST;
+ ctx->Const.FragmentProgram.MaxNativeInstructions =
+ PFS_MAX_ALU_INST + PFS_MAX_TEX_INST;
+ ctx->Const.FragmentProgram.MaxNativeTexIndirections =
+ PFS_MAX_TEX_INDIRECT;
+ ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* and these are?? */
+ _tnl_ProgramCacheInit(ctx);
+ ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
driInitExtensions(ctx, card_extensions, GL_TRUE);
-
+
+ if (driQueryOptionb
+ (&r300->radeon.optionCache, "disable_stencil_two_side"))
+ _mesa_disable_extension(ctx, "GL_EXT_stencil_two_side");
+
+ if (r300->radeon.glCtx->Mesa_DXTn
+ && !driQueryOptionb(&r300->radeon.optionCache, "disable_s3tc")) {
+ _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
+ _mesa_enable_extension(ctx, "GL_S3_s3tc");
+ } else
+ if (driQueryOptionb(&r300->radeon.optionCache, "force_s3tc_enable"))
+ {
+ _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
+ }
+
+ r300->disable_lowimpact_fallback =
+ driQueryOptionb(&r300->radeon.optionCache,
+ "disable_lowimpact_fallback");
+
radeonInitSpanFuncs(ctx);
r300InitCmdBuf(r300);
r300InitState(r300);
+ if (!(screen->chip_flags & RADEON_CHIPSET_TCL))
+ r300InitSwtcl(ctx);
-#if 0
- /* plug in a few more device driver functions */
- /* XXX these should really go right after _mesa_init_driver_functions() */
- r300InitPixelFuncs(ctx);
- r300InitSwtcl(ctx);
-#endif
TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
tcl_mode = driQueryOptioni(&r300->radeon.optionCache, "tcl_mode");
#endif
}
if (tcl_mode == DRI_CONF_TCL_SW ||
- !(r300->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL)) {
- if (r300->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL) {
- r300->radeon.radeonScreen->chipset &= ~RADEON_CHIPSET_TCL;
+ !(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) {
+ if (r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
+ r300->radeon.radeonScreen->chip_flags &=
+ ~RADEON_CHIPSET_TCL;
fprintf(stderr, "Disabling HW TCL support\n");
}
- TCL_FALLBACK(r300->radeon.glCtx, RADEON_TCL_FALLBACK_TCL_DISABLE, 1);
+ TCL_FALLBACK(r300->radeon.glCtx,
+ RADEON_TCL_FALLBACK_TCL_DISABLE, 1);
}
return GL_TRUE;
}
+static void r300FreeGartAllocations(r300ContextPtr r300)
+{
+ int i, ret, tries = 0, done_age, in_use = 0;
+ drm_radeon_mem_free_t memfree;
+
+ memfree.region = RADEON_MEM_REGION_GART;
+
+#ifdef USER_BUFFERS
+ for (i = r300->rmm->u_last; i > 0; i--) {
+ if (r300->rmm->u_list[i].ptr == NULL) {
+ continue;
+ }
+
+ /* check whether this buffer is still in use */
+ if (r300->rmm->u_list[i].pending) {
+ in_use++;
+ }
+ }
+ /* Cannot flush/lock if no context exists. */
+ if (in_use)
+ r300FlushCmdBuf(r300, __FUNCTION__);
+
+ done_age = radeonGetAge((radeonContextPtr) r300);
+
+ for (i = r300->rmm->u_last; i > 0; i--) {
+ if (r300->rmm->u_list[i].ptr == NULL) {
+ continue;
+ }
+
+ /* check whether this buffer is still in use */
+ if (!r300->rmm->u_list[i].pending) {
+ continue;
+ }
+
+ assert(r300->rmm->u_list[i].h_pending == 0);
+
+ tries = 0;
+ while (r300->rmm->u_list[i].age > done_age && tries++ < 1000) {
+ usleep(10);
+ done_age = radeonGetAge((radeonContextPtr) r300);
+ }
+ if (tries >= 1000) {
+ WARN_ONCE("Failed to idle region!");
+ }
+
+ memfree.region_offset = (char *)r300->rmm->u_list[i].ptr -
+ (char *)r300->radeon.radeonScreen->gartTextures.map;
+
+ ret = drmCommandWrite(r300->radeon.radeonScreen->driScreen->fd,
+ DRM_RADEON_FREE, &memfree,
+ sizeof(memfree));
+ if (ret) {
+ fprintf(stderr, "Failed to free at %p\nret = %s\n",
+ r300->rmm->u_list[i].ptr, strerror(-ret));
+ } else {
+ if (i == r300->rmm->u_last)
+ r300->rmm->u_last--;
+
+ r300->rmm->u_list[i].pending = 0;
+ r300->rmm->u_list[i].ptr = NULL;
+ }
+ }
+ r300->rmm->u_head = i;
+#endif /* USER_BUFFERS */
+}
+
/* Destroy the device specific context.
*/
void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
{
GET_CURRENT_CONTEXT(ctx);
r300ContextPtr r300 = (r300ContextPtr) driContextPriv->driverPrivate;
+ radeonContextPtr radeon = (radeonContextPtr) r300;
radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL;
if (RADEON_DEBUG & DEBUG_DRI) {
if (r300) {
GLboolean release_texture_heaps;
- release_texture_heaps = (r300->radeon.glCtx->Shared->RefCount == 1);
+ release_texture_heaps =
+ (r300->radeon.glCtx->Shared->RefCount == 1);
_swsetup_DestroyContext(r300->radeon.glCtx);
+ _tnl_ProgramCacheDestroy(r300->radeon.glCtx);
_tnl_DestroyContext(r300->radeon.glCtx);
- _ac_DestroyContext(r300->radeon.glCtx);
+ _vbo_DestroyContext(r300->radeon.glCtx);
_swrast_DestroyContext(r300->radeon.glCtx);
+ if (r300->dma.current.buf) {
+ r300ReleaseDmaRegion(r300, &r300->dma.current,
+ __FUNCTION__);
+#ifndef USER_BUFFERS
+ r300FlushCmdBuf(r300, __FUNCTION__);
+#endif
+ }
+ r300FreeGartAllocations(r300);
r300DestroyCmdBuf(r300);
+ if (radeon->state.scissor.pClipRects) {
+ FREE(radeon->state.scissor.pClipRects);
+ radeon->state.scissor.pClipRects = NULL;
+ }
+
+ if (release_texture_heaps) {
+ /* This share group is about to go away, free our private
+ * texture object data.
+ */
+ int i;
+
+ for (i = 0; i < r300->nr_heaps; i++) {
+ driDestroyTextureHeap(r300->texture_heaps[i]);
+ r300->texture_heaps[i] = NULL;
+ }
+
+ assert(is_empty_list(&r300->swapped));
+ }
+
radeonCleanupContext(&r300->radeon);
+#ifdef USER_BUFFERS
+ /* the memory manager might be accessed when Mesa frees the shared
+ * state, so don't destroy it earlier
+ */
+ r300_mem_destroy(r300);
+#endif
+
/* free the option cache */
driDestroyOptionCache(&r300->radeon.optionCache);