raedon/r200/r300: mega-FBO commits.

Re work depth issues.
Do a lot more FBO abstactions
fixup depth/stencil buffer interactions
This commit is contained in:
Dave Airlie 2009-03-23 18:27:49 +10:00
parent c607a664dd
commit 8c7e30fb95
21 changed files with 610 additions and 690 deletions

View file

@ -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 */

View file

@ -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))

View file

@ -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;
}

View file

@ -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; */
@ -1611,6 +1612,7 @@ void r200UpdateWindow( GLcontext *ctx )
GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
const GLfloat *v = ctx->Viewport._WindowMap.m;
const GLboolean render_to_fbo = (ctx->DrawBuffer ? (ctx->DrawBuffer->Name != 0) : 0);
const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
GLfloat y_scale, y_bias;
if (render_to_fbo) {
@ -1625,8 +1627,8 @@ void r200UpdateWindow( GLcontext *ctx )
float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X };
float_ui32_type sy = { v[MAT_SY] * y_scale };
float_ui32_type ty = { (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y };
float_ui32_type sz = { v[MAT_SZ] * rmesa->radeon.state.depth.scale };
float_ui32_type tz = { v[MAT_TZ] * rmesa->radeon.state.depth.scale };
float_ui32_type sz = { v[MAT_SZ] * depthScale };
float_ui32_type tz = { v[MAT_TZ] * depthScale };
R200_STATECHANGE( rmesa, vpt );
@ -2014,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;
} else {
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 {
FALLBACK( rmesa, R200_FALLBACK_STENCIL, state );
}
} else {
FALLBACK( rmesa, R200_FALLBACK_STENCIL, state );
}
break;

View file

@ -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;

View file

@ -113,7 +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_framebuffer_object", GL_EXT_framebuffer_object_functions },
{"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},
@ -141,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.
@ -421,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"))

View file

@ -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,68 +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 (mask & BUFFER_BIT_BACK_LEFT) {
flags |= BUFFER_BIT_BACK_LEFT;
mask &= ~BUFFER_BIT_BACK_LEFT;
if (colorMask == ~0)
tri_mask |= (mask & BUFFER_BITS_COLOR);
/* 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.
*/
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;
}
}
}
if (mask & BUFFER_BIT_COLOR0) {
flags |= BUFFER_BIT_COLOR0;
mask &= ~BUFFER_BIT_COLOR0;
}
/* SW fallback clearing */
swrast_mask = mask & ~tri_mask;
if (mask) {
if (tri_mask) {
if (r300->radeon.radeonScreen->kernel_mm)
r300UserClear(ctx, tri_mask);
else
r300KernelClear(ctx, tri_mask);
}
if (swrast_mask) {
if (RADEON_DEBUG & DEBUG_FALLBACKS)
fprintf(stderr, "%s: swrast clear, mask: %x\n",
__FUNCTION__, mask);
_swrast_Clear(ctx, mask);
__FUNCTION__, swrast_mask);
_swrast_Clear(ctx, swrast_mask);
}
/* Make sure it fits there. */
rcommonEnsureCmdBufSpace(&r300->radeon, 421 * 3, __FUNCTION__);
if (flags || bits)
r300EmitClearState(ctx);
rrbd = (void *)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer;
if (flags & BUFFER_BIT_COLOR0) {
rrb = (void *)rfb->base.Attachment[BUFFER_COLOR0].Renderbuffer;
r300ClearBuffer(r300, CLEARBUFFER_COLOR, rrb, NULL);
bits = 0;
}
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 (flags & BUFFER_BIT_BACK_LEFT) {
rrb = (void *)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd);
bits = 0;
}
if (bits)
r300ClearBuffer(r300, bits, NULL, rrbd);
COMMIT_BATCH();
}
void r300InitIoctlFuncs(struct dd_function_table *functions)
{
functions->Clear = r300Clear;

View file

@ -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,7 +939,8 @@ 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 GLboolean render_to_fbo = (ctx->DrawBuffer ? (ctx->DrawBuffer->Name != 0) : 0);
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) {
@ -948,8 +955,8 @@ static void r300UpdateWindow(GLcontext * ctx)
GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X;
GLfloat sy = v[MAT_SY] * y_scale;
GLfloat ty = (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y;
GLfloat sz = v[MAT_SZ] * rmesa->radeon.state.depth.scale;
GLfloat tz = v[MAT_TZ] * rmesa->radeon.state.depth.scale;
GLfloat sz = v[MAT_SZ] * depthScale;
GLfloat tz = v[MAT_TZ] * depthScale;
R300_STATECHANGE(rmesa, vpt);
@ -2032,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],
@ -2207,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;
@ -2530,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);

