mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-06-02 17:48:17 +02:00
radeon/r200/r300: bring back old style DMA buffer on top of BOs.
this gets back a lot of the lots speed in gears on r500 at least I also fixed the legacy bufmgr to deal when the dma space fills up
This commit is contained in:
parent
682ebc79d5
commit
5ba92a5b05
19 changed files with 243 additions and 754 deletions
|
|
@ -18,7 +18,6 @@ DRIVER_SOURCES = r200_context.c \
|
|||
r200_cmdbuf.c \
|
||||
r200_pixel.c \
|
||||
r200_tex.c \
|
||||
r200_texmem.c \
|
||||
r200_texstate.c \
|
||||
r200_tcl.c \
|
||||
r200_swtcl.c \
|
||||
|
|
|
|||
|
|
@ -365,9 +365,6 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
|
|||
}
|
||||
|
||||
|
||||
if (!rmesa->radeon.radeonScreen->kernel_mm)
|
||||
rmesa->dma.buf0_address = rmesa->radeon.radeonScreen->buffers->list[0].address;
|
||||
|
||||
(void) memset( rmesa->radeon.texture_heaps, 0, sizeof( rmesa->radeon.texture_heaps ) );
|
||||
make_empty_list( & rmesa->radeon.swapped );
|
||||
|
||||
|
|
@ -587,8 +584,8 @@ void r200DestroyContext( __DRIcontextPrivate *driContextPriv )
|
|||
r200DestroySwtcl( rmesa->radeon.glCtx );
|
||||
r200ReleaseArrays( rmesa->radeon.glCtx, ~0 );
|
||||
|
||||
if (rmesa->dma.current.buf) {
|
||||
// r200ReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ );
|
||||
if (rmesa->dma.current) {
|
||||
radeonReleaseDmaRegion(rmesa);
|
||||
rcommonFlushCmdBuf( &rmesa->radeon, __FUNCTION__ );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -525,10 +525,6 @@ struct r200_state {
|
|||
GLuint envneeded;
|
||||
};
|
||||
|
||||
#define GET_START(rvb) (rmesa->radeon.radeonScreen->gart_buffer_offset + \
|
||||
(rvb)->address - rmesa->dma.buf0_address + \
|
||||
(rvb)->start)
|
||||
|
||||
#define R200_CMD_BUF_SZ (16*1024)
|
||||
|
||||
#define R200_ELT_BUF_SZ (16*1024)
|
||||
|
|
|
|||
|
|
@ -50,110 +50,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#include "r200_maos.h"
|
||||
#include "r200_tcl.h"
|
||||
|
||||
|
||||
#if 0
|
||||
/* Usage:
|
||||
* - from r200_tcl_render
|
||||
* - call r200EmitArrays to ensure uptodate arrays in dma
|
||||
* - emit primitives (new type?) which reference the data
|
||||
* -- need to use elts for lineloop, quads, quadstrip/flat
|
||||
* -- other primitives are all well-formed (need tristrip-1,fake-poly)
|
||||
*
|
||||
*/
|
||||
static void emit_ubyte_rgba3( GLcontext *ctx,
|
||||
struct radeon_dma_region *rvb,
|
||||
char *data,
|
||||
int stride,
|
||||
int count )
|
||||
{
|
||||
int i;
|
||||
r200_color_t *out = (r200_color_t *)(rvb->start + rvb->address);
|
||||
|
||||
if (R200_DEBUG & DEBUG_VERTS)
|
||||
fprintf(stderr, "%s count %d stride %d out %p\n",
|
||||
__FUNCTION__, count, stride, (void *)out);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
out->red = *data;
|
||||
out->green = *(data+1);
|
||||
out->blue = *(data+2);
|
||||
out->alpha = 0xFF;
|
||||
out++;
|
||||
data += stride;
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_ubyte_rgba4( GLcontext *ctx,
|
||||
struct radeon_dma_region *rvb,
|
||||
char *data,
|
||||
int stride,
|
||||
int count )
|
||||
{
|
||||
int i;
|
||||
int *out = (int *)(rvb->address + rvb->start);
|
||||
|
||||
if (R200_DEBUG & DEBUG_VERTS)
|
||||
fprintf(stderr, "%s count %d stride %d\n",
|
||||
__FUNCTION__, count, stride);
|
||||
|
||||
if (stride == 4) {
|
||||
for (i = 0; i < count; i++)
|
||||
((int *)out)[i] = LE32_TO_CPU(((int *)data)[i]);
|
||||
} else {
|
||||
for (i = 0; i < count; i++) {
|
||||
*(int *)out++ = LE32_TO_CPU(*(int *)data);
|
||||
data += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void emit_ubyte_rgba( GLcontext *ctx,
|
||||
struct radeon_dma_region *rvb,
|
||||
char *data,
|
||||
int size,
|
||||
int stride,
|
||||
int count )
|
||||
{
|
||||
r200ContextPtr rmesa = R200_CONTEXT(ctx);
|
||||
|
||||
if (R200_DEBUG & DEBUG_VERTS)
|
||||
fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size);
|
||||
|
||||
assert (!rvb->buf);
|
||||
|
||||
if (stride == 0) {
|
||||
// r200AllocDmaRegion( rmesa, rvb, 4, 4 );
|
||||
count = 1;
|
||||
rvb->aos_start = GET_START(rvb);
|
||||
rvb->aos_stride = 0;
|
||||
rvb->aos_size = 1;
|
||||
}
|
||||
else {
|
||||
// r200AllocDmaRegion( rmesa, rvb, 4 * count, 4 ); /* alignment? */
|
||||
rvb->aos_start = GET_START(rvb);
|
||||
rvb->aos_stride = 1;
|
||||
rvb->aos_size = 1;
|
||||
}
|
||||
|
||||
/* Emit the data
|
||||
*/
|
||||
switch (size) {
|
||||
case 3:
|
||||
emit_ubyte_rgba3( ctx, rvb, data, stride, count );
|
||||
break;
|
||||
case 4:
|
||||
emit_ubyte_rgba4( ctx, rvb, data, stride, count );
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(USE_X86_ASM)
|
||||
#define COPY_DWORDS( dst, src, nr ) \
|
||||
do { \
|
||||
|
|
|
|||
|
|
@ -1,531 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright (C) Tungsten Graphics 2002. All Rights Reserved.
|
||||
The Weather Channel, Inc. funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86
|
||||
license. This notice must be preserved.
|
||||
|
||||
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 on 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 ATI, VA LINUX SYSTEMS AND/OR THEIR
|
||||
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.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Kevin E. Martin <martin@valinux.com>
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "main/imports.h"
|
||||
#include "main/context.h"
|
||||
#include "main/colormac.h"
|
||||
#include "main/macros.h"
|
||||
#include "r200_context.h"
|
||||
#include "r200_ioctl.h"
|
||||
#include "r200_tex.h"
|
||||
#include "radeon_reg.h"
|
||||
|
||||
#include <unistd.h> /* for usleep() */
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Destroy any device-dependent state associated with the texture. This may
|
||||
* include NULLing out hardware state that points to the texture.
|
||||
*/
|
||||
void
|
||||
r200DestroyTexObj( r200ContextPtr rmesa, radeonTexObjPtr t )
|
||||
{
|
||||
if ( R200_DEBUG & DEBUG_TEXTURE ) {
|
||||
fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__,
|
||||
(void *)t, (void *)t->base.tObj );
|
||||
}
|
||||
|
||||
if ( rmesa != NULL ) {
|
||||
unsigned i;
|
||||
|
||||
|
||||
for ( i = 0 ; i < rmesa->radeon.glCtx->Const.MaxTextureUnits ; i++ ) {
|
||||
if ( t == rmesa->state.texture.unit[i].texobj ) {
|
||||
rmesa->state.texture.unit[i].texobj = NULL;
|
||||
rmesa->hw.tex[i].dirty = GL_FALSE;
|
||||
rmesa->hw.cube[i].dirty = GL_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* Texture image conversions
|
||||
*/
|
||||
|
||||
|
||||
static void r200UploadGARTClientSubImage( r200ContextPtr rmesa,
|
||||
radeonTexObjPtr t,
|
||||
struct gl_texture_image *texImage,
|
||||
GLint hwlevel,
|
||||
GLint x, GLint y,
|
||||
GLint width, GLint height )
|
||||
{
|
||||
const struct gl_texture_format *texFormat = texImage->TexFormat;
|
||||
GLuint srcPitch, dstPitch;
|
||||
int blit_format;
|
||||
int srcOffset;
|
||||
|
||||
/*
|
||||
* XXX it appears that we always upload the full image, not a subimage.
|
||||
* I.e. x==0, y==0, width=texWidth, height=texWidth. If this is ever
|
||||
* changed, the src pitch will have to change.
|
||||
*/
|
||||
switch ( texFormat->TexelBytes ) {
|
||||
case 1:
|
||||
blit_format = R200_CP_COLOR_FORMAT_CI8;
|
||||
srcPitch = t->image[0][0].width * texFormat->TexelBytes;
|
||||
dstPitch = t->image[0][0].width * texFormat->TexelBytes;
|
||||
break;
|
||||
case 2:
|
||||
blit_format = R200_CP_COLOR_FORMAT_RGB565;
|
||||
srcPitch = t->image[0][0].width * texFormat->TexelBytes;
|
||||
dstPitch = t->image[0][0].width * texFormat->TexelBytes;
|
||||
break;
|
||||
case 4:
|
||||
blit_format = R200_CP_COLOR_FORMAT_ARGB8888;
|
||||
srcPitch = t->image[0][0].width * texFormat->TexelBytes;
|
||||
dstPitch = t->image[0][0].width * texFormat->TexelBytes;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
t->image[0][hwlevel].data = texImage->Data;
|
||||
srcOffset = r200GartOffsetFromVirtual( rmesa, texImage->Data );
|
||||
|
||||
assert( srcOffset != ~0 );
|
||||
|
||||
/* Don't currently need to cope with small pitches?
|
||||
*/
|
||||
width = texImage->Width;
|
||||
height = texImage->Height;
|
||||
|
||||
r200EmitWait( rmesa, RADEON_WAIT_3D );
|
||||
|
||||
r200EmitBlit( rmesa, blit_format,
|
||||
srcPitch,
|
||||
srcOffset,
|
||||
dstPitch,
|
||||
t->bufAddr,
|
||||
x,
|
||||
y,
|
||||
t->image[0][hwlevel].x + x,
|
||||
t->image[0][hwlevel].y + y,
|
||||
width,
|
||||
height );
|
||||
|
||||
r200EmitWait( rmesa, RADEON_WAIT_2D );
|
||||
}
|
||||
|
||||
static void r200UploadRectSubImage( r200ContextPtr rmesa,
|
||||
radeonTexObjPtr t,
|
||||
struct gl_texture_image *texImage,
|
||||
GLint x, GLint y,
|
||||
GLint width, GLint height )
|
||||
{
|
||||
const struct gl_texture_format *texFormat = texImage->TexFormat;
|
||||
int blit_format, dstPitch, done;
|
||||
|
||||
switch ( texFormat->TexelBytes ) {
|
||||
case 1:
|
||||
blit_format = R200_CP_COLOR_FORMAT_CI8;
|
||||
break;
|
||||
case 2:
|
||||
blit_format = R200_CP_COLOR_FORMAT_RGB565;
|
||||
break;
|
||||
case 4:
|
||||
blit_format = R200_CP_COLOR_FORMAT_ARGB8888;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
t->image[0][0].data = texImage->Data;
|
||||
|
||||
/* Currently don't need to cope with small pitches.
|
||||
*/
|
||||
width = texImage->Width;
|
||||
height = texImage->Height;
|
||||
dstPitch = t->pp_txpitch + 32;
|
||||
|
||||
if (rmesa->prefer_gart_client_texturing && texImage->IsClientData) {
|
||||
/* In this case, could also use GART texturing. This is
|
||||
* currently disabled, but has been tested & works.
|
||||
*/
|
||||
if ( !t->image_override )
|
||||
t->pp_txoffset = r200GartOffsetFromVirtual( rmesa, texImage->Data );
|
||||
t->pp_txpitch = texImage->RowStride * texFormat->TexelBytes - 32;
|
||||
|
||||
if (R200_DEBUG & DEBUG_TEXTURE)
|
||||
fprintf(stderr,
|
||||
"Using GART texturing for rectangular client texture\n");
|
||||
|
||||
/* Release FB memory allocated for this image:
|
||||
*/
|
||||
/* FIXME This may not be correct as driSwapOutTextureObject sets
|
||||
* FIXME dirty_images. It may be fine, though.
|
||||
*/
|
||||
if ( t->base.memBlock ) {
|
||||
driSwapOutTextureObject( (driTextureObject *) t );
|
||||
}
|
||||
}
|
||||
else if (texImage->IsClientData) {
|
||||
/* Data already in GART memory, with usable pitch.
|
||||
*/
|
||||
GLuint srcPitch;
|
||||
srcPitch = texImage->RowStride * texFormat->TexelBytes;
|
||||
r200EmitBlit( rmesa,
|
||||
blit_format,
|
||||
srcPitch,
|
||||
r200GartOffsetFromVirtual( rmesa, texImage->Data ),
|
||||
dstPitch, t->bufAddr,
|
||||
0, 0,
|
||||
0, 0,
|
||||
width, height );
|
||||
}
|
||||
else {
|
||||
/* Data not in GART memory, or bad pitch.
|
||||
*/
|
||||
for (done = 0; done < height ; ) {
|
||||
struct radeon_dma_region region;
|
||||
int lines = MIN2( height - done, RADEON_BUFFER_SIZE / dstPitch );
|
||||
int src_pitch;
|
||||
char *tex;
|
||||
|
||||
src_pitch = texImage->RowStride * texFormat->TexelBytes;
|
||||
|
||||
tex = (char *)texImage->Data + done * src_pitch;
|
||||
|
||||
memset(®ion, 0, sizeof(region));
|
||||
// r200AllocDmaRegion( rmesa, ®ion, lines * dstPitch, 1024 );
|
||||
|
||||
/* Copy texdata to dma:
|
||||
*/
|
||||
if (0)
|
||||
fprintf(stderr, "%s: src_pitch %d dst_pitch %d\n",
|
||||
__FUNCTION__, src_pitch, dstPitch);
|
||||
|
||||
if (src_pitch == dstPitch) {
|
||||
memcpy( region.address + region.start, tex, lines * src_pitch );
|
||||
}
|
||||
else {
|
||||
char *buf = region.address + region.start;
|
||||
int i;
|
||||
for (i = 0 ; i < lines ; i++) {
|
||||
memcpy( buf, tex, src_pitch );
|
||||
buf += dstPitch;
|
||||
tex += src_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
r200EmitWait( rmesa, RADEON_WAIT_3D );
|
||||
|
||||
/* Blit to framebuffer
|
||||
*/
|
||||
r200EmitBlit( rmesa,
|
||||
blit_format,
|
||||
dstPitch, GET_START( ®ion ),
|
||||
dstPitch | (t->tile_bits >> 16),
|
||||
t->bufAddr,
|
||||
0, 0,
|
||||
0, done,
|
||||
width, lines );
|
||||
|
||||
r200EmitWait( rmesa, RADEON_WAIT_2D );
|
||||
|
||||
// r200ReleaseDmaRegion( rmesa, ®ion, __FUNCTION__ );
|
||||
done += lines;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Upload the texture image associated with texture \a t at the specified
|
||||
* level at the address relative to \a start.
|
||||
*/
|
||||
static void uploadSubImage( r200ContextPtr rmesa, radeonTexObjPtr t,
|
||||
GLint hwlevel,
|
||||
GLint x, GLint y, GLint width, GLint height,
|
||||
GLuint face )
|
||||
{
|
||||
struct gl_texture_image *texImage = NULL;
|
||||
GLuint offset;
|
||||
GLint imageWidth, imageHeight;
|
||||
GLint ret;
|
||||
drm_radeon_texture_t tex;
|
||||
drm_radeon_tex_image_t tmp;
|
||||
const int level = hwlevel + t->base.firstLevel;
|
||||
|
||||
if ( R200_DEBUG & DEBUG_TEXTURE ) {
|
||||
fprintf( stderr, "%s( %p, %p ) level/width/height/face = %d/%d/%d/%u\n",
|
||||
__FUNCTION__, (void *)t, (void *)t->base.tObj,
|
||||
level, width, height, face );
|
||||
}
|
||||
|
||||
ASSERT(face < 6);
|
||||
|
||||
/* Ensure we have a valid texture to upload */
|
||||
if ( ( hwlevel < 0 ) || ( hwlevel >= RADEON_MAX_TEXTURE_LEVELS ) ) {
|
||||
_mesa_problem(NULL, "bad texture level in %s", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
texImage = t->base.tObj->Image[face][level];
|
||||
|
||||
if ( !texImage ) {
|
||||
if ( R200_DEBUG & DEBUG_TEXTURE )
|
||||
fprintf( stderr, "%s: texImage %d is NULL!\n", __FUNCTION__, level );
|
||||
return;
|
||||
}
|
||||
if ( !texImage->Data ) {
|
||||
if ( R200_DEBUG & DEBUG_TEXTURE )
|
||||
fprintf( stderr, "%s: image data is NULL!\n", __FUNCTION__ );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (t->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
|
||||
assert(level == 0);
|
||||
assert(hwlevel == 0);
|
||||
if ( R200_DEBUG & DEBUG_TEXTURE )
|
||||
fprintf( stderr, "%s: image data is rectangular\n", __FUNCTION__);
|
||||
r200UploadRectSubImage( rmesa, t, texImage, x, y, width, height );
|
||||
return;
|
||||
}
|
||||
else if (texImage->IsClientData) {
|
||||
if ( R200_DEBUG & DEBUG_TEXTURE )
|
||||
fprintf( stderr, "%s: image data is in GART client storage\n",
|
||||
__FUNCTION__);
|
||||
r200UploadGARTClientSubImage( rmesa, t, texImage, hwlevel,
|
||||
x, y, width, height );
|
||||
return;
|
||||
}
|
||||
else if ( R200_DEBUG & DEBUG_TEXTURE )
|
||||
fprintf( stderr, "%s: image data is in normal memory\n",
|
||||
__FUNCTION__);
|
||||
|
||||
|
||||
imageWidth = texImage->Width;
|
||||
imageHeight = texImage->Height;
|
||||
|
||||
offset = t->bufAddr + t->base.totalSize / 6 * face;
|
||||
|
||||
if ( R200_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) {
|
||||
GLint imageX = 0;
|
||||
GLint imageY = 0;
|
||||
GLint blitX = t->image[face][hwlevel].x;
|
||||
GLint blitY = t->image[face][hwlevel].y;
|
||||
GLint blitWidth = t->image[face][hwlevel].width;
|
||||
GLint blitHeight = t->image[face][hwlevel].height;
|
||||
fprintf( stderr, " upload image: %d,%d at %d,%d\n",
|
||||
imageWidth, imageHeight, imageX, imageY );
|
||||
fprintf( stderr, " upload blit: %d,%d at %d,%d\n",
|
||||
blitWidth, blitHeight, blitX, blitY );
|
||||
fprintf( stderr, " blit ofs: 0x%07x level: %d/%d\n",
|
||||
(GLuint)offset, hwlevel, level );
|
||||
}
|
||||
|
||||
t->image[face][hwlevel].data = texImage->Data;
|
||||
|
||||
/* Init the DRM_RADEON_TEXTURE command / drm_radeon_texture_t struct.
|
||||
* NOTE: we're always use a 1KB-wide blit and I8 texture format.
|
||||
* We used to use 1, 2 and 4-byte texels and used to use the texture
|
||||
* width to dictate the blit width - but that won't work for compressed
|
||||
* textures. (Brian)
|
||||
* NOTE: can't do that with texture tiling. (sroland)
|
||||
*/
|
||||
tex.offset = offset;
|
||||
tex.image = &tmp;
|
||||
/* copy (x,y,width,height,data) */
|
||||
memcpy( &tmp, &t->image[face][hwlevel], sizeof(tmp) );
|
||||
|
||||
if (texImage->TexFormat->TexelBytes) {
|
||||
/* use multi-byte upload scheme */
|
||||
tex.height = imageHeight;
|
||||
tex.width = imageWidth;
|
||||
tex.format = t->pp_txformat & R200_TXFORMAT_FORMAT_MASK;
|
||||
if (tex.format == R200_TXFORMAT_ABGR8888) {
|
||||
/* drm will refuse abgr8888 textures. */
|
||||
tex.format = R200_TXFORMAT_ARGB8888;
|
||||
}
|
||||
tex.pitch = MAX2((texImage->Width * texImage->TexFormat->TexelBytes) / 64, 1);
|
||||
tex.offset += tmp.x & ~1023;
|
||||
tmp.x = tmp.x % 1024;
|
||||
if (t->tile_bits & R200_TXO_MICRO_TILE) {
|
||||
/* need something like "tiled coordinates" ? */
|
||||
tmp.y = tmp.x / (tex.pitch * 128) * 2;
|
||||
tmp.x = tmp.x % (tex.pitch * 128) / 2 / texImage->TexFormat->TexelBytes;
|
||||
tex.pitch |= RADEON_DST_TILE_MICRO >> 22;
|
||||
}
|
||||
else {
|
||||
tmp.x = tmp.x >> (texImage->TexFormat->TexelBytes >> 1);
|
||||
}
|
||||
if ((t->tile_bits & R200_TXO_MACRO_TILE) &&
|
||||
(texImage->Width * texImage->TexFormat->TexelBytes >= 256) &&
|
||||
((!(t->tile_bits & R200_TXO_MICRO_TILE) && (texImage->Height >= 8)) ||
|
||||
(texImage->Height >= 16))) {
|
||||
/* weird: R200 disables macro tiling if mip width is smaller than 256 bytes,
|
||||
OR if height is smaller than 8 automatically, but if micro tiling is active
|
||||
the limit is height 16 instead ? */
|
||||
tex.pitch |= RADEON_DST_TILE_MACRO >> 22;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* In case of for instance 8x8 texture (2x2 dxt blocks), padding after the first two blocks is
|
||||
needed (only with dxt1 since 2 dxt3/dxt5 blocks already use 32 Byte). */
|
||||
/* set tex.height to 1/4 since 1 "macropixel" (dxt-block) has 4 real pixels. Needed
|
||||
so the kernel module reads the right amount of data. */
|
||||
tex.format = R200_TXFORMAT_I8; /* any 1-byte texel format */
|
||||
tex.pitch = (BLIT_WIDTH_BYTES / 64);
|
||||
tex.height = (imageHeight + 3) / 4;
|
||||
tex.width = (imageWidth + 3) / 4;
|
||||
switch (t->pp_txformat & R200_TXFORMAT_FORMAT_MASK) {
|
||||
case R200_TXFORMAT_DXT1:
|
||||
tex.width *= 8;
|
||||
break;
|
||||
case R200_TXFORMAT_DXT23:
|
||||
case R200_TXFORMAT_DXT45:
|
||||
tex.width *= 16;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unknown compressed tex format in uploadSubImage\n");
|
||||
}
|
||||
}
|
||||
|
||||
LOCK_HARDWARE( &rmesa->radeon );
|
||||
do {
|
||||
ret = drmCommandWriteRead( rmesa->radeon.dri.fd, DRM_RADEON_TEXTURE,
|
||||
&tex, sizeof(drm_radeon_texture_t) );
|
||||
if (ret) {
|
||||
if (R200_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "DRM_RADEON_TEXTURE: again!\n");
|
||||
usleep(1);
|
||||
}
|
||||
} while ( ret == -EAGAIN );
|
||||
|
||||
UNLOCK_HARDWARE( &rmesa->radeon );
|
||||
|
||||
if ( ret ) {
|
||||
fprintf( stderr, "DRM_RADEON_TEXTURE: return = %d\n", ret );
|
||||
fprintf( stderr, " offset=0x%08x\n",
|
||||
offset );
|
||||
fprintf( stderr, " image width=%d height=%d\n",
|
||||
imageWidth, imageHeight );
|
||||
fprintf( stderr, " blit width=%d height=%d data=%p\n",
|
||||
t->image[face][hwlevel].width, t->image[face][hwlevel].height,
|
||||
t->image[face][hwlevel].data );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Upload the texture images associated with texture \a t. This might
|
||||
* require the allocation of texture memory.
|
||||
*
|
||||
* \param rmesa Context pointer
|
||||
* \param t Texture to be uploaded
|
||||
* \param face Cube map face to be uploaded. Zero for non-cube maps.
|
||||
*/
|
||||
|
||||
int r200UploadTexImages( r200ContextPtr rmesa, radeonTexObjPtr t, GLuint face )
|
||||
{
|
||||
const int numLevels = t->base.lastLevel - t->base.firstLevel + 1;
|
||||
|
||||
if ( R200_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) {
|
||||
fprintf( stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n", __FUNCTION__,
|
||||
(void *)rmesa->radeon.glCtx, (void *)t->base.tObj, t->base.totalSize,
|
||||
t->base.firstLevel, t->base.lastLevel );
|
||||
}
|
||||
|
||||
if ( !t || t->base.totalSize == 0 || t->image_override )
|
||||
return 0;
|
||||
|
||||
if (R200_DEBUG & DEBUG_SYNC) {
|
||||
fprintf(stderr, "%s: Syncing\n", __FUNCTION__ );
|
||||
r200Finish( rmesa->radeon.glCtx );
|
||||
}
|
||||
|
||||
LOCK_HARDWARE( &rmesa->radeon );
|
||||
|
||||
if ( t->base.memBlock == NULL ) {
|
||||
int heap;
|
||||
|
||||
heap = driAllocateTexture( rmesa->radeon.texture_heaps, rmesa->radeon.nr_heaps,
|
||||
(driTextureObject *) t );
|
||||
if ( heap == -1 ) {
|
||||
UNLOCK_HARDWARE( &rmesa->radeon );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set the base offset of the texture image */
|
||||
t->bufAddr = rmesa->radeon.radeonScreen->texOffset[heap]
|
||||
+ t->base.memBlock->ofs;
|
||||
t->pp_txoffset = t->bufAddr;
|
||||
|
||||
if (!(t->base.tObj->Image[0][0]->IsClientData)) {
|
||||
/* hope it's safe to add that here... */
|
||||
t->pp_txoffset |= t->tile_bits;
|
||||
}
|
||||
|
||||
/* Mark this texobj as dirty on all units:
|
||||
*/
|
||||
t->dirty_state = R200_TEX_ALL;
|
||||
}
|
||||
|
||||
/* Let the world know we've used this memory recently.
|
||||
*/
|
||||
driUpdateTextureLRU( (driTextureObject *) t );
|
||||
UNLOCK_HARDWARE( &rmesa->radeon );
|
||||
|
||||
/* Upload any images that are new */
|
||||
if (t->base.dirty_images[face]) {
|
||||
int i;
|
||||
for ( i = 0 ; i < numLevels ; i++ ) {
|
||||
if ( (t->base.dirty_images[face] & (1 << (i+t->base.firstLevel))) != 0 ) {
|
||||
uploadSubImage( rmesa, t, i, 0, 0, t->image[face][i].width,
|
||||
t->image[face][i].height, face );
|
||||
}
|
||||
}
|
||||
t->base.dirty_images[face] = 0;
|
||||
}
|
||||
|
||||
|
||||
if (R200_DEBUG & DEBUG_SYNC) {
|
||||
fprintf(stderr, "%s: Syncing\n", __FUNCTION__ );
|
||||
r200Finish( rmesa->radeon.glCtx );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -259,6 +259,7 @@ static void r300_init_vtbl(radeonContextPtr radeon)
|
|||
radeon->vtbl.update_draw_buffer = r300UpdateDrawBuffer;
|
||||
radeon->vtbl.emit_cs_header = r300_vtbl_emit_cs_header;
|
||||
radeon->vtbl.emit_state = r300_vtbl_emit_state;
|
||||
radeon->vtbl.flush_vertices = r300_vtbl_flush_vertices;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -699,7 +699,6 @@ struct r300_swtcl_info {
|
|||
GLuint specoffset;
|
||||
|
||||
struct radeon_bo *bo;
|
||||
void (*flush) (r300ContextPtr);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -301,28 +301,28 @@ int r300EmitArrays(GLcontext * ctx)
|
|||
}
|
||||
|
||||
/* Setup INPUT_ROUTE. */
|
||||
if (rmesa->radeon.radeonScreen->kernel_mm) {
|
||||
R300_STATECHANGE(rmesa, vir[0]);
|
||||
rmesa->hw.vir[0].cmd[0] &= 0xC000FFFF;
|
||||
rmesa->hw.vir[1].cmd[0] &= 0xC000FFFF;
|
||||
rmesa->hw.vir[0].cmd[0] |=
|
||||
(r300VAPInputRoute0(&rmesa->hw.vir[0].cmd[R300_VIR_CNTL_0],
|
||||
vb->AttribPtr, inputs, tab, nr) & 0x3FFF) << 16;
|
||||
R300_STATECHANGE(rmesa, vir[1]);
|
||||
rmesa->hw.vir[1].cmd[0] |=
|
||||
(r300VAPInputRoute1(&rmesa->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle,
|
||||
nr) & 0x3FFF) << 16;
|
||||
} else {
|
||||
R300_STATECHANGE(rmesa, vir[0]);
|
||||
((drm_r300_cmd_header_t *) rmesa->hw.vir[0].cmd)->packet0.count =
|
||||
r300VAPInputRoute0(&rmesa->hw.vir[0].cmd[R300_VIR_CNTL_0],
|
||||
vb->AttribPtr, inputs, tab, nr);
|
||||
R300_STATECHANGE(rmesa, vir[1]);
|
||||
((drm_r300_cmd_header_t *) rmesa->hw.vir[1].cmd)->packet0.count =
|
||||
r300VAPInputRoute1(&rmesa->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle,
|
||||
nr);
|
||||
}
|
||||
|
||||
if (rmesa->radeon.radeonScreen->kernel_mm) {
|
||||
R300_STATECHANGE(rmesa, vir[0]);
|
||||
rmesa->hw.vir[0].cmd[0] &= 0xC000FFFF;
|
||||
rmesa->hw.vir[1].cmd[0] &= 0xC000FFFF;
|
||||
rmesa->hw.vir[0].cmd[0] |=
|
||||
(r300VAPInputRoute0(&rmesa->hw.vir[0].cmd[R300_VIR_CNTL_0],
|
||||
vb->AttribPtr, inputs, tab, nr) & 0x3FFF) << 16;
|
||||
R300_STATECHANGE(rmesa, vir[1]);
|
||||
rmesa->hw.vir[1].cmd[0] |=
|
||||
(r300VAPInputRoute1(&rmesa->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle,
|
||||
nr) & 0x3FFF) << 16;
|
||||
} else {
|
||||
R300_STATECHANGE(rmesa, vir[0]);
|
||||
((drm_r300_cmd_header_t *) rmesa->hw.vir[0].cmd)->packet0.count =
|
||||
r300VAPInputRoute0(&rmesa->hw.vir[0].cmd[R300_VIR_CNTL_0],
|
||||
vb->AttribPtr, inputs, tab, nr);
|
||||
R300_STATECHANGE(rmesa, vir[1]);
|
||||
((drm_r300_cmd_header_t *) rmesa->hw.vir[1].cmd)->packet0.count =
|
||||
r300VAPInputRoute1(&rmesa->hw.vir[1].cmd[R300_VIR_CNTL_0], swizzle,
|
||||
nr);
|
||||
}
|
||||
|
||||
/* Setup INPUT_CNTL. */
|
||||
R300_STATECHANGE(rmesa, vic);
|
||||
rmesa->hw.vic.cmd[R300_VIC_CNTL_0] = r300VAPInputCntl0(ctx, InputsRead);
|
||||
|
|
@ -337,6 +337,8 @@ int r300EmitArrays(GLcontext * ctx)
|
|||
|
||||
rmesa->state.aos_count = nr;
|
||||
|
||||
radeon_bo_unmap(rmesa->radeon.dma.current);
|
||||
|
||||
return R300_FALLBACK_NONE;
|
||||
}
|
||||
|
||||
|
|
@ -347,13 +349,15 @@ void r300ReleaseArrays(GLcontext * ctx)
|
|||
|
||||
if (rmesa->state.elt_dma_bo) {
|
||||
radeon_bo_unref(rmesa->state.elt_dma_bo);
|
||||
rmesa->state.elt_dma_bo = 0;
|
||||
rmesa->state.elt_dma_bo = NULL;
|
||||
}
|
||||
for (i = 0; i < rmesa->state.aos_count; i++) {
|
||||
if (rmesa->state.aos[i].bo) {
|
||||
rmesa->state.aos[i].bo = radeon_bo_unref(rmesa->state.aos[i].bo);
|
||||
radeon_bo_unref(rmesa->state.aos[i].bo);
|
||||
rmesa->state.aos[i].bo = NULL;
|
||||
}
|
||||
}
|
||||
radeonReleaseDmaRegion(&rmesa->radeon);
|
||||
}
|
||||
|
||||
void r300EmitCacheFlush(r300ContextPtr rmesa)
|
||||
|
|
|
|||
|
|
@ -393,7 +393,7 @@ static void r300EmitClearState(GLcontext * ctx)
|
|||
R300_STATECHANGE(r300, fp);
|
||||
R300_STATECHANGE(r300, r500fp);
|
||||
|
||||
BEGIN_BATCH(14);
|
||||
BEGIN_BATCH(7);
|
||||
OUT_BATCH_REGSEQ(R500_US_CONFIG, 2);
|
||||
OUT_BATCH(R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO);
|
||||
OUT_BATCH(0x0);
|
||||
|
|
@ -619,10 +619,10 @@ void r300Flush(GLcontext * ctx)
|
|||
if (RADEON_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
if (rmesa->swtcl.flush) {
|
||||
rmesa->swtcl.flush(rmesa);
|
||||
}
|
||||
|
||||
if (rmesa->radeon.dma.flush) {
|
||||
rmesa->radeon.dma.flush(ctx);
|
||||
}
|
||||
|
||||
if (rmesa->radeon.cmdbuf.cs->cdw) {
|
||||
rcommonFlushCmdBuf(&rmesa->radeon, __FUNCTION__);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,10 +177,8 @@ static void r300EmitElts(GLcontext * ctx, void *elts, unsigned long n_elts)
|
|||
r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
||||
void *out;
|
||||
|
||||
rmesa->state.elt_dma_bo = radeon_bo_open(rmesa->radeon.radeonScreen->bom,
|
||||
0, n_elts * 4, 4,
|
||||
RADEON_GEM_DOMAIN_GTT, 0);
|
||||
rmesa->state.elt_dma_offset = 0;
|
||||
radeonAllocDmaRegion(&rmesa->radeon, &rmesa->state.elt_dma_bo,
|
||||
&rmesa->state.elt_dma_offset, n_elts * 4, 4);
|
||||
radeon_bo_map(rmesa->state.elt_dma_bo, 1);
|
||||
out = rmesa->state.elt_dma_bo->ptr + rmesa->state.elt_dma_offset;
|
||||
memcpy(out, elts, n_elts * 4);
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#include "r300_ioctl.h"
|
||||
#include "r300_emit.h"
|
||||
|
||||
static void flush_last_swtcl_prim( r300ContextPtr rmesa );
|
||||
static void flush_last_swtcl_prim( GLcontext *ctx);
|
||||
|
||||
|
||||
void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, struct radeon_bo *bo, GLuint offset);
|
||||
|
|
@ -241,26 +241,45 @@ static void r300SetVertexFormat( GLcontext *ctx )
|
|||
|
||||
/* Flush vertices in the current dma region.
|
||||
*/
|
||||
static void flush_last_swtcl_prim( r300ContextPtr rmesa )
|
||||
static void flush_last_swtcl_prim( GLcontext *ctx )
|
||||
{
|
||||
r300ContextPtr rmesa = R300_CONTEXT(ctx);
|
||||
struct radeon_dma *dma = &rmesa->radeon.dma;
|
||||
|
||||
|
||||
if (RADEON_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
rmesa->swtcl.flush = NULL;
|
||||
radeon_bo_unmap(rmesa->swtcl.bo);
|
||||
rcommonEnsureCmdBufSpace(rmesa,
|
||||
rmesa->hw.max_state_size + (12*sizeof(int)),
|
||||
__FUNCTION__);
|
||||
r300EmitState(rmesa);
|
||||
r300EmitVertexAOS(rmesa,
|
||||
rmesa->swtcl.vertex_size,
|
||||
rmesa->swtcl.bo,
|
||||
0);
|
||||
r300EmitVbufPrim(rmesa,
|
||||
rmesa->swtcl.hw_primitive,
|
||||
rmesa->swtcl.numverts);
|
||||
r300EmitCacheFlush(rmesa);
|
||||
COMMIT_BATCH();
|
||||
rmesa->swtcl.numverts = 0;
|
||||
dma->flush = NULL;
|
||||
|
||||
if (dma->current) {
|
||||
GLuint current_offset = dma->current_used;
|
||||
|
||||
assert (dma->current_used +
|
||||
rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
|
||||
dma->current_vertexptr);
|
||||
|
||||
radeon_bo_unmap(dma->current);
|
||||
if (dma->current_used != dma->current_vertexptr) {
|
||||
dma->current_used = dma->current_vertexptr;
|
||||
|
||||
rcommonEnsureCmdBufSpace(rmesa,
|
||||
rmesa->hw.max_state_size + (12*sizeof(int)),
|
||||
__FUNCTION__);
|
||||
r300EmitState(rmesa);
|
||||
r300EmitVertexAOS(rmesa,
|
||||
rmesa->swtcl.vertex_size,
|
||||
dma->current,
|
||||
current_offset);
|
||||
|
||||
r300EmitVbufPrim(rmesa,
|
||||
rmesa->swtcl.hw_primitive,
|
||||
rmesa->swtcl.numverts);
|
||||
r300EmitCacheFlush(rmesa);
|
||||
COMMIT_BATCH();
|
||||
}
|
||||
radeonReleaseDmaRegion(&rmesa->radeon);
|
||||
rmesa->swtcl.numverts = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Alloc space in the current dma region.
|
||||
|
|
@ -269,15 +288,29 @@ static void *
|
|||
r300AllocDmaLowVerts( r300ContextPtr rmesa, int nverts, int vsize )
|
||||
{
|
||||
GLuint bytes = vsize * nverts;
|
||||
void *head;
|
||||
|
||||
rmesa->swtcl.bo = radeon_bo_open(rmesa->radeon.radeonScreen->bom,
|
||||
0, bytes, 4, RADEON_GEM_DOMAIN_GTT, 0);
|
||||
radeon_bo_map(rmesa->swtcl.bo, 1);
|
||||
if (rmesa->swtcl.flush == NULL) {
|
||||
rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
|
||||
rmesa->swtcl.flush = flush_last_swtcl_prim;
|
||||
if (!rmesa->radeon.dma.current || rmesa->radeon.dma.current_vertexptr + bytes > rmesa->radeon.dma.current->size) {
|
||||
radeonRefillCurrentDmaRegion( &rmesa->radeon, bytes);
|
||||
}
|
||||
return rmesa->swtcl.bo->ptr;
|
||||
|
||||
if (!rmesa->radeon.dma.flush) {
|
||||
rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
|
||||
rmesa->radeon.dma.flush = flush_last_swtcl_prim;
|
||||
}
|
||||
|
||||
ASSERT( vsize == rmesa->swtcl.vertex_size * 4 );
|
||||
ASSERT( rmesa->radeon.dma.flush == flush_last_swtcl_prim );
|
||||
ASSERT( rmesa->radeon.dma.current_used +
|
||||
rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
|
||||
rmesa->dma.current_vertexptr );
|
||||
|
||||
// fprintf(stderr,"current %p %x\n", rmesa->radeon.dma.current->ptr,
|
||||
// rmesa->radeon.dma.current_vertexptr);
|
||||
head = (rmesa->radeon.dma.current->ptr + rmesa->radeon.dma.current_vertexptr);
|
||||
rmesa->radeon.dma.current_vertexptr += bytes;
|
||||
rmesa->swtcl.numverts += nverts;
|
||||
return head;
|
||||
}
|
||||
|
||||
static GLuint reduced_prim[] = {
|
||||
|
|
@ -550,9 +583,9 @@ static void r300RenderStart(GLcontext *ctx)
|
|||
r300UpdateShaderStates(rmesa);
|
||||
|
||||
r300EmitCacheFlush(rmesa);
|
||||
if (rmesa->swtcl.flush != NULL) {
|
||||
rmesa->swtcl.flush(rmesa);
|
||||
}
|
||||
if (rmesa->radeon.dma.flush != NULL) {
|
||||
rmesa->radeon.dma.flush(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static void r300RenderFinish(GLcontext *ctx)
|
||||
|
|
|
|||
|
|
@ -225,16 +225,26 @@ struct radeon_aos {
|
|||
};
|
||||
|
||||
struct radeon_dma {
|
||||
/* Active dma region. Allocations for vertices and retained
|
||||
* regions come from here. Also used for emitting random vertices,
|
||||
* these may be flushed by calling flush_current();
|
||||
*/
|
||||
struct radeon_dma_region current;
|
||||
|
||||
void (*flush)( GLcontext *ctx );
|
||||
/* Active dma region. Allocations for vertices and retained
|
||||
* regions come from here. Also used for emitting random vertices,
|
||||
* these may be flushed by calling flush_current();
|
||||
*/
|
||||
struct radeon_bo *current; /** Buffer that DMA memory is allocated from */
|
||||
int current_used; /** Number of bytes allocated and forgotten about */
|
||||
int current_vertexptr; /** End of active vertex region */
|
||||
|
||||
char *buf0_address; /* start of buf[0], for index calcs */
|
||||
GLuint nr_released_bufs; /* flush after so many buffers released */
|
||||
/**
|
||||
* If current_vertexptr != current_used then flush must be non-zero.
|
||||
* flush must be called before non-active vertex allocations can be
|
||||
* performed.
|
||||
*/
|
||||
void (*flush) (GLcontext *);
|
||||
|
||||
/* Number of "in-flight" DMA buffers, i.e. the number of buffers
|
||||
* for which a DISCARD command is currently queued in the command buffer
|
||||
.
|
||||
*/
|
||||
GLuint nr_released_bufs;
|
||||
};
|
||||
|
||||
struct radeon_ioctl {
|
||||
|
|
@ -266,6 +276,8 @@ static INLINE GLuint radeonPackColor(GLuint cpp,
|
|||
|
||||
#define MAX_CMD_BUF_SZ (16*1024)
|
||||
|
||||
#define MAX_DMA_BUF_SZ (64*1024)
|
||||
|
||||
struct radeon_store {
|
||||
GLuint statenr;
|
||||
GLuint primnr;
|
||||
|
|
@ -354,6 +366,7 @@ struct radeon_context {
|
|||
int texture_depth;
|
||||
float initialMaxAnisotropy;
|
||||
|
||||
struct radeon_dma dma;
|
||||
/* Rasterization and vertex state:
|
||||
*/
|
||||
GLuint TclFallback;
|
||||
|
|
|
|||
|
|
@ -1316,22 +1316,19 @@ void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos,
|
|||
uint32_t *out;
|
||||
uint32_t bo_size;
|
||||
|
||||
memset(aos, 0, sizeof(struct radeon_aos));
|
||||
if (stride == 0) {
|
||||
bo_size = size * 4;
|
||||
radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * 4, 32);
|
||||
count = 1;
|
||||
aos->stride = 0;
|
||||
} else {
|
||||
bo_size = size * count * 4;
|
||||
radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * count * 4, 32);
|
||||
aos->stride = size;
|
||||
}
|
||||
aos->bo = radeon_bo_open(rmesa->radeonScreen->bom,
|
||||
0, bo_size, 32, RADEON_GEM_DOMAIN_GTT, 0);
|
||||
aos->offset = 0;
|
||||
|
||||
aos->components = size;
|
||||
aos->count = count;
|
||||
|
||||
radeon_bo_map(aos->bo, 1);
|
||||
// radeon_bo_map(aos->bo, 1);
|
||||
out = (uint32_t*)((char*)aos->bo->ptr + aos->offset);
|
||||
switch (size) {
|
||||
case 1: radeonEmitVec4(out, data, stride, count); break;
|
||||
|
|
@ -1342,7 +1339,7 @@ void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos,
|
|||
assert(0);
|
||||
break;
|
||||
}
|
||||
radeon_bo_unmap(aos->bo);
|
||||
// radeon_bo_unmap(aos->bo);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2321,3 +2318,75 @@ void radeonSpanRenderFinish(GLcontext * ctx)
|
|||
unmap_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped);
|
||||
}
|
||||
|
||||
void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size)
|
||||
{
|
||||
size = MAX2(size, MAX_DMA_BUF_SZ * 16);
|
||||
|
||||
if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
if (rmesa->dma.flush) {
|
||||
radeon_bo_unmap(rmesa->dma.current);
|
||||
rmesa->dma.flush(rmesa->glCtx);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (rmesa->dma.nr_released_bufs > 4) {
|
||||
rcommonFlushCmdBuf(rmesa, __FUNCTION__);
|
||||
rmesa->dma.nr_released_bufs = 0;
|
||||
}
|
||||
|
||||
if (rmesa->dma.current) {
|
||||
radeon_bo_unref(rmesa->dma.current);
|
||||
rmesa->dma.current = 0;
|
||||
}
|
||||
|
||||
rmesa->dma.current = radeon_bo_open(rmesa->radeonScreen->bom,
|
||||
0, size, 4, RADEON_GEM_DOMAIN_GTT,
|
||||
0);
|
||||
|
||||
rmesa->dma.current_used = 0;
|
||||
rmesa->dma.current_vertexptr = 0;
|
||||
radeon_bo_map(rmesa->dma.current, 1);
|
||||
}
|
||||
|
||||
/* Allocates a region from rmesa->dma.current. If there isn't enough
|
||||
* space in current, grab a new buffer (and discard what was left of current)
|
||||
*/
|
||||
void radeonAllocDmaRegion(radeonContextPtr rmesa,
|
||||
struct radeon_bo **pbo, int *poffset,
|
||||
int bytes, int alignment)
|
||||
{
|
||||
if (RADEON_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
|
||||
|
||||
if (rmesa->dma.flush)
|
||||
rmesa->dma.flush(rmesa->glCtx);
|
||||
|
||||
assert(rmesa->dma.current_used == rmesa->dma.current_vertexptr);
|
||||
|
||||
alignment--;
|
||||
rmesa->dma.current_used = (rmesa->dma.current_used + alignment) & ~alignment;
|
||||
|
||||
if (!rmesa->dma.current || rmesa->dma.current_used + bytes > rmesa->dma.current->size)
|
||||
radeonRefillCurrentDmaRegion(rmesa, (bytes + 15) & ~15);
|
||||
|
||||
*poffset = rmesa->dma.current_used;
|
||||
*pbo = rmesa->dma.current;
|
||||
radeon_bo_ref(*pbo);
|
||||
|
||||
/* Always align to at least 16 bytes */
|
||||
rmesa->dma.current_used = (rmesa->dma.current_used + bytes + 15) & ~15;
|
||||
rmesa->dma.current_vertexptr = rmesa->dma.current_used;
|
||||
|
||||
assert(rmesa->dma.current_used <= rmesa->dma.current->size);
|
||||
}
|
||||
|
||||
void radeonReleaseDmaRegion(radeonContextPtr rmesa)
|
||||
{
|
||||
rmesa->dma.nr_released_bufs++;
|
||||
radeon_bo_unref(rmesa->dma.current);
|
||||
rmesa->dma.current = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -118,4 +118,8 @@ GLubyte *radeon_ptr16(const struct radeon_renderbuffer * rrb,
|
|||
GLint x, GLint y);
|
||||
GLubyte *radeon_ptr32(const struct radeon_renderbuffer * rrb,
|
||||
GLint x, GLint y);
|
||||
void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size);
|
||||
void radeonAllocDmaRegion(radeonContextPtr rmesa,
|
||||
struct radeon_bo **pbo, int *poffset,
|
||||
int bytes, int alignment);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ struct bo_manager_legacy {
|
|||
uint32_t fb_location;
|
||||
uint32_t texture_offset;
|
||||
unsigned dma_alloc_size;
|
||||
uint32_t dma_buf_count;
|
||||
unsigned cpendings;
|
||||
driTextureObject texture_swapped;
|
||||
driTexHeap *texture_heap;
|
||||
|
|
@ -221,7 +222,7 @@ static int legacy_wait_pending(struct radeon_bo *bo)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void legacy_track_pending(struct bo_manager_legacy *boml)
|
||||
static void legacy_track_pending(struct bo_manager_legacy *boml, int debug)
|
||||
{
|
||||
struct bo_legacy *bo_legacy;
|
||||
struct bo_legacy *next;
|
||||
|
|
@ -229,6 +230,9 @@ static void legacy_track_pending(struct bo_manager_legacy *boml)
|
|||
legacy_get_current_age(boml);
|
||||
bo_legacy = boml->pending_bos.pnext;
|
||||
while (bo_legacy) {
|
||||
if (debug)
|
||||
fprintf(stderr,"pending %p %d %d %d\n", bo_legacy, bo_legacy->base.size,
|
||||
boml->current_age, bo_legacy->pending);
|
||||
next = bo_legacy->pnext;
|
||||
if (legacy_is_pending(&(bo_legacy->base))) {
|
||||
}
|
||||
|
|
@ -236,6 +240,19 @@ static void legacy_track_pending(struct bo_manager_legacy *boml)
|
|||
}
|
||||
}
|
||||
|
||||
static int legacy_wait_any_pending(struct bo_manager_legacy *boml)
|
||||
{
|
||||
struct bo_legacy *bo_legacy;
|
||||
struct bo_legacy *next;
|
||||
|
||||
legacy_get_current_age(boml);
|
||||
bo_legacy = boml->pending_bos.pnext;
|
||||
if (!bo_legacy)
|
||||
return -1;
|
||||
legacy_wait_pending(&bo_legacy->base);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct bo_legacy *bo_allocate(struct bo_manager_legacy *boml,
|
||||
uint32_t size,
|
||||
uint32_t alignment,
|
||||
|
|
@ -292,13 +309,13 @@ static int bo_dma_alloc(struct radeon_bo *bo)
|
|||
if (r) {
|
||||
/* ptr is set to NULL if dma allocation failed */
|
||||
bo_legacy->ptr = NULL;
|
||||
exit(0);
|
||||
return r;
|
||||
}
|
||||
bo_legacy->ptr = boml->screen->gartTextures.map + base_offset;
|
||||
bo_legacy->offset = boml->screen->gart_texture_offset + base_offset;
|
||||
bo->size = size;
|
||||
boml->dma_alloc_size += size;
|
||||
boml->dma_buf_count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -328,6 +345,7 @@ static int bo_dma_free(struct radeon_bo *bo)
|
|||
return r;
|
||||
}
|
||||
boml->dma_alloc_size -= bo_legacy->base.size;
|
||||
boml->dma_buf_count--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -388,15 +406,20 @@ static struct radeon_bo *bo_open(struct radeon_bo_manager *bom,
|
|||
return NULL;
|
||||
}
|
||||
if (bo_legacy->base.domains & RADEON_GEM_DOMAIN_GTT) {
|
||||
legacy_track_pending(boml);
|
||||
retry:
|
||||
legacy_track_pending(boml, 0);
|
||||
/* dma buffers */
|
||||
|
||||
r = bo_dma_alloc(&(bo_legacy->base));
|
||||
if (r) {
|
||||
fprintf(stderr, "Ran out of GART memory (for %d)!\n", size);
|
||||
if (legacy_wait_any_pending(boml) == -1) {
|
||||
fprintf(stderr, "Ran out of GART memory (for %d)!\n", size);
|
||||
fprintf(stderr, "Please consider adjusting GARTSize option.\n");
|
||||
bo_free(bo_legacy);
|
||||
exit(-1);
|
||||
return NULL;
|
||||
}
|
||||
goto retry;
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
bo_legacy->ptr = malloc(bo_legacy->base.size);
|
||||
|
|
@ -460,7 +483,6 @@ static int bo_map(struct radeon_bo *bo, int write)
|
|||
volatile int *buf = (int*)boml->screen->driScreen->pFB;
|
||||
p = *buf;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -318,7 +318,7 @@ radeonCreateContext( const __GLcontextModes *glVisual,
|
|||
screen->sarea_priv_offset);
|
||||
|
||||
|
||||
rmesa->dma.buf0_address = rmesa->radeon.radeonScreen->buffers->list[0].address;
|
||||
//rmesa->dma.buf0_address = rmesa->radeon.radeonScreen->buffers->list[0].address;
|
||||
|
||||
(void) memset( rmesa->radeon.texture_heaps, 0, sizeof( rmesa->radeon.texture_heaps ) );
|
||||
make_empty_list( & rmesa->radeon.swapped );
|
||||
|
|
@ -522,8 +522,8 @@ void radeonDestroyContext( __DRIcontextPrivate *driContextPriv )
|
|||
|
||||
radeonDestroySwtcl( rmesa->radeon.glCtx );
|
||||
radeonReleaseArrays( rmesa->radeon.glCtx, ~0 );
|
||||
if (rmesa->dma.current.buf) {
|
||||
radeonReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ );
|
||||
if (rmesa->radeon.dma.current) {
|
||||
radeonReleaseDmaRegion( rmesa, &rmesa->radeon.dma.current, __FUNCTION__ );
|
||||
radeonFlushCmdBuf( rmesa, __FUNCTION__ );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -425,7 +425,6 @@ struct r100_context {
|
|||
/* Vertex buffers
|
||||
*/
|
||||
struct radeon_ioctl ioctl;
|
||||
struct radeon_dma dma;
|
||||
struct radeon_store store;
|
||||
/* A full state emit as of the first state emit in the main store, in case
|
||||
* the context is lost.
|
||||
|
|
|
|||
|
|
@ -117,12 +117,12 @@ static void radeonBackUpAndEmitLostStateLocked( r100ContextPtr rmesa )
|
|||
|
||||
rmesa->radeon.lost_context = GL_FALSE;
|
||||
|
||||
nr_released_bufs = rmesa->dma.nr_released_bufs;
|
||||
nr_released_bufs = rmesa->radeon.dma.nr_released_bufs;
|
||||
saved_store = rmesa->store;
|
||||
rmesa->dma.nr_released_bufs = 0;
|
||||
rmesa->radeon.dma.nr_released_bufs = 0;
|
||||
rmesa->store = rmesa->backup_store;
|
||||
radeonFlushCmdBufLocked( rmesa, __FUNCTION__ );
|
||||
rmesa->dma.nr_released_bufs = nr_released_bufs;
|
||||
rmesa->radeon.dma.nr_released_bufs = nr_released_bufs;
|
||||
rmesa->store = saved_store;
|
||||
}
|
||||
|
||||
|
|
@ -308,8 +308,8 @@ void radeonFlushElts( GLcontext *ctx )
|
|||
if (RADEON_DEBUG & DEBUG_IOCTL)
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
assert( rmesa->dma.flush == radeonFlushElts );
|
||||
rmesa->dma.flush = NULL;
|
||||
assert( rmesa->radeon.dma.flush == radeonFlushElts );
|
||||
rmesa->radeon.dma.flush = NULL;
|
||||
|
||||
/* Cope with odd number of elts:
|
||||
*/
|
||||
|
|
@ -381,9 +381,9 @@ GLushort *radeonAllocEltsOpenEnded( r100ContextPtr rmesa,
|
|||
__FUNCTION__,
|
||||
cmd[1].i, vertex_format, primitive);
|
||||
|
||||
assert(!rmesa->dma.flush);
|
||||
assert(!rmesa->radeon.dma.flush);
|
||||
rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
|
||||
rmesa->dma.flush = radeonFlushElts;
|
||||
rmesa->radeon.dma.flush = radeonFlushElts;
|
||||
|
||||
rmesa->store.elts_start = ((char *)cmd) - rmesa->store.cmd_buf;
|
||||
|
||||
|
|
|
|||
|
|
@ -76,16 +76,6 @@ extern void radeonEmitBlit( r100ContextPtr rmesa,
|
|||
extern void radeonEmitWait( r100ContextPtr rmesa, GLuint flags );
|
||||
|
||||
extern void radeonFlushCmdBuf( r100ContextPtr rmesa, const char * );
|
||||
extern void radeonRefillCurrentDmaRegion( r100ContextPtr rmesa );
|
||||
|
||||
extern void radeonAllocDmaRegion( r100ContextPtr rmesa,
|
||||
struct radeon_dma_region *region,
|
||||
int bytes,
|
||||
int alignment );
|
||||
|
||||
extern void radeonReleaseDmaRegion( r100ContextPtr rmesa,
|
||||
struct radeon_dma_region *region,
|
||||
const char *caller );
|
||||
|
||||
extern void radeonFlush( GLcontext *ctx );
|
||||
extern void radeonFinish( GLcontext *ctx );
|
||||
|
|
@ -101,8 +91,8 @@ extern void radeonSetUpAtomList( r100ContextPtr rmesa );
|
|||
*/
|
||||
#define RADEON_NEWPRIM( rmesa ) \
|
||||
do { \
|
||||
if ( rmesa->dma.flush ) \
|
||||
rmesa->dma.flush( rmesa->radeon.glCtx ); \
|
||||
if ( rmesa->radeon.dma.flush ) \
|
||||
rmesa->radeon.dma.flush( rmesa->radeon.glCtx ); \
|
||||
} while (0)
|
||||
|
||||
/* Can accomodate several state changes and primitive changes without
|
||||
|
|
@ -142,7 +132,7 @@ static INLINE int RADEON_DB_STATECHANGE(
|
|||
*/
|
||||
#define RADEON_FIREVERTICES( rmesa ) \
|
||||
do { \
|
||||
if ( rmesa->store.cmd_used || rmesa->dma.flush ) { \
|
||||
if ( rmesa->store.cmd_used || rmesa->radeon.dma.flush ) { \
|
||||
radeonFlush( rmesa->radeon.glCtx ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue