summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/r300/r300_context.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/r300/r300_context.c')
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.c658
1 files changed, 305 insertions, 353 deletions
diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
index 7d6705058fe..2ea1b826de9 100644
--- a/src/mesa/drivers/dri/r300/r300_context.c
+++ b/src/mesa/drivers/dri/r300/r300_context.c
@@ -43,8 +43,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "main/matrix.h"
#include "main/extensions.h"
#include "main/state.h"
-#include "main/texobj.h"
#include "main/bufferobj.h"
+#include "main/texobj.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
@@ -56,46 +56,47 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#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_emit.h"
#include "r300_swtcl.h"
-
-#ifdef USER_BUFFERS
-#include "r300_mem.h"
-#endif
+#include "radeon_bocs_wrapper.h"
+#include "radeon_buffer_objects.h"
+#include "radeon_queryobj.h"
#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 = 1;
-int hw_tcl_on = 1;
-
#define need_GL_VERSION_2_0
+#define need_GL_ARB_occlusion_query
#define need_GL_ARB_point_parameters
#define need_GL_ARB_vertex_program
#define need_GL_EXT_blend_equation_separate
#define need_GL_EXT_blend_func_separate
#define need_GL_EXT_blend_minmax
+#define need_GL_EXT_framebuffer_blit
+#define need_GL_EXT_framebuffer_object
#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_depth_texture", NULL},
{"GL_ARB_fragment_program", NULL},
+ {"GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions},
{"GL_ARB_multitexture", NULL},
{"GL_ARB_point_parameters", GL_ARB_point_parameters_functions},
{"GL_ARB_shadow", NULL},
@@ -112,6 +113,7 @@ const struct dri_extension card_extensions[] = {
{"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_packed_depth_stencil", NULL},
{"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},
@@ -125,6 +127,8 @@ const struct dri_extension card_extensions[] = {
{"GL_EXT_texture_lod_bias", NULL},
{"GL_EXT_texture_mirror_clamp", NULL},
{"GL_EXT_texture_rectangle", NULL},
+ {"GL_EXT_texture_sRGB", NULL},
+ {"GL_EXT_vertex_array_bgra", NULL},
{"GL_ATI_separate_stencil", GL_ATI_separate_stencil_functions},
{"GL_ATI_texture_env_combine3", NULL},
{"GL_ATI_texture_mirror_once", NULL},
@@ -139,6 +143,12 @@ const struct dri_extension card_extensions[] = {
};
+const struct dri_extension mm_extensions[] = {
+ { "GL_EXT_framebuffer_blit", GL_EXT_framebuffer_blit_functions },
+ { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions },
+ { NULL, NULL }
+};
+
/**
* The GL 2.0 functions are needed to make display lists work with
* functions added by GL_ATI_separate_stencil.
@@ -147,16 +157,7 @@ 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;
-
static const struct tnl_pipeline_stage *r300_pipeline[] = {
-
- /* Try and go straight to t&l
- */
- &_r300_tcl_stage,
-
/* Catch any t&l fallbacks
*/
&_tnl_vertex_transform_stage,
@@ -165,147 +166,188 @@ static const struct tnl_pipeline_stage *r300_pipeline[] = {
&_tnl_fog_coordinate_stage,
&_tnl_texgen_stage,
&_tnl_texture_transform_stage,
+ &_tnl_point_attenuation_stage,
&_tnl_vertex_program_stage,
-
- /* Try again to go to tcl?
- * - no good for asymmetric-twoside (do with multipass)
- * - no good for asymmetric-unfilled (do with multipass)
- * - good for material
- * - good for texgen
- * - need to manipulate a bit of state
- *
- * - worth it/not worth it?
- */
-
- /* Else do them here.
- */
- &_r300_render_stage,
- &_tnl_render_stage, /* FALLBACK */
+ &_tnl_render_stage,
0,
};
-/* Create the device specific rendering context.
- */
-GLboolean r300CreateContext(const __GLcontextModes * glVisual,
- __DRIcontextPrivate * driContextPriv,
- void *sharedContextPrivate)
+static void r300_get_lock(radeonContextPtr rmesa)
{
- __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
- radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
- struct dd_function_table functions;
- r300ContextPtr r300;
- GLcontext *ctx;
- int tcl_mode, i;
-
- assert(glVisual);
- assert(driContextPriv);
- assert(screen);
+ drm_radeon_sarea_t *sarea = rmesa->sarea;
- /* Allocate the R300 context */
- r300 = (r300ContextPtr) CALLOC(sizeof(*r300));
- if (!r300)
- return GL_FALSE;
+ 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);
+ }
+}
- if (!(screen->chip_flags & RADEON_CHIPSET_TCL))
- hw_tcl_on = future_hw_tcl_on = 0;
+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));
+}
- /* 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");
+static void r300_vtbl_pre_emit_atoms(radeonContextPtr radeon)
+{
+ BATCH_LOCALS(radeon);
- /* Init default driver functions then plug in our R300-specific functions
- * (the texture functions are especially important)
- */
- _mesa_init_driver_functions(&functions);
- r300InitIoctlFuncs(&functions);
- r300InitStateFuncs(&functions);
- r300InitTextureFuncs(&functions);
- r300InitShaderFuncs(&functions);
+ 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);
+}
-#ifdef USER_BUFFERS
- r300_mem_init(r300);
-#endif
+static void r300_fallback(GLcontext *ctx, GLuint bit, GLboolean mode)
+{
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+ if (mode)
+ r300->radeon.Fallback |= bit;
+ else
+ r300->radeon.Fallback &= ~bit;
+}
- if (!radeonInitContext(&r300->radeon, &functions,
- glVisual, driContextPriv,
- sharedContextPrivate)) {
- FREE(r300);
- return GL_FALSE;
+static void r300_emit_query_finish(radeonContextPtr radeon)
+{
+ r300ContextPtr r300 = (r300ContextPtr)radeon;
+ struct radeon_query_object *query = radeon->query.current;
+ BATCH_LOCALS(radeon);
+
+ BEGIN_BATCH_NO_AUTOSTATE(3 * 2 *r300->radeon.radeonScreen->num_gb_pipes + 2);
+ switch (r300->radeon.radeonScreen->num_gb_pipes) {
+ case 4:
+ OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_3);
+ OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+ OUT_BATCH_RELOC(0, query->bo, query->curr_offset+3*sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
+ case 3:
+ OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_2);
+ OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+ OUT_BATCH_RELOC(0, query->bo, query->curr_offset+2*sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
+ case 2:
+ if (r300->radeon.radeonScreen->chip_family <= CHIP_FAMILY_RV380) {
+ OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_3);
+ } else {
+ OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_1);
+ }
+ OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+ OUT_BATCH_RELOC(0, query->bo, query->curr_offset+1*sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
+ case 1:
+ default:
+ OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_0);
+ OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+ OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
+ break;
}
+ OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_ALL);
+ END_BATCH();
+ query->curr_offset += r300->radeon.radeonScreen->num_gb_pipes * sizeof(uint32_t);
+ assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
+ query->emitted_begin = GL_FALSE;
+}
- /* 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,
- "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;
-
- /* Set the maximum texture size small enough that we can guarentee that
- * all texture units can bind a maximal texture and have them both in
- * texturable memory at once.
- */
+static void rv530_emit_query_finish_single_z(radeonContextPtr radeon)
+{
+ BATCH_LOCALS(radeon);
+ struct radeon_query_object *query = radeon->query.current;
+
+ BEGIN_BATCH_NO_AUTOSTATE(8);
+ OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0);
+ OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+ OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
+ OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
+ END_BATCH();
+
+ query->curr_offset += sizeof(uint32_t);
+ assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
+ query->emitted_begin = GL_FALSE;
+}
- ctx = r300->radeon.glCtx;
+static void rv530_emit_query_finish_double_z(radeonContextPtr radeon)
+{
+ BATCH_LOCALS(radeon);
+ struct radeon_query_object *query = radeon->query.current;
+
+ BEGIN_BATCH_NO_AUTOSTATE(14);
+ OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0);
+ OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+ OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
+ OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_1);
+ OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+ OUT_BATCH_RELOC(0, query->bo, query->curr_offset + sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
+ OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
+ END_BATCH();
+
+ query->curr_offset += 2 * sizeof(uint32_t);
+ assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
+ query->emitted_begin = GL_FALSE;
+}
+
+static void r300_init_vtbl(radeonContextPtr radeon)
+{
+ radeon->vtbl.get_lock = r300_get_lock;
+ radeon->vtbl.update_viewport_offset = r300UpdateViewportOffset;
+ 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;
+ radeon->vtbl.fallback = r300_fallback;
+ if (radeon->radeonScreen->chip_family == CHIP_FAMILY_RV530) {
+ if (radeon->radeonScreen->num_z_pipes == 2)
+ radeon->vtbl.emit_query_finish = rv530_emit_query_finish_double_z;
+ else
+ radeon->vtbl.emit_query_finish = rv530_emit_query_finish_single_z;
+ } else
+ radeon->vtbl.emit_query_finish = r300_emit_query_finish;
+}
+
+static void r300InitConstValues(GLcontext *ctx, radeonScreenPtr screen)
+{
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
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.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;
- else
- ctx->Const.MaxTextureLevels = 12;
-
- driCalculateMaxTextureLevels( r300->texture_heaps,
- r300->nr_heaps,
- & ctx->Const,
- 4,
- ctx->Const.MaxTextureLevels - 1,
- MIN2(ctx->Const.MaxTextureLevels,
- MAX_3D_TEXTURE_LEVELS) - 1,
- ctx->Const.MaxTextureLevels - 1,
- ctx->Const.MaxTextureLevels - 1,
- ctx->Const.MaxTextureLevels - 1,
- GL_FALSE,
- 2 );
+ if (screen->chip_family >= CHIP_FAMILY_RV515) {
+ ctx->Const.MaxTextureLevels = 13;
+ ctx->Const.MaxCubeTextureLevels = 13;
+ ctx->Const.MaxTextureRectSize = 4096;
+ }
+ else {
+ ctx->Const.MaxTextureLevels = 12;
+ ctx->Const.MaxCubeTextureLevels = 12;
+ ctx->Const.MaxTextureRectSize = 2048;
+ }
ctx->Const.MinPointSize = 1.0;
ctx->Const.MinPointSizeAA = 1.0;
@@ -317,263 +359,173 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
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;
- _mesa_set_mvp_with_dp4( ctx, GL_TRUE );
-
- /* Initialize the software rasterizer and helper modules.
- */
- _swrast_CreateContext(ctx);
- _vbo_CreateContext(ctx);
- _tnl_CreateContext(ctx);
- _swsetup_CreateContext(ctx);
- _swsetup_Wakeup(ctx);
- _ae_create_context(ctx);
-
- /* Install the customized pipeline:
- */
- _tnl_destroy_pipeline(ctx);
- _tnl_install_pipeline(ctx, r300_pipeline);
-
- /* Try and keep materials and vertices separate:
- */
-/* _tnl_isolate_materials(ctx, GL_TRUE); */
-
- /* Configure swrast and TNL to match hardware characteristics:
- */
- _swrast_allow_pixel_fog(ctx, GL_FALSE);
- _swrast_allow_vertex_fog(ctx, GL_TRUE);
- _tnl_allow_pixel_fog(ctx, GL_FALSE);
- _tnl_allow_vertex_fog(ctx, GL_TRUE);
-
/* currently bogus data */
- 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;
+ if (r300->options.hw_tcl_enabled) {
+ ctx->Const.VertexProgram.MaxNativeInstructions = VSF_MAX_FRAGMENT_LENGTH / 4;
+ ctx->Const.VertexProgram.MaxNativeAluInstructions = 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.MaxNativeTemps = 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?? */
- ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;
- ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
+ if (screen->chip_family >= CHIP_FAMILY_RV515) {
+ ctx->Const.FragmentProgram.MaxNativeTemps = R500_PFS_NUM_TEMP_REGS;
+ ctx->Const.FragmentProgram.MaxNativeAttribs = 11; /* copy i915... */
+ ctx->Const.FragmentProgram.MaxNativeParameters = R500_PFS_NUM_CONST_REGS;
+ ctx->Const.FragmentProgram.MaxNativeAluInstructions = R500_PFS_MAX_INST;
+ ctx->Const.FragmentProgram.MaxNativeTexInstructions = R500_PFS_MAX_INST;
+ ctx->Const.FragmentProgram.MaxNativeInstructions = R500_PFS_MAX_INST;
+ ctx->Const.FragmentProgram.MaxNativeTexIndirections = R500_PFS_MAX_INST;
+ ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0;
+ } else {
+ ctx->Const.FragmentProgram.MaxNativeTemps = R300_PFS_NUM_TEMP_REGS;
+ ctx->Const.FragmentProgram.MaxNativeAttribs = 11; /* copy i915... */
+ ctx->Const.FragmentProgram.MaxNativeParameters = R300_PFS_NUM_CONST_REGS;
+ ctx->Const.FragmentProgram.MaxNativeAluInstructions = R300_PFS_MAX_ALU_INST;
+ ctx->Const.FragmentProgram.MaxNativeTexInstructions = R300_PFS_MAX_TEX_INST;
+ ctx->Const.FragmentProgram.MaxNativeInstructions = R300_PFS_MAX_ALU_INST + R300_PFS_MAX_TEX_INST;
+ ctx->Const.FragmentProgram.MaxNativeTexIndirections = R300_PFS_MAX_TEX_INDIRECT;
+ ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0;
+ }
- driInitExtensions(ctx, card_extensions, GL_TRUE);
+}
- if (driQueryOptionb
- (&r300->radeon.optionCache, "disable_stencil_two_side"))
- _mesa_disable_extension(ctx, "GL_EXT_stencil_two_side");
+static void r300ParseOptions(r300ContextPtr r300, radeonScreenPtr screen)
+{
+ struct r300_options options = { 0 };
- 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");
- }
+ driParseConfigFiles(&r300->radeon.optionCache, &screen->optionCache,
+ screen->driScreen->myNum, "r300");
- r300->disable_lowimpact_fallback =
- driQueryOptionb(&r300->radeon.optionCache,
- "disable_lowimpact_fallback");
+ r300->radeon.initialMaxAnisotropy = driQueryOptionf(&r300->radeon.optionCache, "def_max_anisotropy");
- radeonInitSpanFuncs(ctx);
- r300InitCmdBuf(r300);
- r300InitState(r300);
- if (!(screen->chip_flags & RADEON_CHIPSET_TCL))
- r300InitSwtcl(ctx);
+ options.stencil_two_side_disabled = driQueryOptionb(&r300->radeon.optionCache, "disable_stencil_two_side");
+ options.s3tc_force_enabled = driQueryOptionb(&r300->radeon.optionCache, "force_s3tc_enable");
+ options.s3tc_force_disabled = driQueryOptionb(&r300->radeon.optionCache, "disable_s3tc");
- TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
+ if (!(screen->chip_flags & RADEON_CHIPSET_TCL) || driQueryOptioni(&r300->radeon.optionCache, "tcl_mode") == DRI_CONF_TCL_SW)
+ options.hw_tcl_enabled = 0;
+ else
+ options.hw_tcl_enabled = 1;
- tcl_mode = driQueryOptioni(&r300->radeon.optionCache, "tcl_mode");
- if (driQueryOptionb(&r300->radeon.optionCache, "no_rast")) {
- fprintf(stderr, "disabling 3D acceleration\n");
-#if R200_MERGED
- FALLBACK(&r300->radeon, RADEON_FALLBACK_DISABLE, 1);
-#endif
- }
- if (tcl_mode == DRI_CONF_TCL_SW ||
- !(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);
- }
+ options.conformance_mode = !driQueryOptionb(&r300->radeon.optionCache, "disable_lowimpact_fallback");
- return GL_TRUE;
+ r300->options = options;
}
-static void r300FreeGartAllocations(r300ContextPtr r300)
+static void r300InitGLExtensions(GLcontext *ctx)
{
- int i, ret, tries = 0, done_age, in_use = 0;
- drm_radeon_mem_free_t memfree;
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
- memfree.region = RADEON_MEM_REGION_GART;
+ driInitExtensions(ctx, card_extensions, GL_TRUE);
+ if (r300->radeon.radeonScreen->kernel_mm)
+ driInitExtensions(ctx, mm_extensions, GL_FALSE);
-#ifdef USER_BUFFERS
- for (i = r300->rmm->u_last; i > 0; i--) {
- if (r300->rmm->u_list[i].ptr == NULL) {
- continue;
- }
+ if (r300->options.stencil_two_side_disabled)
+ _mesa_disable_extension(ctx, "GL_EXT_stencil_two_side");
- /* check whether this buffer is still in use */
- if (r300->rmm->u_list[i].pending) {
- in_use++;
- }
+ if (r300->options.s3tc_force_enabled) {
+ _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
+ _mesa_enable_extension(ctx, "GL_S3_s3tc");
+ } else if (r300->options.s3tc_force_disabled) {
+ _mesa_disable_extension(ctx, "GL_EXT_texture_compression_s3tc");
}
- /* Cannot flush/lock if no context exists. */
- if (in_use)
- r300FlushCmdBuf(r300, __FUNCTION__);
- done_age = radeonGetAge((radeonContextPtr) r300);
+ if (!r300->radeon.radeonScreen->drmSupportsOcclusionQueries) {
+ _mesa_disable_extension(ctx, "GL_ARB_occlusion_query");
+ }
+}
- for (i = r300->rmm->u_last; i > 0; i--) {
- if (r300->rmm->u_list[i].ptr == NULL) {
- continue;
- }
+/* Create the device specific rendering context.
+ */
+GLboolean r300CreateContext(const __GLcontextModes * glVisual,
+ __DRIcontextPrivate * driContextPriv,
+ void *sharedContextPrivate)
+{
+ __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+ radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
+ struct dd_function_table functions;
+ r300ContextPtr r300;
+ GLcontext *ctx;
- /* check whether this buffer is still in use */
- if (!r300->rmm->u_list[i].pending) {
- continue;
- }
+ assert(glVisual);
+ assert(driContextPriv);
+ assert(screen);
- assert(r300->rmm->u_list[i].h_pending == 0);
+ r300 = (r300ContextPtr) CALLOC(sizeof(*r300));
+ if (!r300)
+ return GL_FALSE;
- 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!");
- }
+ r300ParseOptions(r300, screen);
- memfree.region_offset = (char *)r300->rmm->u_list[i].ptr -
- (char *)r300->radeon.radeonScreen->gartTextures.map;
+ r300->radeon.radeonScreen = screen;
+ r300_init_vtbl(&r300->radeon);
- 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--;
+ _mesa_init_driver_functions(&functions);
+ r300InitIoctlFuncs(&functions);
+ r300InitStateFuncs(&functions);
+ r300InitTextureFuncs(&functions);
+ r300InitShaderFuncs(&functions);
+ radeonInitQueryObjFunctions(&functions);
+ radeonInitBufferObjectFuncs(&functions);
- r300->rmm->u_list[i].pending = 0;
- r300->rmm->u_list[i].ptr = NULL;
- }
+ if (!radeonInitContext(&r300->radeon, &functions,
+ glVisual, driContextPriv,
+ sharedContextPrivate)) {
+ FREE(r300);
+ return GL_FALSE;
}
- 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;
- int i;
-
- if (RADEON_DEBUG & DEBUG_DRI) {
- fprintf(stderr, "Destroying context !\n");
- }
+ ctx = r300->radeon.glCtx;
- /* check if we're deleting the currently bound context */
- if (&r300->radeon == current) {
- radeonFlush(r300->radeon.glCtx);
- _mesa_make_current(NULL, NULL, NULL);
- }
+ r300->fallback = 0;
+ if (r300->options.hw_tcl_enabled)
+ ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;
- /* Free r300 context resources */
- 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_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);
+ ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
- if (radeon->state.scissor.pClipRects) {
- FREE(radeon->state.scissor.pClipRects);
- radeon->state.scissor.pClipRects = NULL;
- }
+ r300InitConstValues(ctx, screen);
- if (release_texture_heaps) {
- /* This share group is about to go away, free our private
- * texture object data.
- */
- int i;
+ _mesa_set_mvp_with_dp4( ctx, GL_TRUE );
- for (i = 0; i < r300->nr_heaps; i++) {
- driDestroyTextureHeap(r300->texture_heaps[i]);
- r300->texture_heaps[i] = NULL;
- }
+ /* Initialize the software rasterizer and helper modules.
+ */
+ _swrast_CreateContext(ctx);
+ _vbo_CreateContext(ctx);
+ _tnl_CreateContext(ctx);
+ _swsetup_CreateContext(ctx);
+ _swsetup_Wakeup(ctx);
- assert(is_empty_list(&r300->swapped));
- }
+ /* Install the customized pipeline:
+ */
+ _tnl_destroy_pipeline(ctx);
+ _tnl_install_pipeline(ctx, r300_pipeline);
+ TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
- /* Drop texture object references from current hardware state */
- for (i = 0; i < 8; i++) {
- _mesa_reference_texobj(&r300->state.texture.unit[i].texobj, NULL);
- }
+ /* Configure swrast and TNL to match hardware characteristics:
+ */
+ _swrast_allow_pixel_fog(ctx, GL_FALSE);
+ _swrast_allow_vertex_fog(ctx, GL_TRUE);
+ _tnl_allow_pixel_fog(ctx, GL_FALSE);
+ _tnl_allow_vertex_fog(ctx, GL_TRUE);
- radeonCleanupContext(&r300->radeon);
+ if (r300->options.hw_tcl_enabled) {
+ r300InitDraw(ctx);
+ } else {
+ r300InitSwtcl(ctx);
+ }
-#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
+ radeon_fbo_init(&r300->radeon);
+ radeonInitSpanFuncs( ctx );
+ r300InitCmdBuf(r300);
+ r300InitState(r300);
+ r300InitShaderFunctions(r300);
- /* free the option cache */
- driDestroyOptionCache(&r300->radeon.optionCache);
+ r300InitGLExtensions(ctx);
- FREE(r300);
- }
+ return GL_TRUE;
}
+