diff options
26 files changed, 1311 insertions, 799 deletions
diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index 10a6362afd..6fd0575898 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -72,6 +72,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define need_GL_EXT_blend_func_separate #define need_GL_NV_vertex_program #define need_GL_ARB_point_parameters +#define need_GL_EXT_framebuffer_object #include "extension_helper.h" #define DRIVER_DATE "20060602" @@ -124,6 +125,7 @@ const struct dri_extension card_extensions[] = { "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions }, { "GL_EXT_blend_subtract", NULL }, { "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 }, @@ -165,6 +167,11 @@ const struct dri_extension point_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 _r200_render_stage; extern const struct tnl_pipeline_stage _r200_tcl_stage; @@ -418,6 +425,9 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, _math_matrix_set_identity( &rmesa->tmpmat ); driInitExtensions( ctx, card_extensions, GL_TRUE ); + + if (rmesa->radeon.radeonScreen->kernel_mm) + driInitExtensions(ctx, mm_extensions, GL_FALSE); if (!(rmesa->radeon.radeonScreen->chip_flags & R200_CHIPSET_YCBCR_BROKEN)) { /* yuv textures don't work with some chips - R200 / rv280 okay so far others get the bit ordering right but don't actually do YUV-RGB conversion */ @@ -453,6 +463,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, #endif /* plug in a few more device driver functions */ /* XXX these should really go right after _mesa_init_driver_functions() */ + radeon_fbo_init(&rmesa->radeon); radeonInitSpanFuncs( ctx ); r200InitPixelFuncs( ctx ); r200InitTnlFuncs( ctx ); diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h index f7bad2a241..fcbe725d6f 100644 --- a/src/mesa/drivers/dri/r200/r200_context.h +++ b/src/mesa/drivers/dri/r200/r200_context.h @@ -621,21 +621,6 @@ struct r200_context { GLboolean texmicrotile; struct ati_fragment_shader *afs_loaded; - - 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; - }; #define R200_CONTEXT(ctx) ((r200ContextPtr)(ctx->DriverCtx)) diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c index 96ed49665b..ccb56202f6 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.c +++ b/src/mesa/drivers/dri/r200/r200_ioctl.c @@ -41,19 +41,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/context.h" #include "swrast/swrast.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 "radeon_common.h" #include "radeon_lock.h" @@ -70,217 +58,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define R200_TIMEOUT 512 #define R200_IDLE_RETRY 16 -static void -r200_meta_set_passthrough_transform(r200ContextPtr r200) -{ - GLcontext *ctx = r200->radeon.glCtx; - - r200->meta.saved_vp_x = ctx->Viewport.X; - r200->meta.saved_vp_y = ctx->Viewport.Y; - r200->meta.saved_vp_width = ctx->Viewport.Width; - r200->meta.saved_vp_height = ctx->Viewport.Height; - r200->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 -r200_meta_restore_transform(r200ContextPtr r200) -{ - _mesa_MatrixMode(GL_PROJECTION); - _mesa_PopMatrix(); - _mesa_MatrixMode(GL_MODELVIEW); - _mesa_PopMatrix(); - - _mesa_MatrixMode(r200->meta.saved_matrix_mode); - - _mesa_Viewport(r200->meta.saved_vp_x, r200->meta.saved_vp_y, - r200->meta.saved_vp_width, r200->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) -{ - r200ContextPtr rmesa = R200_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); - } - } - } - - r200_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; - } - - r200_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 r200UserClear(GLcontext *ctx, GLuint mask) { radeon_clear_tris(ctx, mask); @@ -449,7 +226,7 @@ static void r200Clear( 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; } @@ -467,8 +244,7 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask ) flags |= RADEON_USE_COMP_ZBUF; /* if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R200) 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 & R200_STENCIL_WRITE_MASK) == R200_STENCIL_WRITE_MASK))) { flags |= RADEON_CLEAR_FASTZ; } diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index 5eb61c8804..ca4dee8a5b 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -740,7 +740,8 @@ static void r200PolygonOffset( GLcontext *ctx, GLfloat factor, GLfloat units ) { r200ContextPtr rmesa = R200_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 }; /* factor *= 2; */ @@ -1610,13 +1611,24 @@ void r200UpdateWindow( GLcontext *ctx ) GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0; 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) { + y_scale = 1.0; + y_bias = 0; + } else { + y_scale = -1.0; + y_bias = yoffset; + } float_ui32_type sx = { v[MAT_SX] }; float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X }; - float_ui32_type sy = { - v[MAT_SY] }; - float_ui32_type ty = { (- v[MAT_TY]) + yoffset + 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 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] * depthScale }; + float_ui32_type tz = { v[MAT_TZ] * depthScale }; R200_STATECHANGE( rmesa, vpt ); @@ -2004,15 +2016,24 @@ static void r200Enable( GLcontext *ctx, GLenum cap, GLboolean state ) break; case GL_STENCIL_TEST: - if ( rmesa->radeon.state.stencil.hwBuffer ) { - R200_STATECHANGE( rmesa, ctx ); - if ( state ) { - rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_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) { + R200_STATECHANGE( rmesa, ctx ); + if ( state ) { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_STENCIL_ENABLE; + } else { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_STENCIL_ENABLE; + } } else { - rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_STENCIL_ENABLE; + FALLBACK( rmesa, R200_FALLBACK_STENCIL, state ); } - } else { - FALLBACK( rmesa, R200_FALLBACK_STENCIL, state ); } break; diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c index a71f33ca3b..30326c2960 100644 --- a/src/mesa/drivers/dri/r200/r200_state_init.c +++ b/src/mesa/drivers/dri/r200/r200_state_init.c @@ -674,21 +674,15 @@ void r200InitState( r200ContextPtr 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: default: rmesa->radeon.state.depth.clear = 0x00ffffff; - rmesa->radeon.state.depth.scale = 1.0 / (GLfloat)0xffffff; rmesa->radeon.state.stencil.clear = 0xffff0000; 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; rmesa->radeon.hw.max_state_size = 0; diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile index 497b1ec528..0dff9a1273 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile @@ -31,7 +31,8 @@ RADEON_COMMON_SOURCES = \ radeon_bo_legacy.c \ radeon_cs_legacy.c \ radeon_mipmap_tree.c \ - radeon_span.c + radeon_span.c \ + radeon_fbo.c DRIVER_SOURCES = \ radeon_screen.c \ @@ -96,7 +97,8 @@ COMMON_SYMLINKS = \ radeon_mipmap_tree.c \ radeon_mipmap_tree.h \ radeon_texture.c \ - radeon_texture.h + radeon_texture.h \ + radeon_fbo.c DRI_LIB_DEPS += $(RADEON_LDFLAGS) diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index 2c6618fc60..d85f106c11 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -213,6 +213,7 @@ static void emit_cb_offset(GLcontext *ctx, struct radeon_state_atom * atom) BATCH_LOCALS(&r300->radeon); struct radeon_renderbuffer *rrb; uint32_t cbpitch; + uint32_t offset = r300->radeon.state.color.draw_offset; rrb = radeon_get_colorbuffer(&r300->radeon); if (!rrb || !rrb->bo) { @@ -231,7 +232,7 @@ static void emit_cb_offset(GLcontext *ctx, struct radeon_state_atom * atom) BEGIN_BATCH_NO_AUTOSTATE(6); OUT_BATCH_REGSEQ(R300_RB3D_COLOROFFSET0, 1); - OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); + OUT_BATCH_RELOC(offset, rrb->bo, offset, 0, RADEON_GEM_DOMAIN_VRAM, 0); OUT_BATCH_REGSEQ(R300_RB3D_COLORPITCH0, 1); OUT_BATCH(cbpitch); END_BATCH(); diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 5bae37e1b1..c6bd69ed14 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -82,14 +82,17 @@ int hw_tcl_on = 1; #define need_GL_EXT_blend_equation_separate #define need_GL_EXT_blend_func_separate #define need_GL_EXT_blend_minmax +#define need_GL_EXT_framebuffer_object #define need_GL_EXT_fog_coord #define need_GL_EXT_gpu_program_parameters #define need_GL_EXT_secondary_color #define need_GL_EXT_stencil_two_side #define need_GL_ATI_separate_stencil #define need_GL_NV_vertex_program + #include "extension_helper.h" + const struct dri_extension card_extensions[] = { /* *INDENT-OFF* */ {"GL_ARB_depth_texture", NULL}, @@ -110,6 +113,7 @@ const struct dri_extension card_extensions[] = { {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, {"GL_EXT_blend_subtract", NULL}, + {"GL_EXT_packed_depth_stencil", NULL}, {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions }, {"GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions}, {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, @@ -137,6 +141,11 @@ const struct dri_extension card_extensions[] = { }; +const struct dri_extension mm_extensions[] = { + { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions }, + { NULL, NULL } +}; + /** * The GL 2.0 functions are needed to make display lists work with * functions added by GL_ATI_separate_stencil. @@ -417,6 +426,8 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; driInitExtensions(ctx, card_extensions, GL_TRUE); + if (r300->radeon.radeonScreen->kernel_mm) + driInitExtensions(ctx, mm_extensions, GL_FALSE); if (driQueryOptionb (&r300->radeon.optionCache, "disable_stencil_two_side")) @@ -435,7 +446,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, r300->disable_lowimpact_fallback = driQueryOptionb(&r300->radeon.optionCache, "disable_lowimpact_fallback"); - + radeon_fbo_init(&r300->radeon); radeonInitSpanFuncs( ctx ); r300InitCmdBuf(r300); r300InitState(r300); diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index d1cf57959f..71661eef19 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -66,6 +66,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define CLEARBUFFER_DEPTH 0x2 #define CLEARBUFFER_STENCIL 0x4 +static void r300EmitClearState(GLcontext * ctx); + +static void r300UserClear(GLcontext *ctx, GLuint mask) +{ + radeon_clear_tris(ctx, mask); +} + static void r300ClearBuffer(r300ContextPtr r300, int flags, struct radeon_renderbuffer *rrb, struct radeon_renderbuffer *rrbd) @@ -534,6 +541,47 @@ static void r300EmitClearState(GLcontext * ctx) } } +static void r300KernelClear(GLcontext *ctx, GLuint flags) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable; + struct radeon_framebuffer *rfb = dPriv->driverPrivate; + struct radeon_renderbuffer *rrb; + struct radeon_renderbuffer *rrbd; + int bits = 0; + + /* Make sure it fits there. */ + rcommonEnsureCmdBufSpace(&r300->radeon, 421 * 3, __FUNCTION__); + if (flags || bits) + r300EmitClearState(ctx); + rrbd = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH); + if (rrbd && (flags & BUFFER_BIT_DEPTH)) + bits |= CLEARBUFFER_DEPTH; + + if (flags & BUFFER_BIT_COLOR0) { + rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_COLOR0); + r300ClearBuffer(r300, CLEARBUFFER_COLOR, rrb, NULL); + bits = 0; + } + + if (flags & BUFFER_BIT_FRONT_LEFT) { + rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT); + r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd); + bits = 0; + } + + if (flags & BUFFER_BIT_BACK_LEFT) { + rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_BACK_LEFT); + r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd); + bits = 0; + } + + if (bits) + r300ClearBuffer(r300, bits, NULL, rrbd); + + COMMIT_BATCH(); +} + /** * Buffer clear */ @@ -541,16 +589,15 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) { r300ContextPtr r300 = R300_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable; - struct radeon_framebuffer *rfb = dPriv->driverPrivate; - struct radeon_renderbuffer *rrb; - struct radeon_renderbuffer *rrbd; - int flags = 0; - int bits = 0; + const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask); + GLbitfield swrast_mask = 0, tri_mask = 0; + int i; + struct gl_framebuffer *fb = ctx->DrawBuffer; if (RADEON_DEBUG & DEBUG_IOCTL) fprintf(stderr, "r300Clear\n"); - { + if (!r300->radeon.radeonScreen->driScreen->dri2.enabled) { LOCK_HARDWARE(&r300->radeon); UNLOCK_HARDWARE(&r300->radeon); if (dPriv->numClipRects == 0) @@ -563,57 +610,52 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) */ R300_NEWPRIM(r300); - if (mask & BUFFER_BIT_FRONT_LEFT) { - flags |= BUFFER_BIT_FRONT_LEFT; - mask &= ~BUFFER_BIT_FRONT_LEFT; - } + if (colorMask == ~0) + tri_mask |= (mask & BUFFER_BITS_COLOR); + - if (mask & BUFFER_BIT_BACK_LEFT) { - flags |= BUFFER_BIT_BACK_LEFT; - mask &= ~BUFFER_BIT_BACK_LEFT; + /* HW stencil */ + if (mask & BUFFER_BIT_STENCIL) { + tri_mask |= BUFFER_BIT_STENCIL; } + /* HW depth */ if (mask & BUFFER_BIT_DEPTH) { - bits |= CLEARBUFFER_DEPTH; - mask &= ~BUFFER_BIT_DEPTH; + tri_mask |= BUFFER_BIT_DEPTH; } - if ((mask & BUFFER_BIT_STENCIL) && r300->radeon.state.stencil.hwBuffer) { - bits |= CLEARBUFFER_STENCIL; - mask &= ~BUFFER_BIT_STENCIL; - } + /* If we're doing a tri pass for depth/stencil, include a likely color + * buffer with it. + */ - if (mask) { - if (RADEON_DEBUG & DEBUG_FALLBACKS) - fprintf(stderr, "%s: swrast clear, mask: %x\n", - __FUNCTION__, mask); - _swrast_Clear(ctx, mask); + for (i = 0; i < BUFFER_COUNT; i++) { + GLuint bufBit = 1 << i; + if ((tri_mask) & bufBit) { + if (!fb->Attachment[i].Renderbuffer->ClassID) { + tri_mask &= ~bufBit; + swrast_mask |= bufBit; + } + } } - /* Make sure it fits there. */ - rcommonEnsureCmdBufSpace(&r300->radeon, 421 * 3, __FUNCTION__); - if (flags || bits) - r300EmitClearState(ctx); - rrbd = (void *)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer; + /* SW fallback clearing */ + swrast_mask = mask & ~tri_mask; - if (flags & BUFFER_BIT_FRONT_LEFT) { - rrb = (void *)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd); - bits = 0; + if (tri_mask) { + if (r300->radeon.radeonScreen->kernel_mm) + r300UserClear(ctx, tri_mask); + else + r300KernelClear(ctx, tri_mask); } - - if (flags & BUFFER_BIT_BACK_LEFT) { - rrb = (void *)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; - r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd); - bits = 0; + if (swrast_mask) { + if (RADEON_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "%s: swrast clear, mask: %x\n", + __FUNCTION__, swrast_mask); + _swrast_Clear(ctx, swrast_mask); } - - if (bits) - r300ClearBuffer(r300, bits, NULL, rrbd); - - COMMIT_BATCH(); } + void r300InitIoctlFuncs(struct dd_function_table *functions) { functions->Clear = r300Clear; diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index f423029ee6..f49b43c207 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -587,8 +587,14 @@ static void r300SetDepthState(GLcontext * ctx) static void r300SetStencilState(GLcontext * ctx, GLboolean state) { r300ContextPtr r300 = R300_CONTEXT(ctx); + 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 (r300->radeon.state.stencil.hwBuffer) { + if (hw_stencil) { R300_STATECHANGE(r300, zs); if (state) { r300->hw.zs.cmd[R300_ZS_CNTL_0] |= @@ -933,13 +939,24 @@ static void r300UpdateWindow(GLcontext * ctx) GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0; GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0; const GLfloat *v = ctx->Viewport._WindowMap.m; + const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; + const GLboolean render_to_fbo = (ctx->DrawBuffer->Name != 0); + GLfloat y_scale, y_bias; + + if (render_to_fbo) { + y_scale = 1.0; + y_bias = 0; + } else { + y_scale = -1.0; + y_bias = yoffset; + } GLfloat sx = v[MAT_SX]; GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X; - GLfloat sy = -v[MAT_SY]; - GLfloat ty = (-v[MAT_TY]) + yoffset + SUBPIXEL_Y; - GLfloat sz = v[MAT_SZ] * rmesa->radeon.state.depth.scale; - GLfloat tz = v[MAT_TZ] * rmesa->radeon.state.depth.scale; + GLfloat sy = v[MAT_SY] * y_scale; + GLfloat ty = (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y; + GLfloat sz = v[MAT_SZ] * depthScale; + GLfloat tz = v[MAT_TZ] * depthScale; R300_STATECHANGE(rmesa, vpt); @@ -2022,7 +2039,7 @@ static void r300ResetHwState(r300ContextPtr r300) fprintf(stderr, "%s\n", __FUNCTION__); radeon_firevertices(&r300->radeon); - r300UpdateWindow(ctx); + //r300UpdateWindow(ctx); r300ColorMask(ctx, ctx->Color.ColorMask[RCOMP], @@ -2197,16 +2214,6 @@ static void r300ResetHwState(r300ContextPtr r300) r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[1] = 0x00000000; r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[2] = 0xffffffff; - rrb = r300->radeon.state.depth.rrb; - if (rrb && rrb->bo && (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE)) { - /* XXX: Turn off when clearing buffers ? */ - r300->hw.zb.cmd[R300_ZB_PITCH] |= R300_DEPTHMACROTILE_ENABLE; - - if (ctx->Visual.depthBits == 24) - r300->hw.zb.cmd[R300_ZB_PITCH] |= - R300_DEPTHMICROTILE_TILED; - } - r300->hw.zb_depthclearvalue.cmd[1] = 0; r300->hw.zstencil_format.cmd[2] = R300_ZTOP_DISABLE; @@ -2520,10 +2527,6 @@ void r300InitState(r300ContextPtr r300) GLcontext *ctx = r300->radeon.glCtx; GLuint depth_fmt; - /* Only have hw stencil when depth buffer is 24 bits deep */ - r300->radeon.state.stencil.hwBuffer = (ctx->Visual.stencilBits > 0 && - ctx->Visual.depthBits == 24); - memset(&(r300->state.texture), 0, sizeof(r300->state.texture)); r300ResetHwState(r300); 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 840233ff89..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" @@ -132,10 +147,10 @@ void radeonRecalcScissorRects(radeonContextPtr radeon) } } -static void radeon_get_cliprects(radeonContextPtr radeon, - struct drm_clip_rect **cliprects, - unsigned int *num_cliprects, - int *x_off, int *y_off) +void radeon_get_cliprects(radeonContextPtr radeon, + struct drm_clip_rect **cliprects, + unsigned int *num_cliprects, + int *x_off, int *y_off) { __DRIdrawablePrivate *dPriv = radeon->dri.drawable; struct radeon_framebuffer *rfb = dPriv->driverPrivate; @@ -619,6 +634,7 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb) radeonContextPtr radeon = RADEON_CONTEXT(ctx); struct radeon_renderbuffer *rrbDepth = NULL, *rrbStencil = NULL, *rrbColor = NULL; + uint32_t offset = 0; if (!fb) { @@ -657,17 +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]; - rrbColor = rrb; + rrb = radeon_renderbuffer(fb->_ColorDrawBuffers[0]); + if (rrb) { + offset = rrb->draw_offset; + rrbColor = rrb; + } radeon->constant_cliprect = GL_TRUE; } @@ -677,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 { @@ -690,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 { @@ -725,26 +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: */ @@ -752,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; } /** @@ -799,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); } @@ -946,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) { @@ -1105,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 814da1b4f5..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,12 +36,24 @@ 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 ); void radeonReadBuffer( GLcontext *ctx, GLenum mode ); void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height); +void radeon_get_cliprects(radeonContextPtr radeon, + struct drm_clip_rect **cliprects, + unsigned int *num_cliprects, + int *x_off, int *y_off); +void radeon_fbo_init(struct radeon_context *radeon); +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) { struct radeon_renderbuffer *rrb = (struct radeon_renderbuffer *)rb; @@ -60,12 +84,8 @@ static inline struct radeon_renderbuffer *radeon_get_depthbuffer(radeonContextPt static inline struct radeon_renderbuffer *radeon_get_colorbuffer(radeonContextPtr rmesa) { struct radeon_renderbuffer *rrb; - struct radeon_framebuffer *rfb = rmesa->dri.drawable->driverPrivate; rrb = rmesa->state.color.rrb; - if (rmesa->radeonScreen->driScreen->dri2.enabled) { - rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_BACK_LEFT); - } if (!rrb) return NULL; return rrb; 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 e5ada622b0..0ce72c9198 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h @@ -82,6 +82,7 @@ struct radeon_renderbuffer unsigned int width; unsigned int height; + uint32_t draw_offset; /* FBO */ /* boo Xorg 6.8.2 compat */ int has_surface; @@ -117,11 +118,11 @@ struct radeon_colorbuffer_state { GLuint clear; int roundEnable; struct radeon_renderbuffer *rrb; + uint32_t draw_offset; /* offset into color renderbuffer - FBOs */ }; struct radeon_depthbuffer_state { GLuint clear; - GLfloat scale; struct radeon_renderbuffer *rrb; }; @@ -135,7 +136,6 @@ struct radeon_scissor_state { }; struct radeon_stencilbuffer_state { - GLboolean hwBuffer; GLuint clear; /* rb3d_stencilrefmask value */ }; @@ -442,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 47ebe41c6d..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) { @@ -352,6 +361,7 @@ radeonCreateContext( const __GLcontextModes *glVisual, _mesa_enable_extension( ctx, "GL_NV_texture_rectangle"); /* XXX these should really go right after _mesa_init_driver_functions() */ + radeon_fbo_init(&rmesa->radeon); radeonInitSpanFuncs( ctx ); radeonInitIoctlFuncs( ctx ); radeonInitStateFuncs( ctx ); 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 new file mode 100644 index 0000000000..f914c8c8d0 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c @@ -0,0 +1,574 @@ +/************************************************************************** + * + * Copyright 2008 Red Hat Inc. + * 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 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 TUNGSTEN GRAPHICS 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. + * + **************************************************************************/ + + +#include "main/imports.h" +#include "main/macros.h" +#include "main/mtypes.h" +#include "main/fbobject.h" +#include "main/framebuffer.h" +#include "main/renderbuffer.h" +#include "main/context.h" +#include "main/texformat.h" +#include "main/texrender.h" + +#include "radeon_common.h" +#include "radeon_mipmap_tree.h" + +#define FILE_DEBUG_FLAG DEBUG_TEXTURE +#define DBG(...) do { \ + if (RADEON_DEBUG & FILE_DEBUG_FLAG) \ + _mesa_printf(__VA_ARGS__); \ +} while(0) + +static struct gl_framebuffer * +radeon_new_framebuffer(GLcontext *ctx, GLuint name) +{ + return _mesa_new_framebuffer(ctx, name); +} + +static void +radeon_delete_renderbuffer(struct gl_renderbuffer *rb) +{ + struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); + + ASSERT(rrb); + + if (rrb && rrb->bo) { + radeon_bo_unref(rrb->bo); + } + _mesa_free(rrb); +} + +static void * +radeon_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb, + GLint x, GLint y) +{ + return NULL; +} + +/** + * Called via glRenderbufferStorageEXT() to set the format and allocate + * storage for a user-created renderbuffer. + */ +static GLboolean +radeon_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) +{ + struct radeon_context *radeon = RADEON_CONTEXT(ctx); + struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); + GLboolean software_buffer = GL_FALSE; + int cpp; + + ASSERT(rb->Name != 0); + switch (internalFormat) { + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + rb->_ActualFormat = GL_RGB5; + rb->DataType = GL_UNSIGNED_BYTE; + rb->RedBits = 5; + rb->GreenBits = 6; + rb->BlueBits = 5; + cpp = 2; + break; + case GL_RGB: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + rb->_ActualFormat = GL_RGB8; + rb->DataType = GL_UNSIGNED_BYTE; + rb->RedBits = 8; + rb->GreenBits = 8; + rb->BlueBits = 8; + rb->AlphaBits = 0; + cpp = 4; + break; + case GL_RGBA: + case GL_RGBA2: + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + rb->_ActualFormat = GL_RGBA8; + rb->DataType = GL_UNSIGNED_BYTE; + rb->RedBits = 8; + rb->GreenBits = 8; + rb->BlueBits = 8; + rb->AlphaBits = 8; + cpp = 4; + break; + case GL_STENCIL_INDEX: + case GL_STENCIL_INDEX1_EXT: + case GL_STENCIL_INDEX4_EXT: + case GL_STENCIL_INDEX8_EXT: + case GL_STENCIL_INDEX16_EXT: + /* alloc a depth+stencil buffer */ + rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; + rb->DataType = GL_UNSIGNED_INT_24_8_EXT; + rb->StencilBits = 8; + cpp = 4; + break; + case GL_DEPTH_COMPONENT16: + rb->_ActualFormat = GL_DEPTH_COMPONENT16; + rb->DataType = GL_UNSIGNED_SHORT; + rb->DepthBits = 16; + cpp = 2; + break; + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: + rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; + rb->DataType = GL_UNSIGNED_INT_24_8_EXT; + rb->DepthBits = 24; + cpp = 4; + break; + case GL_DEPTH_STENCIL_EXT: + case GL_DEPTH24_STENCIL8_EXT: + rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; + rb->DataType = GL_UNSIGNED_INT_24_8_EXT; + rb->DepthBits = 24; + rb->StencilBits = 8; + cpp = 4; + break; + default: + _mesa_problem(ctx, + "Unexpected format in intel_alloc_renderbuffer_storage"); + return GL_FALSE; + } + + radeonFlush(ctx); + + if (rrb->bo) + radeon_bo_unref(rrb->bo); + + + if (software_buffer) { + return _mesa_soft_renderbuffer_storage(ctx, rb, internalFormat, + width, height); + } + else { + uint32_t size = width * height * cpp; + uint32_t pitch = ((cpp * width + 63) & ~63) / cpp; + + fprintf(stderr,"Allocating %d x %d radeon RBO (pitch %d)\n", width, + height, pitch); + + rrb->pitch = pitch * cpp; + rrb->cpp = cpp; + rrb->bo = radeon_bo_open(radeon->radeonScreen->bom, + 0, + size, + 0, + RADEON_GEM_DOMAIN_VRAM, + 0); + rb->Width = width; + rb->Height = height; + return GL_TRUE; + } + +} + + +/** + * Called for each hardware renderbuffer when a _window_ is resized. + * Just update fields. + * Not used for user-created renderbuffers! + */ +static GLboolean +radeon_alloc_window_storage(GLcontext * ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, GLuint width, GLuint height) +{ + ASSERT(rb->Name == 0); + rb->Width = width; + rb->Height = height; + rb->_ActualFormat = internalFormat; + + return GL_TRUE; +} + + +static void +radeon_resize_buffers(GLcontext *ctx, struct gl_framebuffer *fb, + GLuint width, GLuint height) +{ + struct radeon_framebuffer *radeon_fb = (struct radeon_framebuffer*)fb; + int i; + + _mesa_resize_framebuffer(ctx, fb, width, height); + + fb->Initialized = GL_TRUE; /* XXX remove someday */ + + if (fb->Name != 0) { + return; + } + + /* Make sure all window system renderbuffers are up to date */ + for (i = 0; i < 2; i++) { + struct gl_renderbuffer *rb = &radeon_fb->color_rb[i]->base; + + /* only resize if size is changing */ + if (rb && (rb->Width != width || rb->Height != height)) { + rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height); + } + } +} + + +/** Dummy function for gl_renderbuffer::AllocStorage() */ +static GLboolean +radeon_nop_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, GLuint width, GLuint height) +{ + _mesa_problem(ctx, "radeon_op_alloc_storage should never be called."); + return GL_FALSE; +} + +struct radeon_renderbuffer * +radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv) +{ + struct radeon_renderbuffer *rrb; + + rrb = CALLOC_STRUCT(radeon_renderbuffer); + if (!rrb) + return NULL; + + _mesa_init_renderbuffer(&rrb->base, 0); + rrb->base.ClassID = RADEON_RB_CLASS; + + /* XXX format junk */ + switch (format) { + case GL_RGB5: + rrb->base._ActualFormat = GL_RGB5; + rrb->base._BaseFormat = GL_RGBA; + rrb->base.RedBits = 5; + rrb->base.GreenBits = 6; + rrb->base.BlueBits = 5; + rrb->base.DataType = GL_UNSIGNED_BYTE; + break; + case GL_RGBA8: + rrb->base._ActualFormat = GL_RGBA8; + rrb->base._BaseFormat = GL_RGBA; + rrb->base.RedBits = 8; + rrb->base.GreenBits = 8; + rrb->base.BlueBits = 8; + rrb->base.AlphaBits = 8; + rrb->base.DataType = GL_UNSIGNED_BYTE; + break; + case GL_STENCIL_INDEX8_EXT: + rrb->base._ActualFormat = GL_STENCIL_INDEX8_EXT; + rrb->base._BaseFormat = GL_STENCIL_INDEX; + rrb->base.StencilBits = 8; + rrb->base.DataType = GL_UNSIGNED_BYTE; + break; + case GL_DEPTH_COMPONENT16: + rrb->base._ActualFormat = GL_DEPTH_COMPONENT16; + rrb->base._BaseFormat = GL_DEPTH_COMPONENT; + rrb->base.DepthBits = 16; + rrb->base.DataType = GL_UNSIGNED_SHORT; + break; + case GL_DEPTH_COMPONENT24: + rrb->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; + rrb->base._BaseFormat = GL_DEPTH_COMPONENT; + rrb->base.DepthBits = 24; + rrb->base.DataType = GL_UNSIGNED_INT; + break; + case GL_DEPTH24_STENCIL8_EXT: + rrb->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; + rrb->base._BaseFormat = GL_DEPTH_STENCIL_EXT; + rrb->base.DepthBits = 24; + rrb->base.StencilBits = 8; + rrb->base.DataType = GL_UNSIGNED_INT_24_8_EXT; + break; + default: + fprintf(stderr, "%s: Unknown format 0x%04x\n", __FUNCTION__, format); + _mesa_delete_renderbuffer(&rrb->base); + return NULL; + } + + rrb->dPriv = driDrawPriv; + rrb->base.InternalFormat = format; + + rrb->base.Delete = radeon_delete_renderbuffer; + rrb->base.AllocStorage = radeon_alloc_window_storage; + rrb->base.GetPointer = radeon_get_pointer; + + rrb->bo = NULL; + return rrb; +} + +static struct gl_renderbuffer * +radeon_new_renderbuffer(GLcontext * ctx, GLuint name) +{ + struct radeon_renderbuffer *rrb; + + rrb = CALLOC_STRUCT(radeon_renderbuffer); + if (!rrb) + return NULL; + + _mesa_init_renderbuffer(&rrb->base, name); + rrb->base.ClassID = RADEON_RB_CLASS; + + rrb->base.Delete = radeon_delete_renderbuffer; + rrb->base.AllocStorage = radeon_alloc_renderbuffer_storage; + rrb->base.GetPointer = radeon_get_pointer; + + return &rrb->base; +} + +static void +radeon_bind_framebuffer(GLcontext * ctx, GLenum target, + struct gl_framebuffer *fb, struct gl_framebuffer *fbread) +{ + if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { + radeon_draw_buffer(ctx, fb); + } + else { + /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */ + } +} + +static void +radeon_framebuffer_renderbuffer(GLcontext * ctx, + struct gl_framebuffer *fb, + GLenum attachment, struct gl_renderbuffer *rb) +{ + + radeonFlush(ctx); + + _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); + radeon_draw_buffer(ctx, fb); +} + + +static GLboolean +radeon_update_wrapper(GLcontext *ctx, struct radeon_renderbuffer *rrb, + struct gl_texture_image *texImage) +{ + if (texImage->TexFormat == &_mesa_texformat_argb8888) { + rrb->cpp = 4; + rrb->base._ActualFormat = GL_RGBA8; + rrb->base._BaseFormat = GL_RGBA; + 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; + rrb->base._BaseFormat = GL_RGB; + rrb->base.DataType = GL_UNSIGNED_SHORT; + DBG("Render to RGB5 texture OK\n"); + } + else if (texImage->TexFormat == &_mesa_texformat_z16) { + rrb->cpp = 2; + rrb->base._ActualFormat = GL_DEPTH_COMPONENT16; + rrb->base._BaseFormat = GL_DEPTH_COMPONENT; + rrb->base.DataType = GL_UNSIGNED_SHORT; + DBG("Render to DEPTH16 texture OK\n"); + } + else if (texImage->TexFormat == &_mesa_texformat_s8_z24) { + rrb->cpp = 4; + rrb->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; + rrb->base._BaseFormat = GL_DEPTH_STENCIL_EXT; + rrb->base.DataType = GL_UNSIGNED_INT_24_8_EXT; + DBG("Render to DEPTH_STENCIL texture OK\n"); + } + else { + DBG("Render to texture BAD FORMAT %d\n", + texImage->TexFormat->MesaFormat); + return GL_FALSE; + } + + rrb->pitch = texImage->Width * rrb->cpp; + rrb->base.InternalFormat = rrb->base._ActualFormat; + rrb->base.Width = texImage->Width; + rrb->base.Height = texImage->Height; + rrb->base.RedBits = texImage->TexFormat->RedBits; + rrb->base.GreenBits = texImage->TexFormat->GreenBits; + rrb->base.BlueBits = texImage->TexFormat->BlueBits; + rrb->base.AlphaBits = texImage->TexFormat->AlphaBits; + rrb->base.DepthBits = texImage->TexFormat->DepthBits; + + rrb->base.Delete = radeon_delete_renderbuffer; + rrb->base.AllocStorage = radeon_nop_alloc_storage; + + return GL_TRUE; +} + + +static struct radeon_renderbuffer * +radeon_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage) +{ + const GLuint name = ~0; /* not significant, but distinct for debugging */ + struct radeon_renderbuffer *rrb; + + /* make an radeon_renderbuffer to wrap the texture image */ + rrb = CALLOC_STRUCT(radeon_renderbuffer); + if (!rrb) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture"); + return NULL; + } + + _mesa_init_renderbuffer(&rrb->base, name); + rrb->base.ClassID = RADEON_RB_CLASS; + + if (!radeon_update_wrapper(ctx, rrb, texImage)) { + _mesa_free(rrb); + return NULL; + } + + return rrb; + +} +static void +radeon_render_texture(GLcontext * ctx, + struct gl_framebuffer *fb, + struct gl_renderbuffer_attachment *att) +{ + struct gl_texture_image *newImage + = att->Texture->Image[att->CubeMapFace][att->TextureLevel]; + struct radeon_renderbuffer *rrb = radeon_renderbuffer(att->Renderbuffer); + radeon_texture_image *radeon_image; + GLuint imageOffset; + + (void) fb; + + ASSERT(newImage); + + if (newImage->Border != 0) { + /* Fallback on drawing to a texture with a border, which won't have a + * miptree. + */ + _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); + _mesa_render_texture(ctx, fb, att); + return; + } + else if (!rrb) { + rrb = radeon_wrap_texture(ctx, newImage); + if (rrb) { + /* bind the wrapper to the attachment point */ + _mesa_reference_renderbuffer(&att->Renderbuffer, &rrb->base); + } + else { + /* fallback to software rendering */ + _mesa_render_texture(ctx, fb, att); + return; + } + } + + if (!radeon_update_wrapper(ctx, rrb, newImage)) { + _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); + _mesa_render_texture(ctx, fb, att); + return; + } + + 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); + + /* point the renderbufer's region to the texture image region */ + radeon_image = (radeon_texture_image *)newImage; + if (rrb->bo != radeon_image->mt->bo) { + if (rrb->bo) + radeon_bo_unref(rrb->bo); + rrb->bo = radeon_image->mt->bo; + radeon_bo_ref(rrb->bo); + } + + /* compute offset of the particular 2D image within the texture region */ + imageOffset = radeon_miptree_image_offset(radeon_image->mt, + att->CubeMapFace, + att->TextureLevel); + + if (att->Texture->Target == GL_TEXTURE_3D) { + const GLuint *offsets = radeon_miptree_depth_offsets(radeon_image->mt, + att->TextureLevel); + imageOffset += offsets[att->Zoffset]; + } + + /* store that offset in the region */ + rrb->draw_offset = imageOffset; + + /* update drawing region, etc */ + radeon_draw_buffer(ctx, fb); +} + +static void +radeon_finish_render_texture(GLcontext * ctx, + struct gl_renderbuffer_attachment *att) +{ + +} +static void +radeon_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) +{ +} + +static void +radeon_blit_framebuffer(GLcontext *ctx, + GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) +{ +} + +void radeon_fbo_init(struct radeon_context *radeon) +{ + radeon->glCtx->Driver.NewFramebuffer = radeon_new_framebuffer; + radeon->glCtx->Driver.NewRenderbuffer = radeon_new_renderbuffer; + radeon->glCtx->Driver.BindFramebuffer = radeon_bind_framebuffer; + radeon->glCtx->Driver.FramebufferRenderbuffer = radeon_framebuffer_renderbuffer; + radeon->glCtx->Driver.RenderTexture = radeon_render_texture; + radeon->glCtx->Driver.FinishRenderTexture = radeon_finish_render_texture; + radeon->glCtx->Driver.ResizeBuffers = radeon_resize_buffers; + radeon->glCtx->Driver.ValidateFramebuffer = radeon_validate_framebuffer; + radeon->glCtx->Driver.BlitFramebuffer = radeon_blit_framebuffer; +} + + +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_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c index 3203ee1cba..228629e3c4 100644 --- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c @@ -358,3 +358,29 @@ void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t, texImage->Width, texImage->Height, texImage->Depth, texImage->TexFormat->TexelBytes, t->tile_bits, compressed); } + +/* Although we use the image_offset[] array to store relative offsets + * to cube faces, Mesa doesn't know anything about this and expects + * each cube face to be treated as a separate image. + * + * These functions present that view to mesa: + */ +const GLuint * +radeon_miptree_depth_offsets(radeon_mipmap_tree *mt, GLuint level) +{ + static const GLuint zero = 0; + if (mt->target != GL_TEXTURE_3D || mt->faces == 1) + return &zero; + else + return mt->levels[level].faces[0].offset; +} + +GLuint +radeon_miptree_image_offset(radeon_mipmap_tree *mt, + GLuint face, GLuint level) +{ + if (mt->target == GL_TEXTURE_CUBE_MAP_ARB) + return (mt->levels[level].faces[face].offset); + else + return mt->levels[level].faces[0].offset; +} diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h index 43dfa48aa7..d9ad5ad39a 100644 --- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h @@ -92,6 +92,8 @@ GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt, GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct gl_texture_object *texObj); void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t, struct gl_texture_image *texImage, GLuint face, GLuint level); - - +GLuint radeon_miptree_image_offset(radeon_mipmap_tree *mt, + GLuint face, GLuint level); +const GLuint * +radeon_miptree_depth_offsets(radeon_mipmap_tree *mt, GLuint level); #endif /* __RADEON_MIPMAP_TREE_H_ */ diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index bbcf19ccee..2d3bb619cd 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -1089,6 +1089,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; @@ -1178,90 +1181,7 @@ radeonInitDriver( __DRIscreenPrivate *sPriv ) return GL_TRUE; } -static GLboolean -radeon_alloc_window_storage(GLcontext *ctx, struct gl_renderbuffer *rb, - GLenum intFormat, GLuint w, GLuint h) -{ - rb->Width = w; - rb->Height = h; - rb->_ActualFormat = intFormat; - return GL_TRUE; -} - - -static struct radeon_renderbuffer * -radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv) -{ - struct radeon_renderbuffer *ret; - - ret = CALLOC_STRUCT(radeon_renderbuffer); - if (!ret) - return NULL; - - _mesa_init_renderbuffer(&ret->base, 0); - ret->base.ClassID = RADEON_RB_CLASS; - - /* XXX format junk */ - switch (format) { - case GL_RGB5: - ret->base._ActualFormat = GL_RGB5; - ret->base._BaseFormat = GL_RGBA; - ret->base.RedBits = 5; - ret->base.GreenBits = 6; - ret->base.BlueBits = 5; - ret->base.DataType = GL_UNSIGNED_BYTE; - break; - case GL_RGBA8: - ret->base._ActualFormat = GL_RGBA8; - ret->base._BaseFormat = GL_RGBA; - ret->base.RedBits = 8; - ret->base.GreenBits = 8; - ret->base.BlueBits = 8; - ret->base.AlphaBits = 8; - ret->base.DataType = GL_UNSIGNED_BYTE; - break; - case GL_STENCIL_INDEX8_EXT: - ret->base._ActualFormat = GL_STENCIL_INDEX8_EXT; - ret->base._BaseFormat = GL_STENCIL_INDEX; - ret->base.StencilBits = 8; - ret->base.DataType = GL_UNSIGNED_BYTE; - break; - case GL_DEPTH_COMPONENT16: - ret->base._ActualFormat = GL_DEPTH_COMPONENT16; - ret->base._BaseFormat = GL_DEPTH_COMPONENT; - ret->base.DepthBits = 16; - ret->base.DataType = GL_UNSIGNED_SHORT; - break; - case GL_DEPTH_COMPONENT24: - ret->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; - ret->base._BaseFormat = GL_DEPTH_COMPONENT; - ret->base.DepthBits = 24; - ret->base.DataType = GL_UNSIGNED_INT; - break; - case GL_DEPTH24_STENCIL8_EXT: - ret->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; - ret->base._BaseFormat = GL_DEPTH_STENCIL_EXT; - ret->base.DepthBits = 24; - ret->base.StencilBits = 8; - ret->base.DataType = GL_UNSIGNED_INT_24_8_EXT; - break; - default: - fprintf(stderr, "%s: Unknown format 0x%04x\n", __FUNCTION__, format); - _mesa_delete_renderbuffer(&ret->base); - return NULL; - } - - ret->dPriv = driDrawPriv; - ret->base.InternalFormat = format; - - ret->base.AllocStorage = radeon_alloc_window_storage; - - radeonSetSpanFunctions(ret); - - ret->bo = NULL; - return ret; -} /** * Create the Mesa framebuffer and renderbuffers for a given window/drawable. @@ -1283,7 +1203,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) @@ -1295,11 +1214,6 @@ 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_create_renderbuffer(rgbFormat, driDrawPriv); _mesa_add_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT, &rfb->color_rb[0]->base); @@ -1307,25 +1221,28 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, /* back color renderbuffer */ if (mesaVis->doubleBufferMode) { - rfb->color_rb[1] = 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_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_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 49ec2c378e..3d2c5da4c0 100644 --- a/src/mesa/drivers/dri/radeon/radeon_span.c +++ b/src/mesa/drivers/dri/radeon/radeon_span.c @@ -49,19 +49,17 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define DBG 0 +static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb); + static GLubyte *radeon_ptr32(const struct radeon_renderbuffer * rrb, GLint x, GLint y) { GLubyte *ptr = rrb->bo->ptr; - const __DRIdrawablePrivate *dPriv = rrb->dPriv; uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; GLint offset; GLint nmacroblkpl; GLint nmicroblkpl; - x += dPriv->x; - y += dPriv->y; - if (rrb->has_surface || !(rrb->bo->flags & mask)) { offset = x * rrb->cpp + y * rrb->pitch; } else { @@ -97,15 +95,11 @@ static GLubyte *radeon_ptr16(const struct radeon_renderbuffer * rrb, GLint x, GLint y) { GLubyte *ptr = rrb->bo->ptr; - const __DRIdrawablePrivate *dPriv = rrb->dPriv; uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; GLint offset; GLint nmacroblkpl; GLint nmicroblkpl; - x += dPriv->x; - y += dPriv->y; - if (rrb->has_surface || !(rrb->bo->flags & mask)) { offset = x * rrb->cpp + y * rrb->pitch; } else { @@ -141,7 +135,6 @@ static GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb, GLint x, GLint y) { GLubyte *ptr = rrb->bo->ptr; - const __DRIdrawablePrivate *dPriv = rrb->dPriv; uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; GLint offset; GLint microblkxs; @@ -149,9 +142,6 @@ static GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb, GLint nmacroblkpl; GLint nmicroblkpl; - x += dPriv->x; - y += dPriv->y; - if (rrb->has_surface || !(rrb->bo->flags & mask)) { offset = x * rrb->cpp + y * rrb->pitch; } else { @@ -195,25 +185,48 @@ static GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb, * information. */ #define LOCAL_VARS \ + struct radeon_context *radeon = RADEON_CONTEXT(ctx); \ struct radeon_renderbuffer *rrb = (void *) rb; \ - const __DRIdrawablePrivate *dPriv = rrb->dPriv; \ - const GLuint bottom = dPriv->h - 1; \ + const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1; \ + const GLint yBias = ctx->DrawBuffer->Name ? 0 : rrb->base.Height - 1;\ + unsigned int num_cliprects; \ + struct drm_clip_rect *cliprects; \ + int x_off, y_off; \ GLuint p; \ - (void)p; + (void)p; \ + radeon_get_cliprects(radeon, &cliprects, &num_cliprects, &x_off, &y_off); #define LOCAL_DEPTH_VARS \ + struct radeon_context *radeon = RADEON_CONTEXT(ctx); \ struct radeon_renderbuffer *rrb = (void *) rb; \ - const __DRIdrawablePrivate *dPriv = rrb->dPriv; \ - const GLuint bottom = dPriv->h - 1; + const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1; \ + const GLint yBias = ctx->DrawBuffer->Name ? 0 : rrb->base.Height - 1;\ + unsigned int num_cliprects; \ + struct drm_clip_rect *cliprects; \ + int x_off, y_off; \ + radeon_get_cliprects(radeon, &cliprects, &num_cliprects, &x_off, &y_off); #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS -#define Y_FLIP(Y) (bottom - (Y)) +#define Y_FLIP(_y) ((_y) * yScale + yBias) #define HW_LOCK() #define HW_UNLOCK() +/* XXX FBO: this is identical to the macro in spantmp2.h except we get + * the cliprect info from the context, not the driDrawable. + * Move this into spantmp2.h someday. + */ +#define HW_CLIPLOOP() \ + do { \ + int _nc = num_cliprects; \ + while ( _nc-- ) { \ + int minx = cliprects[_nc].x1 - x_off; \ + int miny = cliprects[_nc].y1 - y_off; \ + int maxx = cliprects[_nc].x2 - x_off; \ + int maxy = cliprects[_nc].y2 - y_off; + /* ================================================================ * Color buffer */ @@ -225,7 +238,17 @@ static GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb, #define TAG(x) radeon##x##_RGB565 #define TAG2(x,y) radeon##x##_RGB565##y -#define GET_PTR(X,Y) radeon_ptr16(rrb, (X), (Y)) +#define GET_PTR(X,Y) radeon_ptr16(rrb, (X) + x_off, (Y) + y_off) +#include "spantmp2.h" + +/* 32 bit, xRGB8888 color spanline and pixel functions + */ +#define SPANTMP_PIXEL_FMT GL_BGRA +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV + +#define TAG(x) radeon##x##_xRGB8888 +#define TAG2(x,y) radeon##x##_xRGB8888##y +#define GET_PTR(X,Y) radeon_ptr32(rrb, (X) + x_off, (Y) + y_off) #include "spantmp2.h" /* 32 bit, ARGB8888 color spanline and pixel functions @@ -235,7 +258,7 @@ static GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb, #define TAG(x) radeon##x##_ARGB8888 #define TAG2(x,y) radeon##x##_ARGB8888##y -#define GET_PTR(X,Y) radeon_ptr32(rrb, (X), (Y)) +#define GET_PTR(X,Y) radeon_ptr32(rrb, (X) + x_off, (Y) + y_off) #include "spantmp2.h" /* ================================================================ @@ -257,10 +280,10 @@ static GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb, #define VALUE_TYPE GLushort #define WRITE_DEPTH( _x, _y, d ) \ - *(GLushort *)radeon_ptr(rrb, _x, _y) = d + *(GLushort *)radeon_ptr(rrb, _x + x_off, _y + y_off) = d #define READ_DEPTH( d, _x, _y ) \ - d = *(GLushort *)radeon_ptr(rrb, _x, _y) + d = *(GLushort *)radeon_ptr(rrb, _x + x_off, _y + y_off) #define TAG(x) radeon##x##_z16 #include "depthtmp.h" @@ -275,7 +298,7 @@ static GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb, #ifdef COMPILE_R300 #define WRITE_DEPTH( _x, _y, d ) \ do { \ - GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x, _y ); \ + GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \ GLuint tmp = *_ptr; \ tmp &= 0x000000ff; \ tmp |= ((d << 8) & 0xffffff00); \ @@ -284,8 +307,8 @@ do { \ #else #define WRITE_DEPTH( _x, _y, d ) \ do { \ - GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x, _y ); \ - GLuint tmp = *_ptr; \ + GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \ + GLuint tmp = *_ptr; \ tmp &= 0xff000000; \ tmp |= ((d) & 0x00ffffff); \ *_ptr = tmp; \ @@ -295,11 +318,11 @@ do { \ #ifdef COMPILE_R300 #define READ_DEPTH( d, _x, _y ) \ do { \ - d = (*(GLuint*)(radeon_ptr32(rrb, _x, _y)) & 0xffffff00) >> 8; \ + d = (*(GLuint*)(radeon_ptr32(rrb, _x + x_off, _y + y_off)) & 0xffffff00) >> 8; \ }while(0) #else #define READ_DEPTH( d, _x, _y ) \ - d = *(GLuint*)(radeon_ptr32(rrb, _x, _y )) & 0x00ffffff; + d = *(GLuint*)(radeon_ptr32(rrb, _x + x_off, _y + y_off )) & 0x00ffffff; #endif /* fprintf(stderr, "dval(%d, %d, %d, %d)=0x%08X\n", _x, xo, _y, yo, d);\ @@ -317,7 +340,7 @@ do { \ #ifdef COMPILE_R300 #define WRITE_STENCIL( _x, _y, d ) \ do { \ - GLuint *_ptr = (GLuint*)radeon_ptr32(rrb, _x, _y); \ + GLuint *_ptr = (GLuint*)radeon_ptr32(rrb, _x + x_off, _y + y_off); \ GLuint tmp = *_ptr; \ tmp &= 0xffffff00; \ tmp |= (d) & 0xff; \ @@ -326,7 +349,7 @@ do { \ #else #define WRITE_STENCIL( _x, _y, d ) \ do { \ - GLuint *_ptr = (GLuint*)radeon_ptr32(rrb, _x, _y); \ + GLuint *_ptr = (GLuint*)radeon_ptr32(rrb, _x + x_off, _y + y_off); \ GLuint tmp = *_ptr; \ tmp &= 0x00ffffff; \ tmp |= (((d) & 0xff) << 24); \ @@ -337,14 +360,14 @@ do { \ #ifdef COMPILE_R300 #define READ_STENCIL( d, _x, _y ) \ do { \ - GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x, _y ); \ + GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \ GLuint tmp = *_ptr; \ d = tmp & 0x000000ff; \ } while (0) #else #define READ_STENCIL( d, _x, _y ) \ do { \ - GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x, _y ); \ + GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \ GLuint tmp = *_ptr; \ d = (tmp & 0xff000000) >> 24; \ } while (0) @@ -354,29 +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); + } 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); + } } -} + + 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); @@ -389,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 @@ -423,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) @@ -446,17 +484,21 @@ void radeonInitSpanFuncs(GLcontext * ctx) /** * Plug in the Get/Put routines for the given driRenderbuffer. */ -void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb) +static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb) { - if (rrb->base.InternalFormat == GL_RGB5) { + if (rrb->base._ActualFormat == GL_RGB5) { radeonInitPointers_RGB565(&rrb->base); - } else if (rrb->base.InternalFormat == GL_RGBA8) { + } else if (rrb->base._ActualFormat == GL_RGB8) { + radeonInitPointers_xRGB8888(&rrb->base); + } else if (rrb->base._ActualFormat == GL_RGBA8) { radeonInitPointers_ARGB8888(&rrb->base); - } else if (rrb->base.InternalFormat == GL_DEPTH_COMPONENT16) { + } else if (rrb->base._ActualFormat == GL_DEPTH_COMPONENT16) { radeonInitDepthPointers_z16(&rrb->base); - } else if (rrb->base.InternalFormat == GL_DEPTH_COMPONENT24) { + } else if (rrb->base._ActualFormat == GL_DEPTH_COMPONENT24) { radeonInitDepthPointers_z24_s8(&rrb->base); - } else if (rrb->base.InternalFormat == GL_STENCIL_INDEX8_EXT) { + } 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_span.h b/src/mesa/drivers/dri/radeon/radeon_span.h index dd44ab517a..ea6a2e7fb4 100644 --- a/src/mesa/drivers/dri/radeon/radeon_span.h +++ b/src/mesa/drivers/dri/radeon/radeon_span.h @@ -44,5 +44,4 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. extern void radeonInitSpanFuncs(GLcontext * ctx); -extern void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb); #endif diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index 42b65cbee6..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 ); @@ -1390,13 +1391,24 @@ void radeonUpdateWindow( GLcontext *ctx ) GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0; 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) { + y_scale = 1.0; + y_bias = 0; + } else { + y_scale = -1.0; + y_bias = yoffset; + } float_ui32_type sx = { v[MAT_SX] }; float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X }; - float_ui32_type sy = { - v[MAT_SY] }; - float_ui32_type ty = { (- v[MAT_TY]) + yoffset + 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 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] * depthScale }; + float_ui32_type tz = { v[MAT_TZ] * depthScale }; RADEON_STATECHANGE( rmesa, vpt ); @@ -1790,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; |