diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index 8d4d604..fde4dc0 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -380,8 +380,10 @@ void r300InitCmdBuf(r300ContextPtr r300) r300->hw.ga_point_minmax.cmd[0] = cmdpacket0(R300_GA_POINT_MINMAX, 3); ALLOC_STATE(lcntl, always, 2, 0); r300->hw.lcntl.cmd[0] = cmdpacket0(R300_GA_LINE_CNTL, 1); - ALLOC_STATE(ga_line_stipple, always, 4, 0); - r300->hw.ga_line_stipple.cmd[0] = cmdpacket0(R300_GA_LINE_STIPPLE_VALUE, 3); + ALLOC_STATE(ga_line_stipple_config, always, 2, 0); + r300->hw.ga_line_stipple_config.cmd[0] = cmdpacket0(R300_GA_LINE_STIPPLE_CONFIG, 1); + ALLOC_STATE(ga_line_stipple_value, always, 2, 0); + r300->hw.ga_line_stipple_value.cmd[0] = cmdpacket0(R300_GA_LINE_STIPPLE_VALUE, 1); ALLOC_STATE(shade, always, 5, 0); r300->hw.shade.cmd[0] = cmdpacket0(R300_GA_ENHANCE, 4); ALLOC_STATE(polygon_mode, always, 4, 0); diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 53e5d18..1c73fba 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -494,7 +494,8 @@ struct r300_hw_state { struct r300_state_atom ps; /* pointsize (421C) */ struct r300_state_atom ga_point_minmax; /* (4230) */ struct r300_state_atom lcntl; /* line control */ - struct r300_state_atom ga_line_stipple; /* (4260) */ + struct r300_state_atom ga_line_stipple_config; /* (4238) */ + struct r300_state_atom ga_line_stipple_value; /* (4260) */ struct r300_state_atom shade; struct r300_state_atom polygon_mode; struct r300_state_atom fogp; /* fog parameters (4294) */ @@ -920,6 +921,7 @@ struct r300_swtcl_info { struct r300_dma_region indexed_verts; }; +#define STIPPLE_PATTERN_MAX 16 /** * \brief R300 context structure. @@ -962,6 +964,10 @@ struct r300_context { DECLARE_RENDERINPUTS(tnl_index_bitset); /* index of bits for last tnl_install_attrs */ struct r300_swtcl_info swtcl; + + GLboolean stipple_line_flag; + struct gl_texture_object *stipple_textures[STIPPLE_PATTERN_MAX]; + struct gl_texture_object *current_stipple_tex; }; struct r300_buffer_object { diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index fc07105..3072b37 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -267,6 +267,11 @@ static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx, if (type < 0 || num_verts <= 0) return; + if ((type == GL_LINES) && (ctx->stipple_line_flag == GL_TRUE)) + { + // bind current_stipple_tex to this primitive + } + if (vb->Elts) { r300EmitAOS(rmesa, rmesa->state.aos_count, start); if (num_verts > 65535) { @@ -373,7 +378,7 @@ static int r300Fallback(GLcontext * ctx) if (!r300->disable_lowimpact_fallback) { FALLBACK_IF(ctx->Polygon.StippleFlag); FALLBACK_IF(ctx->Multisample.Enabled); - FALLBACK_IF(ctx->Line.StippleFlag); +// FALLBACK_IF(ctx->Line.StippleFlag); FALLBACK_IF(ctx->Line.SmoothFlag); FALLBACK_IF(ctx->Point.SmoothFlag); } diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index dc14759..efcb0f6 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -852,6 +852,57 @@ static void r300LineWidth(GLcontext * ctx, GLfloat widthf) R300_LINE_CNT_HO | R300_LINE_CNT_VE | (int)(widthf * 6.0); } +static void r300SetStippleLineState(GLcontext * ctx, GLboolean state) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + r300->stipple_line_flag = state; +} + +static void r300LineStipple(GLcontext * ctx, GLint factor, GLushort pattern) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + int n = -1; // index of current stipple texture + + for (int i=0; istipple_textures[i]) + { + ctx->stipple_textures[i] = r300NewStippleTexture(ctx, pattern); + if (!ctx->stipple_textures[i]) + { + // error + return; + } + n = i; + break; + } + + if (ctx->stipple_textures[i]->Name == pattern) + { + n = i; + break; + } + } + + if (n == -1) + { + // stipple_textures array is full + // and there is no similiar stipple tex in here + // print error + return; + } + + ctx->current_stipple_tex = ctx->stipple_textures[n]; + + R300_STATECHANGE(r300, ga_line_stipple_config); + R300_STATECHANGE(r300, ga_line_stipple_value); + + //it's somehow related to factor, but not to pattern + r300->hw.ga_line_stipple_config.cmd[1] = 0x3b2aaaaa; + + r300->hw.ga_line_stipple_value.cmd[1] = 0; +} + static void r300PolygonMode(GLcontext * ctx, GLenum face, GLenum mode) { (void)face; @@ -2106,6 +2157,9 @@ static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state) case GL_POLYGON_OFFSET_FILL: r300SetPolygonOffsetState(ctx, state); break; + case GL_LINE_STIPPLE: + r300SetStippleLineState(ctx, state); + break; default: radeonEnable(ctx, cap, state); break; @@ -2247,9 +2301,9 @@ static void r300ResetHwState(r300ContextPtr r300) r300LineWidth(ctx, 1.0); - r300->hw.ga_line_stipple.cmd[1] = 0; - r300->hw.ga_line_stipple.cmd[2] = r300PackFloat32(0.0); - r300->hw.ga_line_stipple.cmd[3] = r300PackFloat32(1.0); + r300->hw.ga_line_stipple_config.cmd[1] = 0; +// r300->hw.ga_line_stipple.cmd[2] = r300PackFloat32(0.0); +// r300->hw.ga_line_stipple.cmd[3] = r300PackFloat32(1.0); r300ShadeModel(ctx, ctx->Light.ShadeModel); @@ -2674,6 +2728,7 @@ void r300InitStateFuncs(struct dd_function_table *functions) functions->Fogfv = r300Fogfv; functions->FrontFace = r300FrontFace; functions->ShadeModel = r300ShadeModel; + functions->LineStipple = r300LineStipple; /* Stencil related */ functions->ClearStencil = r300ClearStencil; diff --git a/src/mesa/drivers/dri/r300/r300_tex.c b/src/mesa/drivers/dri/r300/r300_tex.c index 0b4acec..b81547e 100644 --- a/src/mesa/drivers/dri/r300/r300_tex.c +++ b/src/mesa/drivers/dri/r300/r300_tex.c @@ -1161,6 +1161,47 @@ static struct gl_texture_object *r300NewTextureObject(GLcontext * ctx, return obj; } +struct gl_texture_object *r300NewStippleTexture(GLcontext *ctx, + GLushort pattern) +{ + struct gl_texture_object *obj; + struct gl_texture_image *img; + char *pixels; + obj = r300NewTextureObject(ctx, pattern, GL_TEXTURE_1D); + if (!obj) + return NULL; + + img = _mesa_new_texture_image(ctx); + if (!img) + { + r300DeleteTexture(ctx, obj); + return NULL; + } + + pixels = _mesa_alloc_texmemory(sizeof(GLushort)*8); + if (!pixels) + { + r300DeleteTexture(ctx, obj); + _mesa_delete_texture_image(ctx, img); + return NULL; + } + + for (int i=(sizeof(GLushort)*8) - 1; i>=0; ++i) + { + pixels[i] = (pattern & 1); + pattern >>= 1; + } + + r300TexImage1D(ctx, GL_TEXTURE_1D, 0, GL_ALPHA, + (sizeof(GLushort)*8), 0, GL_ALPHA, GL_UNSIGNED_BYTE, + pixels, NULL, obj, img); + + _mesa_set_tex_image(obj, GL_TEXTURE_1D, 0, img); + + r300SetTexFilter(obj->DriverData, GL_LINEAR, GL_LINEAR); + return obj; +} + void r300InitTextureFuncs(struct dd_function_table *functions) { /* Note: we only plug in the functions we implement in the driver