View file

@ -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)
{

View file

@ -58,6 +58,21 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "tnl/t_pipeline.h"
#include "swrast_setup/swrast_setup.h"
#include "main/blend.h"
#include "main/bufferobj.h"
#include "main/buffers.h"
#include "main/depth.h"
#include "main/shaders.h"
#include "main/texstate.h"
#include "main/varray.h"
#include "glapi/dispatch.h"
#include "swrast/swrast.h"
#include "main/stencil.h"
#include "main/matrix.h"
#include "main/attrib.h"
#include "main/enable.h"
#include "main/viewport.h"
#include "dri_util.h"
#include "vblank.h"
@ -658,18 +673,20 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
/* none */
if (fb->Name == 0) {
if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
rrbColor = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
rrbColor = radeon_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
radeon->front_cliprects = GL_TRUE;
} else {
rrbColor = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
rrbColor = radeon_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
radeon->front_cliprects = GL_FALSE;
}
} else {
/* user FBO in theory */
struct radeon_renderbuffer *rrb;
rrb = (void *)fb->_ColorDrawBuffers[0];
offset = rrb->draw_offset;
rrbColor = rrb;
rrb = radeon_renderbuffer(fb->_ColorDrawBuffers[0]);
if (rrb) {
offset = rrb->draw_offset;
rrbColor = rrb;
}
radeon->constant_cliprect = GL_TRUE;
}
@ -679,9 +696,8 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE);
if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) {
rrbDepth = (struct radeon_renderbuffer *)fb->_DepthBuffer->Wrapped;
rrbDepth = radeon_renderbuffer(fb->_DepthBuffer->Wrapped);
if (rrbDepth && rrbDepth->bo) {
radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_FALSE);
} else {
@ -692,16 +708,11 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
rrbDepth = NULL;
}
/* TODO stencil things */
if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) {
rrbStencil = (struct radeon_renderbuffer *)fb->_DepthBuffer->Wrapped;
rrbStencil = radeon_renderbuffer(fb->_DepthBuffer->Wrapped);
if (rrbStencil && rrbStencil->bo) {
radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE);
/* need to re-compute stencil hw state */
if (ctx->Driver.Enable != NULL)
ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled);
else
ctx->NewState |= _NEW_STENCIL;
if (!rrbDepth)
rrbDepth = rrbStencil;
} else {
@ -727,27 +738,28 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
* Update depth test state
*/
if (ctx->Driver.Enable) {
if (ctx->Depth.Test && fb->Visual.depthBits > 0) {
ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_TRUE);
} else {
ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_FALSE);
}
ctx->Driver.Enable(ctx, GL_DEPTH_TEST,
(ctx->Depth.Test && fb->Visual.depthBits > 0));
ctx->Driver.Enable(ctx, GL_STENCIL_TEST,
(ctx->Stencil._Enabled && fb->Visual.stencilBits > 0));
} else {
ctx->NewState |= _NEW_DEPTH;
ctx->NewState |= (_NEW_DEPTH | _NEW_STENCIL);
}
radeon->state.depth.rrb = rrbDepth;
radeon->state.color.rrb = rrbColor;
radeon->state.color.draw_offset = offset;
#if 0
/* update viewport since it depends on window size */
if (ctx->Driver.Viewport) {
ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y,
ctx->Viewport.Width, ctx->Viewport.Height);
} else {
ctx->NewState |= _NEW_VIEWPORT;
}
#endif
ctx->NewState |= _NEW_VIEWPORT;
/* Set state we know depends on drawable parameters:
*/
@ -755,6 +767,19 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
ctx->Scissor.Width, ctx->Scissor.Height);
radeon->NewGLState |= _NEW_SCISSOR;
if (ctx->Driver.DepthRange)
ctx->Driver.DepthRange(ctx,
ctx->Viewport.Near,
ctx->Viewport.Far);
/* Update culling direction which changes depending on the
* orientation of the buffer:
*/
if (ctx->Driver.FrontFace)
ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace);
else
ctx->NewState |= _NEW_POLYGON;
}
/**
@ -802,10 +827,6 @@ void radeonUpdatePageFlipping(radeonContextPtr radeon)
void radeon_window_moved(radeonContextPtr radeon)
{
GLcontext *ctx = radeon->glCtx;
__DRIdrawablePrivate *dPriv = radeon->dri.drawable;
struct radeon_framebuffer *rfb = dPriv->driverPrivate;
if (!radeon->radeonScreen->driScreen->dri2.enabled) {
radeonUpdatePageFlipping(radeon);
}
@ -949,8 +970,14 @@ void radeonFinish(GLcontext * ctx)
if (radeon->radeonScreen->kernel_mm) {
for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
struct radeon_renderbuffer *rrb;
rrb = (struct radeon_renderbuffer *)fb->_ColorDrawBuffers[i];
if (rrb->bo)
rrb = radeon_renderbuffer(fb->_ColorDrawBuffers[i]);
if (rrb && rrb->bo)
radeon_bo_wait(rrb->bo);
}
{
struct radeon_renderbuffer *rrb;
rrb = radeon_get_depthbuffer(radeon);
if (rrb && rrb->bo)
radeon_bo_wait(rrb->bo);
}
} else if (radeon->do_irqs) {
@ -1108,3 +1135,219 @@ void rcommonBeginBatch(radeonContextPtr rmesa, int n,
static void
radeon_meta_set_passthrough_transform(radeonContextPtr radeon)
{
GLcontext *ctx = radeon->glCtx;
radeon->meta.saved_vp_x = ctx->Viewport.X;
radeon->meta.saved_vp_y = ctx->Viewport.Y;
radeon->meta.saved_vp_width = ctx->Viewport.Width;
radeon->meta.saved_vp_height = ctx->Viewport.Height;
radeon->meta.saved_matrix_mode = ctx->Transform.MatrixMode;
_mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height);
_mesa_MatrixMode(GL_PROJECTION);
_mesa_PushMatrix();
_mesa_LoadIdentity();
_mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1);
_mesa_MatrixMode(GL_MODELVIEW);
_mesa_PushMatrix();
_mesa_LoadIdentity();
}
static void
radeon_meta_restore_transform(radeonContextPtr radeon)
{
_mesa_MatrixMode(GL_PROJECTION);
_mesa_PopMatrix();
_mesa_MatrixMode(GL_MODELVIEW);
_mesa_PopMatrix();
_mesa_MatrixMode(radeon->meta.saved_matrix_mode);
_mesa_Viewport(radeon->meta.saved_vp_x, radeon->meta.saved_vp_y,
radeon->meta.saved_vp_width, radeon->meta.saved_vp_height);
}
/**
* Perform glClear where mask contains only color, depth, and/or stencil.
*
* The implementation is based on calling into Mesa to set GL state and
* performing normal triangle rendering. The intent of this path is to
* have as generic a path as possible, so that any driver could make use of
* it.
*/
void radeon_clear_tris(GLcontext *ctx, GLbitfield mask)
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
GLfloat vertices[4][3];
GLfloat color[4][4];
GLfloat dst_z;
struct gl_framebuffer *fb = ctx->DrawBuffer;
int i;
GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE;
GLboolean saved_shader_program = 0;
unsigned int saved_active_texture;
assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH |
BUFFER_BIT_STENCIL)) == 0);
_mesa_PushAttrib(GL_COLOR_BUFFER_BIT |
GL_CURRENT_BIT |
GL_DEPTH_BUFFER_BIT |
GL_ENABLE_BIT |
GL_STENCIL_BUFFER_BIT |
GL_TRANSFORM_BIT |
GL_CURRENT_BIT);
_mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
saved_active_texture = ctx->Texture.CurrentUnit;
/* Disable existing GL state we don't want to apply to a clear. */
_mesa_Disable(GL_ALPHA_TEST);
_mesa_Disable(GL_BLEND);
_mesa_Disable(GL_CULL_FACE);
_mesa_Disable(GL_FOG);
_mesa_Disable(GL_POLYGON_SMOOTH);
_mesa_Disable(GL_POLYGON_STIPPLE);
_mesa_Disable(GL_POLYGON_OFFSET_FILL);
_mesa_Disable(GL_LIGHTING);
_mesa_Disable(GL_CLIP_PLANE0);
_mesa_Disable(GL_CLIP_PLANE1);
_mesa_Disable(GL_CLIP_PLANE2);
_mesa_Disable(GL_CLIP_PLANE3);
_mesa_Disable(GL_CLIP_PLANE4);
_mesa_Disable(GL_CLIP_PLANE5);
if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) {
saved_fp_enable = GL_TRUE;
_mesa_Disable(GL_FRAGMENT_PROGRAM_ARB);
}
if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) {
saved_vp_enable = GL_TRUE;
_mesa_Disable(GL_VERTEX_PROGRAM_ARB);
}
if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) {
saved_shader_program = ctx->Shader.CurrentProgram->Name;
_mesa_UseProgramObjectARB(0);
}
if (ctx->Texture._EnabledUnits != 0) {
int i;
for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
_mesa_ActiveTextureARB(GL_TEXTURE0 + i);
_mesa_Disable(GL_TEXTURE_1D);
_mesa_Disable(GL_TEXTURE_2D);
_mesa_Disable(GL_TEXTURE_3D);
if (ctx->Extensions.ARB_texture_cube_map)
_mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB);
if (ctx->Extensions.NV_texture_rectangle)
_mesa_Disable(GL_TEXTURE_RECTANGLE_NV);
if (ctx->Extensions.MESA_texture_array) {
_mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT);
_mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT);
}
}
}
radeon_meta_set_passthrough_transform(rmesa);
for (i = 0; i < 4; i++) {
color[i][0] = ctx->Color.ClearColor[0];
color[i][1] = ctx->Color.ClearColor[1];
color[i][2] = ctx->Color.ClearColor[2];
color[i][3] = ctx->Color.ClearColor[3];
}
/* convert clear Z from [0,1] to NDC coord in [-1,1] */
dst_z = -1.0 + 2.0 * ctx->Depth.Clear;
/* Prepare the vertices, which are the same regardless of which buffer we're
* drawing to.
*/
vertices[0][0] = fb->_Xmin;
vertices[0][1] = fb->_Ymin;
vertices[0][2] = dst_z;
vertices[1][0] = fb->_Xmax;
vertices[1][1] = fb->_Ymin;
vertices[1][2] = dst_z;
vertices[2][0] = fb->_Xmax;
vertices[2][1] = fb->_Ymax;
vertices[2][2] = dst_z;
vertices[3][0] = fb->_Xmin;
vertices[3][1] = fb->_Ymax;
vertices[3][2] = dst_z;
_mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &color);
_mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), &vertices);
_mesa_Enable(GL_COLOR_ARRAY);
_mesa_Enable(GL_VERTEX_ARRAY);
while (mask != 0) {
GLuint this_mask = 0;
GLuint color_bit;
color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS);
if (color_bit != 0)
this_mask |= (1 << (color_bit - 1));
/* Clear depth/stencil in the same pass as color. */
this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL));
/* Select the current color buffer and use the color write mask if
* we have one, otherwise don't write any color channels.
*/
if (this_mask & BUFFER_BIT_FRONT_LEFT)
_mesa_DrawBuffer(GL_FRONT_LEFT);
else if (this_mask & BUFFER_BIT_BACK_LEFT)
_mesa_DrawBuffer(GL_BACK_LEFT);
else if (color_bit != 0)
_mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 +
(color_bit - BUFFER_COLOR0 - 1));
else
_mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
/* Control writing of the depth clear value to depth. */
if (this_mask & BUFFER_BIT_DEPTH) {
_mesa_DepthFunc(GL_ALWAYS);
_mesa_DepthMask(GL_TRUE);
_mesa_Enable(GL_DEPTH_TEST);
} else {
_mesa_Disable(GL_DEPTH_TEST);
_mesa_DepthMask(GL_FALSE);
}
/* Control writing of the stencil clear value to stencil. */
if (this_mask & BUFFER_BIT_STENCIL) {
_mesa_Enable(GL_STENCIL_TEST);
_mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
_mesa_StencilFuncSeparate(GL_FRONT, GL_ALWAYS, ctx->Stencil.Clear,
ctx->Stencil.WriteMask[0]);
} else {
_mesa_Disable(GL_STENCIL_TEST);
}
CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4));
mask &= ~this_mask;
}
radeon_meta_restore_transform(rmesa);
_mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture);
if (saved_fp_enable)
_mesa_Enable(GL_FRAGMENT_PROGRAM_ARB);
if (saved_vp_enable)
_mesa_Enable(GL_VERTEX_PROGRAM_ARB);
if (saved_shader_program)
_mesa_UseProgramObjectARB(saved_shader_program);
_mesa_PopClientAttrib();
_mesa_PopAttrib();
}

