Merge branch 'radeon-fbo-hacking' into radeon-rewrite

This commit is contained in:
Dave Airlie 2009-03-23 18:56:34 +10:00
commit cb68588c93
26 changed files with 1317 additions and 805 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 */
@ -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 );

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

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

View file

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

View file

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

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,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 (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) {
/* SW fallback clearing */
swrast_mask = mask & ~tri_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_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,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);

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"
@ -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();
}

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

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

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

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

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

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

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

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

View file

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

View file

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

View file

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

View file

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

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