diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index 8d4d604..baee815 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -380,8 +380,12 @@ 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(ga_line_s, always, 3, 0); + r300->hw.ga_line_s.cmd[0] = cmdpacket0(R300_GA_LINE_S0, 2); 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.c b/src/mesa/drivers/dri/r300/r300_context.c index 31cc00a..c2c093d 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -398,6 +398,10 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, RADEON_TCL_FALLBACK_TCL_DISABLE, 1); } + // default stipple pattern + r300->sline.tex = r300_mem_ptr(r300, r300_mem_alloc(r300, 4096, 16)); + r300UpdateStippleTexture(ctx, 0xffff); + return GL_TRUE; } diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 53e5d18..62ec3de 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -494,7 +494,9 @@ 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 ga_line_s; /* (4264/4268) */ struct r300_state_atom shade; struct r300_state_atom polygon_mode; struct r300_state_atom fogp; /* fog parameters (4294) */ @@ -920,6 +922,10 @@ struct r300_swtcl_info { struct r300_dma_region indexed_verts; }; +struct r300_stipple_line { + GLvoid *tex; + GLushort pattern; +}; /** * \brief R300 context structure. @@ -962,6 +968,8 @@ struct r300_context { DECLARE_RENDERINPUTS(tnl_index_bitset); /* index of bits for last tnl_install_attrs */ struct r300_swtcl_info swtcl; + + struct r300_stipple_line sline; }; 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..8669853 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -290,10 +290,17 @@ static GLboolean r300RunRender(GLcontext * ctx, TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *vb = &tnl->vb; - if (RADEON_DEBUG & DEBUG_PRIMS) fprintf(stderr, "%s\n", __FUNCTION__); - +/* + if (ctx->Line.StippleFlag == GL_TRUE) + { + fprintf(stderr, "current fragprog: %i\n", (int) ctx->FragmentProgram._Current); + struct gl_program *fp = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 1); + fprintf(stderr, "current fragprog: %i\n", (int) ctx->FragmentProgram._Current); + ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, fp); + fprintf(stderr, "current fragprog: %i\n", (int) ctx->FragmentProgram._Current); + }*/ r300UpdateShaders(rmesa); if (r300EmitArrays(ctx)) return GL_TRUE; @@ -373,7 +380,6 @@ 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.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..9e7931e 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -852,6 +852,55 @@ 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_STATECHANGE(r300, gb_enable); + if (state == GL_TRUE) + { + char fps[] = "!!ARBfp1.0\nTEMP a;\nINPUT b;\nTEX a, b, texture[0], 1D;\nKIL a;\nMOV result.color, fragment.color;\nEND"; + //char fps[] = "!!ARBfp1.0\nTEX result.texcoord, fragment.color, texture[0], 1D;\nKIL result.texcoord;\nMOV result.color, fragment.color;\nEND"; + + r300->hw.gb_enable.cmd[1] |= R300_GB_LINE_STUFF_ENABLE; + + struct gl_fragment_program fp; + _mesa_parse_arb_fragment_program(ctx, GL_FRAGMENT_PROGRAM_ARB, (GLvoid *) fps, strlen(fps), &fp); + memcpy(ctx->FragmentProgram._Current, &fp, sizeof(struct gl_fragment_program)); + struct r300_fragment_program *rfp = (struct r300_fragment_program *) ctx->FragmentProgram._Current; + r300TranslateFragmentShader(r300, rfp); + fprintf(stderr, "%s: jestem tu\n", __FUNCTION__); + } + else + { + r300->hw.gb_enable.cmd[1] &= ~R300_GB_LINE_STUFF_ENABLE; + } +} + +static void r300LineStipple(GLcontext * ctx, GLint factor, GLushort pattern) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + + // delete stipple tex when destroying context + if (r300->sline.pattern != pattern) + { + //evict current tex + r300UpdateStippleTexture(ctx, pattern); + } + + R300_STATECHANGE(r300, ga_line_stipple_config); + R300_STATECHANGE(r300, ga_line_stipple_value); + R300_STATECHANGE(r300, ga_line_s); + + r300->hw.ga_line_s.cmd[1] = r300PackFloat32(20.0); + r300->hw.ga_line_s.cmd[2] = r300PackFloat32(80.0); + + //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; @@ -1360,6 +1409,7 @@ static void r300SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings) r300->hw.fpt.cmd[R300_FPT_INSTR_0 + i] = val; } } + } r300->hw.fpt.cmd[R300_FPT_CMD_0] = @@ -1495,6 +1545,30 @@ static void r300SetupTextures(GLcontext * ctx) } } + if (/*(type == GL_LINES) &&*/ (ctx->Line.StippleFlag == GL_TRUE)) + { + GLuint offset; + + if (RADEON_DEBUG & DEBUG_STATE) + fprintf(stderr, "Activating texture unit %d\n", hw_tmu+1); + + offset = r300GartOffsetFromVirtual(r300, r300->sline.tex); + + r300->hw.txe.cmd[R300_TXE_ENABLE] |= (1 << hw_tmu); + r300->hw.tex.filter.cmd[R300_TEX_VALUE_0 + hw_tmu] = + R300_TX_MAG_FILTER_LINEAR | R300_TX_MIN_FILTER_LINEAR + | (hw_tmu << 28); + r300->hw.tex.filter_1.cmd[R300_TEX_VALUE_0 + hw_tmu] = 0x0; + r300->hw.tex.size.cmd[R300_TEX_VALUE_0 + hw_tmu] = 15; //16 bit pattern + r300->hw.tex.format.cmd[R300_TEX_VALUE_0 + hw_tmu] = R300_TX_FORMAT_X8; + r300->hw.tex.pitch.cmd[R300_TEX_VALUE_0 + hw_tmu] = 0x0; + r300->hw.tex.offset.cmd[R300_TEX_VALUE_0 + hw_tmu] = offset; + r300->hw.tex.chroma_key.cmd[R300_TEX_VALUE_0 + hw_tmu] = 0x0; + r300->hw.tex.border_color.cmd[R300_TEX_VALUE_0 + hw_tmu] = 0x0; + + last_hw_tmu = hw_tmu; + } + r300->hw.tex.filter.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_FILTER0_0, last_hw_tmu + 1); r300->hw.tex.filter_1.cmd[R300_TEX_CMD_0] = @@ -1516,7 +1590,7 @@ static void r300SetupTextures(GLcontext * ctx) return; - if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) + if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) r300SetupFragmentShaderTextures(ctx, tmu_mappings); else r500SetupFragmentShaderTextures(ctx, tmu_mappings); @@ -2106,6 +2180,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 +2324,11 @@ 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_value.cmd[1] = 0; + + r300->hw.ga_line_s.cmd[1] = r300PackFloat32(0.0); + r300->hw.ga_line_s.cmd[2] = r300PackFloat32(1.0); r300ShadeModel(ctx, ctx->Light.ShadeModel); @@ -2674,6 +2753,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_swtcl.c b/src/mesa/drivers/dri/r300/r300_swtcl.c index 8aebd9b..4745a07 100644 --- a/src/mesa/drivers/dri/r300/r300_swtcl.c +++ b/src/mesa/drivers/dri/r300/r300_swtcl.c @@ -576,6 +576,18 @@ static void r300RenderStart(GLcontext *ctx) r300SetVertexFormat(ctx); r300UpdateShaders(rmesa); +/* + if (ctx->Line.StippleFlag == GL_TRUE) + { + //fprintf(stderr, "current fragprog: %i\n", (int) ctx->FragmentProgram._Current); + struct gl_program *gfp = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 1); + struct r300_fragment_program *fp = (struct r300_fragment_program *) gfp; + fp->tex.inst[0] = R300_TEX_OP_KIL << R300_TEX_INST_SHIFT; + fprintf(stderr, "current fragprog: %i\n", (int) ctx->FragmentProgram._Current); + _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, 1); + fprintf(stderr, "current fragprog: %i\n", (int) ctx->FragmentProgram._Current); + } + */ r300UpdateShaderStates(rmesa); r300EmitCacheFlush(rmesa); diff --git a/src/mesa/drivers/dri/r300/r300_tex.c b/src/mesa/drivers/dri/r300/r300_tex.c index 0b4acec..db96279 100644 --- a/src/mesa/drivers/dri/r300/r300_tex.c +++ b/src/mesa/drivers/dri/r300/r300_tex.c @@ -1161,6 +1161,24 @@ static struct gl_texture_object *r300NewTextureObject(GLcontext * ctx, return obj; } +void r300UpdateStippleTexture(GLcontext *ctx, GLushort pattern) +{ + r300ContextPtr rmesa = R300_CONTEXT(ctx); + GLubyte *pixels = (GLubyte *) rmesa->sline.tex; + + fprintf(stderr, "pattern: "); + + for (int i=15; i>=0; --i) + { + pixels[i] = (pattern & 1) * 10; + fprintf(stderr, "%i ", pixels[i]); + pattern >>= 1; + } + + fprintf(stderr, "\n"); + rmesa->sline.pattern = pattern; +} + void r300InitTextureFuncs(struct dd_function_table *functions) { /* Note: we only plug in the functions we implement in the driver diff --git a/src/mesa/drivers/dri/r300/r300_tex.h b/src/mesa/drivers/dri/r300/r300_tex.h index b86d45b..5520bd6 100644 --- a/src/mesa/drivers/dri/r300/r300_tex.h +++ b/src/mesa/drivers/dri/r300/r300_tex.h @@ -50,4 +50,7 @@ extern void r300DestroyTexObj(r300ContextPtr rmesa, r300TexObjPtr t); extern void r300InitTextureFuncs(struct dd_function_table *functions); + +extern void r300UpdateStippleTexture(GLcontext *ctx, GLushort pattern); + #endif /* __r300_TEX_H__ */ diff --git a/src/mesa/drivers/dri/r300/r300_texmem.c b/src/mesa/drivers/dri/r300/r300_texmem.c index 723601a..3b90aa7 100644 --- a/src/mesa/drivers/dri/r300/r300_texmem.c +++ b/src/mesa/drivers/dri/r300/r300_texmem.c @@ -569,3 +569,104 @@ int r300UploadTexImages(r300ContextPtr rmesa, r300TexObjPtr t, GLuint face) return 0; } +/* +void r300UploadStippleTex(r300ContextPtr rmesa, GLubyte *data) +{ + GLint ret; + drm_radeon_texture_t tex; + drm_radeon_tex_image_t tmp; + GLuint srcPitch, dstPitch; + + if (rmesa->sline.is_dirty == false) + { + return; + } + + if (RADEON_DEBUG & (DEBUG_TEXTURE | DEBUG_IOCTL)) { + fprintf(stderr, "%s: ( %p, %p ) Uploading stipple texture\n", + __FUNCTION__, (void *)rmesa->radeon.glCtx, (void *)data); + } + + if (RADEON_DEBUG & DEBUG_SYNC) { + fprintf(stderr, "%s: Syncing\n", __FUNCTION__); + radeonFinish(rmesa->radeon.glCtx); + } + + if (data == NULL) { + if (RADEON_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, "%s: image data is NULL!\n", __FUNCTION__); + return -1; + } + + tmp.x = 0; + tmp.y = 0; + tmp.width = sizeof(GLushort) * 8; + tmp.height = 1; + tmp.data = (void *) data; + + rmesa->sline.tex_offset = 0; + + r300EmitWait(rmesa, R300_WAIT_3D); + r300EmitBlit(rmesa, + R300_CP_COLOR_FORMAT_CI8, + 16, + r300GartOffsetFromVirtual(rmesa, tmp.data), + 16, + 0, + 0, + 0, + 0, + 0, + 16, + 1); + r300EmitWait(rmesa, R300_WAIT_2D); + tex.image = &tmp; + tex.offset = rmesa->sline.tex_offset; + tex.height = 1; + tex.width = sizeof(GLushort) * 8; + tex.format = RADEON_TXFORMAT_I8; + tex.pitch = 1; + + tex.offset += tmp.x & ~1023; + tmp.x = tmp.x % 1024; +#if 0 + if (t->tile_bits & R300_TXO_MICRO_TILE) { + // need something like "tiled coordinates" ? + tmp.y = tmp.x / (tex.pitch * 128) * 2; + tmp.x = tmp.x % (tex.pitch * 128) / 2; + tex.pitch |= RADEON_DST_TILE_MICRO >> 22; + } +#endif + //fprintf(stderr, "tmp.x=%i, tmp.y=%i\n", tmp.x, tmp.y); + // Macro tiling doesn't apply - tex to small + + LOCK_HARDWARE(&rmesa->radeon); + do { + ret = drmCommandWriteRead(rmesa->radeon.dri.fd, DRM_RADEON_TEXTURE, + &tex, sizeof(drm_radeon_texture_t)); + if (ret) { + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "DRM_RADEON_TEXTURE: again!\n"); + usleep(1); + } + } while (ret == -EAGAIN); + + UNLOCK_HARDWARE(&rmesa->radeon); + + if (ret) { + fprintf(stderr, "DRM_RADEON_TEXTURE: return = %d\n", ret); + fprintf(stderr, " offset=0x%08x\n", tex.offset); + fprintf(stderr, " image width=16 height=1\n"); + fprintf(stderr, " blit width=%d height=%d data=%p\n", + tmp.width, tmp.height, tmp.data); + _mesa_exit(-1); + } + + if (RADEON_DEBUG & DEBUG_SYNC) { + fprintf(stderr, "%s: Syncing\n", __FUNCTION__); + radeonFinish(rmesa->radeon.glCtx); + } + + return 0; +} +*/ \ No newline at end of file