diff options
author | Jouk <joukj@tarantella.(none)> | 2007-07-25 10:16:11 +0200 |
---|---|---|
committer | Jouk <joukj@tarantella.(none)> | 2007-07-25 10:16:11 +0200 |
commit | eb9a5b6d5127858b01ec12672c999e7d25cd7aed (patch) | |
tree | 91c0302c4d007ddcd0c42fbb8d8de71bf23d3914 /src/mesa/drivers/dri | |
parent | 55f8b7053065ce88296608071feed6f9540f6c0d (diff) | |
parent | 03ec41ddc51e539c989a546f33d22daa2af69095 (diff) |
Merge branch 'master' of git+ssh://[email protected]/git/mesa/mesa
Diffstat (limited to 'src/mesa/drivers/dri')
62 files changed, 2459 insertions, 1351 deletions
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index dd52f7e9151..c30e66f1722 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -428,10 +428,12 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) if (pdp->pClipRects) { _mesa_free(pdp->pClipRects); + pdp->pClipRects = NULL; } if (pdp->pBackClipRects) { _mesa_free(pdp->pBackClipRects); + pdp->pBackClipRects = NULL; } DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); diff --git a/src/mesa/drivers/dri/common/extension_helper.h b/src/mesa/drivers/dri/common/extension_helper.h index 10f75edaaa4..bf103a3931f 100644 --- a/src/mesa/drivers/dri/common/extension_helper.h +++ b/src/mesa/drivers/dri/common/extension_helper.h @@ -1478,9 +1478,10 @@ static const char ImageTransformParameterfvHP_names[] = ""; #endif -#if defined(need_GL_ARB_vertex_program) +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) static const char VertexAttrib4ivARB_names[] = "ip\0" /* Parameter signature */ + "glVertexAttrib4iv\0" "glVertexAttrib4ivARB\0" ""; #endif @@ -1586,9 +1587,10 @@ static const char PixelTransformParameterfvEXT_names[] = ""; #endif -#if defined(need_GL_ARB_vertex_program) +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) static const char VertexAttrib4bvARB_names[] = "ip\0" /* Parameter signature */ + "glVertexAttrib4bv\0" "glVertexAttrib4bvARB\0" ""; #endif @@ -2391,9 +2393,10 @@ static const char GetAttribLocationARB_names[] = ""; #endif -#if defined(need_GL_ARB_vertex_program) +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) static const char VertexAttrib4ubvARB_names[] = "ip\0" /* Parameter signature */ + "glVertexAttrib4ubv\0" "glVertexAttrib4ubvARB\0" ""; #endif @@ -2910,9 +2913,10 @@ static const char ReplacementCodeuiColor4ubVertex3fSUN_names[] = ""; #endif -#if defined(need_GL_ARB_vertex_program) +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) static const char VertexAttrib4usvARB_names[] = "ip\0" /* Parameter signature */ + "glVertexAttrib4usv\0" "glVertexAttrib4usvARB\0" ""; #endif @@ -4393,9 +4397,10 @@ static const char WindowPos4iMESA_names[] = ""; #endif -#if defined(need_GL_ARB_vertex_program) +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) static const char VertexAttrib4uivARB_names[] = "ip\0" /* Parameter signature */ + "glVertexAttrib4uiv\0" "glVertexAttrib4uivARB\0" ""; #endif @@ -6257,6 +6262,8 @@ static const struct dri_extension_function GL_VERSION_2_0_functions[] = { { GetVertexAttribivARB_names, GetVertexAttribivARB_remap_index, -1 }, { CreateProgram_names, CreateProgram_remap_index, -1 }, { StencilFuncSeparate_names, StencilFuncSeparate_remap_index, -1 }, + { VertexAttrib4ivARB_names, VertexAttrib4ivARB_remap_index, -1 }, + { VertexAttrib4bvARB_names, VertexAttrib4bvARB_remap_index, -1 }, { VertexAttrib3dARB_names, VertexAttrib3dARB_remap_index, -1 }, { VertexAttrib4fARB_names, VertexAttrib4fARB_remap_index, -1 }, { VertexAttrib4fvARB_names, VertexAttrib4fvARB_remap_index, -1 }, @@ -6270,6 +6277,7 @@ static const struct dri_extension_function GL_VERSION_2_0_functions[] = { { VertexAttrib1dvARB_names, VertexAttrib1dvARB_remap_index, -1 }, { GetVertexAttribfvARB_names, GetVertexAttribfvARB_remap_index, -1 }, { GetAttribLocationARB_names, GetAttribLocationARB_remap_index, -1 }, + { VertexAttrib4ubvARB_names, VertexAttrib4ubvARB_remap_index, -1 }, { Uniform3ivARB_names, Uniform3ivARB_remap_index, -1 }, { VertexAttrib4sARB_names, VertexAttrib4sARB_remap_index, -1 }, { VertexAttrib2dvARB_names, VertexAttrib2dvARB_remap_index, -1 }, @@ -6282,6 +6290,7 @@ static const struct dri_extension_function GL_VERSION_2_0_functions[] = { { VertexAttrib4NuivARB_names, VertexAttrib4NuivARB_remap_index, -1 }, { Uniform4fARB_names, Uniform4fARB_remap_index, -1 }, { VertexAttrib1dARB_names, VertexAttrib1dARB_remap_index, -1 }, + { VertexAttrib4usvARB_names, VertexAttrib4usvARB_remap_index, -1 }, { LinkProgramARB_names, LinkProgramARB_remap_index, -1 }, { ShaderSourceARB_names, ShaderSourceARB_remap_index, -1 }, { VertexAttrib3svARB_names, VertexAttrib3svARB_remap_index, -1 }, @@ -6311,6 +6320,7 @@ static const struct dri_extension_function GL_VERSION_2_0_functions[] = { { DrawBuffersARB_names, DrawBuffersARB_remap_index, -1 }, { Uniform1fvARB_names, Uniform1fvARB_remap_index, -1 }, { EnableVertexAttribArrayARB_names, EnableVertexAttribArrayARB_remap_index, -1 }, + { VertexAttrib4uivARB_names, VertexAttrib4uivARB_remap_index, -1 }, { VertexAttrib4svARB_names, VertexAttrib4svARB_remap_index, -1 }, { GetShaderiv_names, GetShaderiv_remap_index, -1 }, { VertexAttrib2svARB_names, VertexAttrib2svARB_remap_index, -1 }, diff --git a/src/mesa/drivers/dri/i810/i810state.c b/src/mesa/drivers/dri/i810/i810state.c index 3ad25282d90..e0d5b2b4876 100644 --- a/src/mesa/drivers/dri/i810/i810state.c +++ b/src/mesa/drivers/dri/i810/i810state.c @@ -380,7 +380,10 @@ static void i810CullFaceFrontFace(GLcontext *ctx, GLenum unused) static void i810LineWidth( GLcontext *ctx, GLfloat widthf ) { i810ContextPtr imesa = I810_CONTEXT( ctx ); - int width = (int)ctx->Line._Width; + /* AA, non-AA limits are same */ + const int width = (int) CLAMP(ctx->Line.Width, + ctx->Const.MinLineWidth, + ctx->Const.MaxLineWidth); imesa->LcsLineWidth = 0; if (width & 1) imesa->LcsLineWidth |= LCS_LINEWIDTH_1_0; @@ -396,7 +399,10 @@ static void i810LineWidth( GLcontext *ctx, GLfloat widthf ) static void i810PointSize( GLcontext *ctx, GLfloat sz ) { i810ContextPtr imesa = I810_CONTEXT( ctx ); - int size = (int)ctx->Point._Size; + /* AA, non-AA limits are same */ + const int size = (int) CLAMP(ctx->Point.Size, + ctx->Const.MinPointSize, + ctx->Const.MaxPointSize); imesa->LcsPointSize = 0; if (size & 1) imesa->LcsPointSize |= LCS_LINEWIDTH_1_0; diff --git a/src/mesa/drivers/dri/i810/i810tris.c b/src/mesa/drivers/dri/i810/i810tris.c index 3e09427bb94..2c4ee06633d 100644 --- a/src/mesa/drivers/dri/i810/i810tris.c +++ b/src/mesa/drivers/dri/i810/i810tris.c @@ -112,7 +112,9 @@ static __inline__ void i810_draw_quad( i810ContextPtr imesa, static __inline__ void i810_draw_point( i810ContextPtr imesa, i810VertexPtr tmp ) { - GLfloat sz = imesa->glCtx->Point._Size * .5; + GLfloat sz = 0.5 * CLAMP(imesa->glCtx->Point.Size, + imesa->glCtx->Const.MinPointSize, + imesa->glCtx->Const.MaxPointSize); int vertsize = imesa->vertex_size; GLuint *vb = i810AllocDmaLow( imesa, 2 * 4 * vertsize ); int j; diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c index b0e5f87fc75..cc8a605e505 100644 --- a/src/mesa/drivers/dri/i915/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -64,6 +64,7 @@ static void i915_reduced_primitive_state( intelContextPtr intel, st1 &= ~ST1_ENABLE; switch (rprim) { + case GL_QUADS: /* from RASTERIZE(GL_QUADS) in t_dd_tritemp.h */ case GL_TRIANGLES: if (intel->ctx.Polygon.StippleFlag && intel->hw_stipple) diff --git a/src/mesa/drivers/dri/i915/intel_pixel.c b/src/mesa/drivers/dri/i915/intel_pixel.c index 535cbfcb26e..c3030d42b04 100644 --- a/src/mesa/drivers/dri/i915/intel_pixel.c +++ b/src/mesa/drivers/dri/i915/intel_pixel.c @@ -439,10 +439,32 @@ intelDrawPixels( GLcontext *ctx, if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s\n", __FUNCTION__); - if (!intelTryDrawPixels( ctx, x, y, width, height, format, type, - unpack, pixels )) + if (intelTryDrawPixels( ctx, x, y, width, height, format, type, + unpack, pixels )) + return; + + if (ctx->FragmentProgram._Current == ctx->FragmentProgram._TexEnvProgram) { + /* + * We don't want the i915 texenv program to be applied to DrawPixels. + * This is really just a performance optimization (mesa will other- + * wise happily run the fragment program on each pixel in the image). + */ + struct gl_fragment_program *fpSave = ctx->FragmentProgram._Current; + /* can't just set current frag prog to 0 here as on buffer resize + we'll get new state checks which will segfault. Remains a hack. */ + ctx->FragmentProgram._Current = NULL; + ctx->FragmentProgram._UseTexEnvProgram = GL_FALSE; + ctx->FragmentProgram._Active = GL_FALSE; + _swrast_DrawPixels( ctx, x, y, width, height, format, type, + unpack, pixels ); + ctx->FragmentProgram._Current = fpSave; + ctx->FragmentProgram._UseTexEnvProgram = GL_TRUE; + ctx->FragmentProgram._Active = GL_TRUE; + } + else { _swrast_DrawPixels( ctx, x, y, width, height, format, type, - unpack, pixels ); + unpack, pixels ); + } } diff --git a/src/mesa/drivers/dri/i915tex/i830_vtbl.c b/src/mesa/drivers/dri/i915tex/i830_vtbl.c index dd0670dec37..e432648ada0 100644 --- a/src/mesa/drivers/dri/i915tex/i830_vtbl.c +++ b/src/mesa/drivers/dri/i915tex/i830_vtbl.c @@ -490,11 +490,13 @@ i830_emit_state(struct intel_context *intel) DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, state->tex_offset[i] | TM0S0_USE_FENCE); } - else { - assert(i == 0); - assert(state == &i830->meta); - OUT_BATCH(0); - } + else if (state == &i830->meta) { + assert(i == 0); + OUT_BATCH(0); + } + else { + OUT_BATCH(state->tex_offset[i]); + } OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S1]); OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S2]); diff --git a/src/mesa/drivers/dri/i915tex/i915_vtbl.c b/src/mesa/drivers/dri/i915tex/i915_vtbl.c index f80e8d6327f..ad333b490b7 100644 --- a/src/mesa/drivers/dri/i915tex/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915tex/i915_vtbl.c @@ -61,6 +61,7 @@ i915_reduced_primitive_state(struct intel_context *intel, GLenum rprim) st1 &= ~ST1_ENABLE; switch (rprim) { + case GL_QUADS: /* from RASTERIZE(GL_QUADS) in t_dd_tritemp.h */ case GL_TRIANGLES: if (intel->ctx.Polygon.StippleFlag && intel->hw_stipple) st1 |= ST1_ENABLE; diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h index 59261f72741..212f1301012 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h @@ -9,7 +9,7 @@ struct intel_context; #define BATCH_SZ 16384 #define BATCH_RESERVED 16 -#define MAX_RELOCS 400 +#define MAX_RELOCS 4096 #define INTEL_BATCH_NO_CLIPRECTS 0x1 #define INTEL_BATCH_CLIPRECTS 0x2 diff --git a/src/mesa/drivers/dri/i915tex/intel_buffers.c b/src/mesa/drivers/dri/i915tex/intel_buffers.c index 62ff54b0075..15d02f8e2cf 100644 --- a/src/mesa/drivers/dri/i915tex/intel_buffers.c +++ b/src/mesa/drivers/dri/i915tex/intel_buffers.c @@ -316,7 +316,8 @@ intelWindowMoved(struct intel_context *intel) flags = intel_fb->vblank_flags & ~VBLANK_FLAG_SECONDARY; } - if (flags != intel_fb->vblank_flags) { + if (flags != intel_fb->vblank_flags && intel_fb->vblank_flags && + !(intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ)) { drmVBlank vbl; int i; @@ -327,7 +328,9 @@ intelWindowMoved(struct intel_context *intel) } for (i = 0; i < intel_fb->pf_num_pages; i++) { - if (!intel_fb->color_rb[i]) + if (!intel_fb->color_rb[i] || + (intel_fb->vbl_waited - intel_fb->color_rb[i]->vbl_pending) <= + (1<<23)) continue; vbl.request.sequence = intel_fb->color_rb[i]->vbl_pending; @@ -828,7 +831,8 @@ intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target) drm_i915_vblank_swap_t swap; GLboolean ret; - if ((intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) || + if (!intel_fb->vblank_flags || + (intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) || intelScreen->current_rotation != 0 || intelScreen->drmMinor < (intel_fb->pf_active ? 9 : 6)) return GL_FALSE; diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c index c927dca8e5a..40ea7564126 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.c +++ b/src/mesa/drivers/dri/i915tex/intel_context.c @@ -619,12 +619,23 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv, if (intel->ctx.DrawBuffer == &intel_fb->Base) { if (intel->driDrawable != driDrawPriv) { - intel_fb->vblank_flags = (intel->intelScreen->irq_active != 0) - ? driGetDefaultVBlankFlags(&intel->optionCache) - : VBLANK_FLAG_NO_IRQ; - (*dri_interface->getUST) (&intel_fb->swap_ust); - driDrawableInitVBlank(driDrawPriv, intel_fb->vblank_flags, - &intel_fb->vbl_seq); + if (driDrawPriv->pdraw->swap_interval == (unsigned)-1) { + int i; + + intel_fb->vblank_flags = (intel->intelScreen->irq_active != 0) + ? driGetDefaultVBlankFlags(&intel->optionCache) + : VBLANK_FLAG_NO_IRQ; + + (*dri_interface->getUST) (&intel_fb->swap_ust); + driDrawableInitVBlank(driDrawPriv, intel_fb->vblank_flags, + &intel_fb->vbl_seq); + intel_fb->vbl_waited = intel_fb->vbl_seq; + + for (i = 0; i < (intel->intelScreen->third.handle ? 3 : 2); i++) { + if (intel_fb->color_rb[i]) + intel_fb->color_rb[i]->vbl_pending = intel_fb->vbl_seq; + } + } intel->driDrawable = driDrawPriv; intelWindowMoved(intel); } @@ -670,37 +681,27 @@ intelContendedLock(struct intel_context *intel, GLuint flags) if (sarea->width != intel->width || sarea->height != intel->height || sarea->rotation != intel->current_rotation) { - - void *batchMap = intel->batch->map; - + int numClipRects = intel->numClipRects; + /* * FIXME: Really only need to do this when drawing to a * common back- or front buffer. */ /* - * This will drop the outstanding batchbuffer on the floor + * This will essentially drop the outstanding batchbuffer on the floor. */ + intel->numClipRects = 0; - if (batchMap != NULL) { - driBOUnmap(intel->batch->buffer); - intel->batch->map = NULL; - } - - intel_batchbuffer_reset(intel->batch); + if (intel->Fallback) + _swrast_flush(&intel->ctx); - if (batchMap == NULL) { - driBOUnmap(intel->batch->buffer); - intel->batch->map = NULL; - } + INTEL_FIREVERTICES(intel); - /* lose all primitives */ - intel->prim.primitive = ~0; - intel->prim.start_ptr = 0; - intel->prim.flush = 0; + if (intel->batch->map != intel->batch->ptr) + intel_batchbuffer_flush(intel->batch); - /* re-emit all state */ - intel->vtbl.lost_hardware(intel); + intel->numClipRects = numClipRects; /* force window update */ intel->lastStamp = 0; @@ -741,7 +742,9 @@ void LOCK_HARDWARE( struct intel_context *intel ) BUFFER_BACK_LEFT); } - if (intel_rb && (intel_fb->vbl_waited - intel_rb->vbl_pending) > (1<<23)) { + if (intel_rb && intel_fb->vblank_flags && + !(intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) && + (intel_fb->vbl_waited - intel_rb->vbl_pending) > (1<<23)) { drmVBlank vbl; vbl.request.type = DRM_VBLANK_ABSOLUTE; diff --git a/src/mesa/drivers/dri/i915tex/intel_fbo.c b/src/mesa/drivers/dri/i915tex/intel_fbo.c index 349912ffecd..6f99f401c7c 100644 --- a/src/mesa/drivers/dri/i915tex/intel_fbo.c +++ b/src/mesa/drivers/dri/i915tex/intel_fbo.c @@ -488,7 +488,7 @@ intel_new_renderbuffer(GLcontext * ctx, GLuint name) */ static void intel_bind_framebuffer(GLcontext * ctx, GLenum target, - struct gl_framebuffer *fb) + struct gl_framebuffer *fb, struct gl_framebuffer *fbread) { if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { intel_draw_buffer(ctx, fb); diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c b/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c index 10a079896ae..e4e57cb3a7e 100644 --- a/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c +++ b/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c @@ -363,5 +363,26 @@ intelDrawPixels(GLcontext * ctx, if (INTEL_DEBUG & DEBUG_PIXEL) _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); - _swrast_DrawPixels(ctx, x, y, width, height, format, type, unpack, pixels); + if (ctx->FragmentProgram._Current == ctx->FragmentProgram._TexEnvProgram) { + /* + * We don't want the i915 texenv program to be applied to DrawPixels. + * This is really just a performance optimization (mesa will other- + * wise happily run the fragment program on each pixel in the image). + */ + struct gl_fragment_program *fpSave = ctx->FragmentProgram._Current; + /* can't just set current frag prog to 0 here as on buffer resize + we'll get new state checks which will segfault. Remains a hack. */ + ctx->FragmentProgram._Current = NULL; + ctx->FragmentProgram._UseTexEnvProgram = GL_FALSE; + ctx->FragmentProgram._Active = GL_FALSE; + _swrast_DrawPixels( ctx, x, y, width, height, format, type, + unpack, pixels ); + ctx->FragmentProgram._Current = fpSave; + ctx->FragmentProgram._UseTexEnvProgram = GL_TRUE; + ctx->FragmentProgram._Active = GL_TRUE; + } + else { + _swrast_DrawPixels( ctx, x, y, width, height, format, type, + unpack, pixels ); + } } diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c index 0ae4fee1ba0..af18c26d55c 100644 --- a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c +++ b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c @@ -116,7 +116,7 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) /* We know/require this is true by now: */ - assert(intelObj->base.Complete); + assert(intelObj->base._Complete); /* What levels must the tree include at a minimum? */ diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c index bfac52d765b..9a6e5f5f192 100644 --- a/src/mesa/drivers/dri/i965/brw_sf_state.c +++ b/src/mesa/drivers/dri/i965/brw_sf_state.c @@ -173,7 +173,8 @@ static void upload_sf_unit( struct brw_context *brw ) /* _NEW_LINE */ - sf.sf6.line_width = brw->attribs.Line->_Width * (1<<1); + /* XXX use ctx->Const.Min/MaxLineWidth here */ + sf.sf6.line_width = CLAMP(brw->attribs.Line->Width, 1.0, 5.0) * (1<<1); sf.sf6.line_endcap_aa_region_width = 1; if (brw->attribs.Line->SmoothFlag) @@ -183,7 +184,8 @@ static void upload_sf_unit( struct brw_context *brw ) /* _NEW_POINT */ sf.sf6.point_rast_rule = 1; /* opengl conventions */ - sf.sf7.point_size = brw->attribs.Point->_Size * (1<<3); + /* XXX clamp max depends on AA vs. non-AA */ + sf.sf7.point_size = CLAMP(brw->attribs.Point->Size, 1.0, 3.0) * (1<<3); sf.sf7.use_point_size_state = !brw->attribs.Point->_Attenuated; /* might be BRW_NEW_PRIMITIVE if we have to adjust pv for polygons: diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c index 173d1d5b6c2..f88cbb2328d 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.c +++ b/src/mesa/drivers/dri/i965/intel_blit.c @@ -532,12 +532,15 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel, GLuint dst_offset, GLboolean dst_tiled, GLshort x, GLshort y, - GLshort w, GLshort h) + GLshort w, GLshort h, + GLenum logic_op) { struct xy_setup_blit setup; struct xy_text_immediate_blit text; int dwords = ((src_size + 7) & ~7) / 4; + assert( logic_op - GL_CLEAR >= 0 ); + assert( logic_op - GL_CLEAR < 0x10 ); if (w < 0 || h < 0) return; @@ -561,7 +564,7 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel, setup.br0.length = (sizeof(setup) / sizeof(int)) - 2; setup.br13.dest_pitch = dst_pitch; - setup.br13.rop = 0xcc; + setup.br13.rop = translate_raster_op(logic_op); setup.br13.color_depth = (cpp == 4) ? BR13_8888 : BR13_565; setup.br13.clipping_enable = 0; setup.br13.mono_source_transparency = 1; diff --git a/src/mesa/drivers/dri/i965/intel_blit.h b/src/mesa/drivers/dri/i965/intel_blit.h index 8b0cc65243c..e361545c8fa 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.h +++ b/src/mesa/drivers/dri/i965/intel_blit.h @@ -72,6 +72,7 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel, GLuint dst_offset, GLboolean dst_tiled, GLshort dst_x, GLshort dst_y, - GLshort w, GLshort h); + GLshort w, GLshort h, + GLenum logic_op ); #endif diff --git a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c index 5841afaa3ef..421fcc5e511 100644 --- a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c @@ -260,7 +260,9 @@ do_blit_bitmap( GLcontext *ctx, int h = MIN2(DY, box_h - py); int w = MIN2(DX, box_w - px); GLuint sz = align(align(w,8) * h, 64)/8; - + GLenum logic_op = ctx->Color.ColorLogicOpEnabled ? + ctx->Color.LogicOp : GL_COPY; + assert(sz <= sizeof(stipple)); memset(stipple, 0, sz); @@ -288,7 +290,8 @@ do_blit_bitmap( GLcontext *ctx, dst->tiled, rect.x1 + px, rect.y2 - (py + h), - w, h); + w, h, + logic_op); } } } diff --git a/src/mesa/drivers/dri/i965/intel_tex_validate.c b/src/mesa/drivers/dri/i965/intel_tex_validate.c index cb23b9dd879..44ee94614d5 100644 --- a/src/mesa/drivers/dri/i965/intel_tex_validate.c +++ b/src/mesa/drivers/dri/i965/intel_tex_validate.c @@ -138,7 +138,7 @@ GLuint intel_finalize_mipmap_tree( struct intel_context *intel, /* We know/require this is true by now: */ - assert(intelObj->base.Complete); + assert(intelObj->base._Complete); /* What levels must the tree include at a minimum? */ diff --git a/src/mesa/drivers/dri/mach64/mach64_native_vb.c b/src/mesa/drivers/dri/mach64/mach64_native_vb.c index 75cf0e2ed2d..248fa2a9a29 100644 --- a/src/mesa/drivers/dri/mach64/mach64_native_vb.c +++ b/src/mesa/drivers/dri/mach64/mach64_native_vb.c @@ -103,7 +103,7 @@ void TAG(translate_vertex)(GLcontext *ctx, assert( p + 1 - (CARD32 *)src == 10 ); - dst->pointSize = ctx->Point._Size; + dst->pointSize = ctx->Point.Size; } diff --git a/src/mesa/drivers/dri/mach64/mach64_tris.c b/src/mesa/drivers/dri/mach64/mach64_tris.c index 08cc1849a12..369f6104428 100644 --- a/src/mesa/drivers/dri/mach64/mach64_tris.c +++ b/src/mesa/drivers/dri/mach64/mach64_tris.c @@ -673,7 +673,10 @@ static __inline void mach64_draw_line( mach64ContextPtr mmesa, #if MACH64_NATIVE_VTXFMT GLcontext *ctx = mmesa->glCtx; const GLuint vertsize = mmesa->vertex_size; - GLint width = (GLint)(mmesa->glCtx->Line._Width * 2.0); /* 2 fractional bits for hardware */ + /* 2 fractional bits for hardware: */ + const int width = (int) (2.0 * CLAMP(mmesa->glCtx->Line.Width, + mmesa->glCtx->Const.MinLineWidth, + mmesa->glCtx->Const.MaxLineWidth)); GLfloat ooa; GLuint *pxy0, *pxy1; GLuint xy0old, xy0, xy1old, xy1; @@ -691,9 +694,6 @@ static __inline void mach64_draw_line( mach64ContextPtr mmesa, mach64_print_vertex( ctx, v1 ); } - if( !width ) - width = 1; /* round to the nearest supported width */ - pxy0 = &v0->ui[xyoffset]; xy0old = *pxy0; xy0 = LE32_IN( &xy0old ); @@ -961,7 +961,10 @@ static __inline void mach64_draw_point( mach64ContextPtr mmesa, #if MACH64_NATIVE_VTXFMT GLcontext *ctx = mmesa->glCtx; const GLuint vertsize = mmesa->vertex_size; - GLint sz = (GLint)(mmesa->glCtx->Point._Size * 2.0); /* 2 fractional bits for hardware */ + /* 2 fractional bits for hardware: */ + GLint sz = (GLint) (2.0 * CLAMP(mmesa->glCtx->Point.Size, + ctx->Const.MinPointSize, + ctx->Const.MaxPointSize)); GLfloat ooa; GLuint *pxy; GLuint xyold, xy; diff --git a/src/mesa/drivers/dri/mga/mgatris.c b/src/mesa/drivers/dri/mga/mgatris.c index 2b7ea05b142..91b413ae760 100644 --- a/src/mesa/drivers/dri/mga/mgatris.c +++ b/src/mesa/drivers/dri/mga/mgatris.c @@ -104,8 +104,10 @@ static void __inline__ mga_draw_quad( mgaContextPtr mmesa, static __inline__ void mga_draw_point( mgaContextPtr mmesa, mgaVertexPtr tmp ) { - GLfloat sz = mmesa->glCtx->Point._Size * .5; - int vertex_size = mmesa->vertex_size; + const GLfloat sz = 0.5 * CLAMP(mmesa->glCtx->Point.Size, + mmesa->glCtx->Const.MinPointSize, + mmesa->glCtx->Const.MaxPointSize); + const int vertex_size = mmesa->vertex_size; GLuint *vb = mgaAllocDmaLow( mmesa, 6 * 4 * vertex_size ); int j; @@ -165,7 +167,9 @@ static __inline__ void mga_draw_line( mgaContextPtr mmesa, GLuint vertex_size = mmesa->vertex_size; GLuint *vb = mgaAllocDmaLow( mmesa, 6 * 4 * vertex_size ); GLfloat dx, dy, ix, iy; - GLfloat width = mmesa->glCtx->Line._Width; + const GLfloat width = CLAMP(mmesa->glCtx->Line.Width, + mmesa->glCtx->Const.MinLineWidth, + mmesa->glCtx->Const.MaxLineWidth); GLint j; #if 0 diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c index 684ed7b017d..fc14060c049 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c @@ -41,7 +41,7 @@ nouveau_bo_download_from_screen(GLcontext *ctx, GLuint offset, GLuint size, DEBUG("..sys_mem\n"); in_mem = nouveau_mem_alloc(ctx, NOUVEAU_MEM_AGP, size, 0); if (in_mem) { - DEBUG("....via AGP\n"); + DEBUG("....via GART\n"); /* otherwise, try blitting to faster memory and * copying from there */ @@ -86,7 +86,7 @@ nouveau_bo_upload_to_screen(GLcontext *ctx, GLuint offset, GLuint size, NOUVEAU_MEM_MAPPED, size, 0); if (out_mem) { - DEBUG("....via AGP\n"); + DEBUG("....via GART\n"); _mesa_memcpy(out_mem->map, nbo->cpu_mem_sys + offset, size); nouveau_memformat_flat_emit(ctx, nbo->gpu_mem, out_mem, @@ -511,7 +511,7 @@ nouveauBufferData(GLcontext *ctx, GLenum target, GLsizeiptrARB size, gpu_flags = 0; break; default: - gpu_flags = NOUVEAU_BO_VRAM_OK | NOUVEAU_BO_AGP_OK; + gpu_flags = NOUVEAU_BO_VRAM_OK | NOUVEAU_BO_GART_OK; break; } nouveau_bo_init_storage(ctx, gpu_flags, size, data, usage, obj); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h index 932450fd877..3439a35e7c8 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h @@ -5,7 +5,7 @@ #include "nouveau_buffers.h" #define NOUVEAU_BO_VRAM_OK (NOUVEAU_MEM_FB | NOUVEAU_MEM_FB_ACCEPTABLE) -#define NOUVEAU_BO_AGP_OK (NOUVEAU_MEM_AGP | NOUVEAU_MEM_AGP_ACCEPTABLE) +#define NOUVEAU_BO_GART_OK (NOUVEAU_MEM_AGP | NOUVEAU_MEM_AGP_ACCEPTABLE) typedef struct nouveau_bufferobj_region_t { uint32_t start; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c index b54f68f4023..d498f616c90 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c @@ -32,8 +32,8 @@ nouveau_memformat_flat_emit(GLcontext *ctx, return GL_FALSE; } - src_handle = (src->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaAGP; - dst_handle = (dst->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaAGP; + src_handle = (src->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaTT; + dst_handle = (dst->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaTT; src_offset += nouveau_mem_gpu_offset_get(ctx, src); dst_offset += nouveau_mem_gpu_offset_get(ctx, dst); @@ -69,7 +69,7 @@ void nouveau_mem_free(GLcontext *ctx, nouveau_mem *mem) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - drm_nouveau_mem_free_t memf; + struct drm_nouveau_mem_free memf; if (NOUVEAU_DEBUG & DEBUG_MEM) { fprintf(stderr, "%s: type=0x%x, offset=0x%x, size=0x%x\n", @@ -78,8 +78,8 @@ nouveau_mem_free(GLcontext *ctx, nouveau_mem *mem) if (mem->map) drmUnmap(mem->map, mem->size); - memf.flags = mem->type; - memf.region_offset = mem->offset; + memf.flags = mem->type; + memf.offset = mem->offset; drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_MEM_FREE, &memf, sizeof(memf)); FREE(mem); } @@ -88,7 +88,7 @@ nouveau_mem * nouveau_mem_alloc(GLcontext *ctx, int type, GLuint size, GLuint align) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - drm_nouveau_mem_alloc_t mema; + struct drm_nouveau_mem_alloc mema; nouveau_mem *mem; int ret; @@ -111,7 +111,7 @@ nouveau_mem_alloc(GLcontext *ctx, int type, GLuint size, GLuint align) FREE(mem); return NULL; } - mem->offset = mema.region_offset; + mem->offset = mema.offset; mem->type = mema.flags; if (NOUVEAU_DEBUG & DEBUG_MEM) { @@ -120,7 +120,7 @@ nouveau_mem_alloc(GLcontext *ctx, int type, GLuint size, GLuint align) } if (type & NOUVEAU_MEM_MAPPED) - ret = drmMap(nmesa->driFd, mem->offset, mem->size, &mem->map); + ret = drmMap(nmesa->driFd, mema.map_handle, mem->size, &mem->map); if (ret) { mem->map = NULL; nouveau_mem_free(ctx, mem); @@ -135,12 +135,7 @@ nouveau_mem_gpu_offset_get(GLcontext *ctx, nouveau_mem *mem) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - if (mem->type & NOUVEAU_MEM_FB) - return (uint32_t)mem->offset - nmesa->vram_phys; - else if (mem->type & NOUVEAU_MEM_AGP) - return (uint32_t)mem->offset - nmesa->agp_phys; - else - return 0xDEADF00D; + return mem->offset; } static GLboolean @@ -299,6 +294,8 @@ nouveau_cliprects_drawable_set(nouveauContextPtr nmesa, nmesa->pClipRects = dPriv->pClipRects; nmesa->drawX = dPriv->x; nmesa->drawY = dPriv->y; + nmesa->drawW = dPriv->w; + nmesa->drawH = dPriv->h; } static void @@ -313,6 +310,8 @@ nouveau_cliprects_renderbuffer_set(nouveauContextPtr nmesa, nmesa->osClipRect.y2 = nrb->mesa.Height; nmesa->drawX = 0; nmesa->drawY = 0; + nmesa->drawW = nrb->mesa.Width; + nmesa->drawH = nrb->mesa.Height; } void @@ -391,9 +390,12 @@ nouveauNewRenderbuffer(GLcontext *ctx, GLuint name) } static void -nouveauBindFramebuffer(GLcontext *ctx, GLenum target, struct gl_framebuffer *fb) +nouveauBindFramebuffer(GLcontext *ctx, GLenum target, + struct gl_framebuffer *fb, struct gl_framebuffer *fbread) { - nouveau_build_framebuffer(ctx, fb); + if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { + nouveau_build_framebuffer(ctx, fb); + } } static void diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 8e11eb61342..44392c0267c 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -145,10 +145,10 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, &nmesa->vram_size)) return GL_FALSE; if (!nouveauDRMGetParam(nmesa, NOUVEAU_GETPARAM_AGP_PHYSICAL, - &nmesa->agp_phys)) + &nmesa->gart_phys)) return GL_FALSE; if (!nouveauDRMGetParam(nmesa, NOUVEAU_GETPARAM_AGP_SIZE, - &nmesa->agp_size)) + &nmesa->gart_size)) return GL_FALSE; if (!nouveauFifoInit(nmesa)) return GL_FALSE; @@ -180,7 +180,7 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, driParseConfigFiles (&nmesa->optionCache, &screen->optionCache, screen->driScreen->myNum, "nouveau"); - nmesa->sarea = (drm_nouveau_sarea_t *)((char *)sPriv->pSAREA + + nmesa->sarea = (struct drm_nouveau_sarea *)((char *)sPriv->pSAREA + screen->sarea_priv_offset); /* Enable any supported extensions */ @@ -224,6 +224,8 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, nv04TriInitFunctions( ctx ); break; case NV_10: + case NV_11: + case NV_17: case NV_20: case NV_30: case NV_40: diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 87e4479da34..9a0be2cb2a5 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -99,19 +99,22 @@ typedef struct nouveau_context { /* The read-only regs */ volatile unsigned char* mmio; + /* The per-channel notifier block */ + volatile void *notifier_block; + /* Physical addresses of AGP/VRAM apertures */ uint64_t vram_phys; uint64_t vram_size; - uint64_t agp_phys; - uint64_t agp_size; + uint64_t gart_phys; + uint64_t gart_size; /* Channel synchronisation */ - nouveau_notifier *syncNotifier; + struct drm_nouveau_notifier_alloc *syncNotifier; /* ARB_occlusion_query / EXT_timer_query */ GLuint query_object_max; GLboolean * query_alloc; - nouveau_notifier *queryNotifier; + struct drm_nouveau_notifier_alloc *queryNotifier; /* Additional hw-specific functions */ nouveau_hw_func hw_func; @@ -150,7 +153,7 @@ typedef struct nouveau_context { GLuint numClipRects; drm_clip_rect_t *pClipRects; drm_clip_rect_t osClipRect; - GLuint drawX, drawY; + GLuint drawX, drawY, drawW, drawH; /* The rendering context information */ GLenum current_primitive; /* the current primitive enum */ @@ -165,7 +168,7 @@ typedef struct nouveau_context { nouveauShader *passthrough_fp; nouveauScreenRec *screen; - drm_nouveau_sarea_t *sarea; + struct drm_nouveau_sarea *sarea; __DRIcontextPrivate *driContext; /* DRI context */ __DRIscreenPrivate *driScreen; /* DRI screen */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.c b/src/mesa/drivers/dri/nouveau/nouveau_driver.c index 00956aa8f8b..ddc9535624b 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_driver.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.c @@ -41,7 +41,7 @@ GLboolean nouveauDRMGetParam(nouveauContextPtr nmesa, unsigned int param, uint64_t* value) { - drm_nouveau_getparam_t getp; + struct drm_nouveau_getparam getp; getp.param = param; if (!value || drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_GETPARAM, @@ -56,7 +56,7 @@ GLboolean nouveauDRMSetParam(nouveauContextPtr nmesa, unsigned int param, uint64_t value) { - drm_nouveau_setparam_t setp; + struct drm_nouveau_setparam setp; setp.param = param; setp.value = value; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c index bd2b2eddd08..7b5e96b4c26 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c @@ -98,14 +98,15 @@ void nouveauWaitForIdle(nouveauContextPtr nmesa) // here we call the fifo initialization ioctl and fill in stuff accordingly GLboolean nouveauFifoInit(nouveauContextPtr nmesa) { - drm_nouveau_fifo_alloc_t fifo_init; - int i; + struct drm_nouveau_fifo_alloc fifo_init; + int i, ret; #ifdef NOUVEAU_RING_DEBUG return GL_TRUE; #endif - int ret; + fifo_init.fb_ctxdma_handle = NvDmaFB; + fifo_init.tt_ctxdma_handle = NvDmaTT; ret=drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_FIFO_ALLOC, &fifo_init, sizeof(fifo_init)); if (ret) { FATAL("Fifo initialization ioctl failed (returned %d)\n",ret); @@ -117,12 +118,21 @@ GLboolean nouveauFifoInit(nouveauContextPtr nmesa) FATAL("Unable to map the fifo (returned %d)\n",ret); return GL_FALSE; } + ret = drmMap(nmesa->driFd, fifo_init.ctrl, fifo_init.ctrl_size, &nmesa->fifo.mmio); if (ret) { FATAL("Unable to map the control regs (returned %d)\n",ret); return GL_FALSE; } + ret = drmMap(nmesa->driFd, fifo_init.notifier, + fifo_init.notifier_size, + &nmesa->notifier_block); + if (ret) { + FATAL("Unable to map the notifier block (returned %d)\n",ret); + return GL_FALSE; + } + /* Setup our initial FIFO tracking params */ nmesa->fifo.channel = fifo_init.channel; nmesa->fifo.put_base = fifo_init.put_base; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_lock.c b/src/mesa/drivers/dri/nouveau/nouveau_lock.c index c119d14dd75..aa86c9e7838 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_lock.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_lock.c @@ -44,7 +44,7 @@ void nouveauGetLock( nouveauContextPtr nmesa, GLuint flags ) { __DRIdrawablePrivate *dPriv = nmesa->driDrawable; __DRIscreenPrivate *sPriv = nmesa->driScreen; - drm_nouveau_sarea_t *sarea = nmesa->sarea; + struct drm_nouveau_sarea *sarea = nmesa->sarea; drmGetLock( nmesa->driFd, nmesa->hHWContext, flags ); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c index b71acff4301..a143488e8d5 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c @@ -7,61 +7,18 @@ GLboolean nouveauCreateContextObject(nouveauContextPtr nmesa, uint32_t handle, int class) { - drm_nouveau_object_init_t cto; + struct drm_nouveau_grobj_alloc cto; int ret; cto.channel = nmesa->fifo.channel; cto.handle = handle; cto.class = class; - ret = drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_OBJECT_INIT, &cto, sizeof(cto)); + ret = drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_GROBJ_ALLOC, + &cto, sizeof(cto)); return ret == 0; } -GLboolean nouveauCreateDmaObject(nouveauContextPtr nmesa, - uint32_t handle, - int class, - uint32_t offset, - uint32_t size, - int target, - int access) -{ - drm_nouveau_dma_object_init_t dma; - int ret; - - dma.channel = nmesa->fifo.channel; - dma.class = class; - dma.handle = handle; - dma.target = target; - dma.access = access; - dma.offset = offset; - dma.size = size; - ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_DMA_OBJECT_INIT, - &dma, sizeof(dma)); - return ret == 0; -} - -GLboolean nouveauCreateDmaObjectFromMem(nouveauContextPtr nmesa, - uint32_t handle, int class, - nouveau_mem *mem, - int access) -{ - uint32_t offset = mem->offset; - int target = mem->type & (NOUVEAU_MEM_FB | NOUVEAU_MEM_AGP); - - if (!target) - return GL_FALSE; - - if (target & NOUVEAU_MEM_FB) - offset -= nmesa->vram_phys; - else if (target & NOUVEAU_MEM_AGP) - offset -= nmesa->agp_phys; - - return nouveauCreateDmaObject(nmesa, handle, class, - offset, mem->size, - target, access); -} - void nouveauObjectOnSubchannel(nouveauContextPtr nmesa, int subchannel, int handle) { BEGIN_RING_SIZE(subchannel, 0, 1); @@ -74,23 +31,16 @@ void nouveauObjectInit(nouveauContextPtr nmesa) return; #endif -/* We need to know vram size.. and AGP size (and even if the card is AGP..) */ - nouveauCreateDmaObject( nmesa, NvDmaFB, NV_DMA_IN_MEMORY, - 0, nmesa->vram_size, - NOUVEAU_MEM_FB, - NOUVEAU_MEM_ACCESS_RW); - nouveauCreateDmaObject( nmesa, NvDmaAGP, NV_DMA_IN_MEMORY, - 0, nmesa->agp_size, - NOUVEAU_MEM_AGP, - NOUVEAU_MEM_ACCESS_RW); - nouveauCreateContextObject(nmesa, Nv3D, nmesa->screen->card->class_3d); if (nmesa->screen->card->type>=NV_10) { nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV10_CONTEXT_SURFACES_2D); - nouveauCreateContextObject(nmesa, NvImageBlit, NV10_IMAGE_BLIT); } else { nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D); nouveauCreateContextObject(nmesa, NvCtxSurf3D, NV04_CONTEXT_SURFACES_3D); + } + if (nmesa->screen->card->type>=NV_11) { + nouveauCreateContextObject(nmesa, NvImageBlit, NV10_IMAGE_BLIT); + } else { nouveauCreateContextObject(nmesa, NvImageBlit, NV_IMAGE_BLIT); } nouveauCreateContextObject(nmesa, NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.h b/src/mesa/drivers/dri/nouveau/nouveau_object.h index 0be9b4309c6..8c72d014daa 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.h @@ -14,7 +14,7 @@ enum DMAObjects { NvMemFormat = 0x80000022, NvCtxSurf3D = 0x80000023, NvDmaFB = 0xD0FB0001, - NvDmaAGP = 0xD0AA0001, + NvDmaTT = 0xD0AA0001, NvSyncNotify = 0xD0000001, NvQueryNotify = 0xD0000002 }; @@ -31,17 +31,5 @@ extern void nouveauObjectOnSubchannel(nouveauContextPtr nmesa, int subchannel, i extern GLboolean nouveauCreateContextObject(nouveauContextPtr nmesa, uint32_t handle, int class); -extern GLboolean nouveauCreateDmaObject(nouveauContextPtr nmesa, - uint32_t handle, - int class, - uint32_t offset, - uint32_t size, - int target, - int access); -extern GLboolean nouveauCreateDmaObjectFromMem(nouveauContextPtr nmesa, - uint32_t handle, - int class, - nouveau_mem *mem, - int access); #endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_query.c b/src/mesa/drivers/dri/nouveau/nouveau_query.c index de3f5b0378b..01541400690 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_query.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_query.c @@ -68,7 +68,7 @@ nouveauBeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); nouveau_query_object *nq = (nouveau_query_object *)q; - nouveau_notifier_reset(nmesa->queryNotifier, nq->notifier_id); + nouveau_notifier_reset(ctx, nmesa->queryNotifier, nq->notifier_id); switch (nmesa->screen->card->type) { case NV_20: @@ -105,12 +105,13 @@ nouveauUpdateQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) nouveau_query_object *nq = (nouveau_query_object *)q; int status; - status = nouveau_notifier_status(nmesa->queryNotifier, + status = nouveau_notifier_status(ctx, nmesa->queryNotifier, nq->notifier_id); q->Ready = (status == NV_NOTIFY_STATE_STATUS_COMPLETED); if (q->Ready) - q->Result = nouveau_notifier_return_val(nmesa->queryNotifier, + q->Result = nouveau_notifier_return_val(ctx, + nmesa->queryNotifier, nq->notifier_id); } @@ -120,7 +121,7 @@ nouveauWaitQueryResult(GLcontext *ctx, GLenum target, struct gl_query_object *q) nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); nouveau_query_object *nq = (nouveau_query_object *)q; - nouveau_notifier_wait_status(nmesa->queryNotifier, nq->notifier_id, + nouveau_notifier_wait_status(ctx, nmesa->queryNotifier, nq->notifier_id, NV_NOTIFY_STATE_STATUS_COMPLETED, 0); nouveauUpdateQuery(ctx, target, q); } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index 7a4b9f1cd00..69b0691bb7b 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -328,7 +328,7 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc static const __DRIversion ddx_expected = { 1, 2, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; static const __DRIversion drm_expected = { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL }; -#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 6 +#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 9 #error nouveau_drm.h version doesn't match expected version #endif dri_interface = interface; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_span.c b/src/mesa/drivers/dri/nouveau/nouveau_span.c index 74dec66afcf..6e3f9fadf4e 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_span.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_span.c @@ -37,6 +37,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define HAVE_HW_STENCIL_SPANS 0 #define HAVE_HW_STENCIL_PIXELS 0 +static char *fake_span[1280*1024*4]; + #define HW_CLIPLOOP() \ do { \ int _nc = nmesa->numClipRects; \ @@ -52,6 +54,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. GLuint height = nrb->mesa.Height; \ GLubyte *map = (GLubyte *)(nrb->map ? nrb->map : nrb->mem->map) + \ (nmesa->drawY * nrb->pitch) + (nmesa->drawX * nrb->cpp); \ + map = fake_span; \ GLuint p; \ (void) p; @@ -120,6 +123,6 @@ nouveauSpanSetFunctions(nouveau_renderbuffer *nrb, const GLvisual *vis) { if (nrb->mesa._ActualFormat == GL_RGBA8) nouveauInitPointers_ARGB8888(&nrb->mesa); - else if (nrb->mesa._ActualFormat == GL_RGB5) + else // if (nrb->mesa._ActualFormat == GL_RGB5) nouveauInitPointers_RGB565(&nrb->mesa); } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index e9fd188d73e..f618dcfc99b 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -60,14 +60,14 @@ static void nouveauCalcViewport(GLcontext *ctx) nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); const GLfloat *v = ctx->Viewport._WindowMap.m; GLfloat *m = nmesa->viewport.m; - GLfloat xoffset = nmesa->drawX, yoffset = nmesa->drawY; + GLfloat xoffset = nmesa->drawX, yoffset = nmesa->drawY + nmesa->drawH; nmesa->depth_scale = 1.0 / ctx->DrawBuffer->_DepthMaxF; m[MAT_SX] = v[MAT_SX]; m[MAT_TX] = v[MAT_TX] + xoffset + SUBPIXEL_X; m[MAT_SY] = - v[MAT_SY]; - m[MAT_TY] = v[MAT_TY] + yoffset + SUBPIXEL_Y; + m[MAT_TY] = (-v[MAT_TY]) + yoffset + SUBPIXEL_Y; m[MAT_SZ] = v[MAT_SZ] * nmesa->depth_scale; m[MAT_TZ] = v[MAT_TZ] * nmesa->depth_scale; @@ -162,6 +162,8 @@ void nouveauDDInitState(nouveauContextPtr nmesa) nv04InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver); break; case NV_10: + case NV_11: + case NV_17: nv10InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver); break; case NV_20: diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.c b/src/mesa/drivers/dri/nouveau/nouveau_sync.c index 30e66962699..8abc847e1e2 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.c @@ -35,53 +35,53 @@ #include "nouveau_msg.h" #include "nouveau_sync.h" -nouveau_notifier * +#define NOTIFIER(__v) \ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); \ + volatile uint32_t *__v = (void*)nmesa->notifier_block + notifier->offset + +struct drm_nouveau_notifier_alloc * nouveau_notifier_new(GLcontext *ctx, GLuint handle, GLuint count) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nouveau_notifier *notifier; + struct drm_nouveau_notifier_alloc *notifier; + int ret; #ifdef NOUVEAU_RING_DEBUG return NULL; #endif - notifier = CALLOC_STRUCT(nouveau_notifier_t); + notifier = CALLOC_STRUCT(drm_nouveau_notifier_alloc); if (!notifier) return NULL; - notifier->mem = nouveau_mem_alloc(ctx, - NOUVEAU_MEM_FB | NOUVEAU_MEM_MAPPED, - count * NV_NOTIFIER_SIZE, - 0); - if (!notifier->mem) { - FREE(notifier); - return NULL; - } - - if (!nouveauCreateDmaObjectFromMem(nmesa, handle, NV_DMA_IN_MEMORY, - notifier->mem, - NOUVEAU_MEM_ACCESS_RW)) { - nouveau_mem_free(ctx, notifier->mem); + notifier->channel = nmesa->fifo.channel; + notifier->handle = handle; + notifier->count = count; + ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_NOTIFIER_ALLOC, + notifier, sizeof(*notifier)); + if (ret) { + MESSAGE("Failed to create notifier 0x%08x: %d\n", handle, ret); FREE(notifier); return NULL; } - notifier->handle = handle; return notifier; } void -nouveau_notifier_destroy(GLcontext *ctx, nouveau_notifier *notifier) +nouveau_notifier_destroy(GLcontext *ctx, + struct drm_nouveau_notifier_alloc *notifier) { - /*XXX: free DMA object.. */ - nouveau_mem_free(ctx, notifier->mem); + /*XXX: free notifier object.. */ FREE(notifier); } void -nouveau_notifier_reset(nouveau_notifier *notifier, GLuint id) +nouveau_notifier_reset(GLcontext *ctx, + struct drm_nouveau_notifier_alloc *notifier, + GLuint id) { - volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE); + NOTIFIER(n); #ifdef NOUVEAU_RING_DEBUG return; @@ -95,26 +95,31 @@ nouveau_notifier_reset(nouveau_notifier *notifier, GLuint id) } GLuint -nouveau_notifier_status(nouveau_notifier *notifier, GLuint id) +nouveau_notifier_status(GLcontext *ctx, + struct drm_nouveau_notifier_alloc *notifier, + GLuint id) { - volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE); + NOTIFIER(n); return n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT; } GLuint -nouveau_notifier_return_val(nouveau_notifier *notifier, GLuint id) +nouveau_notifier_return_val(GLcontext *ctx, + struct drm_nouveau_notifier_alloc *notifier, + GLuint id) { - volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE); + NOTIFIER(n); return n[NV_NOTIFY_RETURN_VALUE/4]; } GLboolean -nouveau_notifier_wait_status(nouveau_notifier *notifier, GLuint id, - GLuint status, GLuint timeout) +nouveau_notifier_wait_status(GLcontext *ctx, + struct drm_nouveau_notifier_alloc *notifier, + GLuint id, GLuint status, GLuint timeout) { - volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE); + NOTIFIER(n); unsigned int time = 0; #ifdef NOUVEAU_RING_DEBUG @@ -144,13 +149,14 @@ nouveau_notifier_wait_status(nouveau_notifier *notifier, GLuint id, } void -nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *notifier, - GLuint subc) +nouveau_notifier_wait_nop(GLcontext *ctx, + struct drm_nouveau_notifier_alloc *notifier, + GLuint subc) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + NOTIFIER(n); GLboolean ret; - nouveau_notifier_reset(notifier, 0); + nouveau_notifier_reset(ctx, notifier, 0); BEGIN_RING_SIZE(subc, NV_NOTIFY, 1); OUT_RING (NV_NOTIFY_STYLE_WRITE_ONLY); @@ -158,7 +164,7 @@ nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *notifier, OUT_RING (0); FIRE_RING(); - ret = nouveau_notifier_wait_status(notifier, 0, + ret = nouveau_notifier_wait_status(ctx, notifier, 0, NV_NOTIFY_STATE_STATUS_COMPLETED, 0 /* no timeout */); if (ret == GL_FALSE) MESSAGE("wait on notifier failed\n"); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.h b/src/mesa/drivers/dri/nouveau/nouveau_sync.h index 019d5f6629b..b76af172762 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.h @@ -47,21 +47,25 @@ #define NV_NOTIFY 0x00000104 #define NV_NOTIFY_STYLE_WRITE_ONLY 0 -typedef struct nouveau_notifier_t { - GLuint handle; - nouveau_mem *mem; -} nouveau_notifier; - -extern nouveau_notifier *nouveau_notifier_new(GLcontext *, GLuint handle, - GLuint count); -extern void nouveau_notifier_destroy(GLcontext *, nouveau_notifier *); -extern void nouveau_notifier_reset(nouveau_notifier *, GLuint id); -extern GLuint nouveau_notifier_status(nouveau_notifier *, GLuint id); -extern GLuint nouveau_notifier_return_val(nouveau_notifier *, GLuint id); -extern GLboolean nouveau_notifier_wait_status(nouveau_notifier *r, GLuint id, - GLuint status, GLuint timeout); -extern void nouveau_notifier_wait_nop(GLcontext *ctx, - nouveau_notifier *, GLuint subc); +extern struct drm_nouveau_notifier_alloc * +nouveau_notifier_new(GLcontext *, GLuint handle, GLuint count); +extern void +nouveau_notifier_destroy(GLcontext *, struct drm_nouveau_notifier_alloc *); +extern void +nouveau_notifier_reset(GLcontext *, struct drm_nouveau_notifier_alloc *, + GLuint id); +extern GLuint +nouveau_notifier_status(GLcontext *, struct drm_nouveau_notifier_alloc *, + GLuint id); +extern GLuint +nouveau_notifier_return_val(GLcontext *, struct drm_nouveau_notifier_alloc *, + GLuint id); +extern GLboolean +nouveau_notifier_wait_status(GLcontext *, struct drm_nouveau_notifier_alloc *, + GLuint id, GLuint status, GLuint timeout); +extern void +nouveau_notifier_wait_nop(GLcontext *ctx, struct drm_nouveau_notifier_alloc *, + GLuint subc); extern GLboolean nouveauSyncInitFuncs(GLcontext *ctx); #endif diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 5f304ccab92..47c4b14ba6b 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -697,8 +697,7 @@ static GLboolean nv10InitCard(nouveauContextPtr nmesa) BEGIN_RING_SIZE(NvSub3D, 0x03f4, 1); OUT_RING(0); - /* not for nv10, only for >= nv11 */ - if ((nmesa->screen->card->id>>4) >= 0x11) { + if (nmesa->screen->card->type >= NV_11) { BEGIN_RING_SIZE(NvSub3D, 0x120, 3); OUT_RING(0); OUT_RING(1); @@ -739,11 +738,11 @@ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, OUT_RING_CACHE(depth ? depth->offset : color[0]->offset); /* Always set to bottom left of buffer */ - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X, 4); + /*BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X, 4); OUT_RING_CACHEf (0.0); OUT_RING_CACHEf ((GLfloat) h); OUT_RING_CACHEf (0.0); - OUT_RING_CACHEf (0.0); + OUT_RING_CACHEf (0.0);*/ return GL_TRUE; } diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 3bc84d862d3..611469b6e41 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -58,7 +58,7 @@ static void nv10ResetLineStipple( GLcontext *ctx ); static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t primitive,uint32_t size) { - if (nmesa->screen->card->type==NV_10) + if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17)) BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1); else if (nmesa->screen->card->type==NV_20) BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_BEGIN_END,1); @@ -66,7 +66,7 @@ static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t pri BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_BEGIN_END,1); OUT_RING(primitive); - if (nmesa->screen->card->type==NV_10) + if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17)) BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_DATA|NONINC_METHOD,size); else if (nmesa->screen->card->type==NV_20) BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_VERTEX_DATA|NONINC_METHOD,size); @@ -76,7 +76,7 @@ static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t pri inline void nv10FinishPrimitive(struct nouveau_context *nmesa) { - if (nmesa->screen->card->type==NV_10) + if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17)) BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1); else if (nmesa->screen->card->type==NV_20) BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_BEGIN_END,1); @@ -392,15 +392,6 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) int i; int slots=0; int total_size=0; - /* t_vertex_generic dereferences a NULL pointer if we - * pass NULL as the vp transform... - */ - const GLfloat ident_vp[16] = { - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - }; nmesa->vertex_attr_count = 0; RENDERINPUTS_COPY(index, nmesa->render_inputs_bitset); @@ -431,28 +422,20 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) if (RENDERINPUTS_TEST(index, i)) { slots=i+1; - if (i==_TNL_ATTRIB_POS) - { - /* special-case POS */ - EMIT_ATTR(_TNL_ATTRIB_POS,EMIT_3F_VIEWPORT); - } - else + switch(attr_size[i]) { - switch(attr_size[i]) - { - case 1: - EMIT_ATTR(i,EMIT_1F); - break; - case 2: - EMIT_ATTR(i,EMIT_2F); - break; - case 3: - EMIT_ATTR(i,EMIT_3F); - break; - case 4: - EMIT_ATTR(i,EMIT_4F); - break; - } + case 1: + EMIT_ATTR(i,EMIT_1F); + break; + case 2: + EMIT_ATTR(i,EMIT_2F); + break; + case 3: + EMIT_ATTR(i,EMIT_3F); + break; + case 4: + EMIT_ATTR(i,EMIT_4F); + break; } if (i==_TNL_ATTRIB_COLOR0) nmesa->color_offset=total_size; @@ -465,13 +448,13 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) nmesa->vertex_size=_tnl_install_attrs( ctx, nmesa->vertex_attrs, nmesa->vertex_attr_count, - ident_vp, 0 ); + NULL, 0 ); assert(nmesa->vertex_size==total_size*4); /* * Tell the hardware about the vertex format */ - if (nmesa->screen->card->type==NV_10) { + if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17)) { int size; #define NV_VERTEX_ATTRIBUTE_TYPE_FLOAT 2 diff --git a/src/mesa/drivers/dri/nouveau/nv20_state.c b/src/mesa/drivers/dri/nouveau/nv20_state.c index 3d8d83a865a..ccf2f6148b4 100644 --- a/src/mesa/drivers/dri/nouveau/nv20_state.c +++ b/src/mesa/drivers/dri/nouveau/nv20_state.c @@ -568,10 +568,10 @@ static void nv20Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) y += nmesa->drawY; } - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SCISSOR_X2_X1, 1); + /*BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SCISSOR_X2_X1, 1); OUT_RING_CACHE((w << 16) | x ); BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SCISSOR_Y2_Y1, 1); - OUT_RING_CACHE((h << 16) | y ); + OUT_RING_CACHE((h << 16) | y );*/ } @@ -764,11 +764,11 @@ static GLboolean nv20BindBuffers(nouveauContextPtr nmesa, int num_color, } /* Always set to bottom left of buffer */ - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X, 4); + /*BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X, 4); OUT_RING_CACHEf (0.0); OUT_RING_CACHEf ((GLfloat) h); OUT_RING_CACHEf (0.0); - OUT_RING_CACHEf (0.0); + OUT_RING_CACHEf (0.0);*/ return GL_TRUE; } diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index ad21fa27302..9b010954b33 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -639,25 +639,45 @@ void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); /** Set rasterization mode */ void (*RenderMode)(GLcontext *ctx, GLenum mode ); +/* Translate GL coords to window coords, clamping w/h to the + * dimensions of the window. + */ +static void nv30WindowCoords(nouveauContextPtr nmesa, + GLuint x, GLuint y, GLuint w, GLuint h, + GLuint *wX, GLuint *wY, GLuint *wW, GLuint *wH) +{ + if ((x+w) > nmesa->drawW) + w = nmesa->drawW - x; + (*wX) = x + nmesa->drawX; + (*wW) = w; + + if ((y+h) > nmesa->drawH) + h = nmesa->drawH - y; + (*wY) = (nmesa->drawH - y) - h + nmesa->drawY; + (*wH) = h; +} + /** Define the scissor box */ static void nv30Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLuint wX, wY, wW, wH; /* There's no scissor enable bit, so adjust the scissor to cover the * maximum draw buffer bounds */ if (!ctx->Scissor.Enabled) { - x = y = 0; - w = h = 4095; + wX = nmesa->drawX; + wY = nmesa->drawY; + wW = nmesa->drawW; + wH = nmesa->drawH; } else { - x += nmesa->drawX; - y += nmesa->drawY; + nv30WindowCoords(nmesa, x, y, w, h, &wX, &wY, &wW, &wH); } BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2); - OUT_RING_CACHE(((w) << 16) | x); - OUT_RING_CACHE(((h) << 16) | y); + OUT_RING_CACHE ((wW << 16) | wX); + OUT_RING_CACHE ((wH << 16) | wY); } /** Select flat or smooth shading */ @@ -751,19 +771,21 @@ static void nv30WindowMoved(nouveauContextPtr nmesa) { GLcontext *ctx = nmesa->glCtx; GLfloat *v = nmesa->viewport.m; - GLuint w = ctx->Viewport.Width; - GLuint h = ctx->Viewport.Height; - GLuint x = ctx->Viewport.X + nmesa->drawX; - GLuint y = ctx->Viewport.Y + nmesa->drawY; + GLuint wX, wY, wW, wH; + nv30WindowCoords(nmesa, ctx->Viewport.X, ctx->Viewport.Y, + ctx->Viewport.Width, ctx->Viewport.Height, + &wX, &wY, &wW, &wH); BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0, 2); - OUT_RING_CACHE((w << 16) | x); - OUT_RING_CACHE((h << 16) | y); + OUT_RING_CACHE ((wW << 16) | wX); + OUT_RING_CACHE ((wH << 16) | wY); + /* something to do with clears, possibly doesn't belong here */ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_OFS0, 2); - OUT_RING_CACHE(((w+x) << 16) | x); - OUT_RING_CACHE(((h+y) << 16) | y); + OUT_RING_CACHE(((nmesa->drawX + nmesa->drawW) << 16) | nmesa->drawX); + OUT_RING_CACHE(((nmesa->drawY + nmesa->drawH) << 16) | nmesa->drawY); + /* viewport transform */ BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OX, 8); OUT_RING_CACHEf (v[MAT_TX]); @@ -786,7 +808,7 @@ static GLboolean nv30InitCard(nouveauContextPtr nmesa) BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1, 3); OUT_RING(NvDmaFB); - OUT_RING(NvDmaAGP); + OUT_RING(NvDmaTT); OUT_RING(NvDmaFB); BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT8, 1); OUT_RING(NvDmaFB); diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index 2115799b9b6..1d975ecd57d 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -772,9 +772,11 @@ static void r200LineWidth( GLcontext *ctx, GLfloat widthf ) R200_STATECHANGE( rmesa, set ); /* Line width is stored in U6.4 format. + * Same min/max limits for AA, non-AA lines. */ rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] &= ~0xffff; - rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] |= (GLuint)(ctx->Line._Width * 16.0); + rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] |= (GLuint) + (CLAMP(widthf, ctx->Const.MinLineWidth, ctx->Const.MaxLineWidth) * 16.0); if ( widthf > 1.0 ) { rmesa->hw.set.cmd[SET_SE_CNTL] |= R200_WIDELINE_ENABLE; diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile index c1d223c7600..44248964fdb 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile @@ -41,6 +41,7 @@ DRIVER_SOURCES = \ r300_fragprog.c \ r300_shader.c \ r300_emit.c \ + r300_swtcl.c \ $(EGL_SOURCES) C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index 7055286ba95..9eca41fa38c 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -321,8 +321,12 @@ void r300InitCmdBuf(r300ContextPtr r300) r300->hw.unk221C.cmd[0] = cmdpacket0(R300_VAP_UNKNOWN_221C, 1); ALLOC_STATE(vap_clip, always, 5, 0); r300->hw.vap_clip.cmd[0] = cmdpacket0(R300_VAP_CLIP_X_0, 4); - ALLOC_STATE(unk2288, always, 2, 0); - r300->hw.unk2288.cmd[0] = cmdpacket0(R300_VAP_UNKNOWN_2288, 1); + + if (has_tcl) { + ALLOC_STATE(unk2288, always, 2, 0); + r300->hw.unk2288.cmd[0] = cmdpacket0(R300_VAP_UNKNOWN_2288, 1); + } + ALLOC_STATE(vof, always, R300_VOF_CMDSIZE, 0); r300->hw.vof.cmd[R300_VOF_CMD_0] = cmdpacket0(R300_VAP_OUTPUT_VTX_FMT_0, 2); diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 9ea14ab4c78..14e0f052fd5 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -63,6 +63,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_ioctl.h" #include "r300_tex.h" #include "r300_emit.h" +#include "r300_swtcl.h" #ifdef USER_BUFFERS #include "r300_mem.h" @@ -317,15 +318,17 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, _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... */ @@ -363,6 +366,8 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, radeonInitSpanFuncs(ctx); r300InitCmdBuf(r300); r300InitState(r300); + if (!(screen->chip_flags & RADEON_CHIPSET_TCL)) + r300InitSwtcl(ctx); TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline; diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 076bb49a006..be6909724a3 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -568,38 +568,21 @@ struct r300_vertex_shader_fragment { union { GLuint d[VSF_MAX_FRAGMENT_LENGTH]; float f[VSF_MAX_FRAGMENT_LENGTH]; - VERTEX_SHADER_INSTRUCTION i[VSF_MAX_FRAGMENT_LENGTH / 4]; + GLuint i[VSF_MAX_FRAGMENT_LENGTH]; } body; }; -#define VSF_DEST_PROGRAM 0x0 -#define VSF_DEST_MATRIX0 0x200 -#define VSF_DEST_MATRIX1 0x204 -#define VSF_DEST_MATRIX2 0x208 -#define VSF_DEST_VECTOR0 0x20c -#define VSF_DEST_VECTOR1 0x20d -#define VSF_DEST_UNKNOWN1 0x400 -#define VSF_DEST_UNKNOWN2 0x406 - struct r300_vertex_shader_state { struct r300_vertex_shader_fragment program; - - struct r300_vertex_shader_fragment unknown1; - struct r300_vertex_shader_fragment unknown2; - - int program_start; - int unknown_ptr1; /* pointer within program space */ - int program_end; - - int param_offset; - int param_count; - - int unknown_ptr2; /* pointer within program space */ - int unknown_ptr3; /* pointer within program space */ }; extern int hw_tcl_on; +#define COLOR_IS_RGBA +#define TAG(x) r300##x +#include "tnl_dd/t_dd_vertex.h" +#undef TAG + //#define CURRENT_VERTEX_SHADER(ctx) (ctx->VertexProgram._Current) #define CURRENT_VERTEX_SHADER(ctx) (R300_CONTEXT(ctx)->selected_vp) @@ -796,13 +779,10 @@ struct r300_state { GLuint *Elts; struct r300_dma_region elt_dma; - DECLARE_RENDERINPUTS(render_inputs_bitset); /* actual render inputs that R300 was configured for. + struct r300_dma_region swtcl_dma; + DECLARE_RENDERINPUTS(render_inputs_bitset); /* actual render inputs that R300 was configured for. They are the same as tnl->render_inputs for fixed pipeline */ - struct { - int transform_offset; /* Transform matrix offset, -1 if none */ - } vap_param; /* vertex processor parameter allocation - tells where to write parameters */ - struct r300_stencilbuffer_state stencil; }; @@ -811,6 +791,62 @@ struct r300_state { #define R300_FALLBACK_TCL 1 #define R300_FALLBACK_RAST 2 +/* r300_swtcl.c + */ +struct r300_swtcl_info { + GLuint RenderIndex; + + /** + * Size of a hardware vertex. This is calculated when \c ::vertex_attrs is + * installed in the Mesa state vector. + */ + GLuint vertex_size; + + /** + * Attributes instructing the Mesa TCL pipeline where / how to put vertex + * data in the hardware buffer. + */ + struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; + + /** + * Number of elements of \c ::vertex_attrs that are actually used. + */ + GLuint vertex_attr_count; + + /** + * Cached pointer to the buffer where Mesa will store vertex data. + */ + GLubyte *verts; + + /* Fallback rasterization functions + */ + // r200_point_func draw_point; + // r200_line_func draw_line; + // r200_tri_func draw_tri; + + GLuint hw_primitive; + GLenum render_primitive; + GLuint numverts; + + /** + * Offset of the 4UB color data within a hardware (swtcl) vertex. + */ + GLuint coloroffset; + + /** + * Offset of the 3UB specular color data within a hardware (swtcl) vertex. + */ + GLuint specoffset; + + /** + * Should Mesa project vertex data or will the hardware do it? + */ + GLboolean needproj; + + struct r300_dma_region indexed_verts; +}; + + /** * \brief R300 context structure. */ @@ -849,6 +885,9 @@ struct r300_context { GLvector4f *temp_attrib[_TNL_ATTRIB_MAX]; GLboolean disable_lowimpact_fallback; + + DECLARE_RENDERINPUTS(tnl_index_bitset); /* index of bits for last tnl_install_attrs */ + struct r300_swtcl_info swtcl; }; struct r300_buffer_object { diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c index 4670c28a02f..424bf44e595 100644 --- a/src/mesa/drivers/dri/r300/r300_emit.c +++ b/src/mesa/drivers/dri/r300/r300_emit.c @@ -217,14 +217,14 @@ static GLuint r300VAPInputRoute0(uint32_t * dst, GLvector4f ** attribptr, dw = R300_INPUT_ROUTE_FLOAT | (inputs[tab[i]] << 8) | (attribptr[tab[i]]->size - 1); dw |= (R300_INPUT_ROUTE_FLOAT | (inputs[tab[i + 1]] << 8) | (attribptr[tab[i + 1]]->size - 1)) << 16; if (i + 2 == nr) { - dw |= (1 << (13 + 16)); + dw |= (R300_VAP_INPUT_ROUTE_END << 16); } dst[i >> 1] = dw; } if (nr & 1) { dw = R300_INPUT_ROUTE_FLOAT | (inputs[tab[nr - 1]] << 8) | (attribptr[tab[nr - 1]]->size - 1); - dw |= 1 << 13; + dw |= R300_VAP_INPUT_ROUTE_END; dst[nr >> 1] = dw; } @@ -239,7 +239,7 @@ static GLuint r300VAPInputRoute1Swizzle(int swizzle[4]) (swizzle[3] << R300_INPUT_ROUTE_W_SHIFT); } -static GLuint r300VAPInputRoute1(uint32_t * dst, int swizzle[][4], GLuint nr) +GLuint r300VAPInputRoute1(uint32_t * dst, int swizzle[][4], GLuint nr) { GLuint i; @@ -255,14 +255,14 @@ static GLuint r300VAPInputRoute1(uint32_t * dst, int swizzle[][4], GLuint nr) return (nr + 1) >> 1; } -static GLuint r300VAPInputCntl0(GLcontext * ctx, GLuint InputsRead) +GLuint r300VAPInputCntl0(GLcontext * ctx, GLuint InputsRead) { /* No idea what this value means. I have seen other values written to * this register... */ return 0x5555; } -static GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead) +GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead) { r300ContextPtr rmesa = R300_CONTEXT(ctx); GLuint i, vic_1 = 0; @@ -286,7 +286,7 @@ static GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead) return vic_1; } -static GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint OutputsWritten) +GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint OutputsWritten) { GLuint ret = 0; @@ -299,13 +299,14 @@ static GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint OutputsWritten) if (OutputsWritten & (1 << VERT_RESULT_COL1)) ret |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT; -#if 0 - if (OutputsWritten & (1 << VERT_RESULT_BFC0)) - ret |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT; - - if (OutputsWritten & (1 << VERT_RESULT_BFC1)) - ret |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT; + if (OutputsWritten & (1 << VERT_RESULT_BFC0) + || OutputsWritten & (1 << VERT_RESULT_BFC1)) + ret |= + R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT | + R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT | + R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT; +#if 0 if (OutputsWritten & (1 << VERT_RESULT_FOGC)) ; #endif @@ -315,7 +316,7 @@ static GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint OutputsWritten) return ret; } -static GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint OutputsWritten) +GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint OutputsWritten) { GLuint i, ret = 0; @@ -358,9 +359,11 @@ int r300EmitArrays(GLcontext * ctx) DECLARE_RENDERINPUTS(render_inputs_bitset); RENDERINPUTS_COPY(render_inputs_bitset, tnl->render_inputs_bitset); + vb->AttribPtr[VERT_ATTRIB_POS] = vb->ClipPtr; + assert(RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_POS)); assert(RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_NORMAL) == 0); - assert(RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_COLOR0)); + //assert(RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_COLOR0)); if (RENDERINPUTS_TEST(render_inputs_bitset, _TNL_ATTRIB_POS)) { InputsRead |= 1 << VERT_ATTRIB_POS; @@ -392,20 +395,18 @@ int r300EmitArrays(GLcontext * ctx) } } - if (!(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) { - /* Fixed, apply to vir0 only */ - memcpy(vir_inputs, inputs, VERT_ATTRIB_MAX * sizeof(int)); - inputs = vir_inputs; - if (InputsRead & VERT_ATTRIB_POS) - inputs[VERT_ATTRIB_POS] = 0; - if (InputsRead & (1 << VERT_ATTRIB_COLOR0)) - inputs[VERT_ATTRIB_COLOR0] = 2; - if (InputsRead & (1 << VERT_ATTRIB_COLOR1)) - inputs[VERT_ATTRIB_COLOR1] = 3; - for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX7; i++) - if (InputsRead & (1 << i)) - inputs[i] = 6 + (i - VERT_ATTRIB_TEX0); - } + /* Fixed, apply to vir0 only */ + memcpy(vir_inputs, inputs, VERT_ATTRIB_MAX * sizeof(int)); + inputs = vir_inputs; + if (InputsRead & VERT_ATTRIB_POS) + inputs[VERT_ATTRIB_POS] = 0; + if (InputsRead & (1 << VERT_ATTRIB_COLOR0)) + inputs[VERT_ATTRIB_COLOR0] = 2; + if (InputsRead & (1 << VERT_ATTRIB_COLOR1)) + inputs[VERT_ATTRIB_COLOR1] = 3; + for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX7; i++) + if (InputsRead & (1 << i)) + inputs[i] = 6 + (i - VERT_ATTRIB_TEX0); RENDERINPUTS_COPY(rmesa->state.render_inputs_bitset, render_inputs_bitset); } @@ -532,3 +533,19 @@ void r300ReleaseArrays(GLcontext * ctx) r300ReleaseDmaRegion(rmesa, &rmesa->state.aos[i], __FUNCTION__); } } + +void r300EmitCacheFlush(r300ContextPtr rmesa) +{ + int cmd_reserved = 0; + int cmd_written = 0; + + drm_radeon_cmd_header_t *cmd = NULL; + + reg_start(R300_RB3D_DSTCACHE_CTLSTAT, 0); + e32(R300_RB3D_DSTCACHE_UNKNOWN_0A); + + reg_start(R300_RB3D_ZCACHE_CTLSTAT, 0); + e32(R300_RB3D_ZCACHE_UNKNOWN_03); + + +} diff --git a/src/mesa/drivers/dri/r300/r300_emit.h b/src/mesa/drivers/dri/r300/r300_emit.h index 2f79ee3a23a..a6d69ec5ff8 100644 --- a/src/mesa/drivers/dri/r300/r300_emit.h +++ b/src/mesa/drivers/dri/r300/r300_emit.h @@ -225,5 +225,15 @@ void r300UseArrays(GLcontext * ctx); #endif extern void r300ReleaseArrays(GLcontext * ctx); +extern int r300PrimitiveType(r300ContextPtr rmesa, int prim); +extern int r300NumVerts(r300ContextPtr rmesa, int num_verts, int prim); + +extern void r300EmitCacheFlush(r300ContextPtr rmesa); + +extern GLuint r300VAPInputRoute1(uint32_t * dst, int swizzle[][4], GLuint nr); +extern GLuint r300VAPInputCntl0(GLcontext * ctx, GLuint InputsRead); +extern GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead); +extern GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint OutputsWritten); +extern GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint OutputsWritten); #endif diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index 15c2cf3ad7b..90f5027c9ad 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -172,11 +172,7 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer) cmd2[7].u = r300PackFloat32(ctx->Color.ClearColor[2]); cmd2[8].u = r300PackFloat32(ctx->Color.ClearColor[3]); - reg_start(R300_RB3D_DSTCACHE_CTLSTAT, 0); - e32(R300_RB3D_DSTCACHE_UNKNOWN_0A); - - reg_start(R300_RB3D_ZCACHE_CTLSTAT, 0); - e32(R300_RB3D_ZCACHE_UNKNOWN_03); + r300EmitCacheFlush(rmesa); cp_wait(rmesa, R300_WAIT_3D | R300_WAIT_3D_CLEAN); } @@ -412,19 +408,22 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) void r300Flush(GLcontext * ctx) { - r300ContextPtr r300 = R300_CONTEXT(ctx); + r300ContextPtr rmesa = R300_CONTEXT(ctx); if (RADEON_DEBUG & DEBUG_IOCTL) fprintf(stderr, "%s\n", __FUNCTION__); - if (r300->cmdbuf.count_used > r300->cmdbuf.count_reemit) - r300FlushCmdBuf(r300, __FUNCTION__); + if (rmesa->dma.flush) + rmesa->dma.flush( rmesa ); + + if (rmesa->cmdbuf.count_used > rmesa->cmdbuf.count_reemit) + r300FlushCmdBuf(rmesa, __FUNCTION__); } #ifdef USER_BUFFERS #include "r300_mem.h" -static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa, int size) +void r300RefillCurrentDmaRegion(r300ContextPtr rmesa, int size) { struct r300_dma_buffer *dmabuf; size = MAX2(size, RADEON_BUFFER_SIZE * 16); @@ -436,9 +435,12 @@ static void r300RefillCurrentDmaRegion(r300ContextPtr rmesa, int size) rmesa->dma.flush(rmesa); } - if (rmesa->dma.current.buf) + if (rmesa->dma.current.buf) { +#ifdef USER_BUFFERS + r300_mem_use(rmesa, rmesa->dma.current.buf->id); +#endif r300ReleaseDmaRegion(rmesa, &rmesa->dma.current, __FUNCTION__); - + } if (rmesa->dma.nr_released_bufs > 4) r300FlushCmdBuf(rmesa, __FUNCTION__); diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.h b/src/mesa/drivers/dri/r300/r300_ioctl.h index 7a19a2cf3f9..e1143fb6c34 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.h +++ b/src/mesa/drivers/dri/r300/r300_ioctl.h @@ -56,4 +56,5 @@ extern void r300AllocDmaRegion(r300ContextPtr rmesa, extern void r300InitIoctlFuncs(struct dd_function_table *functions); +extern void r300RefillCurrentDmaRegion(r300ContextPtr rmesa, int size); #endif /* __R300_IOCTL_H__ */ diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h index 3ce09c16d3f..1baa74c5269 100644 --- a/src/mesa/drivers/dri/r300/r300_reg.h +++ b/src/mesa/drivers/dri/r300/r300_reg.h @@ -282,9 +282,32 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define R300_VAP_PVS_UPLOAD_ADDRESS 0x2200 # define R300_PVS_UPLOAD_PROGRAM 0x00000000 +/* gap */ # define R300_PVS_UPLOAD_PARAMETERS 0x00000200 +/* gap */ +# define R300_PVS_UPLOAD_CLIP_PLANE0 0x00000400 +# define R300_PVS_UPLOAD_CLIP_PLANE1 0x00000401 +# define R300_PVS_UPLOAD_CLIP_PLANE2 0x00000402 +# define R300_PVS_UPLOAD_CLIP_PLANE3 0x00000403 +# define R300_PVS_UPLOAD_CLIP_PLANE4 0x00000404 +# define R300_PVS_UPLOAD_CLIP_PLANE5 0x00000405 # define R300_PVS_UPLOAD_POINTSIZE 0x00000406 +/* + * These are obsolete defines form r300_context.h, but they might give some + * clues when investigating the addresses further... + */ +#if 0 +#define VSF_DEST_PROGRAM 0x0 +#define VSF_DEST_MATRIX0 0x200 +#define VSF_DEST_MATRIX1 0x204 +#define VSF_DEST_MATRIX2 0x208 +#define VSF_DEST_VECTOR0 0x20c +#define VSF_DEST_VECTOR1 0x20d +#define VSF_DEST_UNKNOWN1 0x400 +#define VSF_DEST_UNKNOWN2 0x406 +#endif + /* gap */ #define R300_VAP_PVS_UPLOAD_DATA 0x2208 @@ -336,13 +359,15 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * The meaning of the two UNKNOWN fields is obviously not known. However, * experiments so far have shown that both *must* point to an instruction * inside the vertex program, otherwise the GPU locks up. + * * fglrx usually sets CNTL_3_UNKNOWN to the end of the program and - * CNTL_1_UNKNOWN points to instruction where last write to position takes - * place. + * R300_PVS_CNTL_1_POS_END_SHIFT points to instruction where last write to + * position takes place. + * * Most likely this is used to ignore rest of the program in cases * where group of verts arent visible. For some reason this "section" * is sometimes accepted other instruction that have no relationship with - *position calculations. + * position calculations. */ #define R300_VAP_PVS_CNTL_1 0x22D0 # define R300_PVS_CNTL_1_PROGRAM_START_SHIFT 0 diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index 1aaf43bfafc..eee1e803a00 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -79,7 +79,7 @@ extern int future_hw_tcl_on; /** * \brief Convert a OpenGL primitive type into a R300 primitive type. */ -static int r300PrimitiveType(r300ContextPtr rmesa, GLcontext * ctx, int prim) +int r300PrimitiveType(r300ContextPtr rmesa, int prim) { switch (prim & PRIM_MODE_MASK) { case GL_POINTS: @@ -119,7 +119,7 @@ static int r300PrimitiveType(r300ContextPtr rmesa, GLcontext * ctx, int prim) } } -static int r300NumVerts(r300ContextPtr rmesa, int num_verts, int prim) +int r300NumVerts(r300ContextPtr rmesa, int num_verts, int prim) { int verts_off = 0; @@ -261,7 +261,7 @@ static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx, TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *vb = &tnl->vb; - type = r300PrimitiveType(rmesa, ctx, prim); + type = r300PrimitiveType(rmesa, prim); num_verts = r300NumVerts(rmesa, end - start, prim); if (type < 0 || num_verts <= 0) @@ -287,29 +287,20 @@ static GLboolean r300RunRender(GLcontext * ctx, { r300ContextPtr rmesa = R300_CONTEXT(ctx); int i; - int cmd_reserved = 0; - int cmd_written = 0; - drm_radeon_cmd_header_t *cmd = NULL; TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *vb = &tnl->vb; + if (RADEON_DEBUG & DEBUG_PRIMS) fprintf(stderr, "%s\n", __FUNCTION__); - if (hw_tcl_on == GL_FALSE) - vb->AttribPtr[VERT_ATTRIB_POS] = vb->ClipPtr; r300UpdateShaders(rmesa); if (r300EmitArrays(ctx)) return GL_TRUE; r300UpdateShaderStates(rmesa); - reg_start(R300_RB3D_DSTCACHE_CTLSTAT, 0); - e32(R300_RB3D_DSTCACHE_UNKNOWN_0A); - - reg_start(R300_RB3D_ZCACHE_CTLSTAT, 0); - e32(R300_RB3D_ZCACHE_UNKNOWN_03); - + r300EmitCacheFlush(rmesa); r300EmitState(rmesa); for (i = 0; i < vb->PrimitiveCount; i++) { @@ -319,11 +310,7 @@ static GLboolean r300RunRender(GLcontext * ctx, r300RunRenderPrimitive(rmesa, ctx, start, end, prim); } - reg_start(R300_RB3D_DSTCACHE_CTLSTAT, 0); - e32(R300_RB3D_DSTCACHE_UNKNOWN_0A); - - reg_start(R300_RB3D_ZCACHE_CTLSTAT, 0); - e32(R300_RB3D_ZCACHE_UNKNOWN_03); + r300EmitCacheFlush(rmesa); #ifdef USER_BUFFERS r300UseArrays(ctx); @@ -371,8 +358,6 @@ static int r300Fallback(GLcontext * ctx) FALLBACK_IF(ctx->Point.PointSprite); if (!r300->disable_lowimpact_fallback) { - FALLBACK_IF(ctx->Polygon.OffsetPoint); - FALLBACK_IF(ctx->Polygon.OffsetLine); FALLBACK_IF(ctx->Polygon.StippleFlag); FALLBACK_IF(ctx->Multisample.Enabled); FALLBACK_IF(ctx->Line.StippleFlag); @@ -386,12 +371,17 @@ static int r300Fallback(GLcontext * ctx) static GLboolean r300RunNonTCLRender(GLcontext * ctx, struct tnl_pipeline_stage *stage) { + r300ContextPtr rmesa = R300_CONTEXT(ctx); + if (RADEON_DEBUG & DEBUG_PRIMS) fprintf(stderr, "%s\n", __FUNCTION__); if (r300Fallback(ctx) >= R300_FALLBACK_RAST) return GL_TRUE; + if (!(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) + return GL_TRUE; + return r300RunRender(ctx, stage); } diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index e6163262743..088216c76ee 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -82,6 +82,8 @@ static void r300BlendColor(GLcontext * ctx, const GLfloat cf[4]) rmesa->hw.blend_color.cmd[1] = PACK_COLOR_8888(color[3], color[0], color[1], color[2]); + rmesa->hw.blend_color.cmd[2] = 0; + rmesa->hw.blend_color.cmd[3] = 0; } /** @@ -317,20 +319,34 @@ static void r300UpdateCulling(GLcontext * ctx) r300ContextPtr r300 = R300_CONTEXT(ctx); uint32_t val = 0; - R300_STATECHANGE(r300, cul); if (ctx->Polygon.CullFlag) { - if (ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) - val = R300_CULL_FRONT | R300_CULL_BACK; - else if (ctx->Polygon.CullFaceMode == GL_FRONT) + switch (ctx->Polygon.CullFaceMode) { + case GL_FRONT: val = R300_CULL_FRONT; - else + break; + case GL_BACK: val = R300_CULL_BACK; + break; + case GL_FRONT_AND_BACK: + val = R300_CULL_FRONT | R300_CULL_BACK; + break; + default: + break; + } + } - if (ctx->Polygon.FrontFace == GL_CW) - val |= R300_FRONT_FACE_CW; - else - val |= R300_FRONT_FACE_CCW; + switch (ctx->Polygon.FrontFace) { + case GL_CW: + val |= R300_FRONT_FACE_CW; + break; + case GL_CCW: + val |= R300_FRONT_FACE_CCW; + break; + default: + break; } + + R300_STATECHANGE(r300, cul); r300->hw.cul.cmd[R300_CUL_CULL] = val; } @@ -344,6 +360,20 @@ static void r300SetEarlyZState(GLcontext * ctx) r300ContextPtr r300 = R300_CONTEXT(ctx); R300_STATECHANGE(r300, zstencil_format); + switch (ctx->Visual.depthBits) { + case 16: + r300->hw.zstencil_format.cmd[1] = R300_DEPTH_FORMAT_16BIT_INT_Z; + break; + case 24: + r300->hw.zstencil_format.cmd[1] = R300_DEPTH_FORMAT_24BIT_INT_Z; + break; + default: + fprintf(stderr, "Error: Unsupported depth %d... exiting\n", ctx->Visual.depthBits); + _mesa_exit(-1); + } + + // r300->hw.zstencil_format.cmd[1] |= R300_DEPTH_FORMAT_UNK32; + if (ctx->Color.AlphaEnabled && ctx->Color.AlphaFunc != GL_ALWAYS) /* disable early Z */ r300->hw.zstencil_format.cmd[2] = R300_EARLY_Z_DISABLE; @@ -355,6 +385,9 @@ static void r300SetEarlyZState(GLcontext * ctx) /* disable early Z */ r300->hw.zstencil_format.cmd[2] = R300_EARLY_Z_DISABLE; } + + r300->hw.zstencil_format.cmd[3] = 0x00000003; + r300->hw.zstencil_format.cmd[4] = 0x00000000; } static void r300SetAlphaState(GLcontext * ctx) @@ -403,6 +436,7 @@ static void r300SetAlphaState(GLcontext * ctx) R300_STATECHANGE(r300, at); r300->hw.at.cmd[R300_AT_ALPHA_TEST] = pp_misc; + r300->hw.at.cmd[R300_AT_UNKNOWN] = 0; r300SetEarlyZState(ctx); } @@ -513,6 +547,9 @@ static void r300UpdatePolygonMode(GLcontext * ctx) R300_STATECHANGE(r300, polygon_mode); r300->hw.polygon_mode.cmd[1] = hw_mode; } + + r300->hw.polygon_mode.cmd[2] = 0x00000001; + r300->hw.polygon_mode.cmd[3] = 0x00000000; } /** @@ -696,8 +733,8 @@ static void r300Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param) static void r300PointSize(GLcontext * ctx, GLfloat size) { r300ContextPtr r300 = R300_CONTEXT(ctx); - - size = ctx->Point._Size; + /* same size limits for AA, non-AA points */ + size = CLAMP(size, ctx->Const.MinPointSize, ctx->Const.MaxPointSize); R300_STATECHANGE(r300, ps); r300->hw.ps.cmd[R300_PS_POINTSIZE] = @@ -712,10 +749,11 @@ static void r300LineWidth(GLcontext * ctx, GLfloat widthf) { r300ContextPtr r300 = R300_CONTEXT(ctx); - widthf = ctx->Line._Width; - + widthf = CLAMP(widthf, + ctx->Const.MinPointSize, + ctx->Const.MaxPointSize); R300_STATECHANGE(r300, lcntl); - r300->hw.lcntl.cmd[1] |= + r300->hw.lcntl.cmd[1] = R300_LINE_CNT_HO | R300_LINE_CNT_VE | (int)(widthf * 6.0); } @@ -762,6 +800,7 @@ static void r300ShadeModel(GLcontext * ctx, GLenum mode) r300ContextPtr rmesa = R300_CONTEXT(ctx); R300_STATECHANGE(rmesa, shade); + rmesa->hw.shade.cmd[1] = 0x00000002; switch (mode) { case GL_FLAT: rmesa->hw.shade.cmd[2] = R300_RE_SHADE_MODEL_FLAT; @@ -772,6 +811,8 @@ static void r300ShadeModel(GLcontext * ctx, GLenum mode) default: return; } + rmesa->hw.shade.cmd[3] = 0x00000000; + rmesa->hw.shade.cmd[4] = 0x00000000; } static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face, @@ -1477,9 +1518,7 @@ static void r300SetupRSUnit(GLcontext * ctx) if(_nc>_p->vpu.count)_p->vpu.count=_nc;\ }while(0) -void static inline setup_vertex_shader_fragment(r300ContextPtr r300, int dest, struct - r300_vertex_shader_fragment - *vsf) +static inline void r300SetupVertexProgramFragment(r300ContextPtr r300, int dest, struct r300_vertex_shader_fragment *vsf) { int i; @@ -1487,8 +1526,7 @@ void static inline setup_vertex_shader_fragment(r300ContextPtr r300, int dest, s return; if (vsf->length & 0x3) { - fprintf(stderr, - "VERTEX_SHADER_FRAGMENT must have length divisible by 4\n"); + fprintf(stderr, "VERTEX_SHADER_FRAGMENT must have length divisible by 4\n"); _mesa_exit(-1); } @@ -1496,147 +1534,101 @@ void static inline setup_vertex_shader_fragment(r300ContextPtr r300, int dest, s case 0: R300_STATECHANGE(r300, vpi); for (i = 0; i < vsf->length; i++) - r300->hw.vpi.cmd[R300_VPI_INSTR_0 + i + - 4 * (dest & 0xff)] = (vsf->body.d[i]); - bump_vpu_count(r300->hw.vpi.cmd, - vsf->length + 4 * (dest & 0xff)); + r300->hw.vpi.cmd[R300_VPI_INSTR_0 + i + 4 * (dest & 0xff)] = (vsf->body.d[i]); + bump_vpu_count(r300->hw.vpi.cmd, vsf->length + 4 * (dest & 0xff)); break; case 2: R300_STATECHANGE(r300, vpp); for (i = 0; i < vsf->length; i++) - r300->hw.vpp.cmd[R300_VPP_PARAM_0 + i + - 4 * (dest & 0xff)] = (vsf->body.d[i]); - bump_vpu_count(r300->hw.vpp.cmd, - vsf->length + 4 * (dest & 0xff)); + r300->hw.vpp.cmd[R300_VPP_PARAM_0 + i + 4 * (dest & 0xff)] = (vsf->body.d[i]); + bump_vpu_count(r300->hw.vpp.cmd, vsf->length + 4 * (dest & 0xff)); break; case 4: R300_STATECHANGE(r300, vps); for (i = 0; i < vsf->length; i++) - r300->hw.vps.cmd[1 + i + 4 * (dest & 0xff)] = - (vsf->body.d[i]); - bump_vpu_count(r300->hw.vps.cmd, - vsf->length + 4 * (dest & 0xff)); + r300->hw.vps.cmd[1 + i + 4 * (dest & 0xff)] = (vsf->body.d[i]); + bump_vpu_count(r300->hw.vps.cmd, vsf->length + 4 * (dest & 0xff)); break; default: - fprintf(stderr, - "%s:%s don't know how to handle dest %04x\n", - __FILE__, __FUNCTION__, dest); + fprintf(stderr, "%s:%s don't know how to handle dest %04x\n", __FILE__, __FUNCTION__, dest); _mesa_exit(-1); } } -/* just a skeleton for now.. */ - -/* Generate a vertex shader that simply transforms vertex and texture coordinates, - while leaving colors intact. Nothing fancy (like lights) - - If implementing lights make a copy first, so it is easy to switch between the two versions */ -static void r300GenerateSimpleVertexShader(r300ContextPtr r300) +static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa) { - int i; + struct r300_vertex_shader_state *prog = &(rmesa->state.vertex_shader); GLuint o_reg = 0; - - /* Allocate parameters */ - r300->state.vap_param.transform_offset = 0x0; /* transform matrix */ - r300->state.vertex_shader.param_offset = 0x0; - r300->state.vertex_shader.param_count = 0x4; /* 4 vector values - 4x4 matrix */ - - r300->state.vertex_shader.program_start = 0x0; - r300->state.vertex_shader.unknown_ptr1 = 0x4; /* magic value ? */ - r300->state.vertex_shader.program_end = 0x0; - - r300->state.vertex_shader.unknown_ptr2 = 0x0; /* magic value */ - r300->state.vertex_shader.unknown_ptr3 = 0x4; /* magic value */ - - r300->state.vertex_shader.unknown1.length = 0; - r300->state.vertex_shader.unknown2.length = 0; - -#define WRITE_OP(oper,source1,source2,source3) {\ - r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].op=(oper); \ - r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src[0]=(source1); \ - r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src[1]=(source2); \ - r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src[2]=(source3); \ - r300->state.vertex_shader.program_end++; \ - } - - for (i = VERT_ATTRIB_POS; i < VERT_ATTRIB_MAX; i++) - if (r300->state.sw_tcl_inputs[i] != -1) { - WRITE_OP(EASY_VSF_OP(MUL, o_reg++, ALL, RESULT), - VSF_REG(r300->state.sw_tcl_inputs[i]), - VSF_ATTR_UNITY(r300->state. - sw_tcl_inputs[i]), - VSF_UNITY(r300->state.sw_tcl_inputs[i]) - ) - + int i; + int inst_count = 0; + int param_count = 0; + int program_end = 0; + + for (i = VERT_ATTRIB_POS; i < VERT_ATTRIB_MAX; i++) { + if (rmesa->state.sw_tcl_inputs[i] != -1) { + prog->program.body.i[program_end + 0] = EASY_VSF_OP(MUL, o_reg++, ALL, RESULT); + prog->program.body.i[program_end + 1] = VSF_REG(rmesa->state.sw_tcl_inputs[i]); + prog->program.body.i[program_end + 2] = VSF_ATTR_UNITY(rmesa->state.sw_tcl_inputs[i]); + prog->program.body.i[program_end + 3] = VSF_UNITY(rmesa->state.sw_tcl_inputs[i]); + program_end += 4; } + } - r300->state.vertex_shader.program_end--; /* r300 wants program length to be one more - no idea why */ - r300->state.vertex_shader.program.length = - (r300->state.vertex_shader.program_end + 1) * 4; + prog->program.length = program_end; - r300->state.vertex_shader.unknown_ptr1 = r300->state.vertex_shader.program_end; /* magic value ? */ - r300->state.vertex_shader.unknown_ptr2 = r300->state.vertex_shader.program_end; /* magic value ? */ - r300->state.vertex_shader.unknown_ptr3 = r300->state.vertex_shader.program_end; /* magic value ? */ + r300SetupVertexProgramFragment(rmesa, R300_PVS_UPLOAD_PROGRAM, + &(prog->program)); + inst_count = (prog->program.length / 4) - 1; + R300_STATECHANGE(rmesa, pvs); + rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] = + (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) | + (inst_count << R300_PVS_CNTL_1_POS_END_SHIFT) | + (inst_count << R300_PVS_CNTL_1_PROGRAM_END_SHIFT); + rmesa->hw.pvs.cmd[R300_PVS_CNTL_2] = + (0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT) | + (param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT); + rmesa->hw.pvs.cmd[R300_PVS_CNTL_3] = + (inst_count << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT) | + (inst_count << R300_PVS_CNTL_3_PROGRAM_UNKNOWN2_SHIFT); } -static void r300SetupVertexProgram(r300ContextPtr rmesa) +static void r300SetupRealVertexProgram(r300ContextPtr rmesa) { GLcontext *ctx = rmesa->radeon.glCtx; - int inst_count; - int param_count; - struct r300_vertex_program *prog = - (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx); + struct r300_vertex_program *prog = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx); + int inst_count = 0; + int param_count = 0; - ((drm_r300_cmd_header_t *) rmesa->hw.vpp.cmd)->vpu.count = 0; + /* FIXME: r300SetupVertexProgramFragment */ R300_STATECHANGE(rmesa, vpp); param_count = - r300VertexProgUpdateParams(ctx, (struct r300_vertex_program_cont *) - ctx->VertexProgram._Current /*prog */ , + r300VertexProgUpdateParams(ctx, + (struct r300_vertex_program_cont *) + ctx->VertexProgram._Current, (float *)&rmesa->hw.vpp. cmd[R300_VPP_PARAM_0]); bump_vpu_count(rmesa->hw.vpp.cmd, param_count); param_count /= 4; - /* Reset state, in case we don't use something */ - ((drm_r300_cmd_header_t *) rmesa->hw.vpi.cmd)->vpu.count = 0; - ((drm_r300_cmd_header_t *) rmesa->hw.vps.cmd)->vpu.count = 0; - - setup_vertex_shader_fragment(rmesa, VSF_DEST_PROGRAM, &(prog->program)); - -#if 0 - setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN1, - &(rmesa->state.vertex_shader.unknown1)); - setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN2, - &(rmesa->state.vertex_shader.unknown2)); -#endif - - inst_count = prog->program.length / 4 - 1; + r300SetupVertexProgramFragment(rmesa, R300_PVS_UPLOAD_PROGRAM, &(prog->program)); + inst_count = (prog->program.length / 4) - 1; R300_STATECHANGE(rmesa, pvs); rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] = - (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) - | (inst_count /*pos_end */ << R300_PVS_CNTL_1_POS_END_SHIFT) - | (inst_count << R300_PVS_CNTL_1_PROGRAM_END_SHIFT); + (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) | + (inst_count << R300_PVS_CNTL_1_POS_END_SHIFT) | + (inst_count << R300_PVS_CNTL_1_PROGRAM_END_SHIFT); rmesa->hw.pvs.cmd[R300_PVS_CNTL_2] = - (0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT) - | (param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT); + (0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT) | + (param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT); rmesa->hw.pvs.cmd[R300_PVS_CNTL_3] = - (0 /*rmesa->state.vertex_shader.unknown_ptr2 */ << - R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT) - | (inst_count /*rmesa->state.vertex_shader.unknown_ptr3 */ << - 0); - - /* This is done for vertex shader fragments, but also needs to be done for vap_pvs, - so I leave it as a reminder */ -#if 0 - reg_start(R300_VAP_PVS_WAITIDLE, 0); - e32(0x00000000); -#endif + (inst_count << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT) | + (inst_count << R300_PVS_CNTL_3_PROGRAM_UNKNOWN2_SHIFT); } -static void r300SetupVertexShader(r300ContextPtr rmesa) +static void r300SetupVertexProgram(r300ContextPtr rmesa) { GLcontext *ctx = rmesa->radeon.glCtx; @@ -1649,46 +1641,16 @@ static void r300SetupVertexShader(r300ContextPtr rmesa) 0x400 area might have something to do with pixel shaders as it appears right after pfs programming. 0x406 is set to { 0.0, 0.0, 1.0, 0.0 } most of the time but should change with smooth points and in other rare cases. */ //setup_vertex_shader_fragment(rmesa, 0x406, &unk4); - if (hw_tcl_on - && ((struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx))-> - translated) { - r300SetupVertexProgram(rmesa); - return; + if (hw_tcl_on && ((struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx))->translated) { + r300SetupRealVertexProgram(rmesa); + } else { + /* FIXME: This needs to be replaced by vertex shader generation code. */ + r300SetupDefaultVertexProgram(rmesa); } - /* This needs to be replaced by vertex shader generation code */ - r300GenerateSimpleVertexShader(rmesa); - - setup_vertex_shader_fragment(rmesa, VSF_DEST_PROGRAM, - &(rmesa->state.vertex_shader.program)); -#if 0 - setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN1, - &(rmesa->state.vertex_shader.unknown1)); - setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN2, - &(rmesa->state.vertex_shader.unknown2)); -#endif - - R300_STATECHANGE(rmesa, pvs); - rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] = - (rmesa->state.vertex_shader. - program_start << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) - | (rmesa->state.vertex_shader. - unknown_ptr1 << R300_PVS_CNTL_1_POS_END_SHIFT) - | (rmesa->state.vertex_shader. - program_end << R300_PVS_CNTL_1_PROGRAM_END_SHIFT); - rmesa->hw.pvs.cmd[R300_PVS_CNTL_2] = - (rmesa->state.vertex_shader. - param_offset << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT) - | (rmesa->state.vertex_shader. - param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT); - rmesa->hw.pvs.cmd[R300_PVS_CNTL_3] = - (rmesa->state.vertex_shader. - unknown_ptr2 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT) - | (rmesa->state.vertex_shader.unknown_ptr3 << 0); - - /* This is done for vertex shader fragments, but also needs to be done for vap_pvs, - so I leave it as a reminder */ + /* FIXME: This is done for vertex shader fragments, but also needs to be + * done for vap_pvs, so I leave it as a reminder. */ #if 0 reg_start(R300_VAP_PVS_WAITIDLE, 0); e32(0x00000000); @@ -1769,8 +1731,6 @@ static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state) case GL_POLYGON_OFFSET_POINT: case GL_POLYGON_OFFSET_LINE: - break; - case GL_POLYGON_OFFSET_FILL: R300_STATECHANGE(r300, occlusion_cntl); if (state) { @@ -1864,13 +1824,15 @@ static void r300ResetHwState(r300ContextPtr r300) r300->hw.vap_clip.cmd[4] = r300PackFloat32(1.0); /* Y */ /* XXX: Other families? */ - switch (r300->radeon.radeonScreen->chip_family) { - case CHIP_FAMILY_R300: - r300->hw.unk2288.cmd[1] = R300_2288_R300; - break; - default: - r300->hw.unk2288.cmd[1] = R300_2288_RV350; - break; + if (has_tcl) { + switch (r300->radeon.radeonScreen->chip_family) { + case CHIP_FAMILY_R300: + r300->hw.unk2288.cmd[1] = R300_2288_R300; + break; + default: + r300->hw.unk2288.cmd[1] = R300_2288_RV350; + break; + } } r300->hw.gb_enable.cmd[1] = R300_GB_POINT_STUFF_ENABLE @@ -1928,19 +1890,16 @@ static void r300ResetHwState(r300ContextPtr r300) r300->hw.unk4260.cmd[2] = r300PackFloat32(0.0); r300->hw.unk4260.cmd[3] = r300PackFloat32(1.0); - r300->hw.shade.cmd[1] = 0x00000002; r300ShadeModel(ctx, ctx->Light.ShadeModel); - r300->hw.shade.cmd[3] = 0x00000000; - r300->hw.shade.cmd[4] = 0x00000000; r300PolygonMode(ctx, GL_FRONT, ctx->Polygon.FrontMode); r300PolygonMode(ctx, GL_BACK, ctx->Polygon.BackMode); - r300->hw.polygon_mode.cmd[2] = 0x00000001; - r300->hw.polygon_mode.cmd[3] = 0x00000000; r300->hw.zbias_cntl.cmd[1] = 0x00000000; r300PolygonOffset(ctx, ctx->Polygon.OffsetFactor, ctx->Polygon.OffsetUnits); + r300Enable(ctx, GL_POLYGON_OFFSET_POINT, ctx->Polygon.OffsetPoint); + r300Enable(ctx, GL_POLYGON_OFFSET_LINE, ctx->Polygon.OffsetLine); r300Enable(ctx, GL_POLYGON_OFFSET_FILL, ctx->Polygon.OffsetFill); r300->hw.unk42C0.cmd[1] = 0x4B7FFFFF; @@ -1965,14 +1924,11 @@ static void r300ResetHwState(r300ContextPtr r300) r300Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color); r300Fogfv(ctx, GL_FOG_COORDINATE_SOURCE_EXT, NULL); - r300->hw.at.cmd[R300_AT_UNKNOWN] = 0; r300->hw.unk4BD8.cmd[1] = 0; r300->hw.unk4E00.cmd[1] = 0; r300BlendColor(ctx, ctx->Color.BlendColor); - r300->hw.blend_color.cmd[2] = 0; - r300->hw.blend_color.cmd[3] = 0; /* Again, r300ClearBuffer uses this */ r300->hw.cb.cmd[R300_CB_OFFSET] = @@ -2003,25 +1959,6 @@ static void r300ResetHwState(r300ContextPtr r300) r300->hw.unk4EA0.cmd[1] = 0x00000000; r300->hw.unk4EA0.cmd[2] = 0xffffffff; - switch (ctx->Visual.depthBits) { - case 16: - r300->hw.zstencil_format.cmd[1] = R300_DEPTH_FORMAT_16BIT_INT_Z; - break; - case 24: - r300->hw.zstencil_format.cmd[1] = R300_DEPTH_FORMAT_24BIT_INT_Z; - break; - default: - fprintf(stderr, "Error: Unsupported depth %d... exiting\n", - ctx->Visual.depthBits); - _mesa_exit(-1); - - } - /* z compress? */ - //r300->hw.zstencil_format.cmd[1] |= R300_DEPTH_FORMAT_UNK32; - - r300->hw.zstencil_format.cmd[3] = 0x00000003; - r300->hw.zstencil_format.cmd[4] = 0x00000000; - r300->hw.zb.cmd[R300_ZB_OFFSET] = r300->radeon.radeonScreen->depthOffset + r300->radeon.radeonScreen->fbLocation; @@ -2094,7 +2031,6 @@ void r300UpdateShaders(r300ContextPtr rmesa) } r300UpdateStateParameters(ctx, _NEW_PROGRAM); } - } static void r300SetupPixelShader(r300ContextPtr rmesa) @@ -2113,62 +2049,61 @@ static void r300SetupPixelShader(r300ContextPtr rmesa) __FUNCTION__); return; } -#define OUTPUT_FIELD(st, reg, field) \ - R300_STATECHANGE(rmesa, st); \ - for(i=0;i<=fp->alu_end;i++) \ - rmesa->hw.st.cmd[R300_FPI_INSTR_0+i]=fp->alu.inst[i].field;\ - rmesa->hw.st.cmd[R300_FPI_CMD_0]=cmdpacket0(reg, fp->alu_end+1); - OUTPUT_FIELD(fpi[0], R300_PFS_INSTR0_0, inst0); - OUTPUT_FIELD(fpi[1], R300_PFS_INSTR1_0, inst1); - OUTPUT_FIELD(fpi[2], R300_PFS_INSTR2_0, inst2); - OUTPUT_FIELD(fpi[3], R300_PFS_INSTR3_0, inst3); -#undef OUTPUT_FIELD + R300_STATECHANGE(rmesa, fpi[0]); + rmesa->hw.fpi[0].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_PFS_INSTR0_0, fp->alu_end + 1); + for (i = 0; i <= fp->alu_end; i++) { + rmesa->hw.fpi[0].cmd[R300_FPI_INSTR_0 + i] = fp->alu.inst[i].inst0; + } + + R300_STATECHANGE(rmesa, fpi[1]); + rmesa->hw.fpi[1].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_PFS_INSTR1_0, fp->alu_end + 1); + for (i = 0; i <= fp->alu_end; i++) { + rmesa->hw.fpi[1].cmd[R300_FPI_INSTR_0 + i] = fp->alu.inst[i].inst1; + } + + R300_STATECHANGE(rmesa, fpi[2]); + rmesa->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_PFS_INSTR2_0, fp->alu_end + 1); + for (i = 0; i <= fp->alu_end; i++) { + rmesa->hw.fpi[2].cmd[R300_FPI_INSTR_0 + i] = fp->alu.inst[i].inst2; + } + + R300_STATECHANGE(rmesa, fpi[3]); + rmesa->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_PFS_INSTR3_0, fp->alu_end + 1); + for (i = 0; i <= fp->alu_end; i++) { + rmesa->hw.fpi[3].cmd[R300_FPI_INSTR_0 + i] = fp->alu.inst[i].inst3; + } R300_STATECHANGE(rmesa, fp); + rmesa->hw.fp.cmd[R300_FP_CNTL0] = fp->cur_node | (fp->first_node_has_tex << 3); + rmesa->hw.fp.cmd[R300_FP_CNTL1] = fp->max_temp_idx; + rmesa->hw.fp.cmd[R300_FP_CNTL2] = + (fp->alu_offset << R300_PFS_CNTL_ALU_OFFSET_SHIFT) | + (fp->alu_end << R300_PFS_CNTL_ALU_END_SHIFT) | + (fp->tex_offset << R300_PFS_CNTL_TEX_OFFSET_SHIFT) | + (fp->tex_end << R300_PFS_CNTL_TEX_END_SHIFT); /* I just want to say, the way these nodes are stored.. weird.. */ for (i = 0, k = (4 - (fp->cur_node + 1)); i < 4; i++, k++) { if (i < (fp->cur_node + 1)) { rmesa->hw.fp.cmd[R300_FP_NODE0 + k] = - (fp->node[i]. - alu_offset << R300_PFS_NODE_ALU_OFFSET_SHIFT) - | (fp->node[i]. - alu_end << R300_PFS_NODE_ALU_END_SHIFT) - | (fp->node[i]. - tex_offset << R300_PFS_NODE_TEX_OFFSET_SHIFT) - | (fp->node[i]. - tex_end << R300_PFS_NODE_TEX_END_SHIFT) - | fp->node[i].flags; + (fp->node[i].alu_offset << R300_PFS_NODE_ALU_OFFSET_SHIFT) | + (fp->node[i].alu_end << R300_PFS_NODE_ALU_END_SHIFT) | + (fp->node[i].tex_offset << R300_PFS_NODE_TEX_OFFSET_SHIFT) | + (fp->node[i].tex_end << R300_PFS_NODE_TEX_END_SHIFT) | + fp->node[i].flags; } else { rmesa->hw.fp.cmd[R300_FP_NODE0 + (3 - i)] = 0; } } - /* PFS_CNTL_0 */ - rmesa->hw.fp.cmd[R300_FP_CNTL0] = - fp->cur_node | (fp->first_node_has_tex << 3); - /* PFS_CNTL_1 */ - rmesa->hw.fp.cmd[R300_FP_CNTL1] = fp->max_temp_idx; - /* PFS_CNTL_2 */ - rmesa->hw.fp.cmd[R300_FP_CNTL2] = - (fp->alu_offset << R300_PFS_CNTL_ALU_OFFSET_SHIFT) - | (fp->alu_end << R300_PFS_CNTL_ALU_END_SHIFT) - | (fp->tex_offset << R300_PFS_CNTL_TEX_OFFSET_SHIFT) - | (fp->tex_end << R300_PFS_CNTL_TEX_END_SHIFT); - R300_STATECHANGE(rmesa, fpp); + rmesa->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(R300_PFS_PARAM_0_X, fp->const_nr * 4); for (i = 0; i < fp->const_nr; i++) { - rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 0] = - r300PackFloat24(fp->constant[i][0]); - rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 1] = - r300PackFloat24(fp->constant[i][1]); - rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 2] = - r300PackFloat24(fp->constant[i][2]); - rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 3] = - r300PackFloat24(fp->constant[i][3]); - } - rmesa->hw.fpp.cmd[R300_FPP_CMD_0] = - cmdpacket0(R300_PFS_PARAM_0_X, fp->const_nr * 4); + rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 0] = r300PackFloat24(fp->constant[i][0]); + rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 1] = r300PackFloat24(fp->constant[i][1]); + rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 2] = r300PackFloat24(fp->constant[i][2]); + rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 3] = r300PackFloat24(fp->constant[i][3]); + } } void r300UpdateShaderStates(r300ContextPtr rmesa) @@ -2182,7 +2117,7 @@ void r300UpdateShaderStates(r300ContextPtr rmesa) r300SetupTextures(ctx); if ((rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) - r300SetupVertexShader(rmesa); + r300SetupVertexProgram(rmesa); r300SetupRSUnit(ctx); } diff --git a/src/mesa/drivers/dri/r300/r300_state.h b/src/mesa/drivers/dri/r300/r300_state.h index 21a49b7f361..365f7ecd0c6 100644 --- a/src/mesa/drivers/dri/r300/r300_state.h +++ b/src/mesa/drivers/dri/r300/r300_state.h @@ -37,8 +37,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_context.h" +#define R300_NEWPRIM( rmesa ) \ + do { \ + if ( rmesa->dma.flush ) \ + rmesa->dma.flush( rmesa ); \ + } while (0) + #define R300_STATECHANGE(r300, atom) \ do { \ + R300_NEWPRIM(r300); \ r300->hw.atom.dirty = GL_TRUE; \ r300->hw.is_dirty = GL_TRUE; \ } while(0) diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.c b/src/mesa/drivers/dri/r300/r300_swtcl.c new file mode 100644 index 00000000000..c949f33bf33 --- /dev/null +++ b/src/mesa/drivers/dri/r300/r300_swtcl.c @@ -0,0 +1,711 @@ +/************************************************************************** + +Copyright (C) 2007 Dave Airlie + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Dave Airlie <[email protected]> + */ + +/* derived from r200 swtcl path */ + + + +#include "glheader.h" +#include "mtypes.h" +#include "colormac.h" +#include "enums.h" +#include "image.h" +#include "imports.h" +#include "macros.h" + +#include "swrast/s_context.h" +#include "swrast/s_fog.h" +#include "swrast_setup/swrast_setup.h" +#include "math/m_translate.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +#include "r300_context.h" +#include "r300_swtcl.h" +#include "r300_state.h" +#include "r300_ioctl.h" +#include "r300_emit.h" +#include "r300_mem.h" + +static void flush_last_swtcl_prim( r300ContextPtr rmesa ); + + +void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, GLuint offset); +void r300EmitVbufPrim(r300ContextPtr rmesa, GLuint primitive, GLuint vertex_nr); +#define EMIT_ATTR( ATTR, STYLE ) \ +do { \ + rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].attrib = (ATTR); \ + rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].format = (STYLE); \ + rmesa->swtcl.vertex_attr_count++; \ +} while (0) + +#define EMIT_PAD( N ) \ +do { \ + rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].attrib = 0; \ + rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].format = EMIT_PAD; \ + rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].offset = (N); \ + rmesa->swtcl.vertex_attr_count++; \ +} while (0) + +/* this differs from the VIR0 in emit.c - TODO merge them using another option */ +static GLuint r300VAPInputRoute0(uint32_t * dst, GLvector4f ** attribptr, + int *inputs, GLint * tab, GLuint nr) +{ + GLuint i, dw; + + /* type, inputs, stop bit, size */ + for (i = 0; i + 1 < nr; i += 2) { + dw = (inputs[tab[i]] << 8) | 0x3; + dw |= ((inputs[tab[i + 1]] << 8) | 0x3) << 16; + if (i + 2 == nr) { + dw |= (R300_VAP_INPUT_ROUTE_END << 16); + } + dst[i >> 1] = dw; + } + + if (nr & 1) { + dw = (inputs[tab[nr - 1]] << 8) | 0x3; + dw |= R300_VAP_INPUT_ROUTE_END; + dst[nr >> 1] = dw; + } + + return (nr + 1) >> 1; +} + +static void r300SetVertexFormat( GLcontext *ctx ) +{ + r300ContextPtr rmesa = R300_CONTEXT( ctx ); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + DECLARE_RENDERINPUTS(index_bitset); + GLuint InputsRead = 0, OutputsWritten = 0; + int vap_fmt_0 = 0; + int vap_vte_cntl = 0; + int offset = 0; + int vte = 0; + GLint inputs[VERT_ATTRIB_MAX]; + GLint tab[VERT_ATTRIB_MAX]; + int swizzle[VERT_ATTRIB_MAX][4]; + GLuint i, nr; + + DECLARE_RENDERINPUTS(render_inputs_bitset); + RENDERINPUTS_COPY(render_inputs_bitset, tnl->render_inputs_bitset); + RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset ); + RENDERINPUTS_COPY(rmesa->state.render_inputs_bitset, render_inputs_bitset); + + /* Important: + */ + if ( VB->NdcPtr != NULL ) { + VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; + } + else { + VB->AttribPtr[VERT_ATTRIB_POS] = VB->ClipPtr; + } + + assert( VB->AttribPtr[VERT_ATTRIB_POS] != NULL ); + rmesa->swtcl.vertex_attr_count = 0; + + /* EMIT_ATTR's must be in order as they tell t_vertex.c how to + * build up a hardware vertex. + */ + if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POS)) { + vap_vte_cntl |= R300_VTX_W0_FMT; + InputsRead |= 1 << VERT_ATTRIB_POS; + OutputsWritten |= 1 << VERT_RESULT_HPOS; + EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F ); + } else + EMIT_PAD(4 * sizeof(float)); + + offset = 4; + + if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POINTSIZE )) { + EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F ); + vap_fmt_0 |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT; + offset += 1; + } + + if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_COLOR0)) { + rmesa->swtcl.coloroffset = offset; + InputsRead |= 1 << VERT_ATTRIB_COLOR0; + OutputsWritten |= 1 << VERT_RESULT_COL0; + EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4F ); + } + + offset += 4; + + rmesa->swtcl.specoffset = 0; + if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) { + rmesa->swtcl.specoffset = offset; + EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4F ); + InputsRead |= 1 << VERT_ATTRIB_COLOR1; + OutputsWritten |= 1 << VERT_RESULT_COL1; + } + + if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) { + int i; + + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { + if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) { + InputsRead |= 1 << (VERT_ATTRIB_TEX0 + i); + OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i); + EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_4F ); + } + } + } + + for (i = 0, nr = 0; i < VERT_ATTRIB_MAX; i++) { + if (InputsRead & (1 << i)) { + inputs[i] = nr++; + } else { + inputs[i] = -1; + } + } + + /* Fixed, apply to vir0 only */ + if (InputsRead & (1 << VERT_ATTRIB_POS)) + inputs[VERT_ATTRIB_POS] = 0; + if (InputsRead & (1 << VERT_ATTRIB_COLOR0)) + inputs[VERT_ATTRIB_COLOR0] = 2; + if (InputsRead & (1 << VERT_ATTRIB_COLOR1)) + inputs[VERT_ATTRIB_COLOR1] = 3; + for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX7; i++) + if (InputsRead & (1 << i)) + inputs[i] = 6 + (i - VERT_ATTRIB_TEX0); + + for (i = 0, nr = 0; i < VERT_ATTRIB_MAX; i++) { + if (InputsRead & (1 << i)) { + tab[nr++] = i; + } + } + + for (i = 0; i < nr; i++) { + int ci; + + swizzle[i][0] = SWIZZLE_ZERO; + swizzle[i][1] = SWIZZLE_ZERO; + swizzle[i][2] = SWIZZLE_ZERO; + swizzle[i][3] = SWIZZLE_ONE; + + for (ci = 0; ci < VB->AttribPtr[tab[i]]->size; ci++) { + swizzle[i][ci] = ci; + } + } + + R300_NEWPRIM(rmesa); + R300_STATECHANGE(rmesa, vir[0]); + ((drm_r300_cmd_header_t *) rmesa->hw.vir[0].cmd)->packet0.count = + r300VAPInputRoute0(&rmesa->hw.vir[0].cmd[R300_VIR_CNTL_0], + VB->AttribPtr, inputs, tab, nr); + R300_STATECHANGE(rmesa, vir[1]); + ((drm_r300_cmd_header_t *) rmesa->hw.vir[1].cmd)->packet0.count = + r300VAPInputRoute1(&rmesa->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle, + nr); + + R300_STATECHANGE(rmesa, vic); + rmesa->hw.vic.cmd[R300_VIC_CNTL_0] = r300VAPInputCntl0(ctx, InputsRead); + rmesa->hw.vic.cmd[R300_VIC_CNTL_1] = r300VAPInputCntl1(ctx, InputsRead); + + R300_STATECHANGE(rmesa, vof); + rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = r300VAPOutputCntl0(ctx, OutputsWritten); + rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = r300VAPOutputCntl1(ctx, OutputsWritten); + + rmesa->swtcl.vertex_size = + _tnl_install_attrs( ctx, + rmesa->swtcl.vertex_attrs, + rmesa->swtcl.vertex_attr_count, + NULL, 0 ); + + rmesa->swtcl.vertex_size /= 4; + + RENDERINPUTS_COPY( rmesa->tnl_index_bitset, index_bitset ); + + vte = rmesa->hw.vte.cmd[1]; + R300_STATECHANGE(rmesa, vte); + rmesa->hw.vte.cmd[1] = vte; + rmesa->hw.vte.cmd[2] = rmesa->swtcl.vertex_size; +} + + +/* Flush vertices in the current dma region. + */ +static void flush_last_swtcl_prim( r300ContextPtr rmesa ) +{ + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s\n", __FUNCTION__); + + rmesa->dma.flush = NULL; + + if (rmesa->dma.current.buf) { + struct r300_dma_region *current = &rmesa->dma.current; + GLuint current_offset = GET_START(current); + + assert (current->start + + rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == + current->ptr); + + if (rmesa->dma.current.start != rmesa->dma.current.ptr) { + + r300EnsureCmdBufSpace( rmesa, rmesa->hw.max_state_size + (12*sizeof(int)), __FUNCTION__); + + r300EmitState(rmesa); + + r300EmitVertexAOS( rmesa, + rmesa->swtcl.vertex_size, + current_offset); + + r300EmitVbufPrim( rmesa, + rmesa->swtcl.hw_primitive, + rmesa->swtcl.numverts); + + r300EmitCacheFlush(rmesa); + } + + rmesa->swtcl.numverts = 0; + current->start = current->ptr; + } +} + +/* Alloc space in the current dma region. + */ +static void * +r300AllocDmaLowVerts( r300ContextPtr rmesa, int nverts, int vsize ) +{ + GLuint bytes = vsize * nverts; + + if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end ) + r300RefillCurrentDmaRegion( rmesa, bytes); + + if (!rmesa->dma.flush) { + rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; + rmesa->dma.flush = flush_last_swtcl_prim; + } + + ASSERT( vsize == rmesa->swtcl.vertex_size * 4 ); + ASSERT( rmesa->dma.flush == flush_last_swtcl_prim ); + ASSERT( rmesa->dma.current.start + + rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == + rmesa->dma.current.ptr ); + + { + GLubyte *head = (GLubyte *) (rmesa->dma.current.address + rmesa->dma.current.ptr); + rmesa->dma.current.ptr += bytes; + rmesa->swtcl.numverts += nverts; + return head; + } +} + +static GLuint reduced_prim[] = { + GL_POINTS, + GL_LINES, + GL_LINES, + GL_LINES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, +}; + +static void r300RasterPrimitive( GLcontext *ctx, GLuint prim ); +static void r300RenderPrimitive( GLcontext *ctx, GLenum prim ); +//static void r300ResetLineStipple( GLcontext *ctx ); + +/*********************************************************************** + * Emit primitives as inline vertices * + ***********************************************************************/ + + +#define HAVE_POINTS 1 +#define HAVE_LINES 1 +#define HAVE_LINE_STRIPS 1 +#define HAVE_TRIANGLES 1 +#define HAVE_TRI_STRIPS 1 +#define HAVE_TRI_STRIP_1 0 +#define HAVE_TRI_FANS 1 +#define HAVE_QUADS 0 +#define HAVE_QUAD_STRIPS 0 +#define HAVE_POLYGONS 1 +#define HAVE_ELTS 1 + +#undef LOCAL_VARS +#undef ALLOC_VERTS +#define CTX_ARG r300ContextPtr rmesa +#define GET_VERTEX_DWORDS() rmesa->swtcl.vertex_size +#define ALLOC_VERTS( n, size ) r300AllocDmaLowVerts( rmesa, n, size * 4 ) +#define LOCAL_VARS \ + r300ContextPtr rmesa = R300_CONTEXT(ctx); \ + const char *r300verts = (char *)rmesa->swtcl.verts; +#define VERT(x) (r300Vertex *)(r300verts + ((x) * vertsize * sizeof(int))) +#define VERTEX r300Vertex +#define DO_DEBUG_VERTS (1 && (RADEON_DEBUG & DEBUG_VERTS)) +#define PRINT_VERTEX(x) +#undef TAG +#define TAG(x) r300_##x +#include "tnl_dd/t_dd_triemit.h" + + + +/*********************************************************************** + * Macros for t_dd_tritmp.h to draw basic primitives * + ***********************************************************************/ + +#define QUAD( a, b, c, d ) r300_quad( rmesa, a, b, c, d ) +#define TRI( a, b, c ) r300_triangle( rmesa, a, b, c ) +#define LINE( a, b ) r300_line( rmesa, a, b ) +#define POINT( a ) r300_point( rmesa, a ) + +/*********************************************************************** + * Build render functions from dd templates * + ***********************************************************************/ + +#define R300_TWOSIDE_BIT 0x01 +#define R300_UNFILLED_BIT 0x02 +#define R300_MAX_TRIFUNC 0x04 + +static struct { + tnl_points_func points; + tnl_line_func line; + tnl_triangle_func triangle; + tnl_quad_func quad; +} rast_tab[R300_MAX_TRIFUNC]; + +#define DO_FALLBACK 0 +#define DO_UNFILLED (IND & R300_UNFILLED_BIT) +#define DO_TWOSIDE (IND & R300_TWOSIDE_BIT) +#define DO_FLAT 0 +#define DO_OFFSET 0 +#define DO_TRI 1 +#define DO_QUAD 1 +#define DO_LINE 1 +#define DO_POINTS 1 +#define DO_FULL_QUAD 1 + +#define HAVE_RGBA 1 +#define HAVE_SPEC 1 +#define HAVE_BACK_COLORS 0 +#define HAVE_HW_FLATSHADE 1 +#define TAB rast_tab + +#define DEPTH_SCALE 1.0 +#define UNFILLED_TRI unfilled_tri +#define UNFILLED_QUAD unfilled_quad +#define VERT_X(_v) _v->v.x +#define VERT_Y(_v) _v->v.y +#define VERT_Z(_v) _v->v.z +#define AREA_IS_CCW( a ) (a < 0) +#define GET_VERTEX(e) (rmesa->swtcl.verts + (e*rmesa->swtcl.vertex_size*sizeof(int))) + +/* Only used to pull back colors into vertices (ie, we know color is + * floating point). + */ +#define R300_COLOR( dst, src ) \ +do { \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[3], (src)[3]); \ +} while (0) + +#define VERT_SET_RGBA( v, c ) if (coloroffset) R300_COLOR( v->ub4[coloroffset], c ) +#define VERT_COPY_RGBA( v0, v1 ) if (coloroffset) v0->ui[coloroffset] = v1->ui[coloroffset] +#define VERT_SAVE_RGBA( idx ) if (coloroffset) color[idx] = v[idx]->ui[coloroffset] +#define VERT_RESTORE_RGBA( idx ) if (coloroffset) v[idx]->ui[coloroffset] = color[idx] + +#define R300_SPEC( dst, src ) \ +do { \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \ +} while (0) + +#define VERT_SET_SPEC( v, c ) if (specoffset) R300_SPEC( v->ub4[specoffset], c ) +#define VERT_COPY_SPEC( v0, v1 ) if (specoffset) COPY_3V(v0->ub4[specoffset], v1->ub4[specoffset]) +#define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->ui[specoffset] +#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx] + +#undef LOCAL_VARS +#undef TAG +#undef INIT + +#define LOCAL_VARS(n) \ + r300ContextPtr rmesa = R300_CONTEXT(ctx); \ + GLuint color[n], spec[n]; \ + GLuint coloroffset = rmesa->swtcl.coloroffset; \ + GLuint specoffset = rmesa->swtcl.specoffset; \ + (void) color; (void) spec; (void) coloroffset; (void) specoffset; + +/*********************************************************************** + * Helpers for rendering unfilled primitives * + ***********************************************************************/ + +#define RASTERIZE(x) r300RasterPrimitive( ctx, reduced_prim[x] ) +#define RENDER_PRIMITIVE rmesa->swtcl.render_primitive +#undef TAG +#define TAG(x) x +#include "tnl_dd/t_dd_unfilled.h" +#undef IND + + +/*********************************************************************** + * Generate GL render functions * + ***********************************************************************/ + + +#define IND (0) +#define TAG(x) x +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (R300_TWOSIDE_BIT) +#define TAG(x) x##_twoside +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (R300_UNFILLED_BIT) +#define TAG(x) x##_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (R300_TWOSIDE_BIT|R300_UNFILLED_BIT) +#define TAG(x) x##_twoside_unfilled +#include "tnl_dd/t_dd_tritmp.h" + + + +static void init_rast_tab( void ) +{ + init(); + init_twoside(); + init_unfilled(); + init_twoside_unfilled(); +} + +/**********************************************************************/ +/* Render unclipped begin/end objects */ +/**********************************************************************/ + +#define RENDER_POINTS( start, count ) \ + for ( ; start < count ; start++) \ + r300_point( rmesa, VERT(start) ) +#define RENDER_LINE( v0, v1 ) \ + r300_line( rmesa, VERT(v0), VERT(v1) ) +#define RENDER_TRI( v0, v1, v2 ) \ + r300_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) ) +#define RENDER_QUAD( v0, v1, v2, v3 ) \ + r300_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) ) +#define INIT(x) do { \ + r300RenderPrimitive( ctx, x ); \ +} while (0) +#undef LOCAL_VARS +#define LOCAL_VARS \ + r300ContextPtr rmesa = R300_CONTEXT(ctx); \ + const GLuint vertsize = rmesa->swtcl.vertex_size; \ + const char *r300verts = (char *)rmesa->swtcl.verts; \ + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ + const GLboolean stipple = ctx->Line.StippleFlag; \ + (void) elt; (void) stipple; +#define RESET_STIPPLE //if ( stipple ) r200ResetLineStipple( ctx ); +#define RESET_OCCLUSION +#define PRESERVE_VB_DEFS +#define ELT(x) (x) +#define TAG(x) r300_##x##_verts +#include "tnl/t_vb_rendertmp.h" +#undef ELT +#undef TAG +#define TAG(x) r300_##x##_elts +#define ELT(x) elt[x] +#include "tnl/t_vb_rendertmp.h" + + + + +/**********************************************************************/ +/* Choose render functions */ +/**********************************************************************/ +static void r300ChooseRenderState( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + r300ContextPtr rmesa = R300_CONTEXT(ctx); + GLuint index = 0; + GLuint flags = ctx->_TriangleCaps; + + if (flags & DD_TRI_LIGHT_TWOSIDE) index |= R300_TWOSIDE_BIT; + if (flags & DD_TRI_UNFILLED) index |= R300_UNFILLED_BIT; + + if (index != rmesa->swtcl.RenderIndex) { + tnl->Driver.Render.Points = rast_tab[index].points; + tnl->Driver.Render.Line = rast_tab[index].line; + tnl->Driver.Render.ClippedLine = rast_tab[index].line; + tnl->Driver.Render.Triangle = rast_tab[index].triangle; + tnl->Driver.Render.Quad = rast_tab[index].quad; + + if (index == 0) { + tnl->Driver.Render.PrimTabVerts = r300_render_tab_verts; + tnl->Driver.Render.PrimTabElts = r300_render_tab_elts; + tnl->Driver.Render.ClippedPolygon = r300_fast_clipped_poly; + } else { + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + } + + rmesa->swtcl.RenderIndex = index; + } +} + + +static void r300RenderStart(GLcontext *ctx) +{ + r300ContextPtr rmesa = R300_CONTEXT( ctx ); + // fprintf(stderr, "%s\n", __FUNCTION__); + + r300ChooseRenderState(ctx); + r300SetVertexFormat(ctx); + + r300UpdateShaderStates(rmesa); + + r300EmitCacheFlush(rmesa); + + if (rmesa->dma.flush != 0 && + rmesa->dma.flush != flush_last_swtcl_prim) + rmesa->dma.flush( rmesa ); + +} + +static void r300RenderFinish(GLcontext *ctx) +{ +} + +static void r300RasterPrimitive( GLcontext *ctx, GLuint hwprim ) +{ + r300ContextPtr rmesa = R300_CONTEXT(ctx); + + if (rmesa->swtcl.hw_primitive != hwprim) { + R300_NEWPRIM( rmesa ); + rmesa->swtcl.hw_primitive = hwprim; + } +} + +static void r300RenderPrimitive(GLcontext *ctx, GLenum prim) +{ + + r300ContextPtr rmesa = R300_CONTEXT(ctx); + rmesa->swtcl.render_primitive = prim; + + if ((prim == GL_TRIANGLES) && (ctx->_TriangleCaps & DD_TRI_UNFILLED)) + return; + + r300RasterPrimitive( ctx, reduced_prim[prim] ); + // fprintf(stderr, "%s\n", __FUNCTION__); + +} + +static void r300ResetLineStipple(GLcontext *ctx) +{ + + +} + +void r300InitSwtcl(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + r300ContextPtr rmesa = R300_CONTEXT(ctx); + static int firsttime = 1; + + if (firsttime) { + init_rast_tab(); + firsttime = 0; + } + + tnl->Driver.Render.Start = r300RenderStart; + tnl->Driver.Render.Finish = r300RenderFinish; + tnl->Driver.Render.PrimitiveNotify = r300RenderPrimitive; + tnl->Driver.Render.ResetLineStipple = r300ResetLineStipple; + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.Interp = _tnl_interp; + + /* FIXME: what are these numbers? */ + _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, + 48 * sizeof(GLfloat) ); + + rmesa->swtcl.verts = (GLubyte *)tnl->clipspace.vertex_buf; + rmesa->swtcl.RenderIndex = ~0; + rmesa->swtcl.render_primitive = GL_TRIANGLES; + rmesa->swtcl.hw_primitive = 0; + + _tnl_invalidate_vertex_state( ctx, ~0 ); + _tnl_invalidate_vertices( ctx, ~0 ); + RENDERINPUTS_ZERO( rmesa->tnl_index_bitset ); + + _tnl_need_projected_coords( ctx, GL_FALSE ); + r300ChooseRenderState(ctx); + + _mesa_validate_all_lighting_tables( ctx ); + + tnl->Driver.NotifyMaterialChange = + _mesa_validate_all_lighting_tables; +} + +void r300DestroySwtcl(GLcontext *ctx) +{ +} + +void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, GLuint offset) +{ + int cmd_reserved = 0; + int cmd_written = 0; + + drm_radeon_cmd_header_t *cmd = NULL; + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s: vertex_size %d, offset 0x%x \n", + __FUNCTION__, vertex_size, offset); + + start_packet3(CP_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, 2), 2); + e32(1); + e32(vertex_size | (vertex_size << 8)); + e32(offset); +} + +void r300EmitVbufPrim(r300ContextPtr rmesa, GLuint primitive, GLuint vertex_nr) +{ + + int cmd_reserved = 0; + int cmd_written = 0; + int type, num_verts; + drm_radeon_cmd_header_t *cmd = NULL; + + type = r300PrimitiveType(rmesa, primitive); + num_verts = r300NumVerts(rmesa, vertex_nr, primitive); + + start_packet3(CP_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2, 0), 0); + e32(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (num_verts << 16) | type); +} diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.h b/src/mesa/drivers/dri/r300/r300_swtcl.h new file mode 100644 index 00000000000..2ea6ceded7b --- /dev/null +++ b/src/mesa/drivers/dri/r300/r300_swtcl.h @@ -0,0 +1,45 @@ +/* +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Authors: + * Keith Whitwell <[email protected]> - original r200 code + * Dave Airlie <[email protected]> + */ + +#ifndef __R300_SWTCL_H__ +#define __R300_SWTCL_H__ + +#include "mtypes.h" +#include "swrast/swrast.h" +#include "r300_context.h" + +extern void r300InitSwtcl( GLcontext *ctx ); +extern void r300DestroySwtcl( GLcontext *ctx ); + +#endif diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c index 16dddf6557d..7d4e8c95112 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertprog.c @@ -29,6 +29,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * \file * * \author Aapo Tahkola <[email protected]> + * + * \author Oliver McFadden <[email protected]> + * + * For a description of the vertex program instruction set see r300_reg.h. */ #include "glheader.h" @@ -55,54 +59,58 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #error Cannot change these! #endif -#define SCALAR_FLAG (1<<31) -#define FLAG_MASK (1<<31) -#define OP_MASK (0xf) /* we are unlikely to have more than 15 */ -#define OPN(operator, ip) {#operator, OPCODE_##operator, ip} - -static struct { - char *name; - int opcode; - unsigned long ip; /* number of input operands and flags */ -} op_names[] = { - /* *INDENT-OFF* */ - OPN(ABS, 1), - OPN(ADD, 2), - OPN(ARL, 1 | SCALAR_FLAG), - OPN(DP3, 2), - OPN(DP4, 2), - OPN(DPH, 2), - OPN(DST, 2), - OPN(EX2, 1 | SCALAR_FLAG), - OPN(EXP, 1 | SCALAR_FLAG), - OPN(FLR, 1), - OPN(FRC, 1), - OPN(LG2, 1 | SCALAR_FLAG), - OPN(LIT, 1), - OPN(LOG, 1 | SCALAR_FLAG), - OPN(MAD, 3), - OPN(MAX, 2), - OPN(MIN, 2), - OPN(MOV, 1), - OPN(MUL, 2), - OPN(POW, 2 | SCALAR_FLAG), - OPN(RCP, 1 | SCALAR_FLAG), - OPN(RSQ, 1 | SCALAR_FLAG), - OPN(SGE, 2), - OPN(SLT, 2), - OPN(SUB, 2), - OPN(SWZ, 1), - OPN(XPD, 2), - OPN(RCC, 0), //extra - OPN(PRINT, 0), - OPN(END, 0) - /* *INDENT-ON* */ -}; - -#undef OPN +/* TODO: Get rid of t_src_class call */ +#define CMP_SRCS(a, b) ((a.RelAddr != b.RelAddr) || (a.Index != b.Index && \ + ((t_src_class(a.File) == VSF_IN_CLASS_PARAM && \ + t_src_class(b.File) == VSF_IN_CLASS_PARAM) || \ + (t_src_class(a.File) == VSF_IN_CLASS_ATTR && \ + t_src_class(b.File) == VSF_IN_CLASS_ATTR)))) \ + +#define ZERO_SRC_0 (MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), \ + SWIZZLE_ZERO, SWIZZLE_ZERO, \ + SWIZZLE_ZERO, SWIZZLE_ZERO, \ + t_src_class(src[0].File), VSF_FLAG_NONE) | (src[0].RelAddr << 4)) + +#define ZERO_SRC_1 (MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), \ + SWIZZLE_ZERO, SWIZZLE_ZERO, \ + SWIZZLE_ZERO, SWIZZLE_ZERO, \ + t_src_class(src[1].File), VSF_FLAG_NONE) | (src[1].RelAddr << 4)) + +#define ZERO_SRC_2 (MAKE_VSF_SOURCE(t_src_index(vp, &src[2]), \ + SWIZZLE_ZERO, SWIZZLE_ZERO, \ + SWIZZLE_ZERO, SWIZZLE_ZERO, \ + t_src_class(src[2].File), VSF_FLAG_NONE) | (src[2].RelAddr << 4)) + +#define ONE_SRC_0 (MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), \ + SWIZZLE_ONE, SWIZZLE_ONE, \ + SWIZZLE_ONE, SWIZZLE_ONE, \ + t_src_class(src[0].File), VSF_FLAG_NONE) | (src[0].RelAddr << 4)) + +#define ONE_SRC_1 (MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), \ + SWIZZLE_ONE, SWIZZLE_ONE, \ + SWIZZLE_ONE, SWIZZLE_ONE, \ + t_src_class(src[1].File), VSF_FLAG_NONE) | (src[1].RelAddr << 4)) + +#define ONE_SRC_2 (MAKE_VSF_SOURCE(t_src_index(vp, &src[2]), \ + SWIZZLE_ONE, SWIZZLE_ONE, \ + SWIZZLE_ONE, SWIZZLE_ONE, \ + t_src_class(src[2].File), VSF_FLAG_NONE) | (src[2].RelAddr << 4)) + +/* DP4 version seems to trigger some hw peculiarity */ +//#define PREFER_DP4 + +#define FREE_TEMPS() \ + do { \ + if(u_temp_i < vp->num_temporaries) { \ + WARN_ONCE("Ran out of temps, num temps %d, us %d\n", vp->num_temporaries, u_temp_i); \ + vp->native = GL_FALSE; \ + } \ + u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1; \ + } while (0) int r300VertexProgUpdateParams(GLcontext * ctx, - struct r300_vertex_program_cont *vp, float *dst) + struct r300_vertex_program_cont *vp, + float *dst) { int pi; struct gl_vertex_program *mesa_vp = &vp->mesa_program; @@ -234,8 +242,8 @@ static void vp_dump_inputs(struct r300_vertex_program *vp, char *caller) int i; if (vp == NULL) { - fprintf(stderr, "vp null in call to %s from %s\n", __FUNCTION__, - caller); + fprintf(stderr, "vp null in call to %s from %s\n", + __FUNCTION__, caller); return; } @@ -276,6 +284,8 @@ static unsigned long t_src_index(struct r300_vertex_program *vp, } } +/* these two functions should probably be merged... */ + static unsigned long t_src(struct r300_vertex_program *vp, struct prog_src_register *src) { @@ -294,7 +304,9 @@ static unsigned long t_src(struct r300_vertex_program *vp, static unsigned long t_src_scalar(struct r300_vertex_program *vp, struct prog_src_register *src) { - + /* src->NegateBase uses the NEGATE_ flags from program_instruction.h, + * which equal our VSF_FLAGS_ values, so it's safe to just pass it here. + */ return MAKE_VSF_SOURCE(t_src_index(vp, src), t_swizzle(GET_SWZ(src->Swizzle, 0)), t_swizzle(GET_SWZ(src->Swizzle, 0)), @@ -306,128 +318,741 @@ static unsigned long t_src_scalar(struct r300_vertex_program *vp, (src->RelAddr << 4); } -static unsigned long t_opcode(enum prog_opcode opcode) +static GLboolean valid_dst(struct r300_vertex_program *vp, + struct prog_dst_register *dst) { + if (dst->File == PROGRAM_OUTPUT && vp->outputs[dst->Index] == -1) { + return GL_FALSE; + } else if (dst->File == PROGRAM_ADDRESS) { + assert(dst->Index == 0); + } - switch (opcode) { - /* *INDENT-OFF* */ - case OPCODE_ARL: return R300_VPI_OUT_OP_ARL; - case OPCODE_DST: return R300_VPI_OUT_OP_DST; - case OPCODE_EX2: return R300_VPI_OUT_OP_EX2; - case OPCODE_EXP: return R300_VPI_OUT_OP_EXP; - case OPCODE_FRC: return R300_VPI_OUT_OP_FRC; - case OPCODE_LG2: return R300_VPI_OUT_OP_LG2; - case OPCODE_LOG: return R300_VPI_OUT_OP_LOG; - case OPCODE_MAX: return R300_VPI_OUT_OP_MAX; - case OPCODE_MIN: return R300_VPI_OUT_OP_MIN; - case OPCODE_MUL: return R300_VPI_OUT_OP_MUL; - case OPCODE_RCP: return R300_VPI_OUT_OP_RCP; - case OPCODE_RSQ: return R300_VPI_OUT_OP_RSQ; - case OPCODE_SGE: return R300_VPI_OUT_OP_SGE; - case OPCODE_SLT: return R300_VPI_OUT_OP_SLT; - case OPCODE_DP4: return R300_VPI_OUT_OP_DOT; - /* *INDENT-ON* */ + return GL_TRUE; +} - default: - fprintf(stderr, "%s: Should not be called with opcode %d!", - __FUNCTION__, opcode); - } - _mesa_exit(-1); - return 0; +/* + * Instruction Inputs Output Description + * ----------- ------ ------ -------------------------------- + * ABS v v absolute value + * ADD v,v v add + * ARL s a address register load + * DP3 v,v ssss 3-component dot product + * DP4 v,v ssss 4-component dot product + * DPH v,v ssss homogeneous dot product + * DST v,v v distance vector + * EX2 s ssss exponential base 2 + * EXP s v exponential base 2 (approximate) + * FLR v v floor + * FRC v v fraction + * LG2 s ssss logarithm base 2 + * LIT v v compute light coefficients + * LOG s v logarithm base 2 (approximate) + * MAD v,v,v v multiply and add + * MAX v,v v maximum + * MIN v,v v minimum + * MOV v v move + * MUL v,v v multiply + * POW s,s ssss exponentiate + * RCP s ssss reciprocal + * RSQ s ssss reciprocal square root + * SGE v,v v set on greater than or equal + * SLT v,v v set on less than + * SUB v,v v subtract + * SWZ v v extended swizzle + * XPD v,v v cross product + * + * Table X.5: Summary of vertex program instructions. "v" indicates a + * floating-point vector input or output, "s" indicates a floating-point + * scalar input, "ssss" indicates a scalar output replicated across a + * 4-component result vector, and "a" indicates a single address register + * component. + */ + +static GLuint *t_opcode_abs(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) +{ + //MAX RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W + + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_MAX, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + + inst[1] = t_src(vp, &src[0]); + inst[2] = + MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), + t_swizzle(GET_SWZ(src[0].Swizzle, 0)), + t_swizzle(GET_SWZ(src[0].Swizzle, 1)), + t_swizzle(GET_SWZ(src[0].Swizzle, 2)), + t_swizzle(GET_SWZ(src[0].Swizzle, 3)), + t_src_class(src[0].File), + (!src[0]. + NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + (src[0].RelAddr << 4); + inst[3] = 0; + + return inst; } -static unsigned long op_operands(enum prog_opcode opcode) +static GLuint *t_opcode_add(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) { - int i; + unsigned long hw_op; - /* Can we trust mesas opcodes to be in order ? */ - for (i = 0; i < sizeof(op_names) / sizeof(*op_names); i++) - if (op_names[i].opcode == opcode) - return op_names[i].ip; +#if 1 + hw_op = (src[0].File == PROGRAM_TEMPORARY + && src[1].File == + PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 : + R300_VPI_OUT_OP_MAD; + + inst[0] = + MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + inst[1] = ONE_SRC_0; + inst[2] = t_src(vp, &src[0]); + inst[3] = t_src(vp, &src[1]); +#else + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + inst[1] = t_src(vp, &src[0]); + inst[2] = t_src(vp, &src[1]); + inst[3] = ZERO_SRC_1; - fprintf(stderr, "op %d not found in op_names\n", opcode); - _mesa_exit(-1); - return 0; +#endif + + return inst; } -static GLboolean valid_dst(struct r300_vertex_program *vp, - struct prog_dst_register *dst) +static GLuint *t_opcode_arl(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) { - if (dst->File == PROGRAM_OUTPUT && vp->outputs[dst->Index] == -1) { - return GL_FALSE; - } else if (dst->File == PROGRAM_ADDRESS) { - assert(dst->Index == 0); - } + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_ARL, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); - return GL_TRUE; + inst[1] = t_src(vp, &src[0]); + inst[2] = ZERO_SRC_0; + inst[3] = ZERO_SRC_0; + + return inst; } -/* TODO: Get rid of t_src_class call */ -#define CMP_SRCS(a, b) ((a.RelAddr != b.RelAddr) || (a.Index != b.Index && \ - ((t_src_class(a.File) == VSF_IN_CLASS_PARAM && \ - t_src_class(b.File) == VSF_IN_CLASS_PARAM) || \ - (t_src_class(a.File) == VSF_IN_CLASS_ATTR && \ - t_src_class(b.File) == VSF_IN_CLASS_ATTR)))) \ +static GLuint *t_opcode_dp3(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) +{ + //DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ZERO} PARAM 0{} {X Y Z ZERO} + + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_DOT, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + + inst[1] = + MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), + t_swizzle(GET_SWZ(src[0].Swizzle, 0)), + t_swizzle(GET_SWZ(src[0].Swizzle, 1)), + t_swizzle(GET_SWZ(src[0].Swizzle, 2)), + SWIZZLE_ZERO, t_src_class(src[0].File), + src[0]. + NegateBase ? VSF_FLAG_XYZ : VSF_FLAG_NONE) | + (src[0].RelAddr << 4); + + inst[2] = + MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), + t_swizzle(GET_SWZ(src[1].Swizzle, 0)), + t_swizzle(GET_SWZ(src[1].Swizzle, 1)), + t_swizzle(GET_SWZ(src[1].Swizzle, 2)), + SWIZZLE_ZERO, t_src_class(src[1].File), + src[1]. + NegateBase ? VSF_FLAG_XYZ : VSF_FLAG_NONE) | + (src[1].RelAddr << 4); + + inst[3] = ZERO_SRC_1; + + return inst; +} -#define ZERO_SRC_0 (MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), \ - SWIZZLE_ZERO, SWIZZLE_ZERO, \ - SWIZZLE_ZERO, SWIZZLE_ZERO, \ - t_src_class(src[0].File), VSF_FLAG_NONE) | (src[0].RelAddr << 4)) +static GLuint *t_opcode_dp4(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) +{ + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_DOT, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); -#define ZERO_SRC_1 (MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), \ - SWIZZLE_ZERO, SWIZZLE_ZERO, \ - SWIZZLE_ZERO, SWIZZLE_ZERO, \ - t_src_class(src[1].File), VSF_FLAG_NONE) | (src[1].RelAddr << 4)) + inst[1] = t_src(vp, &src[0]); + inst[2] = t_src(vp, &src[1]); + inst[3] = ZERO_SRC_1; -#define ZERO_SRC_2 (MAKE_VSF_SOURCE(t_src_index(vp, &src[2]), \ - SWIZZLE_ZERO, SWIZZLE_ZERO, \ - SWIZZLE_ZERO, SWIZZLE_ZERO, \ - t_src_class(src[2].File), VSF_FLAG_NONE) | (src[2].RelAddr << 4)) + return inst; +} -#define ONE_SRC_0 (MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), \ - SWIZZLE_ONE, SWIZZLE_ONE, \ - SWIZZLE_ONE, SWIZZLE_ONE, \ - t_src_class(src[0].File), VSF_FLAG_NONE) | (src[0].RelAddr << 4)) +static GLuint *t_opcode_dph(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) +{ + //DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ONE} PARAM 0{} {X Y Z W} + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_DOT, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + + inst[1] = + MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), + t_swizzle(GET_SWZ(src[0].Swizzle, 0)), + t_swizzle(GET_SWZ(src[0].Swizzle, 1)), + t_swizzle(GET_SWZ(src[0].Swizzle, 2)), + VSF_IN_COMPONENT_ONE, t_src_class(src[0].File), + src[0]. + NegateBase ? VSF_FLAG_XYZ : VSF_FLAG_NONE) | + (src[0].RelAddr << 4); + inst[2] = t_src(vp, &src[1]); + inst[3] = ZERO_SRC_1; + + return inst; +} -#define ONE_SRC_1 (MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), \ - SWIZZLE_ONE, SWIZZLE_ONE, \ - SWIZZLE_ONE, SWIZZLE_ONE, \ - t_src_class(src[1].File), VSF_FLAG_NONE) | (src[1].RelAddr << 4)) +static GLuint *t_opcode_dst(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) +{ + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_DST, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); -#define ONE_SRC_2 (MAKE_VSF_SOURCE(t_src_index(vp, &src[2]), \ - SWIZZLE_ONE, SWIZZLE_ONE, \ - SWIZZLE_ONE, SWIZZLE_ONE, \ - t_src_class(src[2].File), VSF_FLAG_NONE) | (src[2].RelAddr << 4)) + inst[1] = t_src(vp, &src[0]); + inst[2] = t_src(vp, &src[1]); + inst[3] = ZERO_SRC_1; -/* DP4 version seems to trigger some hw peculiarity */ -//#define PREFER_DP4 + return inst; +} -#define FREE_TEMPS() \ - do { \ - if(u_temp_i < vp->num_temporaries) { \ - WARN_ONCE("Ran out of temps, num temps %d, us %d\n", vp->num_temporaries, u_temp_i); \ - vp->native = GL_FALSE; \ - } \ - u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1; \ - } while (0) +static GLuint *t_opcode_ex2(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) +{ + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_EX2, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); -static void r300TranslateVertexShader(struct r300_vertex_program *vp, - struct prog_instruction *vpi) + inst[1] = t_src_scalar(vp, &src[0]); + inst[2] = ZERO_SRC_0; + inst[3] = ZERO_SRC_0; + + return inst; +} + +static GLuint *t_opcode_exp(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) +{ + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_EXP, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + + inst[1] = t_src_scalar(vp, &src[0]); + inst[2] = ZERO_SRC_0; + inst[3] = ZERO_SRC_0; + + return inst; +} + +static GLuint *t_opcode_flr(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3], int *u_temp_i) +{ + /* FRC TMP 0.X Y Z W PARAM 0{} {X Y Z W} + ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} TMP 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W */ + + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_FRC, *u_temp_i, + t_dst_mask(vpi->DstReg.WriteMask), + VSF_OUT_CLASS_TMP); + + inst[1] = t_src(vp, &src[0]); + inst[2] = ZERO_SRC_0; + inst[3] = ZERO_SRC_0; + inst += 4; + + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + + inst[1] = t_src(vp, &src[0]); + inst[2] = + MAKE_VSF_SOURCE(*u_temp_i, VSF_IN_COMPONENT_X, + VSF_IN_COMPONENT_Y, VSF_IN_COMPONENT_Z, + VSF_IN_COMPONENT_W, VSF_IN_CLASS_TMP, + /* Not 100% sure about this */ + (!src[0]. + NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE + /*VSF_FLAG_ALL */ ); + + inst[3] = ZERO_SRC_0; + (*u_temp_i)--; + + return inst; +} + +static GLuint *t_opcode_frc(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) +{ + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_FRC, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + + inst[1] = t_src(vp, &src[0]); + inst[2] = ZERO_SRC_0; + inst[3] = ZERO_SRC_0; + + return inst; +} + +static GLuint *t_opcode_lg2(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) +{ + // LG2 RESULT 1.X Y Z W PARAM 0{} {X X X X} + + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_LG2, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + + inst[1] = + MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), + t_swizzle(GET_SWZ(src[0].Swizzle, 0)), + t_swizzle(GET_SWZ(src[0].Swizzle, 0)), + t_swizzle(GET_SWZ(src[0].Swizzle, 0)), + t_swizzle(GET_SWZ(src[0].Swizzle, 0)), + t_src_class(src[0].File), + src[0]. + NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + (src[0].RelAddr << 4); + inst[2] = ZERO_SRC_0; + inst[3] = ZERO_SRC_0; + + return inst; +} + +static GLuint *t_opcode_lit(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) +{ + //LIT TMP 1.Y Z TMP 1{} {X W Z Y} TMP 1{} {Y W Z X} TMP 1{} {Y X Z W} + + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_LIT, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + /* NOTE: Users swizzling might not work. */ + inst[1] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x + t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w + VSF_IN_COMPONENT_ZERO, // z + t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y + t_src_class(src[0].File), + src[0]. + NegateBase ? VSF_FLAG_ALL : + VSF_FLAG_NONE) | (src[0].RelAddr << 4); + inst[2] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y + t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w + VSF_IN_COMPONENT_ZERO, // z + t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x + t_src_class(src[0].File), + src[0]. + NegateBase ? VSF_FLAG_ALL : + VSF_FLAG_NONE) | (src[0].RelAddr << 4); + inst[3] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y + t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x + VSF_IN_COMPONENT_ZERO, // z + t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w + t_src_class(src[0].File), + src[0]. + NegateBase ? VSF_FLAG_ALL : + VSF_FLAG_NONE) | (src[0].RelAddr << 4); + + return inst; +} + +static GLuint *t_opcode_log(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) +{ + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_LOG, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + + inst[1] = t_src_scalar(vp, &src[0]); + inst[2] = ZERO_SRC_0; + inst[3] = ZERO_SRC_0; + + return inst; +} + +static GLuint *t_opcode_mad(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) { - int i, cur_reg = 0; - VERTEX_SHADER_INSTRUCTION *o_inst; - unsigned long operands; - int are_srcs_scalar; unsigned long hw_op; - /* Initial value should be last tmp reg that hw supports. - Strangely enough r300 doesnt mind even though these would be out of range. - Smart enough to realize that it doesnt need it? */ - int u_temp_i = VSF_MAX_FRAGMENT_TEMPS - 1; - struct prog_src_register src[3]; - vp->pos_end = 0; /* Not supported yet */ - vp->program.length = 0; - /*vp->num_temporaries=mesa_vp->Base.NumTemporaries; */ + hw_op = (src[0].File == PROGRAM_TEMPORARY + && src[1].File == PROGRAM_TEMPORARY + && src[2].File == + PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 : + R300_VPI_OUT_OP_MAD; + + inst[0] = + MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + inst[1] = t_src(vp, &src[0]); + inst[2] = t_src(vp, &src[1]); + inst[3] = t_src(vp, &src[2]); + + return inst; +} + +static GLuint *t_opcode_max(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) +{ + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_MAX, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + + inst[1] = t_src(vp, &src[0]); + inst[2] = t_src(vp, &src[1]); + inst[3] = ZERO_SRC_1; + + return inst; +} + +static GLuint *t_opcode_min(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) +{ + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_MIN, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + + inst[1] = t_src(vp, &src[0]); + inst[2] = t_src(vp, &src[1]); + inst[3] = ZERO_SRC_1; + + return inst; +} + +static GLuint *t_opcode_mov(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) +{ + //ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{} {ZERO ZERO ZERO ZERO} + +#if 1 + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + inst[1] = t_src(vp, &src[0]); + inst[2] = ZERO_SRC_0; + inst[3] = ZERO_SRC_0; +#else + hw_op = + (src[0].File == + PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 : + R300_VPI_OUT_OP_MAD; + + inst[0] = + MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + inst[1] = t_src(vp, &src[0]); + inst[2] = ONE_SRC_0; + inst[3] = ZERO_SRC_0; +#endif + + return inst; +} + +static GLuint *t_opcode_mul(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) +{ + unsigned long hw_op; + + // HW mul can take third arg but appears to have some other limitations. + + hw_op = (src[0].File == PROGRAM_TEMPORARY + && src[1].File == + PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 : + R300_VPI_OUT_OP_MAD; + + inst[0] = + MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + inst[1] = t_src(vp, &src[0]); + inst[2] = t_src(vp, &src[1]); + + inst[3] = ZERO_SRC_1; + + return inst; +} + +static GLuint *t_opcode_pow(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) +{ + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_POW, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + inst[1] = t_src_scalar(vp, &src[0]); + inst[2] = ZERO_SRC_0; + inst[3] = t_src_scalar(vp, &src[1]); + + return inst; +} + +static GLuint *t_opcode_rcp(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) +{ + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_RCP, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + + inst[1] = t_src_scalar(vp, &src[0]); + inst[2] = ZERO_SRC_0; + inst[3] = ZERO_SRC_0; + + return inst; +} + +static GLuint *t_opcode_rsq(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) +{ + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_RSQ, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + + inst[1] = t_src_scalar(vp, &src[0]); + inst[2] = ZERO_SRC_0; + inst[3] = ZERO_SRC_0; + + return inst; +} + +static GLuint *t_opcode_sge(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) +{ + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_SGE, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + + inst[1] = t_src(vp, &src[0]); + inst[2] = t_src(vp, &src[1]); + inst[3] = ZERO_SRC_1; + + return inst; +} + +static GLuint *t_opcode_slt(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) +{ + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_SLT, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + + inst[1] = t_src(vp, &src[0]); + inst[2] = t_src(vp, &src[1]); + inst[3] = ZERO_SRC_1; + + return inst; +} + +static GLuint *t_opcode_sub(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) +{ + unsigned long hw_op; + + //ADD RESULT 1.X Y Z W TMP 0{} {X Y Z W} PARAM 1{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W + +#if 1 + hw_op = (src[0].File == PROGRAM_TEMPORARY + && src[1].File == + PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 : + R300_VPI_OUT_OP_MAD; + + inst[0] = + MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + inst[1] = t_src(vp, &src[0]); + inst[2] = ONE_SRC_0; + inst[3] = + MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), + t_swizzle(GET_SWZ(src[1].Swizzle, 0)), + t_swizzle(GET_SWZ(src[1].Swizzle, 1)), + t_swizzle(GET_SWZ(src[1].Swizzle, 2)), + t_swizzle(GET_SWZ(src[1].Swizzle, 3)), + t_src_class(src[1].File), + (!src[1]. + NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + (src[1].RelAddr << 4); +#else + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + + inst[1] = t_src(vp, &src[0]); + inst[2] = + MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), + t_swizzle(GET_SWZ(src[1].Swizzle, 0)), + t_swizzle(GET_SWZ(src[1].Swizzle, 1)), + t_swizzle(GET_SWZ(src[1].Swizzle, 2)), + t_swizzle(GET_SWZ(src[1].Swizzle, 3)), + t_src_class(src[1].File), + (!src[1]. + NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | + (src[1].RelAddr << 4); + inst[3] = 0; +#endif + + return inst; +} + +static GLuint *t_opcode_swz(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3]) +{ + //ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{} {ZERO ZERO ZERO ZERO} + +#if 1 + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + inst[1] = t_src(vp, &src[0]); + inst[2] = ZERO_SRC_0; + inst[3] = ZERO_SRC_0; +#else + hw_op = + (src[0].File == + PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 : + R300_VPI_OUT_OP_MAD; + + inst[0] = + MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + inst[1] = t_src(vp, &src[0]); + inst[2] = ONE_SRC_0; + inst[3] = ZERO_SRC_0; +#endif + + return inst; +} + +static GLuint *t_opcode_xpd(struct r300_vertex_program *vp, + struct prog_instruction *vpi, GLuint * inst, + struct prog_src_register src[3], int *u_temp_i) +{ + /* mul r0, r1.yzxw, r2.zxyw + mad r0, -r2.yzxw, r1.zxyw, r0 + NOTE: might need MAD_2 + */ + + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_MAD, *u_temp_i, + t_dst_mask(vpi->DstReg.WriteMask), + VSF_OUT_CLASS_TMP); + + inst[1] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y + t_swizzle(GET_SWZ(src[0].Swizzle, 2)), // z + t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x + t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w + t_src_class(src[0].File), + src[0]. + NegateBase ? VSF_FLAG_ALL : + VSF_FLAG_NONE) | (src[0].RelAddr << 4); + + inst[2] = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), t_swizzle(GET_SWZ(src[1].Swizzle, 2)), // z + t_swizzle(GET_SWZ(src[1].Swizzle, 0)), // x + t_swizzle(GET_SWZ(src[1].Swizzle, 1)), // y + t_swizzle(GET_SWZ(src[1].Swizzle, 3)), // w + t_src_class(src[1].File), + src[1]. + NegateBase ? VSF_FLAG_ALL : + VSF_FLAG_NONE) | (src[1].RelAddr << 4); + + inst[3] = ZERO_SRC_1; + inst += 4; + (*u_temp_i)--; + + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_MAD, t_dst_index(vp, &vpi->DstReg), + t_dst_mask(vpi->DstReg.WriteMask), + t_dst_class(vpi->DstReg.File)); + + inst[1] = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), t_swizzle(GET_SWZ(src[1].Swizzle, 1)), // y + t_swizzle(GET_SWZ(src[1].Swizzle, 2)), // z + t_swizzle(GET_SWZ(src[1].Swizzle, 0)), // x + t_swizzle(GET_SWZ(src[1].Swizzle, 3)), // w + t_src_class(src[1].File), + (!src[1]. + NegateBase) ? VSF_FLAG_ALL : + VSF_FLAG_NONE) | (src[1].RelAddr << 4); + + inst[2] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 2)), // z + t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x + t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y + t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w + t_src_class(src[0].File), + src[0]. + NegateBase ? VSF_FLAG_ALL : + VSF_FLAG_NONE) | (src[0].RelAddr << 4); + + inst[3] = + MAKE_VSF_SOURCE(*u_temp_i + 1, VSF_IN_COMPONENT_X, + VSF_IN_COMPONENT_Y, VSF_IN_COMPONENT_Z, + VSF_IN_COMPONENT_W, VSF_IN_CLASS_TMP, + VSF_FLAG_NONE); + + return inst; +} + +static void t_inputs_outputs(struct r300_vertex_program *vp) +{ + int i; + int cur_reg = 0; for (i = 0; i < VERT_ATTRIB_MAX; i++) vp->inputs[i] = -1; @@ -437,39 +1062,71 @@ static void r300TranslateVertexShader(struct r300_vertex_program *vp, assert(vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS)); - /* Assign outputs */ - if (vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS)) + if (vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS)) { vp->outputs[VERT_RESULT_HPOS] = cur_reg++; + } - if (vp->key.OutputsWritten & (1 << VERT_RESULT_PSIZ)) + if (vp->key.OutputsWritten & (1 << VERT_RESULT_PSIZ)) { vp->outputs[VERT_RESULT_PSIZ] = cur_reg++; + } - if (vp->key.OutputsWritten & (1 << VERT_RESULT_COL0)) + if (vp->key.OutputsWritten & (1 << VERT_RESULT_COL0)) { vp->outputs[VERT_RESULT_COL0] = cur_reg++; + } - if (vp->key.OutputsWritten & (1 << VERT_RESULT_COL1)) - vp->outputs[VERT_RESULT_COL1] = cur_reg++; - -#if 0 /* Not supported yet */ - if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0)) - vp->outputs[VERT_RESULT_BFC0] = cur_reg++; + if (vp->key.OutputsWritten & (1 << VERT_RESULT_COL1)) { + vp->outputs[VERT_RESULT_COL1] = + vp->outputs[VERT_RESULT_COL0] + 1; + cur_reg = vp->outputs[VERT_RESULT_COL1] + 1; + } - if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1)) - vp->outputs[VERT_RESULT_BFC1] = cur_reg++; + if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0)) { + vp->outputs[VERT_RESULT_BFC0] = + vp->outputs[VERT_RESULT_COL0] + 2; + cur_reg = vp->outputs[VERT_RESULT_BFC0] + 2; + } - if (vp->key.OutputsWritten & (1 << VERT_RESULT_FOGC)) + if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1)) { + vp->outputs[VERT_RESULT_BFC1] = + vp->outputs[VERT_RESULT_COL0] + 3; + cur_reg = vp->outputs[VERT_RESULT_BFC1] + 1; + } +#if 0 + if (vp->key.OutputsWritten & (1 << VERT_RESULT_FOGC)) { vp->outputs[VERT_RESULT_FOGC] = cur_reg++; + } #endif - for (i = VERT_RESULT_TEX0; i <= VERT_RESULT_TEX7; i++) - if (vp->key.OutputsWritten & (1 << i)) + for (i = VERT_RESULT_TEX0; i <= VERT_RESULT_TEX7; i++) { + if (vp->key.OutputsWritten & (1 << i)) { vp->outputs[i] = cur_reg++; + } + } +} + +static void r300TranslateVertexShader(struct r300_vertex_program *vp, + struct prog_instruction *vpi) +{ + int i; + GLuint *inst; + unsigned long num_operands; + /* Initial value should be last tmp reg that hw supports. + Strangely enough r300 doesnt mind even though these would be out of range. + Smart enough to realize that it doesnt need it? */ + int u_temp_i = VSF_MAX_FRAGMENT_TEMPS - 1; + struct prog_src_register src[3]; + vp->pos_end = 0; /* Not supported yet */ + vp->program.length = 0; + /*vp->num_temporaries=mesa_vp->Base.NumTemporaries; */ vp->translated = GL_TRUE; vp->native = GL_TRUE; - o_inst = vp->program.body.i; - for (; vpi->Opcode != OPCODE_END; vpi++, o_inst++) { + t_inputs_outputs(vp); + + for (inst = vp->program.body.i; vpi->Opcode != OPCODE_END; + vpi++, inst += 4) { + FREE_TEMPS(); if (!valid_dst(vp, &vpi->DstReg)) { @@ -478,61 +1135,62 @@ static void r300TranslateVertexShader(struct r300_vertex_program *vp, vpi->DstReg.Index = u_temp_i; } - operands = op_operands(vpi->Opcode); - are_srcs_scalar = operands & SCALAR_FLAG; - operands &= OP_MASK; + num_operands = _mesa_num_inst_src_regs(vpi->Opcode); - for (i = 0; i < operands; i++) + /* copy the sources (src) from mesa into a local variable... is this needed? */ + for (i = 0; i < num_operands; i++) { src[i] = vpi->SrcReg[i]; + } - if (operands == 3) { /* TODO: scalars */ + if (num_operands == 3) { /* TODO: scalars */ if (CMP_SRCS(src[1], src[2]) || CMP_SRCS(src[0], src[2])) { - o_inst->op = - MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, u_temp_i, - VSF_FLAG_ALL, + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, + u_temp_i, VSF_FLAG_ALL, VSF_OUT_CLASS_TMP); - o_inst->src[0] = - MAKE_VSF_SOURCE(t_src_index(vp, &src[2]), + inst[1] = + MAKE_VSF_SOURCE(t_src_index + (vp, &src[2]), SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W, - t_src_class(src[2].File), - VSF_FLAG_NONE) | (src[2]. - RelAddr << - 4); + t_src_class(src[2]. + File), + VSF_FLAG_NONE) | + (src[2].RelAddr << 4); - o_inst->src[1] = ZERO_SRC_2; - o_inst->src[2] = ZERO_SRC_2; - o_inst++; + inst[2] = ZERO_SRC_2; + inst[3] = ZERO_SRC_2; + inst += 4; src[2].File = PROGRAM_TEMPORARY; src[2].Index = u_temp_i; src[2].RelAddr = 0; u_temp_i--; } - } - if (operands >= 2) { + if (num_operands >= 2) { if (CMP_SRCS(src[1], src[0])) { - o_inst->op = - MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, u_temp_i, - VSF_FLAG_ALL, + inst[0] = + MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, + u_temp_i, VSF_FLAG_ALL, VSF_OUT_CLASS_TMP); - o_inst->src[0] = - MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), + inst[1] = + MAKE_VSF_SOURCE(t_src_index + (vp, &src[0]), SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W, - t_src_class(src[0].File), - VSF_FLAG_NONE) | (src[0]. - RelAddr << - 4); + t_src_class(src[0]. + File), + VSF_FLAG_NONE) | + (src[0].RelAddr << 4); - o_inst->src[1] = ZERO_SRC_0; - o_inst->src[2] = ZERO_SRC_0; - o_inst++; + inst[2] = ZERO_SRC_0; + inst[3] = ZERO_SRC_0; + inst += 4; src[0].File = PROGRAM_TEMPORARY; src[0].Index = u_temp_i; @@ -541,517 +1199,103 @@ static void r300TranslateVertexShader(struct r300_vertex_program *vp, } } - /* These ops need special handling. */ switch (vpi->Opcode) { - case OPCODE_POW: - o_inst->op = - MAKE_VSF_OP(R300_VPI_OUT_OP_POW, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - o_inst->src[0] = t_src_scalar(vp, &src[0]); - o_inst->src[1] = ZERO_SRC_0; - o_inst->src[2] = t_src_scalar(vp, &src[1]); - goto next; - - case OPCODE_MOV: //ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{} {ZERO ZERO ZERO ZERO} - case OPCODE_SWZ: -#if 1 - o_inst->op = - MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - o_inst->src[0] = t_src(vp, &src[0]); - o_inst->src[1] = ZERO_SRC_0; - o_inst->src[2] = ZERO_SRC_0; -#else - hw_op = - (src[0].File == - PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 : - R300_VPI_OUT_OP_MAD; - - o_inst->op = - MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - o_inst->src[0] = t_src(vp, &src[0]); - o_inst->src[1] = ONE_SRC_0; - o_inst->src[2] = ZERO_SRC_0; -#endif - - goto next; - + case OPCODE_ABS: + inst = t_opcode_abs(vp, vpi, inst, src); + break; case OPCODE_ADD: -#if 1 - hw_op = (src[0].File == PROGRAM_TEMPORARY && - src[1].File == - PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 : - R300_VPI_OUT_OP_MAD; - - o_inst->op = - MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - o_inst->src[0] = ONE_SRC_0; - o_inst->src[1] = t_src(vp, &src[0]); - o_inst->src[2] = t_src(vp, &src[1]); -#else - o_inst->op = - MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - o_inst->src[0] = t_src(vp, &src[0]); - o_inst->src[1] = t_src(vp, &src[1]); - o_inst->src[2] = ZERO_SRC_1; - -#endif - goto next; - - case OPCODE_MAD: - hw_op = (src[0].File == PROGRAM_TEMPORARY && - src[1].File == PROGRAM_TEMPORARY && - src[2].File == - PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 : - R300_VPI_OUT_OP_MAD; - - o_inst->op = - MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - o_inst->src[0] = t_src(vp, &src[0]); - o_inst->src[1] = t_src(vp, &src[1]); - o_inst->src[2] = t_src(vp, &src[2]); - goto next; - - case OPCODE_MUL: /* HW mul can take third arg but appears to have some other limitations. */ - hw_op = (src[0].File == PROGRAM_TEMPORARY && - src[1].File == - PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 : - R300_VPI_OUT_OP_MAD; - - o_inst->op = - MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - o_inst->src[0] = t_src(vp, &src[0]); - o_inst->src[1] = t_src(vp, &src[1]); - - o_inst->src[2] = ZERO_SRC_1; - goto next; - - case OPCODE_DP3: //DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ZERO} PARAM 0{} {X Y Z ZERO} - o_inst->op = - MAKE_VSF_OP(R300_VPI_OUT_OP_DOT, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - - o_inst->src[0] = - MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), - t_swizzle(GET_SWZ - (src[0].Swizzle, 0)), - t_swizzle(GET_SWZ - (src[0].Swizzle, 1)), - t_swizzle(GET_SWZ - (src[0].Swizzle, 2)), - SWIZZLE_ZERO, - t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_XYZ : - VSF_FLAG_NONE) | (src[0]. - RelAddr << 4); - - o_inst->src[1] = - MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), - t_swizzle(GET_SWZ - (src[1].Swizzle, 0)), - t_swizzle(GET_SWZ - (src[1].Swizzle, 1)), - t_swizzle(GET_SWZ - (src[1].Swizzle, 2)), - SWIZZLE_ZERO, - t_src_class(src[1].File), - src[1]. - NegateBase ? VSF_FLAG_XYZ : - VSF_FLAG_NONE) | (src[1]. - RelAddr << 4); - - o_inst->src[2] = ZERO_SRC_1; - goto next; - - case OPCODE_SUB: //ADD RESULT 1.X Y Z W TMP 0{} {X Y Z W} PARAM 1{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W -#if 1 - hw_op = (src[0].File == PROGRAM_TEMPORARY && - src[1].File == - PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 : - R300_VPI_OUT_OP_MAD; - - o_inst->op = - MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - o_inst->src[0] = t_src(vp, &src[0]); - o_inst->src[1] = ONE_SRC_0; - o_inst->src[2] = - MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), - t_swizzle(GET_SWZ - (src[1].Swizzle, 0)), - t_swizzle(GET_SWZ - (src[1].Swizzle, 1)), - t_swizzle(GET_SWZ - (src[1].Swizzle, 2)), - t_swizzle(GET_SWZ - (src[1].Swizzle, 3)), - t_src_class(src[1].File), - (!src[1]. - NegateBase) ? VSF_FLAG_ALL : - VSF_FLAG_NONE) | (src[1]. - RelAddr << 4); -#else - o_inst->op = - MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - - o_inst->src[0] = t_src(vp, &src[0]); - o_inst->src[1] = - MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), - t_swizzle(GET_SWZ - (src[1].Swizzle, 0)), - t_swizzle(GET_SWZ - (src[1].Swizzle, 1)), - t_swizzle(GET_SWZ - (src[1].Swizzle, 2)), - t_swizzle(GET_SWZ - (src[1].Swizzle, 3)), - t_src_class(src[1].File), - (!src[1]. - NegateBase) ? VSF_FLAG_ALL : - VSF_FLAG_NONE) | (src[1]. - RelAddr << 4); - o_inst->src[2] = 0; -#endif - goto next; - - case OPCODE_ABS: //MAX RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W - o_inst->op = - MAKE_VSF_OP(R300_VPI_OUT_OP_MAX, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - - o_inst->src[0] = t_src(vp, &src[0]); - o_inst->src[1] = - MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), - t_swizzle(GET_SWZ - (src[0].Swizzle, 0)), - t_swizzle(GET_SWZ - (src[0].Swizzle, 1)), - t_swizzle(GET_SWZ - (src[0].Swizzle, 2)), - t_swizzle(GET_SWZ - (src[0].Swizzle, 3)), - t_src_class(src[0].File), - (!src[0]. - NegateBase) ? VSF_FLAG_ALL : - VSF_FLAG_NONE) | (src[0]. - RelAddr << 4); - o_inst->src[2] = 0; - goto next; - + inst = t_opcode_add(vp, vpi, inst, src); + break; + case OPCODE_ARL: + inst = t_opcode_arl(vp, vpi, inst, src); + break; + case OPCODE_DP3: + inst = t_opcode_dp3(vp, vpi, inst, src); + break; + case OPCODE_DP4: + inst = t_opcode_dp4(vp, vpi, inst, src); + break; + case OPCODE_DPH: + inst = t_opcode_dph(vp, vpi, inst, src); + break; + case OPCODE_DST: + inst = t_opcode_dst(vp, vpi, inst, src); + break; + case OPCODE_EX2: + inst = t_opcode_ex2(vp, vpi, inst, src); + break; + case OPCODE_EXP: + inst = t_opcode_exp(vp, vpi, inst, src); + break; case OPCODE_FLR: - /* FRC TMP 0.X Y Z W PARAM 0{} {X Y Z W} - ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} TMP 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W */ - - o_inst->op = MAKE_VSF_OP(R300_VPI_OUT_OP_FRC, u_temp_i, - t_dst_mask(vpi->DstReg. - WriteMask), - VSF_OUT_CLASS_TMP); - - o_inst->src[0] = t_src(vp, &src[0]); - o_inst->src[1] = ZERO_SRC_0; - o_inst->src[2] = ZERO_SRC_0; - o_inst++; - - o_inst->op = - MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - - o_inst->src[0] = t_src(vp, &src[0]); - o_inst->src[1] = MAKE_VSF_SOURCE(u_temp_i, - VSF_IN_COMPONENT_X, - VSF_IN_COMPONENT_Y, - VSF_IN_COMPONENT_Z, - VSF_IN_COMPONENT_W, - VSF_IN_CLASS_TMP, - /* Not 100% sure about this */ - (!src[0]. - NegateBase) ? - VSF_FLAG_ALL : - VSF_FLAG_NONE - /*VSF_FLAG_ALL */ ); - - o_inst->src[2] = ZERO_SRC_0; - u_temp_i--; - goto next; - - case OPCODE_LG2: // LG2 RESULT 1.X Y Z W PARAM 0{} {X X X X} - o_inst->op = - MAKE_VSF_OP(R300_VPI_OUT_OP_LG2, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - - o_inst->src[0] = - MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), - t_swizzle(GET_SWZ - (src[0].Swizzle, 0)), - t_swizzle(GET_SWZ - (src[0].Swizzle, 0)), - t_swizzle(GET_SWZ - (src[0].Swizzle, 0)), - t_swizzle(GET_SWZ - (src[0].Swizzle, 0)), - t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_ALL : - VSF_FLAG_NONE) | (src[0]. - RelAddr << 4); - o_inst->src[1] = ZERO_SRC_0; - o_inst->src[2] = ZERO_SRC_0; - goto next; - - case OPCODE_LIT: //LIT TMP 1.Y Z TMP 1{} {X W Z Y} TMP 1{} {Y W Z X} TMP 1{} {Y X Z W} - o_inst->op = - MAKE_VSF_OP(R300_VPI_OUT_OP_LIT, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - /* NOTE: Users swizzling might not work. */ - o_inst->src[0] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x - t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w - VSF_IN_COMPONENT_ZERO, // z - t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y - t_src_class(src[0]. - File), - src[0]. - NegateBase ? - VSF_FLAG_ALL : - VSF_FLAG_NONE) | - (src[0].RelAddr << 4); - o_inst->src[1] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y - t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w - VSF_IN_COMPONENT_ZERO, // z - t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x - t_src_class(src[0]. - File), - src[0]. - NegateBase ? - VSF_FLAG_ALL : - VSF_FLAG_NONE) | - (src[0].RelAddr << 4); - o_inst->src[2] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y - t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x - VSF_IN_COMPONENT_ZERO, // z - t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w - t_src_class(src[0]. - File), - src[0]. - NegateBase ? - VSF_FLAG_ALL : - VSF_FLAG_NONE) | - (src[0].RelAddr << 4); - goto next; - - case OPCODE_DPH: //DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ONE} PARAM 0{} {X Y Z W} - o_inst->op = - MAKE_VSF_OP(R300_VPI_OUT_OP_DOT, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - - o_inst->src[0] = - MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), - t_swizzle(GET_SWZ - (src[0].Swizzle, 0)), - t_swizzle(GET_SWZ - (src[0].Swizzle, 1)), - t_swizzle(GET_SWZ - (src[0].Swizzle, 2)), - VSF_IN_COMPONENT_ONE, - t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_XYZ : - VSF_FLAG_NONE) | (src[0]. - RelAddr << 4); - o_inst->src[1] = t_src(vp, &src[1]); - o_inst->src[2] = ZERO_SRC_1; - goto next; - - case OPCODE_XPD: - /* mul r0, r1.yzxw, r2.zxyw - mad r0, -r2.yzxw, r1.zxyw, r0 - NOTE: might need MAD_2 - */ - - o_inst->op = MAKE_VSF_OP(R300_VPI_OUT_OP_MAD, u_temp_i, - t_dst_mask(vpi->DstReg. - WriteMask), - VSF_OUT_CLASS_TMP); - - o_inst->src[0] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y - t_swizzle(GET_SWZ(src[0].Swizzle, 2)), // z - t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x - t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w - t_src_class(src[0]. - File), - src[0]. - NegateBase ? - VSF_FLAG_ALL : - VSF_FLAG_NONE) | - (src[0].RelAddr << 4); - - o_inst->src[1] = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), t_swizzle(GET_SWZ(src[1].Swizzle, 2)), // z - t_swizzle(GET_SWZ(src[1].Swizzle, 0)), // x - t_swizzle(GET_SWZ(src[1].Swizzle, 1)), // y - t_swizzle(GET_SWZ(src[1].Swizzle, 3)), // w - t_src_class(src[1]. - File), - src[1]. - NegateBase ? - VSF_FLAG_ALL : - VSF_FLAG_NONE) | - (src[1].RelAddr << 4); - - o_inst->src[2] = ZERO_SRC_1; - o_inst++; - u_temp_i--; - - o_inst->op = - MAKE_VSF_OP(R300_VPI_OUT_OP_MAD, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - - o_inst->src[0] = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), t_swizzle(GET_SWZ(src[1].Swizzle, 1)), // y - t_swizzle(GET_SWZ(src[1].Swizzle, 2)), // z - t_swizzle(GET_SWZ(src[1].Swizzle, 0)), // x - t_swizzle(GET_SWZ(src[1].Swizzle, 3)), // w - t_src_class(src[1]. - File), - (!src[1]. - NegateBase) ? - VSF_FLAG_ALL : - VSF_FLAG_NONE) | - (src[1].RelAddr << 4); - - o_inst->src[1] = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 2)), // z - t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x - t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y - t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w - t_src_class(src[0]. - File), - src[0]. - NegateBase ? - VSF_FLAG_ALL : - VSF_FLAG_NONE) | - (src[0].RelAddr << 4); - - o_inst->src[2] = MAKE_VSF_SOURCE(u_temp_i + 1, - VSF_IN_COMPONENT_X, - VSF_IN_COMPONENT_Y, - VSF_IN_COMPONENT_Z, - VSF_IN_COMPONENT_W, - VSF_IN_CLASS_TMP, - VSF_FLAG_NONE); - - goto next; - - case OPCODE_RCC: - fprintf(stderr, "Dont know how to handle op %d yet\n", - vpi->Opcode); - _mesa_exit(-1); + inst = + t_opcode_flr(vp, vpi, inst, src, /* FIXME */ + &u_temp_i); + break; + case OPCODE_FRC: + inst = t_opcode_frc(vp, vpi, inst, src); + break; + case OPCODE_LG2: + inst = t_opcode_lg2(vp, vpi, inst, src); + break; + case OPCODE_LIT: + inst = t_opcode_lit(vp, vpi, inst, src); + break; + case OPCODE_LOG: + inst = t_opcode_log(vp, vpi, inst, src); + break; + case OPCODE_MAD: + inst = t_opcode_mad(vp, vpi, inst, src); + break; + case OPCODE_MAX: + inst = t_opcode_max(vp, vpi, inst, src); + break; + case OPCODE_MIN: + inst = t_opcode_min(vp, vpi, inst, src); + break; + case OPCODE_MOV: + inst = t_opcode_mov(vp, vpi, inst, src); break; - case OPCODE_END: + case OPCODE_MUL: + inst = t_opcode_mul(vp, vpi, inst, src); + break; + case OPCODE_POW: + inst = t_opcode_pow(vp, vpi, inst, src); + break; + case OPCODE_RCP: + inst = t_opcode_rcp(vp, vpi, inst, src); + break; + case OPCODE_RSQ: + inst = t_opcode_rsq(vp, vpi, inst, src); + break; + case OPCODE_SGE: + inst = t_opcode_sge(vp, vpi, inst, src); + break; + case OPCODE_SLT: + inst = t_opcode_slt(vp, vpi, inst, src); + break; + case OPCODE_SUB: + inst = t_opcode_sub(vp, vpi, inst, src); + break; + case OPCODE_SWZ: + inst = t_opcode_swz(vp, vpi, inst, src); + break; + case OPCODE_XPD: + inst = + t_opcode_xpd(vp, vpi, inst, src, /* FIXME */ + &u_temp_i); break; default: + assert(0); break; } - - o_inst->op = - MAKE_VSF_OP(t_opcode(vpi->Opcode), - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - - if (are_srcs_scalar) { - switch (operands) { - case 1: - o_inst->src[0] = t_src_scalar(vp, &src[0]); - o_inst->src[1] = ZERO_SRC_0; - o_inst->src[2] = ZERO_SRC_0; - break; - - case 2: - o_inst->src[0] = t_src_scalar(vp, &src[0]); - o_inst->src[1] = t_src_scalar(vp, &src[1]); - o_inst->src[2] = ZERO_SRC_1; - break; - - case 3: - o_inst->src[0] = t_src_scalar(vp, &src[0]); - o_inst->src[1] = t_src_scalar(vp, &src[1]); - o_inst->src[2] = t_src_scalar(vp, &src[2]); - break; - - default: - fprintf(stderr, - "scalars and op RCC not handled yet"); - _mesa_exit(-1); - break; - } - } else { - switch (operands) { - case 1: - o_inst->src[0] = t_src(vp, &src[0]); - o_inst->src[1] = ZERO_SRC_0; - o_inst->src[2] = ZERO_SRC_0; - break; - - case 2: - o_inst->src[0] = t_src(vp, &src[0]); - o_inst->src[1] = t_src(vp, &src[1]); - o_inst->src[2] = ZERO_SRC_1; - break; - - case 3: - o_inst->src[0] = t_src(vp, &src[0]); - o_inst->src[1] = t_src(vp, &src[1]); - o_inst->src[2] = t_src(vp, &src[2]); - break; - - default: - fprintf(stderr, - "scalars and op RCC not handled yet"); - _mesa_exit(-1); - break; - } - } - next:; } - /* Will most likely segfault before we get here... fix later. */ - if (o_inst - vp->program.body.i >= VSF_MAX_FRAGMENT_LENGTH / 4) { + vp->program.length = (inst - vp->program.body.i); + if (vp->program.length >= VSF_MAX_FRAGMENT_LENGTH) { vp->program.length = 0; vp->native = GL_FALSE; - return; } - vp->program.length = (o_inst - vp->program.body.i) * 4; #if 0 fprintf(stderr, "hw program:\n"); for (i = 0; i < vp->program.length; i++) @@ -1065,7 +1309,8 @@ static void position_invariant(struct gl_program *prog) struct gl_program_parameter_list *paramList; int i; - gl_state_index tokens[STATE_LENGTH] = { STATE_MVP_MATRIX, 0, 0, 0, 0 }; + gl_state_index tokens[STATE_LENGTH] = + { STATE_MVP_MATRIX, 0, 0, 0, 0 }; /* tokens[4] = matrix modifier */ #ifdef PREFER_DP4 @@ -1159,8 +1404,8 @@ static void insert_wpos(struct r300_vertex_program *vp, prog->NumInstructions - 1); /* END */ _mesa_copy_instructions(&vpi[prog->NumInstructions + 1], - &prog->Instructions[prog->NumInstructions - 1], - 1); + &prog->Instructions[prog->NumInstructions - + 1], 1); vpi_insert = &vpi[prog->NumInstructions - 1]; vpi_insert[i].Opcode = OPCODE_MOV; @@ -1206,8 +1451,8 @@ static void pos_as_texcoord(struct r300_vertex_program *vp, prog->NumTemporaries++; for (vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++) { - if (vpi->DstReg.File == PROGRAM_OUTPUT && - vpi->DstReg.Index == VERT_RESULT_HPOS) { + if (vpi->DstReg.File == PROGRAM_OUTPUT + && vpi->DstReg.Index == VERT_RESULT_HPOS) { vpi->DstReg.File = PROGRAM_TEMPORARY; vpi->DstReg.Index = tempregi; } @@ -1223,20 +1468,18 @@ static struct r300_vertex_program *build_program(struct r300_vertex_program_key vp = _mesa_calloc(sizeof(*vp)); _mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key)); - vp->wpos_idx = wpos_idx; if (mesa_vp->IsPositionInvariant) { position_invariant(&mesa_vp->Base); } - if (wpos_idx > -1) + if (wpos_idx > -1) { pos_as_texcoord(vp, &mesa_vp->Base); + } assert(mesa_vp->Base.NumInstructions); - vp->num_temporaries = mesa_vp->Base.NumTemporaries; - r300TranslateVertexShader(vp, mesa_vp->Base.Instructions); return vp; @@ -1252,11 +1495,10 @@ void r300SelectVertexShader(r300ContextPtr r300) struct r300_vertex_program *vp; GLint wpos_idx; - vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current; + vpc = + (struct r300_vertex_program_cont *)ctx->VertexProgram._Current; InputsRead = ctx->FragmentProgram._Current->Base.InputsRead; - wanted_key.OutputsWritten |= 1 << VERT_RESULT_HPOS; - wpos_idx = -1; if (InputsRead & FRAG_BIT_WPOS) { for (i = 0; i < ctx->Const.MaxTextureUnits; i++) @@ -1271,28 +1513,35 @@ void r300SelectVertexShader(r300ContextPtr r300) InputsRead |= (FRAG_BIT_TEX0 << i); wpos_idx = i; } + wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead; + wanted_key.OutputsWritten = vpc->mesa_program.Base.OutputsWritten; + + wanted_key.OutputsWritten |= 1 << VERT_RESULT_HPOS; - if (InputsRead & FRAG_BIT_COL0) + if (InputsRead & FRAG_BIT_COL0) { wanted_key.OutputsWritten |= 1 << VERT_RESULT_COL0; + } - if ((InputsRead & FRAG_BIT_COL1) /*|| - (InputsRead & FRAG_BIT_FOGC) */ ) + if ((InputsRead & FRAG_BIT_COL1)) { wanted_key.OutputsWritten |= 1 << VERT_RESULT_COL1; + } - for (i = 0; i < ctx->Const.MaxTextureUnits; i++) - if (InputsRead & (FRAG_BIT_TEX0 << i)) + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { + if (InputsRead & (FRAG_BIT_TEX0 << i)) { wanted_key.OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i); + } + } - wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead; if (vpc->mesa_program.IsPositionInvariant) { /* we wan't position don't we ? */ wanted_key.InputsRead |= (1 << VERT_ATTRIB_POS); + wanted_key.OutputsWritten |= (1 << VERT_RESULT_HPOS); } for (vp = vpc->progs; vp; vp = vp->next) - if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key)) == - 0) { + if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key)) + == 0) { r300->selected_vp = vp; return; } diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.h b/src/mesa/drivers/dri/r300/r300_vertprog.h index 252d5a901f4..3df0eee7991 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.h +++ b/src/mesa/drivers/dri/r300/r300_vertprog.h @@ -3,11 +3,6 @@ #include "r300_reg.h" -typedef struct { - GLuint op; - GLuint src[3]; -} VERTEX_SHADER_INSTRUCTION; - #define VSF_FLAG_X 1 #define VSF_FLAG_Y 2 #define VSF_FLAG_Z 4 diff --git a/src/mesa/drivers/dri/r300/radeon_lock.h b/src/mesa/drivers/dri/r300/radeon_lock.h index c47adc9575b..a344837f475 100644 --- a/src/mesa/drivers/dri/r300/radeon_lock.h +++ b/src/mesa/drivers/dri/r300/radeon_lock.h @@ -42,9 +42,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef __RADEON_LOCK_H__ #define __RADEON_LOCK_H__ -#if 0 -#include "r200_ioctl.h" -#endif #include "radeon_context.h" extern void radeonGetLock(radeonContextPtr rmesa, GLuint flags); diff --git a/src/mesa/drivers/dri/savage/savagetris.c b/src/mesa/drivers/dri/savage/savagetris.c index 3dd821a4d39..4ce2f60b4f3 100644 --- a/src/mesa/drivers/dri/savage/savagetris.c +++ b/src/mesa/drivers/dri/savage/savagetris.c @@ -131,7 +131,9 @@ static __inline__ void savage_draw_point (savageContextPtr imesa, u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize); const GLfloat x = tmp->v.x; const GLfloat y = tmp->v.y; - const GLfloat sz = imesa->glCtx->Point._Size * .5; + const GLfloat sz = 0.5 * CLAMP(imesa->glCtx->Point.Size, + imesa->glCtx->Const.MinPointSize, + imesa->glCtx->Const.MaxPointSize); GLuint j; *(float *)&vb[0] = x - sz; @@ -164,7 +166,9 @@ static __inline__ void savage_draw_line (savageContextPtr imesa, savageVertexPtr v1 ) { GLuint vertsize = imesa->HwVertexSize; u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize); - GLfloat width = imesa->glCtx->Line._Width; + const GLfloat width = CLAMP(imesa->glCtx->Line.Width, + imesa->glCtx->Const.MinLineWidth, + imesa->glCtx->Const.MaxLineWidth); GLfloat dx, dy, ix, iy; GLuint j; @@ -234,7 +238,9 @@ static __inline__ void savage_ptex_line (savageContextPtr imesa, savageVertexPtr v1 ) { GLuint vertsize = imesa->HwVertexSize; u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize); - GLfloat width = imesa->glCtx->Line._Width; + const GLfloat width = CLAMP(imesa->glCtx->Line.Width, + imesa->glCtx->Const.MinLineWidth, + imesa->glCtx->Const.MaxLineWidth); GLfloat dx, dy, ix, iy; savageVertex tmp0, tmp1; GLuint j; @@ -281,7 +287,9 @@ static __inline__ void savage_ptex_point (savageContextPtr imesa, u_int32_t *vb = savageAllocVtxBuf (imesa, 6*vertsize); const GLfloat x = v0->v.x; const GLfloat y = v0->v.y; - const GLfloat sz = imesa->glCtx->Point._Size * .5; + const GLfloat sz = 0.5 * CLAMP(imesa->glCtx->Point.Size, + imesa->glCtx->Const.MinPointSize, + imesa->glCtx->Const.MaxPointSize); savageVertex tmp; GLuint j; diff --git a/src/mesa/drivers/dri/tdfx/tdfx_tris.c b/src/mesa/drivers/dri/tdfx/tdfx_tris.c index 96f9ae27fc1..7252a7e7dc6 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_tris.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_tris.c @@ -184,7 +184,7 @@ tdfx_translate_vertex( GLcontext *ctx, const tdfxVertex *src, SWvertex *dst) } } - dst->pointSize = ctx->Point._Size; + dst->pointSize = ctx->Point.Size; } |