View file

@ -5,6 +5,18 @@
#include "radeon_dma.h"
#include "radeon_texture.h"
#define TRI_CLEAR_COLOR_BITS (BUFFER_BIT_BACK_LEFT | \
BUFFER_BIT_FRONT_LEFT | \
BUFFER_BIT_COLOR0 | \
BUFFER_BIT_COLOR1 | \
BUFFER_BIT_COLOR2 | \
BUFFER_BIT_COLOR3 | \
BUFFER_BIT_COLOR4 | \
BUFFER_BIT_COLOR5 | \
BUFFER_BIT_COLOR6 | \
BUFFER_BIT_COLOR7)
void radeonRecalcScissorRects(radeonContextPtr radeon);
void radeonSetCliprects(radeonContextPtr radeon);
void radeonUpdateScissor( GLcontext *ctx );
@ -24,6 +36,8 @@ void radeonFlush(GLcontext *ctx);
void radeonFinish(GLcontext * ctx);
void radeonEmitState(radeonContextPtr radeon);
void radeon_clear_tris(GLcontext *ctx, GLbitfield mask);
void radeon_window_moved(radeonContextPtr radeon);
void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb);
void radeonDrawBuffer( GLcontext *ctx, GLenum mode );
@ -35,7 +49,10 @@ void radeon_get_cliprects(radeonContextPtr radeon,
int *x_off, int *y_off);
void radeon_fbo_init(struct radeon_context *radeon);
struct gl_renderbuffer *
void
radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb,
struct radeon_bo *bo);
struct radeon_renderbuffer *
radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv);
static inline struct radeon_renderbuffer *radeon_renderbuffer(struct gl_renderbuffer *rb)
{

View file

@ -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);

View file

@ -123,7 +123,6 @@ struct radeon_colorbuffer_state {
struct radeon_depthbuffer_state {
GLuint clear;
GLfloat scale;
struct radeon_renderbuffer *rrb;
};
@ -137,7 +136,6 @@ struct radeon_scissor_state {
};
struct radeon_stencilbuffer_state {
GLboolean hwBuffer;
GLuint clear; /* rb3d_stencilrefmask value */
};
@ -444,9 +442,23 @@ struct radeon_context {
struct radeon_cmdbuf cmdbuf;
drm_clip_rect_t fboRect;
GLboolean constant_cliprect; /* use for FBO or DRI2 rendering */
GLboolean front_cliprects;
drm_clip_rect_t fboRect;
GLboolean constant_cliprect; /* use for FBO or DRI2 rendering */
GLboolean front_cliprects;
struct {
struct gl_fragment_program *bitmap_fp;
struct gl_vertex_program *passthrough_vp;
struct gl_fragment_program *saved_fp;
GLboolean saved_fp_enable;
struct gl_vertex_program *saved_vp;
GLboolean saved_vp_enable;
GLint saved_vp_x, saved_vp_y;
GLsizei saved_vp_width, saved_vp_height;
GLenum saved_matrix_mode;
} meta;
struct {
void (*get_lock)(radeonContextPtr radeon);

View file

@ -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) {

View file

@ -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;
};

View file

@ -54,7 +54,6 @@ radeon_new_framebuffer(GLcontext *ctx, GLuint name)
static void
radeon_delete_renderbuffer(struct gl_renderbuffer *rb)
{
GET_CURRENT_CONTEXT(ctx);
struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
ASSERT(rrb);
@ -62,8 +61,6 @@ radeon_delete_renderbuffer(struct gl_renderbuffer *rb)
if (rrb && rrb->bo) {
radeon_bo_unref(rrb->bo);
}
_mesa_free(rrb);
}
@ -255,7 +252,7 @@ radeon_nop_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
return GL_FALSE;
}
struct gl_renderbuffer *
struct radeon_renderbuffer *
radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv)
{
struct radeon_renderbuffer *rrb;
@ -325,7 +322,7 @@ radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv)
rrb->base.GetPointer = radeon_get_pointer;
rrb->bo = NULL;
return &rrb->base;
return rrb;
}
static struct gl_renderbuffer *
@ -383,6 +380,13 @@ radeon_update_wrapper(GLcontext *ctx, struct radeon_renderbuffer *rrb,
rrb->base.DataType = GL_UNSIGNED_BYTE;
DBG("Render to RGBA8 texture OK\n");
}
else if (texImage->TexFormat == &_mesa_texformat_argb4444) {
rrb->cpp = 2;
rrb->base._ActualFormat = GL_RGBA4;
rrb->base._BaseFormat = GL_RGBA;
rrb->base.DataType = GL_UNSIGNED_BYTE;
DBG("Render to RGBA4 texture OK\n");
}
else if (texImage->TexFormat == &_mesa_texformat_rgb565) {
rrb->cpp = 2;
rrb->base._ActualFormat = GL_RGB5;
@ -493,7 +497,7 @@ radeon_render_texture(GLcontext * ctx,
return;
}
fprintf(stderr,"Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n",
DBG("Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n",
_glthread_GetID(),
att->Texture->Name, newImage->Width, newImage->Height,
rrb->base.RefCount);
@ -558,4 +562,13 @@ void radeon_fbo_init(struct radeon_context *radeon)
}
void radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb,
struct radeon_bo *bo)
{
struct radeon_bo *old;
old = rb->bo;
rb->bo = bo;
radeon_bo_ref(bo);
if (old)
radeon_bo_unref(old);
}

View file

@ -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;
}

View file

@ -1086,6 +1086,9 @@ radeonCreateScreen2(__DRIscreenPrivate *sPriv)
else
screen->chip_flags |= RADEON_CLASS_R300;
if (getenv("R300_NO_TCL"))
screen->chip_flags &= ~RADEON_CHIPSET_TCL;
i = 0;
screen->extensions[i++] = &driCopySubBufferExtension.base;
screen->extensions[i++] = &driFrameTrackingExtension.base;
@ -1197,7 +1200,6 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
const GLboolean swStencil = mesaVis->stencilBits > 0 &&
mesaVis->depthBits != 24;
GLenum rgbFormat = (mesaVis->redBits == 5 ? GL_RGB5 : GL_RGBA8);
GLenum depthFormat = GL_NONE;
struct radeon_framebuffer *rfb;
if (isPixmap)
@ -1209,37 +1211,35 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
_mesa_initialize_framebuffer(&rfb->base, mesaVis);
if (mesaVis->depthBits == 16)
depthFormat = GL_DEPTH_COMPONENT16;
else if (mesaVis->depthBits == 24)
depthFormat = GL_DEPTH_COMPONENT24;
/* front color renderbuffer */
rfb->color_rb[0] = radeon_renderbuffer(radeon_create_renderbuffer(rgbFormat, driDrawPriv));
rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
_mesa_add_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT, &rfb->color_rb[0]->base);
rfb->color_rb[0]->has_surface = 1;
/* back color renderbuffer */
if (mesaVis->doubleBufferMode) {
rfb->color_rb[1] = radeon_renderbuffer(radeon_create_renderbuffer(rgbFormat, driDrawPriv));
rfb->color_rb[1] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
_mesa_add_renderbuffer(&rfb->base, BUFFER_BACK_LEFT, &rfb->color_rb[1]->base);
rfb->color_rb[1]->has_surface = 1;
}
/* depth renderbuffer */
if (depthFormat != GL_NONE) {
struct radeon_renderbuffer *depth = radeon_renderbuffer(
radeon_create_renderbuffer(depthFormat, driDrawPriv));
if (mesaVis->depthBits == 24) {
if (mesaVis->stencilBits == 8) {
struct radeon_renderbuffer *depthStencilRb = radeon_create_renderbuffer(GL_DEPTH24_STENCIL8_EXT, driDrawPriv);
_mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depthStencilRb->base);
_mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &depthStencilRb->base);
depthStencilRb->has_surface = screen->depthHasSurface;
} else {
/* depth renderbuffer */
struct radeon_renderbuffer *depth = radeon_create_renderbuffer(GL_DEPTH_COMPONENT24, driDrawPriv);
_mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base);
depth->has_surface = screen->depthHasSurface;
}
} else if (mesaVis->depthBits == 16) {
/* just 16-bit depth buffer, no hw stencil */
struct radeon_renderbuffer *depth = radeon_create_renderbuffer(GL_DEPTH_COMPONENT16, driDrawPriv);
_mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base);
depth->has_surface = screen->depthHasSurface;
}
/* stencil renderbuffer */
if (mesaVis->stencilBits > 0 && !swStencil) {
struct radeon_renderbuffer *stencil = radeon_renderbuffer(
radeon_create_renderbuffer(GL_STENCIL_INDEX8_EXT, driDrawPriv));
_mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &stencil->base);
stencil->has_surface = screen->depthHasSurface;
}
_mesa_add_soft_renderbuffers(&rfb->base,

View file

@ -377,33 +377,64 @@ do { \
#include "stenciltmp.h"
static void map_buffer(struct gl_renderbuffer *rb, GLboolean write)
void map_unmap_rb(struct gl_renderbuffer *rb, int flag)
{
struct radeon_renderbuffer *rrb = (void*)rb;
struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
int r;
if (rrb->bo) {
r = radeon_bo_map(rrb->bo, write);
if (rrb == NULL || !rrb->bo)
return;
if (flag) {
r = radeon_bo_map(rrb->bo, 1);
if (r) {
fprintf(stderr, "(%s) error(%d) mapping buffer.\n",
__FUNCTION__, r);
}
}
radeonSetSpanFunctions(rrb);
}
static void unmap_buffer(struct gl_renderbuffer *rb)
{
struct radeon_renderbuffer *rrb = (void*)rb;
if (rrb->bo) {
radeonSetSpanFunctions(rrb);
} else {
radeon_bo_unmap(rrb->bo);
rb->GetRow = NULL;
rb->PutRow = NULL;
}
rb->GetRow = NULL;
rb->PutRow = NULL;
}
static void
radeon_map_unmap_buffers(GLcontext *ctx, GLboolean map)
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
GLuint i, j;
/* 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);
@ -416,18 +447,7 @@ static void radeonSpanRenderStart(GLcontext * ctx)
ctx->Driver.MapTexture(ctx, ctx->Texture.Unit[i]._Current);
}
/* color draw buffers */
for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
map_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i], GL_TRUE);
}
map_buffer(ctx->ReadBuffer->_ColorReadBuffer, GL_FALSE);
if (ctx->DrawBuffer->_DepthBuffer) {
map_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped, GL_TRUE);
}
if (ctx->DrawBuffer->_StencilBuffer)
map_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped, GL_TRUE);
radeon_map_unmap_buffers(ctx, 1);
/* The locking and wait for idle should really only be needed in classic mode.
* In a future memory manager based implementation, this should become
@ -450,16 +470,7 @@ static void radeonSpanRenderFinish(GLcontext * ctx)
ctx->Driver.UnmapTexture(ctx, ctx->Texture.Unit[i]._Current);
}
/* color draw buffers */
for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++)
unmap_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i]);
unmap_buffer(ctx->ReadBuffer->_ColorReadBuffer);
if (ctx->DrawBuffer->_DepthBuffer)
unmap_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped);
if (ctx->DrawBuffer->_StencilBuffer)
unmap_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped);
radeon_map_unmap_buffers(ctx, 0);
}
void radeonInitSpanFuncs(GLcontext * ctx)
@ -485,6 +496,8 @@ static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb)
radeonInitDepthPointers_z16(&rrb->base);
} else if (rrb->base._ActualFormat == GL_DEPTH_COMPONENT24) {
radeonInitDepthPointers_z24_s8(&rrb->base);
} else if (rrb->base._ActualFormat == GL_DEPTH24_STENCIL8_EXT) {
radeonInitStencilPointers_z24_s8(&rrb->base);
} else if (rrb->base._ActualFormat == GL_STENCIL_INDEX8_EXT) {
radeonInitStencilPointers_z24_s8(&rrb->base);
}

