From 8c7e30fb950c83f5e9e29e60735e999ac608145a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 23 Mar 2009 18:27:49 +1000 Subject: raedon/r200/r300: mega-FBO commits. Re work depth issues. Do a lot more FBO abstactions fixup depth/stencil buffer interactions --- src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h | 5 +- src/mesa/drivers/dri/radeon/radeon_common.c | 297 +++++++++++++++++++-- src/mesa/drivers/dri/radeon/radeon_common.h | 19 +- .../drivers/dri/radeon/radeon_common_context.c | 49 +++- .../drivers/dri/radeon/radeon_common_context.h | 22 +- src/mesa/drivers/dri/radeon/radeon_context.c | 9 + src/mesa/drivers/dri/radeon/radeon_context.h | 14 - src/mesa/drivers/dri/radeon/radeon_fbo.c | 27 +- src/mesa/drivers/dri/radeon/radeon_ioctl.c | 217 +-------------- src/mesa/drivers/dri/radeon/radeon_screen.c | 40 +-- src/mesa/drivers/dri/radeon/radeon_span.c | 83 +++--- src/mesa/drivers/dri/radeon/radeon_state.c | 31 ++- src/mesa/drivers/dri/radeon/radeon_state_init.c | 6 - 13 files changed, 466 insertions(+), 353 deletions(-) (limited to 'src/mesa/drivers/dri/radeon') diff --git a/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h b/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h index f80f0f7b22..42607df967 100644 --- a/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h +++ b/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h @@ -36,7 +36,10 @@ struct drm_radeon_gem_info { #endif - +uint32_t radeon_gem_bo_name(struct radeon_bo *dummy) +{ + return 0; +} static inline void *radeon_bo_manager_gem_ctor(int fd) { diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index 4fd54c06c3..9f646c4386 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -58,6 +58,21 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" +#include "main/blend.h" +#include "main/bufferobj.h" +#include "main/buffers.h" +#include "main/depth.h" +#include "main/shaders.h" +#include "main/texstate.h" +#include "main/varray.h" +#include "glapi/dispatch.h" +#include "swrast/swrast.h" +#include "main/stencil.h" +#include "main/matrix.h" +#include "main/attrib.h" +#include "main/enable.h" +#include "main/viewport.h" + #include "dri_util.h" #include "vblank.h" @@ -658,18 +673,20 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb) /* none */ if (fb->Name == 0) { if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { - rrbColor = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + rrbColor = radeon_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); radeon->front_cliprects = GL_TRUE; } else { - rrbColor = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + rrbColor = radeon_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); radeon->front_cliprects = GL_FALSE; } } else { /* user FBO in theory */ struct radeon_renderbuffer *rrb; - rrb = (void *)fb->_ColorDrawBuffers[0]; - offset = rrb->draw_offset; - rrbColor = rrb; + rrb = radeon_renderbuffer(fb->_ColorDrawBuffers[0]); + if (rrb) { + offset = rrb->draw_offset; + rrbColor = rrb; + } radeon->constant_cliprect = GL_TRUE; } @@ -679,9 +696,8 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb) radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE); - if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) { - rrbDepth = (struct radeon_renderbuffer *)fb->_DepthBuffer->Wrapped; + rrbDepth = radeon_renderbuffer(fb->_DepthBuffer->Wrapped); if (rrbDepth && rrbDepth->bo) { radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_FALSE); } else { @@ -692,16 +708,11 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb) rrbDepth = NULL; } - /* TODO stencil things */ if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) { - rrbStencil = (struct radeon_renderbuffer *)fb->_DepthBuffer->Wrapped; + rrbStencil = radeon_renderbuffer(fb->_DepthBuffer->Wrapped); if (rrbStencil && rrbStencil->bo) { radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE); /* need to re-compute stencil hw state */ - if (ctx->Driver.Enable != NULL) - ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); - else - ctx->NewState |= _NEW_STENCIL; if (!rrbDepth) rrbDepth = rrbStencil; } else { @@ -727,27 +738,28 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb) * Update depth test state */ if (ctx->Driver.Enable) { - if (ctx->Depth.Test && fb->Visual.depthBits > 0) { - ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_TRUE); - } else { - ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_FALSE); - } + ctx->Driver.Enable(ctx, GL_DEPTH_TEST, + (ctx->Depth.Test && fb->Visual.depthBits > 0)); + ctx->Driver.Enable(ctx, GL_STENCIL_TEST, + (ctx->Stencil._Enabled && fb->Visual.stencilBits > 0)); } else { - ctx->NewState |= _NEW_DEPTH; + ctx->NewState |= (_NEW_DEPTH | _NEW_STENCIL); } radeon->state.depth.rrb = rrbDepth; - radeon->state.color.rrb = rrbColor; radeon->state.color.draw_offset = offset; +#if 0 /* update viewport since it depends on window size */ if (ctx->Driver.Viewport) { ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y, ctx->Viewport.Width, ctx->Viewport.Height); } else { - ctx->NewState |= _NEW_VIEWPORT; + } +#endif + ctx->NewState |= _NEW_VIEWPORT; /* Set state we know depends on drawable parameters: */ @@ -755,6 +767,19 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb) ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, ctx->Scissor.Width, ctx->Scissor.Height); radeon->NewGLState |= _NEW_SCISSOR; + + if (ctx->Driver.DepthRange) + ctx->Driver.DepthRange(ctx, + ctx->Viewport.Near, + ctx->Viewport.Far); + + /* Update culling direction which changes depending on the + * orientation of the buffer: + */ + if (ctx->Driver.FrontFace) + ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); + else + ctx->NewState |= _NEW_POLYGON; } /** @@ -802,10 +827,6 @@ void radeonUpdatePageFlipping(radeonContextPtr radeon) void radeon_window_moved(radeonContextPtr radeon) { - GLcontext *ctx = radeon->glCtx; - __DRIdrawablePrivate *dPriv = radeon->dri.drawable; - struct radeon_framebuffer *rfb = dPriv->driverPrivate; - if (!radeon->radeonScreen->driScreen->dri2.enabled) { radeonUpdatePageFlipping(radeon); } @@ -949,8 +970,14 @@ void radeonFinish(GLcontext * ctx) if (radeon->radeonScreen->kernel_mm) { for (i = 0; i < fb->_NumColorDrawBuffers; i++) { struct radeon_renderbuffer *rrb; - rrb = (struct radeon_renderbuffer *)fb->_ColorDrawBuffers[i]; - if (rrb->bo) + rrb = radeon_renderbuffer(fb->_ColorDrawBuffers[i]); + if (rrb && rrb->bo) + radeon_bo_wait(rrb->bo); + } + { + struct radeon_renderbuffer *rrb; + rrb = radeon_get_depthbuffer(radeon); + if (rrb && rrb->bo) radeon_bo_wait(rrb->bo); } } else if (radeon->do_irqs) { @@ -1108,3 +1135,219 @@ void rcommonBeginBatch(radeonContextPtr rmesa, int n, +static void +radeon_meta_set_passthrough_transform(radeonContextPtr radeon) +{ + GLcontext *ctx = radeon->glCtx; + + radeon->meta.saved_vp_x = ctx->Viewport.X; + radeon->meta.saved_vp_y = ctx->Viewport.Y; + radeon->meta.saved_vp_width = ctx->Viewport.Width; + radeon->meta.saved_vp_height = ctx->Viewport.Height; + radeon->meta.saved_matrix_mode = ctx->Transform.MatrixMode; + + _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); + + _mesa_MatrixMode(GL_PROJECTION); + _mesa_PushMatrix(); + _mesa_LoadIdentity(); + _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1); + + _mesa_MatrixMode(GL_MODELVIEW); + _mesa_PushMatrix(); + _mesa_LoadIdentity(); +} + +static void +radeon_meta_restore_transform(radeonContextPtr radeon) +{ + _mesa_MatrixMode(GL_PROJECTION); + _mesa_PopMatrix(); + _mesa_MatrixMode(GL_MODELVIEW); + _mesa_PopMatrix(); + + _mesa_MatrixMode(radeon->meta.saved_matrix_mode); + + _mesa_Viewport(radeon->meta.saved_vp_x, radeon->meta.saved_vp_y, + radeon->meta.saved_vp_width, radeon->meta.saved_vp_height); +} + + +/** + * Perform glClear where mask contains only color, depth, and/or stencil. + * + * The implementation is based on calling into Mesa to set GL state and + * performing normal triangle rendering. The intent of this path is to + * have as generic a path as possible, so that any driver could make use of + * it. + */ + + +void radeon_clear_tris(GLcontext *ctx, GLbitfield mask) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLfloat vertices[4][3]; + GLfloat color[4][4]; + GLfloat dst_z; + struct gl_framebuffer *fb = ctx->DrawBuffer; + int i; + GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE; + GLboolean saved_shader_program = 0; + unsigned int saved_active_texture; + + assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH | + BUFFER_BIT_STENCIL)) == 0); + + _mesa_PushAttrib(GL_COLOR_BUFFER_BIT | + GL_CURRENT_BIT | + GL_DEPTH_BUFFER_BIT | + GL_ENABLE_BIT | + GL_STENCIL_BUFFER_BIT | + GL_TRANSFORM_BIT | + GL_CURRENT_BIT); + _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); + saved_active_texture = ctx->Texture.CurrentUnit; + + /* Disable existing GL state we don't want to apply to a clear. */ + _mesa_Disable(GL_ALPHA_TEST); + _mesa_Disable(GL_BLEND); + _mesa_Disable(GL_CULL_FACE); + _mesa_Disable(GL_FOG); + _mesa_Disable(GL_POLYGON_SMOOTH); + _mesa_Disable(GL_POLYGON_STIPPLE); + _mesa_Disable(GL_POLYGON_OFFSET_FILL); + _mesa_Disable(GL_LIGHTING); + _mesa_Disable(GL_CLIP_PLANE0); + _mesa_Disable(GL_CLIP_PLANE1); + _mesa_Disable(GL_CLIP_PLANE2); + _mesa_Disable(GL_CLIP_PLANE3); + _mesa_Disable(GL_CLIP_PLANE4); + _mesa_Disable(GL_CLIP_PLANE5); + if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) { + saved_fp_enable = GL_TRUE; + _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); + } + if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) { + saved_vp_enable = GL_TRUE; + _mesa_Disable(GL_VERTEX_PROGRAM_ARB); + } + if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) { + saved_shader_program = ctx->Shader.CurrentProgram->Name; + _mesa_UseProgramObjectARB(0); + } + + if (ctx->Texture._EnabledUnits != 0) { + int i; + + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { + _mesa_ActiveTextureARB(GL_TEXTURE0 + i); + _mesa_Disable(GL_TEXTURE_1D); + _mesa_Disable(GL_TEXTURE_2D); + _mesa_Disable(GL_TEXTURE_3D); + if (ctx->Extensions.ARB_texture_cube_map) + _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB); + if (ctx->Extensions.NV_texture_rectangle) + _mesa_Disable(GL_TEXTURE_RECTANGLE_NV); + if (ctx->Extensions.MESA_texture_array) { + _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT); + _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT); + } + } + } + + radeon_meta_set_passthrough_transform(rmesa); + + for (i = 0; i < 4; i++) { + color[i][0] = ctx->Color.ClearColor[0]; + color[i][1] = ctx->Color.ClearColor[1]; + color[i][2] = ctx->Color.ClearColor[2]; + color[i][3] = ctx->Color.ClearColor[3]; + } + + /* convert clear Z from [0,1] to NDC coord in [-1,1] */ + + dst_z = -1.0 + 2.0 * ctx->Depth.Clear; + /* Prepare the vertices, which are the same regardless of which buffer we're + * drawing to. + */ + vertices[0][0] = fb->_Xmin; + vertices[0][1] = fb->_Ymin; + vertices[0][2] = dst_z; + vertices[1][0] = fb->_Xmax; + vertices[1][1] = fb->_Ymin; + vertices[1][2] = dst_z; + vertices[2][0] = fb->_Xmax; + vertices[2][1] = fb->_Ymax; + vertices[2][2] = dst_z; + vertices[3][0] = fb->_Xmin; + vertices[3][1] = fb->_Ymax; + vertices[3][2] = dst_z; + + _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &color); + _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), &vertices); + _mesa_Enable(GL_COLOR_ARRAY); + _mesa_Enable(GL_VERTEX_ARRAY); + + while (mask != 0) { + GLuint this_mask = 0; + GLuint color_bit; + + color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS); + if (color_bit != 0) + this_mask |= (1 << (color_bit - 1)); + + /* Clear depth/stencil in the same pass as color. */ + this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)); + + /* Select the current color buffer and use the color write mask if + * we have one, otherwise don't write any color channels. + */ + if (this_mask & BUFFER_BIT_FRONT_LEFT) + _mesa_DrawBuffer(GL_FRONT_LEFT); + else if (this_mask & BUFFER_BIT_BACK_LEFT) + _mesa_DrawBuffer(GL_BACK_LEFT); + else if (color_bit != 0) + _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 + + (color_bit - BUFFER_COLOR0 - 1)); + else + _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + + /* Control writing of the depth clear value to depth. */ + if (this_mask & BUFFER_BIT_DEPTH) { + _mesa_DepthFunc(GL_ALWAYS); + _mesa_DepthMask(GL_TRUE); + _mesa_Enable(GL_DEPTH_TEST); + } else { + _mesa_Disable(GL_DEPTH_TEST); + _mesa_DepthMask(GL_FALSE); + } + + /* Control writing of the stencil clear value to stencil. */ + if (this_mask & BUFFER_BIT_STENCIL) { + _mesa_Enable(GL_STENCIL_TEST); + _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); + _mesa_StencilFuncSeparate(GL_FRONT, GL_ALWAYS, ctx->Stencil.Clear, + ctx->Stencil.WriteMask[0]); + } else { + _mesa_Disable(GL_STENCIL_TEST); + } + + CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); + + mask &= ~this_mask; + } + + radeon_meta_restore_transform(rmesa); + + _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture); + if (saved_fp_enable) + _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); + if (saved_vp_enable) + _mesa_Enable(GL_VERTEX_PROGRAM_ARB); + + if (saved_shader_program) + _mesa_UseProgramObjectARB(saved_shader_program); + + _mesa_PopClientAttrib(); + _mesa_PopAttrib(); +} diff --git a/src/mesa/drivers/dri/radeon/radeon_common.h b/src/mesa/drivers/dri/radeon/radeon_common.h index c97492d742..f3e2290cab 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.h +++ b/src/mesa/drivers/dri/radeon/radeon_common.h @@ -5,6 +5,18 @@ #include "radeon_dma.h" #include "radeon_texture.h" + +#define TRI_CLEAR_COLOR_BITS (BUFFER_BIT_BACK_LEFT | \ + BUFFER_BIT_FRONT_LEFT | \ + BUFFER_BIT_COLOR0 | \ + BUFFER_BIT_COLOR1 | \ + BUFFER_BIT_COLOR2 | \ + BUFFER_BIT_COLOR3 | \ + BUFFER_BIT_COLOR4 | \ + BUFFER_BIT_COLOR5 | \ + BUFFER_BIT_COLOR6 | \ + BUFFER_BIT_COLOR7) + void radeonRecalcScissorRects(radeonContextPtr radeon); void radeonSetCliprects(radeonContextPtr radeon); void radeonUpdateScissor( GLcontext *ctx ); @@ -24,6 +36,8 @@ void radeonFlush(GLcontext *ctx); void radeonFinish(GLcontext * ctx); void radeonEmitState(radeonContextPtr radeon); +void radeon_clear_tris(GLcontext *ctx, GLbitfield mask); + void radeon_window_moved(radeonContextPtr radeon); void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb); void radeonDrawBuffer( GLcontext *ctx, GLenum mode ); @@ -35,7 +49,10 @@ void radeon_get_cliprects(radeonContextPtr radeon, int *x_off, int *y_off); void radeon_fbo_init(struct radeon_context *radeon); -struct gl_renderbuffer * +void +radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb, + struct radeon_bo *bo); +struct radeon_renderbuffer * radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv); static inline struct radeon_renderbuffer *radeon_renderbuffer(struct gl_renderbuffer *rb) { diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c index a818440faf..f335eb0313 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c @@ -392,6 +392,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) struct radeon_framebuffer *draw; radeonContextPtr radeon; char *regname; + struct radeon_bo *depth_bo, *bo; if (RADEON_DEBUG & DEBUG_DRI) fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable); @@ -448,7 +449,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) regname = "dri2 depth buffer"; break; case __DRI_BUFFER_STENCIL: - rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH); + rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL); regname = "dri2 stencil buffer"; break; case __DRI_BUFFER_ACCUM: @@ -463,25 +464,49 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) continue; if (rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; + uint32_t name = radeon_gem_name_bo(rb->bo); + if (name == buffers[i].name) + continue; } + + if (RADEON_DEBUG & DEBUG_DRI) + fprintf(stderr, + "attaching buffer %s, %d, at %d, cpp %d, pitch %d\n", + regname, buffers[i].name, buffers[i].attachment, + buffers[i].cpp, buffers[i].pitch); + rb->cpp = buffers[i].cpp; rb->pitch = buffers[i].pitch; rb->width = drawable->w; rb->height = drawable->h; rb->has_surface = 0; - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - buffers[i].name, - 0, - 0, - RADEON_GEM_DOMAIN_VRAM, - buffers[i].flags); - if (rb->bo == NULL) { - fprintf(stderr, "failed to attach %s %d\n", - regname, buffers[i].name); + if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_bo) { + if (RADEON_DEBUG & DEBUG_DRI) + fprintf(stderr, "(reusing depth buffer as stencil)\n"); + bo = depth_bo; + radeon_bo_ref(bo); + } else { + bo = radeon_bo_open(radeon->radeonScreen->bom, + buffers[i].name, + 0, + 0, + RADEON_GEM_DOMAIN_VRAM, + buffers[i].flags); + if (bo == NULL) { + + fprintf(stderr, "failed to attach %s %d\n", + regname, buffers[i].name); + + } } + + if (buffers[i].attachment == __DRI_BUFFER_DEPTH) + depth_bo = bo; + + radeon_renderbuffer_set_bo(rb, bo); + radeon_bo_unref(bo); + } driUpdateFramebufferSize(radeon->glCtx, drawable); diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h index 612cc97f25..0ce72c9198 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h @@ -123,7 +123,6 @@ struct radeon_colorbuffer_state { struct radeon_depthbuffer_state { GLuint clear; - GLfloat scale; struct radeon_renderbuffer *rrb; }; @@ -137,7 +136,6 @@ struct radeon_scissor_state { }; struct radeon_stencilbuffer_state { - GLboolean hwBuffer; GLuint clear; /* rb3d_stencilrefmask value */ }; @@ -444,9 +442,23 @@ struct radeon_context { struct radeon_cmdbuf cmdbuf; - drm_clip_rect_t fboRect; - GLboolean constant_cliprect; /* use for FBO or DRI2 rendering */ - GLboolean front_cliprects; + drm_clip_rect_t fboRect; + GLboolean constant_cliprect; /* use for FBO or DRI2 rendering */ + GLboolean front_cliprects; + + struct { + struct gl_fragment_program *bitmap_fp; + struct gl_vertex_program *passthrough_vp; + + struct gl_fragment_program *saved_fp; + GLboolean saved_fp_enable; + struct gl_vertex_program *saved_vp; + GLboolean saved_vp_enable; + + GLint saved_vp_x, saved_vp_y; + GLsizei saved_vp_width, saved_vp_height; + GLenum saved_matrix_mode; + } meta; struct { void (*get_lock)(radeonContextPtr radeon); diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index 3f69de8d27..ac945ecc4d 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -66,6 +66,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define need_GL_EXT_blend_minmax #define need_GL_EXT_fog_coord #define need_GL_EXT_secondary_color +#define need_GL_EXT_framebuffer_object #include "extension_helper.h" #define DRIVER_DATE "20061018" @@ -88,6 +89,7 @@ const struct dri_extension card_extensions[] = { "GL_EXT_blend_logic_op", NULL }, { "GL_EXT_blend_subtract", GL_EXT_blend_minmax_functions }, { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions }, + { "GL_EXT_packed_depth_stencil", NULL}, { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions }, { "GL_EXT_stencil_wrap", NULL }, { "GL_EXT_texture_edge_clamp", NULL }, @@ -104,6 +106,11 @@ const struct dri_extension card_extensions[] = { NULL, NULL } }; +const struct dri_extension mm_extensions[] = { + { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions }, + { NULL, NULL } +}; + extern const struct tnl_pipeline_stage _radeon_render_stage; extern const struct tnl_pipeline_stage _radeon_tcl_stage; @@ -338,6 +345,8 @@ radeonCreateContext( const __GLcontextModes *glVisual, } driInitExtensions( ctx, card_extensions, GL_TRUE ); + if (rmesa->radeon.radeonScreen->kernel_mm) + driInitExtensions(ctx, mm_extensions, GL_FALSE); if (rmesa->radeon.radeonScreen->drmSupportsCubeMapsR100) _mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" ); if (rmesa->radeon.glCtx->Mesa_DXTn) { diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h index 2015e96a74..5235a6e374 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_context.h @@ -435,20 +435,6 @@ struct r100_context { GLuint c_textureBytes; GLuint c_vertexBuffers; - struct { - struct gl_fragment_program *bitmap_fp; - struct gl_vertex_program *passthrough_vp; - - struct gl_fragment_program *saved_fp; - GLboolean saved_fp_enable; - struct gl_vertex_program *saved_vp; - GLboolean saved_vp_enable; - - GLint saved_vp_x, saved_vp_y; - GLsizei saved_vp_width, saved_vp_height; - GLenum saved_matrix_mode; - } meta; - }; diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c index 7342f2295e..f914c8c8d0 100644 --- a/src/mesa/drivers/dri/radeon/radeon_fbo.c +++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c @@ -54,7 +54,6 @@ radeon_new_framebuffer(GLcontext *ctx, GLuint name) static void radeon_delete_renderbuffer(struct gl_renderbuffer *rb) { - GET_CURRENT_CONTEXT(ctx); struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); ASSERT(rrb); @@ -62,8 +61,6 @@ radeon_delete_renderbuffer(struct gl_renderbuffer *rb) if (rrb && rrb->bo) { radeon_bo_unref(rrb->bo); } - - _mesa_free(rrb); } @@ -255,7 +252,7 @@ radeon_nop_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, return GL_FALSE; } -struct gl_renderbuffer * +struct radeon_renderbuffer * radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv) { struct radeon_renderbuffer *rrb; @@ -325,7 +322,7 @@ radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv) rrb->base.GetPointer = radeon_get_pointer; rrb->bo = NULL; - return &rrb->base; + return rrb; } static struct gl_renderbuffer * @@ -383,6 +380,13 @@ radeon_update_wrapper(GLcontext *ctx, struct radeon_renderbuffer *rrb, rrb->base.DataType = GL_UNSIGNED_BYTE; DBG("Render to RGBA8 texture OK\n"); } + else if (texImage->TexFormat == &_mesa_texformat_argb4444) { + rrb->cpp = 2; + rrb->base._ActualFormat = GL_RGBA4; + rrb->base._BaseFormat = GL_RGBA; + rrb->base.DataType = GL_UNSIGNED_BYTE; + DBG("Render to RGBA4 texture OK\n"); + } else if (texImage->TexFormat == &_mesa_texformat_rgb565) { rrb->cpp = 2; rrb->base._ActualFormat = GL_RGB5; @@ -493,7 +497,7 @@ radeon_render_texture(GLcontext * ctx, return; } - fprintf(stderr,"Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n", + DBG("Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n", _glthread_GetID(), att->Texture->Name, newImage->Width, newImage->Height, rrb->base.RefCount); @@ -558,4 +562,13 @@ void radeon_fbo_init(struct radeon_context *radeon) } - +void radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb, + struct radeon_bo *bo) +{ + struct radeon_bo *old; + old = rb->bo; + rb->bo = bo; + radeon_bo_ref(bo); + if (old) + radeon_bo_unref(old); +} diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index 22584f4817..f18aa1a4da 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -419,218 +419,6 @@ void radeonEmitAOS( r100ContextPtr rmesa, */ #define RADEON_MAX_CLEARS 256 - - -static void -r100_meta_set_passthrough_transform(r100ContextPtr r100) -{ - GLcontext *ctx = r100->radeon.glCtx; - - r100->meta.saved_vp_x = ctx->Viewport.X; - r100->meta.saved_vp_y = ctx->Viewport.Y; - r100->meta.saved_vp_width = ctx->Viewport.Width; - r100->meta.saved_vp_height = ctx->Viewport.Height; - r100->meta.saved_matrix_mode = ctx->Transform.MatrixMode; - - _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); - - _mesa_MatrixMode(GL_PROJECTION); - _mesa_PushMatrix(); - _mesa_LoadIdentity(); - _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1); - - _mesa_MatrixMode(GL_MODELVIEW); - _mesa_PushMatrix(); - _mesa_LoadIdentity(); -} - -static void -r100_meta_restore_transform(r100ContextPtr r100) -{ - _mesa_MatrixMode(GL_PROJECTION); - _mesa_PopMatrix(); - _mesa_MatrixMode(GL_MODELVIEW); - _mesa_PopMatrix(); - - _mesa_MatrixMode(r100->meta.saved_matrix_mode); - - _mesa_Viewport(r100->meta.saved_vp_x, r100->meta.saved_vp_y, - r100->meta.saved_vp_width, r100->meta.saved_vp_height); -} - -/** - * Perform glClear where mask contains only color, depth, and/or stencil. - * - * The implementation is based on calling into Mesa to set GL state and - * performing normal triangle rendering. The intent of this path is to - * have as generic a path as possible, so that any driver could make use of - * it. - */ -static void radeon_clear_tris(GLcontext *ctx, GLbitfield mask) -{ - r100ContextPtr rmesa = R100_CONTEXT(ctx); - GLfloat vertices[4][3]; - GLfloat color[4][4]; - GLfloat dst_z; - struct gl_framebuffer *fb = ctx->DrawBuffer; - int i; - GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE; - GLboolean saved_shader_program = 0; - unsigned int saved_active_texture; - - assert((mask & ~(BUFFER_BIT_BACK_LEFT | BUFFER_BIT_FRONT_LEFT | - BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) == 0); - - _mesa_PushAttrib(GL_COLOR_BUFFER_BIT | - GL_CURRENT_BIT | - GL_DEPTH_BUFFER_BIT | - GL_ENABLE_BIT | - GL_STENCIL_BUFFER_BIT | - GL_TRANSFORM_BIT | - GL_CURRENT_BIT); - _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); - saved_active_texture = ctx->Texture.CurrentUnit; - - /* Disable existing GL state we don't want to apply to a clear. */ - _mesa_Disable(GL_ALPHA_TEST); - _mesa_Disable(GL_BLEND); - _mesa_Disable(GL_CULL_FACE); - _mesa_Disable(GL_FOG); - _mesa_Disable(GL_POLYGON_SMOOTH); - _mesa_Disable(GL_POLYGON_STIPPLE); - _mesa_Disable(GL_POLYGON_OFFSET_FILL); - _mesa_Disable(GL_LIGHTING); - _mesa_Disable(GL_CLIP_PLANE0); - _mesa_Disable(GL_CLIP_PLANE1); - _mesa_Disable(GL_CLIP_PLANE2); - _mesa_Disable(GL_CLIP_PLANE3); - _mesa_Disable(GL_CLIP_PLANE4); - _mesa_Disable(GL_CLIP_PLANE5); - if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) { - saved_fp_enable = GL_TRUE; - _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); - } - if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) { - saved_vp_enable = GL_TRUE; - _mesa_Disable(GL_VERTEX_PROGRAM_ARB); - } - if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) { - saved_shader_program = ctx->Shader.CurrentProgram->Name; - _mesa_UseProgramObjectARB(0); - } - - if (ctx->Texture._EnabledUnits != 0) { - int i; - - for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - _mesa_ActiveTextureARB(GL_TEXTURE0 + i); - _mesa_Disable(GL_TEXTURE_1D); - _mesa_Disable(GL_TEXTURE_2D); - _mesa_Disable(GL_TEXTURE_3D); - if (ctx->Extensions.ARB_texture_cube_map) - _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB); - if (ctx->Extensions.NV_texture_rectangle) - _mesa_Disable(GL_TEXTURE_RECTANGLE_NV); - if (ctx->Extensions.MESA_texture_array) { - _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT); - _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT); - } - } - } - - r100_meta_set_passthrough_transform(rmesa); - - for (i = 0; i < 4; i++) { - color[i][0] = ctx->Color.ClearColor[0]; - color[i][1] = ctx->Color.ClearColor[1]; - color[i][2] = ctx->Color.ClearColor[2]; - color[i][3] = ctx->Color.ClearColor[3]; - } - - /* convert clear Z from [0,1] to NDC coord in [-1,1] */ - dst_z = -1.0 + 2.0 * ctx->Depth.Clear; - - /* Prepare the vertices, which are the same regardless of which buffer we're - * drawing to. - */ - vertices[0][0] = fb->_Xmin; - vertices[0][1] = fb->_Ymin; - vertices[0][2] = dst_z; - vertices[1][0] = fb->_Xmax; - vertices[1][1] = fb->_Ymin; - vertices[1][2] = dst_z; - vertices[2][0] = fb->_Xmax; - vertices[2][1] = fb->_Ymax; - vertices[2][2] = dst_z; - vertices[3][0] = fb->_Xmin; - vertices[3][1] = fb->_Ymax; - vertices[3][2] = dst_z; - - _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &color); - _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), &vertices); - _mesa_Enable(GL_COLOR_ARRAY); - _mesa_Enable(GL_VERTEX_ARRAY); - - while (mask != 0) { - GLuint this_mask = 0; - - if (mask & BUFFER_BIT_BACK_LEFT) - this_mask = BUFFER_BIT_BACK_LEFT; - else if (mask & BUFFER_BIT_FRONT_LEFT) - this_mask = BUFFER_BIT_FRONT_LEFT; - - /* Clear depth/stencil in the same pass as color. */ - this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)); - - /* Select the current color buffer and use the color write mask if - * we have one, otherwise don't write any color channels. - */ - if (this_mask & BUFFER_BIT_FRONT_LEFT) - _mesa_DrawBuffer(GL_FRONT_LEFT); - else if (this_mask & BUFFER_BIT_BACK_LEFT) - _mesa_DrawBuffer(GL_BACK_LEFT); - else - _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - - /* Control writing of the depth clear value to depth. */ - if (this_mask & BUFFER_BIT_DEPTH) { - _mesa_DepthFunc(GL_ALWAYS); - _mesa_Enable(GL_DEPTH_TEST); - } else { - _mesa_Disable(GL_DEPTH_TEST); - _mesa_DepthMask(GL_FALSE); - } - - /* Control writing of the stencil clear value to stencil. */ - if (this_mask & BUFFER_BIT_STENCIL) { - _mesa_Enable(GL_STENCIL_TEST); - _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); - _mesa_StencilFuncSeparate(GL_FRONT, GL_ALWAYS, ctx->Stencil.Clear, - ctx->Stencil.WriteMask[0]); - } else { - _mesa_Disable(GL_STENCIL_TEST); - } - - CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); - - mask &= ~this_mask; - } - - r100_meta_restore_transform(rmesa); - - _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture); - if (saved_fp_enable) - _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); - if (saved_vp_enable) - _mesa_Enable(GL_VERTEX_PROGRAM_ARB); - - if (saved_shader_program) - _mesa_UseProgramObjectARB(saved_shader_program); - - _mesa_PopClientAttrib(); - _mesa_PopAttrib(); -} - static void radeonUserClear(GLcontext *ctx, GLuint mask) { radeon_clear_tris(ctx, mask); @@ -795,7 +583,7 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask ) mask &= ~BUFFER_BIT_DEPTH; } - if ( (mask & BUFFER_BIT_STENCIL) && rmesa->radeon.state.stencil.hwBuffer ) { + if ( (mask & BUFFER_BIT_STENCIL) ) { flags |= RADEON_STENCIL; mask &= ~BUFFER_BIT_STENCIL; } @@ -813,8 +601,7 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask ) flags |= RADEON_USE_COMP_ZBUF; /* if (rmesa->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL) flags |= RADEON_USE_HIERZ; */ - if (!(rmesa->radeon.state.stencil.hwBuffer) || - ((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) && + if (((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) && ((rmesa->radeon.state.stencil.clear & RADEON_STENCIL_WRITE_MASK) == RADEON_STENCIL_WRITE_MASK))) { flags |= RADEON_CLEAR_FASTZ; } diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index a14a0c3cb2..4725f38ae8 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -1086,6 +1086,9 @@ radeonCreateScreen2(__DRIscreenPrivate *sPriv) else screen->chip_flags |= RADEON_CLASS_R300; + if (getenv("R300_NO_TCL")) + screen->chip_flags &= ~RADEON_CHIPSET_TCL; + i = 0; screen->extensions[i++] = &driCopySubBufferExtension.base; screen->extensions[i++] = &driFrameTrackingExtension.base; @@ -1197,7 +1200,6 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, const GLboolean swStencil = mesaVis->stencilBits > 0 && mesaVis->depthBits != 24; GLenum rgbFormat = (mesaVis->redBits == 5 ? GL_RGB5 : GL_RGBA8); - GLenum depthFormat = GL_NONE; struct radeon_framebuffer *rfb; if (isPixmap) @@ -1209,37 +1211,35 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, _mesa_initialize_framebuffer(&rfb->base, mesaVis); - if (mesaVis->depthBits == 16) - depthFormat = GL_DEPTH_COMPONENT16; - else if (mesaVis->depthBits == 24) - depthFormat = GL_DEPTH_COMPONENT24; - /* front color renderbuffer */ - rfb->color_rb[0] = radeon_renderbuffer(radeon_create_renderbuffer(rgbFormat, driDrawPriv)); + rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv); _mesa_add_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT, &rfb->color_rb[0]->base); rfb->color_rb[0]->has_surface = 1; /* back color renderbuffer */ if (mesaVis->doubleBufferMode) { - rfb->color_rb[1] = radeon_renderbuffer(radeon_create_renderbuffer(rgbFormat, driDrawPriv)); + rfb->color_rb[1] = radeon_create_renderbuffer(rgbFormat, driDrawPriv); _mesa_add_renderbuffer(&rfb->base, BUFFER_BACK_LEFT, &rfb->color_rb[1]->base); rfb->color_rb[1]->has_surface = 1; } - /* depth renderbuffer */ - if (depthFormat != GL_NONE) { - struct radeon_renderbuffer *depth = radeon_renderbuffer( - radeon_create_renderbuffer(depthFormat, driDrawPriv)); + if (mesaVis->depthBits == 24) { + if (mesaVis->stencilBits == 8) { + struct radeon_renderbuffer *depthStencilRb = radeon_create_renderbuffer(GL_DEPTH24_STENCIL8_EXT, driDrawPriv); + _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depthStencilRb->base); + _mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &depthStencilRb->base); + depthStencilRb->has_surface = screen->depthHasSurface; + } else { + /* depth renderbuffer */ + struct radeon_renderbuffer *depth = radeon_create_renderbuffer(GL_DEPTH_COMPONENT24, driDrawPriv); + _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base); + depth->has_surface = screen->depthHasSurface; + } + } else if (mesaVis->depthBits == 16) { + /* just 16-bit depth buffer, no hw stencil */ + struct radeon_renderbuffer *depth = radeon_create_renderbuffer(GL_DEPTH_COMPONENT16, driDrawPriv); _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base); depth->has_surface = screen->depthHasSurface; - } - - /* stencil renderbuffer */ - if (mesaVis->stencilBits > 0 && !swStencil) { - struct radeon_renderbuffer *stencil = radeon_renderbuffer( - radeon_create_renderbuffer(GL_STENCIL_INDEX8_EXT, driDrawPriv)); - _mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &stencil->base); - stencil->has_surface = screen->depthHasSurface; } _mesa_add_soft_renderbuffers(&rfb->base, diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c index 768a51b51d..3d2c5da4c0 100644 --- a/src/mesa/drivers/dri/radeon/radeon_span.c +++ b/src/mesa/drivers/dri/radeon/radeon_span.c @@ -377,33 +377,64 @@ do { \ #include "stenciltmp.h" -static void map_buffer(struct gl_renderbuffer *rb, GLboolean write) +void map_unmap_rb(struct gl_renderbuffer *rb, int flag) { - struct radeon_renderbuffer *rrb = (void*)rb; + struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); int r; - if (rrb->bo) { - r = radeon_bo_map(rrb->bo, write); + if (rrb == NULL || !rrb->bo) + return; + + if (flag) { + r = radeon_bo_map(rrb->bo, 1); if (r) { fprintf(stderr, "(%s) error(%d) mapping buffer.\n", __FUNCTION__, r); } - } - radeonSetSpanFunctions(rrb); + radeonSetSpanFunctions(rrb); + } else { + radeon_bo_unmap(rrb->bo); + rb->GetRow = NULL; + rb->PutRow = NULL; + } } -static void unmap_buffer(struct gl_renderbuffer *rb) +static void +radeon_map_unmap_buffers(GLcontext *ctx, GLboolean map) { - struct radeon_renderbuffer *rrb = (void*)rb; + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLuint i, j; - if (rrb->bo) { - radeon_bo_unmap(rrb->bo); + /* color draw buffers */ + for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers; j++) + map_unmap_rb(ctx->DrawBuffer->_ColorDrawBuffers[j], map); + + /* check for render to textures */ + for (i = 0; i < BUFFER_COUNT; i++) { + struct gl_renderbuffer_attachment *att = + ctx->DrawBuffer->Attachment + i; + struct gl_texture_object *tex = att->Texture; + if (tex) { + /* render to texture */ + ASSERT(att->Renderbuffer); + if (map) + ctx->Driver.MapTexture(ctx, tex); + else + ctx->Driver.UnmapTexture(ctx, tex); + } } - rb->GetRow = NULL; - rb->PutRow = NULL; -} + + map_unmap_rb(ctx->ReadBuffer->_ColorReadBuffer, map); + + /* depth buffer (Note wrapper!) */ + if (ctx->DrawBuffer->_DepthBuffer) + map_unmap_rb(ctx->DrawBuffer->_DepthBuffer->Wrapped, map); + + if (ctx->DrawBuffer->_StencilBuffer) + map_unmap_rb(ctx->DrawBuffer->_StencilBuffer->Wrapped, map); +} static void radeonSpanRenderStart(GLcontext * ctx) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); @@ -416,18 +447,7 @@ static void radeonSpanRenderStart(GLcontext * ctx) ctx->Driver.MapTexture(ctx, ctx->Texture.Unit[i]._Current); } - /* color draw buffers */ - for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { - map_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i], GL_TRUE); - } - - map_buffer(ctx->ReadBuffer->_ColorReadBuffer, GL_FALSE); - - if (ctx->DrawBuffer->_DepthBuffer) { - map_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped, GL_TRUE); - } - if (ctx->DrawBuffer->_StencilBuffer) - map_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped, GL_TRUE); + radeon_map_unmap_buffers(ctx, 1); /* The locking and wait for idle should really only be needed in classic mode. * In a future memory manager based implementation, this should become @@ -450,16 +470,7 @@ static void radeonSpanRenderFinish(GLcontext * ctx) ctx->Driver.UnmapTexture(ctx, ctx->Texture.Unit[i]._Current); } - /* color draw buffers */ - for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) - unmap_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i]); - - unmap_buffer(ctx->ReadBuffer->_ColorReadBuffer); - - if (ctx->DrawBuffer->_DepthBuffer) - unmap_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped); - if (ctx->DrawBuffer->_StencilBuffer) - unmap_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped); + radeon_map_unmap_buffers(ctx, 0); } void radeonInitSpanFuncs(GLcontext * ctx) @@ -485,6 +496,8 @@ static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb) radeonInitDepthPointers_z16(&rrb->base); } else if (rrb->base._ActualFormat == GL_DEPTH_COMPONENT24) { radeonInitDepthPointers_z24_s8(&rrb->base); + } else if (rrb->base._ActualFormat == GL_DEPTH24_STENCIL8_EXT) { + radeonInitStencilPointers_z24_s8(&rrb->base); } else if (rrb->base._ActualFormat == GL_STENCIL_INDEX8_EXT) { radeonInitStencilPointers_z24_s8(&rrb->base); } diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index 635fe43ce4..19ff2688e6 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -528,7 +528,8 @@ static void radeonPolygonOffset( GLcontext *ctx, GLfloat factor, GLfloat units ) { r100ContextPtr rmesa = R100_CONTEXT(ctx); - float_ui32_type constant = { units * rmesa->radeon.state.depth.scale }; + const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; + float_ui32_type constant = { units * depthScale }; float_ui32_type factoru = { factor }; RADEON_STATECHANGE( rmesa, zbs ); @@ -1391,6 +1392,7 @@ void radeonUpdateWindow( GLcontext *ctx ) GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0; const GLfloat *v = ctx->Viewport._WindowMap.m; const GLboolean render_to_fbo = (ctx->DrawBuffer ? (ctx->DrawBuffer->Name != 0) : 0); + const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; GLfloat y_scale, y_bias; if (render_to_fbo) { @@ -1405,8 +1407,8 @@ void radeonUpdateWindow( GLcontext *ctx ) float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X }; float_ui32_type sy = { v[MAT_SY] * y_scale }; float_ui32_type ty = { (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y }; - float_ui32_type sz = { v[MAT_SZ] * rmesa->radeon.state.depth.scale }; - float_ui32_type tz = { v[MAT_TZ] * rmesa->radeon.state.depth.scale }; + float_ui32_type sz = { v[MAT_SZ] * depthScale }; + float_ui32_type tz = { v[MAT_TZ] * depthScale }; RADEON_STATECHANGE( rmesa, vpt ); @@ -1800,15 +1802,24 @@ static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state ) break; case GL_STENCIL_TEST: - if ( rmesa->radeon.state.stencil.hwBuffer ) { - RADEON_STATECHANGE( rmesa, ctx ); - if ( state ) { - rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_STENCIL_ENABLE; + { + GLboolean hw_stencil = GL_FALSE; + if (ctx->DrawBuffer) { + struct radeon_renderbuffer *rrbStencil + = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); + hw_stencil = (rrbStencil && rrbStencil->bo); + } + + if (hw_stencil) { + RADEON_STATECHANGE( rmesa, ctx ); + if ( state ) { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_STENCIL_ENABLE; + } else { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE; + } } else { - rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE; + FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state ); } - } else { - FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state ); } break; diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c index 8b6caf19d3..3d0cd8d3f8 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state_init.c +++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c @@ -592,22 +592,16 @@ void radeonInitState( r100ContextPtr rmesa ) switch ( ctx->Visual.depthBits ) { case 16: rmesa->radeon.state.depth.clear = 0x0000ffff; - rmesa->radeon.state.depth.scale = 1.0 / (GLfloat)0xffff; rmesa->radeon.state.stencil.clear = 0x00000000; break; case 24: rmesa->radeon.state.depth.clear = 0x00ffffff; - rmesa->radeon.state.depth.scale = 1.0 / (GLfloat)0xffffff; rmesa->radeon.state.stencil.clear = 0xffff0000; break; default: break; } - /* Only have hw stencil when depth buffer is 24 bits deep */ - rmesa->radeon.state.stencil.hwBuffer = ( ctx->Visual.stencilBits > 0 && - ctx->Visual.depthBits == 24 ); - rmesa->radeon.Fallback = 0; -- cgit v1.2.3