**************************************************************************/
-/*
- * 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 "simple_list.h"
-#include "imports.h"
-#include "matrix.h"
-#include "extensions.h"
-#include "state.h"
-#include "bufferobj.h"
+
+#include "main/glheader.h"
+#include "main/api_arrayelt.h"
+#include "main/context.h"
+#include "main/simple_list.h"
+#include "main/imports.h"
+#include "main/matrix.h"
+#include "main/extensions.h"
+#include "main/state.h"
+#include "main/bufferobj.h"
+#include "main/texobj.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "drivers/common/driverfuncs.h"
-#include "radeon_ioctl.h"
-#include "radeon_span.h"
#include "r300_context.h"
+#include "radeon_context.h"
+#include "radeon_span.h"
#include "r300_cmdbuf.h"
#include "r300_state.h"
#include "r300_ioctl.h"
#include "r300_tex.h"
-#include "r300_maos.h"
+#include "r300_emit.h"
+#include "r300_swtcl.h"
+#include "radeon_bocs_wrapper.h"
-#ifdef USER_BUFFERS
-#include "r300_mem.h"
-#endif
#include "vblank.h"
#include "utils.h"
int future_hw_tcl_on = 1;
int hw_tcl_on = 1;
-#define need_GL_EXT_stencil_two_side
-#define need_GL_ARB_multisample
-#define need_GL_ARB_texture_compression
-#define need_GL_ARB_vertex_buffer_object
+#define need_GL_VERSION_2_0
+#define need_GL_ARB_point_parameters
#define need_GL_ARB_vertex_program
-#define need_GL_EXT_blend_minmax
-//#define need_GL_EXT_fog_coord
-#define need_GL_EXT_secondary_color
#define need_GL_EXT_blend_equation_separate
#define need_GL_EXT_blend_func_separate
+#define need_GL_EXT_blend_minmax
+//#define need_GL_EXT_fog_coord
#define need_GL_EXT_gpu_program_parameters
+#define need_GL_EXT_secondary_color
+#define need_GL_EXT_stencil_two_side
+#define need_GL_ATI_separate_stencil
#define need_GL_NV_vertex_program
#include "extension_helper.h"
const struct dri_extension card_extensions[] = {
/* *INDENT-OFF* */
- {"GL_ARB_multisample", GL_ARB_multisample_functions},
+ {"GL_ARB_depth_texture", NULL},
+ {"GL_ARB_fragment_program", NULL},
{"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},
{"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", GL_ARB_vertex_buffer_object_functions},
{"GL_ARB_vertex_program", GL_ARB_vertex_program_functions},
- {"GL_ARB_fragment_program", NULL},
{"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_fog_coord", GL_EXT_fog_coord_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_lod_bias", NULL},
{"GL_EXT_texture_mirror_clamp", NULL},
{"GL_EXT_texture_rectangle", NULL},
+ {"GL_ATI_separate_stencil", GL_ATI_separate_stencil_functions},
{"GL_ATI_texture_env_combine3", NULL},
{"GL_ATI_texture_mirror_once", NULL},
{"GL_MESA_pack_invert", NULL},
/* *INDENT-ON* */
};
+
+/**
+ * The GL 2.0 functions are needed to make display lists work with
+ * functions added by GL_ATI_separate_stencil.
+ */
+const struct dri_extension gl_20_extension[] = {
+ {"GL_VERSION_2_0", GL_VERSION_2_0_functions },
+};
+
+
extern struct tnl_pipeline_stage _r300_render_stage;
extern const struct tnl_pipeline_stage _r300_tcl_stage;
0,
};
+static void r300RunPipeline(GLcontext * ctx)
+{
+ _mesa_lock_context_textures(ctx);
+
+ if (ctx->NewState)
+ _mesa_update_state_locked(ctx);
+
+ _tnl_run_pipeline(ctx);
+ _mesa_unlock_context_textures(ctx);
+}
+
+static void r300_get_lock(radeonContextPtr rmesa)
+{
+ drm_radeon_sarea_t *sarea = rmesa->sarea;
+
+ if (sarea->ctx_owner != rmesa->dri.hwContext) {
+ sarea->ctx_owner = rmesa->dri.hwContext;
+ if (!rmesa->radeonScreen->kernel_mm)
+ radeon_bo_legacy_texture_age(rmesa->radeonScreen->bom);
+ }
+}
+
+static void r300_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmesa)
+{
+ /* please flush pipe do all pending work */
+ radeon_cs_write_dword(cs, cmdpacket0(rmesa->radeonScreen,
+ R300_SC_SCREENDOOR, 1));
+ radeon_cs_write_dword(cs, 0x0);
+ radeon_cs_write_dword(cs, cmdpacket0(rmesa->radeonScreen,
+ R300_SC_SCREENDOOR, 1));
+ radeon_cs_write_dword(cs, 0x00FFFFFF);
+ radeon_cs_write_dword(cs, cmdpacket0(rmesa->radeonScreen,
+ R300_SC_HYPERZ, 1));
+ radeon_cs_write_dword(cs, 0x0);
+ radeon_cs_write_dword(cs, cmdpacket0(rmesa->radeonScreen,
+ R300_US_CONFIG, 1));
+ radeon_cs_write_dword(cs, 0x0);
+ radeon_cs_write_dword(cs, cmdpacket0(rmesa->radeonScreen,
+ R300_ZB_CNTL, 1));
+ radeon_cs_write_dword(cs, 0x0);
+ radeon_cs_write_dword(cs, cmdwait(rmesa->radeonScreen, R300_WAIT_3D));
+ radeon_cs_write_dword(cs, cmdpacket0(rmesa->radeonScreen,
+ R300_RB3D_DSTCACHE_CTLSTAT, 1));
+ radeon_cs_write_dword(cs, R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D);
+ radeon_cs_write_dword(cs, cmdpacket0(rmesa->radeonScreen,
+ R300_ZB_ZCACHE_CTLSTAT, 1));
+ radeon_cs_write_dword(cs, R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE);
+ radeon_cs_write_dword(cs, cmdwait(rmesa->radeonScreen,
+ R300_WAIT_3D | R300_WAIT_3D_CLEAN));
+}
+
+static void r300_vtbl_pre_emit_atoms(radeonContextPtr radeon)
+{
+ BATCH_LOCALS(radeon);
+ cp_wait(radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
+ BEGIN_BATCH_NO_AUTOSTATE(2);
+ OUT_BATCH_REGVAL(R300_TX_INVALTAGS, R300_TX_FLUSH);
+ END_BATCH();
+ end_3d(radeon);
+}
+
+static void r300_init_vtbl(radeonContextPtr radeon)
+{
+ radeon->vtbl.get_lock = r300_get_lock;
+ radeon->vtbl.update_viewport_offset = r300UpdateViewportOffset;
+ radeon->vtbl.update_draw_buffer = r300UpdateDrawBuffer;
+ radeon->vtbl.emit_cs_header = r300_vtbl_emit_cs_header;
+ radeon->vtbl.swtcl_flush = r300_swtcl_flush;
+ radeon->vtbl.pre_emit_atoms = r300_vtbl_pre_emit_atoms;
+}
+
+
/* Create the device specific rendering context.
*/
GLboolean r300CreateContext(const __GLcontextModes * glVisual,
struct dd_function_table functions;
r300ContextPtr r300;
GLcontext *ctx;
- int tcl_mode, i;
+ int tcl_mode;
assert(glVisual);
assert(driContextPriv);
if (!(screen->chip_flags & RADEON_CHIPSET_TCL))
hw_tcl_on = future_hw_tcl_on = 0;
+ r300_init_vtbl(&r300->radeon);
/* 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,
+ r300->radeon.initialMaxAnisotropy = driQueryOptionf(&r300->radeon.optionCache,
"def_max_anisotropy");
- //r300->texmicrotile = GL_TRUE;
-
/* Init default driver functions then plug in our R300-specific functions
* (the texture functions are especially important)
*/
r300InitTextureFuncs(&functions);
r300InitShaderFuncs(&functions);
-#ifdef USER_BUFFERS
- r300_mem_init(r300);
-#endif
-
if (!radeonInitContext(&r300->radeon, &functions,
glVisual, driContextPriv,
sharedContextPrivate)) {
}
/* Init r300 context data */
- 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 < 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,
- RADEON_NR_TEX_REGIONS,
- (drmTextureRegionPtr)
- r300->radeon.sarea->
- tex_list[i],
- &r300->radeon.sarea->
- tex_age[i],
- &r300->swapped,
- sizeof
- (r300TexObj),
- (destroy_texture_object_t
- *)
- r300DestroyTexObj);
- /* *INDENT-ON* */
- }
- r300->texture_depth = driQueryOptioni(&r300->radeon.optionCache,
+ r300->radeon.texture_depth = driQueryOptioni(&r300->radeon.optionCache,
"texture_depth");
- if (r300->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
- r300->texture_depth = (screen->cpp == 4) ?
+ if (r300->radeon.texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
+ r300->radeon.texture_depth = (screen->cpp == 4) ?
DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
/* Set the maximum texture size small enough that we can guarentee that
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
+ ctx->Const.MaxDrawBuffers = 1;
+
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext(ctx);
_tnl_allow_vertex_fog(ctx, GL_TRUE);
/* currently bogus data */
- 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;
+ 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.MaxNativeTexIndirections =
PFS_MAX_TEX_INDIRECT;
ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* and these are?? */
- _tnl_ProgramCacheInit(ctx);
+ ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;
ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
driInitExtensions(ctx, card_extensions, GL_TRUE);
driQueryOptionb(&r300->radeon.optionCache,
"disable_lowimpact_fallback");
- radeonInitSpanFuncs(ctx);
+ radeonInitSpanFuncs( ctx );
r300InitCmdBuf(r300);
r300InitState(r300);
+ if (!(screen->chip_flags & RADEON_CHIPSET_TCL))
+ r300InitSwtcl(ctx);
- TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
+ TNL_CONTEXT(ctx)->Driver.RunPipeline = r300RunPipeline;
tcl_mode = driQueryOptioni(&r300->radeon.optionCache, "tcl_mode");
if (driQueryOptionb(&r300->radeon.optionCache, "no_rast")) {
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;
- if (r300->rmm->u_list[i].fb) {
- LOCK_HARDWARE(&(r300->radeon));
- ret = mmFreeMem(r300->rmm->u_list[i].fb);
- UNLOCK_HARDWARE(&(r300->radeon));
- if (ret)
- fprintf(stderr, "failed to free!\n");
- r300->rmm->u_list[i].fb = NULL;
- }
- r300->rmm->u_list[i].ref_count = 0;
- }
- }
- r300->rmm->u_head = i;
-#endif /* USER_BUFFERS */
-}
-
/* Destroy the device specific context.
*/
void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
assert(r300); /* should never be null */
if (r300) {
- GLboolean release_texture_heaps;
-
- release_texture_heaps =
- (r300->radeon.glCtx->Shared->RefCount == 1);
_swsetup_DestroyContext(r300->radeon.glCtx);
- _tnl_ProgramCacheDestroy(r300->radeon.glCtx);
_tnl_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);
+ rcommonFlushCmdBuf(&r300->radeon, __FUNCTION__);
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));
- }
+ r300DestroyCmdBuf(r300);
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);
FREE(r300);
}