View file

@ -528,7 +528,8 @@ static void radeonPolygonOffset( GLcontext *ctx,
GLfloat factor, GLfloat units )
{
r100ContextPtr rmesa = R100_CONTEXT(ctx);
float_ui32_type constant = { units * rmesa->radeon.state.depth.scale };
const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
float_ui32_type constant = { units * depthScale };
float_ui32_type factoru = { factor };
RADEON_STATECHANGE( rmesa, zbs );
@ -1391,6 +1392,7 @@ void radeonUpdateWindow( GLcontext *ctx )
GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
const GLfloat *v = ctx->Viewport._WindowMap.m;
const GLboolean render_to_fbo = (ctx->DrawBuffer ? (ctx->DrawBuffer->Name != 0) : 0);
const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
GLfloat y_scale, y_bias;
if (render_to_fbo) {
@ -1405,8 +1407,8 @@ void radeonUpdateWindow( GLcontext *ctx )
float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X };
float_ui32_type sy = { v[MAT_SY] * y_scale };
float_ui32_type ty = { (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y };
float_ui32_type sz = { v[MAT_SZ] * rmesa->radeon.state.depth.scale };
float_ui32_type tz = { v[MAT_TZ] * rmesa->radeon.state.depth.scale };
float_ui32_type sz = { v[MAT_SZ] * depthScale };
float_ui32_type tz = { v[MAT_TZ] * depthScale };
RADEON_STATECHANGE( rmesa, vpt );
@ -1800,15 +1802,24 @@ static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state )
break;
case GL_STENCIL_TEST:
if ( rmesa->radeon.state.stencil.hwBuffer ) {
RADEON_STATECHANGE( rmesa, ctx );
if ( state ) {
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_STENCIL_ENABLE;
} else {
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 {
FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state );
}
} else {
FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state );
}
break;

View file

@ -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;