Compare commits
	
		
			2 Commits
		
	
	
		
			noisy_cube
			...
			red_tinted
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					2fc9351ee7 | ||
| 
						 | 
					63fd67e561 | 
@@ -33,6 +33,9 @@ DRIVER_SOURCES = \
 | 
			
		||||
		 r300_state.c \
 | 
			
		||||
		 r300_render.c \
 | 
			
		||||
		 r300_lib.c \
 | 
			
		||||
		 r300_texmem.c \
 | 
			
		||||
		 r300_tex.c \
 | 
			
		||||
		 r300_texstate.c \
 | 
			
		||||
		 \
 | 
			
		||||
		 r200_context.c \
 | 
			
		||||
		 r200_ioctl.c \
 | 
			
		||||
@@ -52,6 +55,7 @@ DRIVER_SOURCES = \
 | 
			
		||||
		 r200_vtxfmt_sse.c \
 | 
			
		||||
		 r200_vtxfmt_x86.c
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES)
 | 
			
		||||
 | 
			
		||||
X86_SOURCES = r200_vtxtmp_x86.S
 | 
			
		||||
 
 | 
			
		||||
@@ -46,6 +46,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#include "radeon_ioctl.h"
 | 
			
		||||
#include "r300_context.h"
 | 
			
		||||
#include "r300_ioctl.h"
 | 
			
		||||
#include "radeon_reg.h"
 | 
			
		||||
#include "r300_reg.h"
 | 
			
		||||
#include "r300_cmdbuf.h"
 | 
			
		||||
 | 
			
		||||
@@ -273,10 +274,13 @@ CHECK( vpu, vpucount(atom->cmd) ? (1 + vpucount(atom->cmd)*4) : 0 )
 | 
			
		||||
 */
 | 
			
		||||
void r300InitCmdBuf(r300ContextPtr r300)
 | 
			
		||||
{
 | 
			
		||||
	int size;
 | 
			
		||||
	int size, i, mtu;
 | 
			
		||||
 | 
			
		||||
	r300->hw.max_state_size = 0;
 | 
			
		||||
	
 | 
			
		||||
	mtu = r300->radeon.glCtx->Const.MaxTextureUnits;
 | 
			
		||||
	fprintf(stderr, "Using %d maximum texture units..\n", mtu);
 | 
			
		||||
 | 
			
		||||
	/* Initialize state atoms */
 | 
			
		||||
	ALLOC_STATE( vpt, always, R300_VPT_CMDSIZE, "vpt", 0 );
 | 
			
		||||
		r300->hw.vpt.cmd[R300_VPT_CMD_0] = cmducs(R300_SE_VPORT_XSCALE, 6);
 | 
			
		||||
@@ -408,6 +412,29 @@ void r300InitCmdBuf(r300ContextPtr r300)
 | 
			
		||||
	ALLOC_STATE( vps, vpu, R300_VPS_CMDSIZE, "vps", 0 );
 | 
			
		||||
		r300->hw.vps.cmd[R300_VPS_CMD_0] = cmdvpu(R300_PVS_UPLOAD_POINTSIZE, 1);
 | 
			
		||||
 | 
			
		||||
	/* Textures */
 | 
			
		||||
	ALLOC_STATE( tex.filter, always, mtu, "tex_filter", 0 );
 | 
			
		||||
		r300->hw.tex.filter.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_FILTER_0, mtu-1);
 | 
			
		||||
		
 | 
			
		||||
	ALLOC_STATE( tex.unknown1, always, mtu, "tex_unknown1", 0 );
 | 
			
		||||
		r300->hw.tex.unknown1.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_UNK1_0, mtu-1);
 | 
			
		||||
		
 | 
			
		||||
	ALLOC_STATE( tex.size, always, mtu, "tex_size", 0 );
 | 
			
		||||
		r300->hw.tex.size.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_SIZE_0, mtu-1);
 | 
			
		||||
		
 | 
			
		||||
	ALLOC_STATE( tex.format, always, mtu, "tex_format", 0 );
 | 
			
		||||
		r300->hw.tex.format.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_FORMAT_0, mtu-1);
 | 
			
		||||
		
 | 
			
		||||
	ALLOC_STATE( tex.offset, always, mtu, "tex_offset", 0 );
 | 
			
		||||
		r300->hw.tex.offset.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_OFFSET_0, mtu-1);
 | 
			
		||||
		
 | 
			
		||||
	ALLOC_STATE( tex.unknown4, always, mtu, "tex_unknown4", 0 );
 | 
			
		||||
		r300->hw.tex.unknown4.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_UNK4_0, mtu-1);
 | 
			
		||||
		
 | 
			
		||||
	ALLOC_STATE( tex.unknown5, always, mtu, "tex_unknown5", 0 );
 | 
			
		||||
		r300->hw.tex.unknown5.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_UNK5_0, mtu-1);
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	/* Setup the atom linked list */
 | 
			
		||||
	make_empty_list(&r300->hw.atomlist);
 | 
			
		||||
	r300->hw.atomlist.name = "atom-list";
 | 
			
		||||
@@ -477,6 +504,14 @@ void r300InitCmdBuf(r300ContextPtr r300)
 | 
			
		||||
	insert_at_tail(&r300->hw.atomlist, &r300->hw.vpp);
 | 
			
		||||
	insert_at_tail(&r300->hw.atomlist, &r300->hw.vps);
 | 
			
		||||
 | 
			
		||||
	insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.filter);	
 | 
			
		||||
	insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.unknown1);
 | 
			
		||||
	insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.size);
 | 
			
		||||
	insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.format);
 | 
			
		||||
	insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.offset);
 | 
			
		||||
	insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.unknown4);
 | 
			
		||||
	insert_at_tail(&r300->hw.atomlist, &r300->hw.tex.unknown5);
 | 
			
		||||
 | 
			
		||||
	r300->hw.is_dirty = GL_TRUE;
 | 
			
		||||
	r300->hw.all_dirty = GL_TRUE;
 | 
			
		||||
 | 
			
		||||
@@ -511,3 +546,65 @@ void r300DestroyCmdBuf(r300ContextPtr r300)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void r300EmitBlit(r300ContextPtr rmesa,
 | 
			
		||||
		  GLuint color_fmt,
 | 
			
		||||
		  GLuint src_pitch,
 | 
			
		||||
		  GLuint src_offset,
 | 
			
		||||
		  GLuint dst_pitch,
 | 
			
		||||
		  GLuint dst_offset,
 | 
			
		||||
		  GLint srcx, GLint srcy,
 | 
			
		||||
		  GLint dstx, GLint dsty, GLuint w, GLuint h)
 | 
			
		||||
{
 | 
			
		||||
	drm_radeon_cmd_header_t *cmd;
 | 
			
		||||
 | 
			
		||||
	if (RADEON_DEBUG & DEBUG_IOCTL)
 | 
			
		||||
		fprintf(stderr,
 | 
			
		||||
			"%s src %x/%x %d,%d dst: %x/%x %d,%d sz: %dx%d\n",
 | 
			
		||||
			__FUNCTION__, src_pitch, src_offset, srcx, srcy,
 | 
			
		||||
			dst_pitch, dst_offset, dstx, dsty, w, h);
 | 
			
		||||
 | 
			
		||||
	assert((src_pitch & 63) == 0);
 | 
			
		||||
	assert((dst_pitch & 63) == 0);
 | 
			
		||||
	assert((src_offset & 1023) == 0);
 | 
			
		||||
	assert((dst_offset & 1023) == 0);
 | 
			
		||||
	assert(w < (1 << 16));
 | 
			
		||||
	assert(h < (1 << 16));
 | 
			
		||||
 | 
			
		||||
	cmd =
 | 
			
		||||
	    (drm_radeon_cmd_header_t *) r200AllocCmdBuf(rmesa, 8 * sizeof(int),
 | 
			
		||||
							__FUNCTION__);
 | 
			
		||||
 | 
			
		||||
	cmd[0].header.cmd_type = RADEON_CMD_PACKET3;
 | 
			
		||||
	cmd[1].i = R200_CP_CMD_BITBLT_MULTI | (5 << 16);
 | 
			
		||||
	cmd[2].i = (RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
 | 
			
		||||
		    RADEON_GMC_DST_PITCH_OFFSET_CNTL |
 | 
			
		||||
		    RADEON_GMC_BRUSH_NONE |
 | 
			
		||||
		    (color_fmt << 8) |
 | 
			
		||||
		    RADEON_GMC_SRC_DATATYPE_COLOR |
 | 
			
		||||
		    RADEON_ROP3_S |
 | 
			
		||||
		    RADEON_DP_SRC_SOURCE_MEMORY |
 | 
			
		||||
		    RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS);
 | 
			
		||||
 | 
			
		||||
	cmd[3].i = ((src_pitch / 64) << 22) | (src_offset >> 10);
 | 
			
		||||
	cmd[4].i = ((dst_pitch / 64) << 22) | (dst_offset >> 10);
 | 
			
		||||
	cmd[5].i = (srcx << 16) | srcy;
 | 
			
		||||
	cmd[6].i = (dstx << 16) | dsty;	/* dst */
 | 
			
		||||
	cmd[7].i = (w << 16) | h;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void r300EmitWait(r300ContextPtr rmesa, GLuint flags)
 | 
			
		||||
{
 | 
			
		||||
	if (rmesa->radeon.dri.drmMinor >= 6) {
 | 
			
		||||
		drm_radeon_cmd_header_t *cmd;
 | 
			
		||||
 | 
			
		||||
		assert(!(flags & ~(RADEON_WAIT_2D | RADEON_WAIT_3D)));
 | 
			
		||||
 | 
			
		||||
		cmd =
 | 
			
		||||
		    (drm_radeon_cmd_header_t *) r200AllocCmdBuf(rmesa,
 | 
			
		||||
								1 * sizeof(int),
 | 
			
		||||
								__FUNCTION__);
 | 
			
		||||
		cmd[0].i = 0;
 | 
			
		||||
		cmd[0].wait.cmd_type = RADEON_CMD_WAIT;
 | 
			
		||||
		cmd[0].wait.flags = flags;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -57,6 +57,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#include "r300_cmdbuf.h"
 | 
			
		||||
#include "r300_state.h"
 | 
			
		||||
#include "r300_ioctl.h"
 | 
			
		||||
#include "r300_tex.h"
 | 
			
		||||
 | 
			
		||||
#include "vblank.h"
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
@@ -147,7 +148,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
 | 
			
		||||
	struct dd_function_table functions;
 | 
			
		||||
	r300ContextPtr r300;
 | 
			
		||||
	GLcontext *ctx;
 | 
			
		||||
	int tcl_mode;
 | 
			
		||||
	int tcl_mode, i;
 | 
			
		||||
 | 
			
		||||
	assert(glVisual);
 | 
			
		||||
	assert(driContextPriv);
 | 
			
		||||
@@ -171,7 +172,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
 | 
			
		||||
	_mesa_init_driver_functions(&functions);
 | 
			
		||||
	r300InitIoctlFuncs(&functions);
 | 
			
		||||
	r300InitStateFuncs(&functions);
 | 
			
		||||
	//r200InitTextureFuncs(&functions);
 | 
			
		||||
	r300InitTextureFuncs(&functions);
 | 
			
		||||
 | 
			
		||||
	if (!radeonInitContext(&r300->radeon, &functions,
 | 
			
		||||
			       glVisual, driContextPriv, sharedContextPrivate)) {
 | 
			
		||||
@@ -180,6 +181,35 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Init r300 context data */
 | 
			
		||||
	r300->dma.buf0_address = r300->radeon.radeonScreen->buffers->list[0].address;
 | 
			
		||||
 | 
			
		||||
	(void)memset(r300->texture_heaps, 0, sizeof(r300->texture_heaps));
 | 
			
		||||
	make_empty_list(&r300->swapped);
 | 
			
		||||
 | 
			
		||||
	r300->nr_heaps = 1 /* screen->numTexHeaps */ ;
 | 
			
		||||
	assert(r300->nr_heaps < R200_NR_TEX_HEAPS);
 | 
			
		||||
	for (i = 0; i < r300->nr_heaps; i++) {
 | 
			
		||||
		r300->texture_heaps[i] = driCreateTextureHeap(i, r300,
 | 
			
		||||
							       screen->
 | 
			
		||||
							       texSize[i], 12,
 | 
			
		||||
							       RADEON_NR_TEX_REGIONS,
 | 
			
		||||
							       (drmTextureRegionPtr)
 | 
			
		||||
							       r300->radeon.sarea->
 | 
			
		||||
							       tex_list[i],
 | 
			
		||||
							       &r300->radeon.sarea->
 | 
			
		||||
							       tex_age[i],
 | 
			
		||||
							       &r300->swapped,
 | 
			
		||||
							       sizeof
 | 
			
		||||
							       (r300TexObj),
 | 
			
		||||
							       (destroy_texture_object_t
 | 
			
		||||
								*)
 | 
			
		||||
							       r300DestroyTexObj);
 | 
			
		||||
	}
 | 
			
		||||
	r300->texture_depth = driQueryOptioni(&r300->radeon.optionCache,
 | 
			
		||||
					       "texture_depth");
 | 
			
		||||
	if (r300->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
 | 
			
		||||
		r300->texture_depth = (screen->cpp == 4) ?
 | 
			
		||||
		    DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
 | 
			
		||||
 | 
			
		||||
	/* Set the maximum texture size small enough that we can guarentee that
 | 
			
		||||
	 * all texture units can bind a maximal texture and have them both in
 | 
			
		||||
@@ -239,8 +269,8 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
 | 
			
		||||
#if 0
 | 
			
		||||
	/* plug in a few more device driver functions */
 | 
			
		||||
	/* XXX these should really go right after _mesa_init_driver_functions() */
 | 
			
		||||
	r200InitPixelFuncs(ctx);
 | 
			
		||||
	r200InitSwtcl(ctx);
 | 
			
		||||
	r300InitPixelFuncs(ctx);
 | 
			
		||||
	r300InitSwtcl(ctx);
 | 
			
		||||
#endif
 | 
			
		||||
	TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -66,6 +66,104 @@ static __inline__ uint32_t r300PackFloat32(float fl)
 | 
			
		||||
	return u.u;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/************ DMA BUFFERS **************/
 | 
			
		||||
 | 
			
		||||
/* Need refcounting on dma buffers:
 | 
			
		||||
 */
 | 
			
		||||
struct r300_dma_buffer {
 | 
			
		||||
	int refcount;		/* the number of retained regions in buf */
 | 
			
		||||
	drmBufPtr buf;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define GET_START(rvb) (rmesa->radeon.radeonScreen->gart_buffer_offset +		\
 | 
			
		||||
			(rvb)->address - rmesa->dma.buf0_address +	\
 | 
			
		||||
			(rvb)->start)
 | 
			
		||||
 | 
			
		||||
/* A retained region, eg vertices for indexed vertices.
 | 
			
		||||
 */
 | 
			
		||||
struct r300_dma_region {
 | 
			
		||||
	struct r300_dma_buffer *buf;
 | 
			
		||||
	char *address;		/* == buf->address */
 | 
			
		||||
	int start, end, ptr;	/* offsets from start of buf */
 | 
			
		||||
	int aos_start;
 | 
			
		||||
	int aos_stride;
 | 
			
		||||
	int aos_size;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct r300_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 r300_dma_region current;
 | 
			
		||||
 | 
			
		||||
	void (*flush) (r300ContextPtr);
 | 
			
		||||
 | 
			
		||||
	char *buf0_address;	/* start of buf[0], for index calcs */
 | 
			
		||||
	GLuint nr_released_bufs;	/* flush after so many buffers released */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
       /* Texture related */
 | 
			
		||||
 | 
			
		||||
#define TEX_0   0x1
 | 
			
		||||
#define TEX_1   0x2
 | 
			
		||||
#define TEX_2	0x4
 | 
			
		||||
#define TEX_3	0x8
 | 
			
		||||
#define TEX_4	0x10
 | 
			
		||||
#define TEX_5	0x20
 | 
			
		||||
#define TEX_6	0x40
 | 
			
		||||
#define TEX_7	0x80
 | 
			
		||||
#define TEX_ALL 0xff
 | 
			
		||||
 | 
			
		||||
typedef struct r300_tex_obj r300TexObj, *r300TexObjPtr;
 | 
			
		||||
 | 
			
		||||
/* Texture object in locally shared texture space.
 | 
			
		||||
 */
 | 
			
		||||
struct r300_tex_obj {
 | 
			
		||||
	driTextureObject base;
 | 
			
		||||
 | 
			
		||||
	GLuint bufAddr;		/* Offset to start of locally
 | 
			
		||||
				   shared texture block */
 | 
			
		||||
 | 
			
		||||
	GLuint dirty_state;	/* Flags (1 per texunit) for
 | 
			
		||||
				   whether or not this texobj
 | 
			
		||||
				   has dirty hardware state
 | 
			
		||||
				   (pp_*) that needs to be
 | 
			
		||||
				   brought into the
 | 
			
		||||
				   texunit. */
 | 
			
		||||
 | 
			
		||||
	drm_radeon_tex_image_t image[6][RADEON_MAX_TEXTURE_LEVELS];
 | 
			
		||||
	/* Six, for the cube faces */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/* hardware register values */
 | 
			
		||||
	/* Note that R200 has 8 registers per texture and R300 only 7 */
 | 
			
		||||
	GLuint filter;	
 | 
			
		||||
	GLuint pitch; /* one of the unknown registers.. unknown 1 ?*/
 | 
			
		||||
	GLuint size;	/* npot only */
 | 
			
		||||
	GLuint format;
 | 
			
		||||
	GLuint offset;	/* Image location in texmem.
 | 
			
		||||
				   All cube faces follow. */
 | 
			
		||||
	GLuint unknown4;
 | 
			
		||||
	GLuint unknown5; 
 | 
			
		||||
	/* end hardware registers */
 | 
			
		||||
	
 | 
			
		||||
	GLboolean border_fallback;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct r300_texture_env_state {
 | 
			
		||||
	r300TexObjPtr texobj;
 | 
			
		||||
	GLenum format;
 | 
			
		||||
	GLenum envMode;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define R300_MAX_TEXTURE_UNITS 6
 | 
			
		||||
 | 
			
		||||
struct r300_texture_state {
 | 
			
		||||
	struct r300_texture_env_state unit[R300_MAX_TEXTURE_UNITS];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A block of hardware state.
 | 
			
		||||
 *
 | 
			
		||||
@@ -233,6 +331,13 @@ struct r300_state_atom {
 | 
			
		||||
#define R300_VPS_ZERO_3		4
 | 
			
		||||
#define R300_VPS_CMDSIZE	5
 | 
			
		||||
 | 
			
		||||
	/* the layout is common for all fields inside tex */
 | 
			
		||||
#define R300_TEX_CMD_0		0
 | 
			
		||||
#define R300_TEX_VALUE_0	1
 | 
			
		||||
/* We don't really use this, instead specify mtu+1 dynamically 
 | 
			
		||||
#define R300_TEX_CMDSIZE	(MAX_TEXTURE_UNITS+1)
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Cache for hardware register state.
 | 
			
		||||
 */
 | 
			
		||||
@@ -303,6 +408,21 @@ struct r300_hw_state {
 | 
			
		||||
	struct r300_state_atom vpi;	/* vp instructions */
 | 
			
		||||
	struct r300_state_atom vpp;	/* vp parameters */
 | 
			
		||||
	struct r300_state_atom vps;	/* vertex point size (?) */
 | 
			
		||||
 | 
			
		||||
		/* 8 texture units */
 | 
			
		||||
		/* the state is grouped by function and not by 
 | 
			
		||||
		   texture unit. This makes single unit updates
 | 
			
		||||
		   really awkward - we are much better off 
 | 
			
		||||
		   updating the whole thing at once */
 | 
			
		||||
	struct {
 | 
			
		||||
		struct r300_state_atom filter;
 | 
			
		||||
		struct r300_state_atom unknown1;
 | 
			
		||||
		struct r300_state_atom size;
 | 
			
		||||
		struct r300_state_atom format;
 | 
			
		||||
		struct r300_state_atom offset;
 | 
			
		||||
		struct r300_state_atom unknown4;
 | 
			
		||||
		struct r300_state_atom unknown5;		
 | 
			
		||||
		} tex;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -331,6 +451,7 @@ struct r300_depthbuffer_state {
 | 
			
		||||
 | 
			
		||||
struct r300_state {
 | 
			
		||||
	struct r300_depthbuffer_state depth;
 | 
			
		||||
	struct r300_texture_state texture;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -348,6 +469,38 @@ struct r300_context {
 | 
			
		||||
	int elt_count;  /* size of the buffer for vertices */
 | 
			
		||||
	int attrib_count; /* size of the buffer for vertex attributes.. Somehow it can be different ? */
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	/* Vertex buffers
 | 
			
		||||
	 */
 | 
			
		||||
	#if 0 /* we'll need it later, but not now */
 | 
			
		||||
	struct r300_ioctl ioctl;
 | 
			
		||||
	#endif
 | 
			
		||||
	struct r300_dma dma;
 | 
			
		||||
	GLboolean save_on_next_unlock;
 | 
			
		||||
 | 
			
		||||
	/* Texture object bookkeeping
 | 
			
		||||
	 */
 | 
			
		||||
	unsigned nr_heaps;
 | 
			
		||||
	driTexHeap *texture_heaps[R200_NR_TEX_HEAPS];
 | 
			
		||||
	driTextureObject swapped;
 | 
			
		||||
	int texture_depth;
 | 
			
		||||
	float initialMaxAnisotropy;
 | 
			
		||||
 | 
			
		||||
	/* Clientdata textures;
 | 
			
		||||
	 */
 | 
			
		||||
	GLuint prefer_gart_client_texturing;
 | 
			
		||||
 | 
			
		||||
	/* TCL stuff
 | 
			
		||||
	 */
 | 
			
		||||
	GLmatrix TexGenMatrix[R300_MAX_TEXTURE_UNITS];
 | 
			
		||||
	GLboolean recheck_texgen[R300_MAX_TEXTURE_UNITS];
 | 
			
		||||
	GLboolean TexGenNeedNormals[R300_MAX_TEXTURE_UNITS];
 | 
			
		||||
	GLuint TexMatEnabled;
 | 
			
		||||
	GLuint TexMatCompSel;
 | 
			
		||||
	GLuint TexGenEnabled;
 | 
			
		||||
	GLuint TexGenInputs;
 | 
			
		||||
	GLuint TexGenCompSel;
 | 
			
		||||
	GLmatrix tmpmat;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define R300_CONTEXT(ctx)		((r300ContextPtr)(ctx->DriverCtx))
 | 
			
		||||
 
 | 
			
		||||
@@ -282,6 +282,195 @@ void r300Flush(GLcontext * ctx)
 | 
			
		||||
		r300FlushCmdBuf(r300, __FUNCTION__);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void r300RefillCurrentDmaRegion(r300ContextPtr rmesa)
 | 
			
		||||
{
 | 
			
		||||
	struct r200_dma_buffer *dmabuf;
 | 
			
		||||
	int fd = rmesa->radeon.dri.fd;
 | 
			
		||||
	int index = 0;
 | 
			
		||||
	int size = 0;
 | 
			
		||||
	drmDMAReq dma;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
 | 
			
		||||
		fprintf(stderr, "%s\n", __FUNCTION__);
 | 
			
		||||
 | 
			
		||||
	if (rmesa->dma.flush) {
 | 
			
		||||
		rmesa->dma.flush(rmesa);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (rmesa->dma.current.buf)
 | 
			
		||||
		r300ReleaseDmaRegion(rmesa, &rmesa->dma.current, __FUNCTION__);
 | 
			
		||||
 | 
			
		||||
	if (rmesa->dma.nr_released_bufs > 4)
 | 
			
		||||
		r300FlushCmdBuf(rmesa, __FUNCTION__);
 | 
			
		||||
 | 
			
		||||
	dma.context = rmesa->radeon.dri.hwContext;
 | 
			
		||||
	dma.send_count = 0;
 | 
			
		||||
	dma.send_list = NULL;
 | 
			
		||||
	dma.send_sizes = NULL;
 | 
			
		||||
	dma.flags = 0;
 | 
			
		||||
	dma.request_count = 1;
 | 
			
		||||
	dma.request_size = RADEON_BUFFER_SIZE;
 | 
			
		||||
	dma.request_list = &index;
 | 
			
		||||
	dma.request_sizes = &size;
 | 
			
		||||
	dma.granted_count = 0;
 | 
			
		||||
 | 
			
		||||
	LOCK_HARDWARE(&rmesa->radeon);	/* no need to validate */
 | 
			
		||||
 | 
			
		||||
	while (1) {
 | 
			
		||||
		ret = drmDMA(fd, &dma);
 | 
			
		||||
		if (ret == 0)
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		if (rmesa->dma.nr_released_bufs) {
 | 
			
		||||
			r200FlushCmdBufLocked(rmesa, __FUNCTION__);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (rmesa->radeon.do_usleeps) {
 | 
			
		||||
			UNLOCK_HARDWARE(&rmesa->radeon);
 | 
			
		||||
			DO_USLEEP(1);
 | 
			
		||||
			LOCK_HARDWARE(&rmesa->radeon);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	UNLOCK_HARDWARE(&rmesa->radeon);
 | 
			
		||||
 | 
			
		||||
	if (RADEON_DEBUG & DEBUG_DMA)
 | 
			
		||||
		fprintf(stderr, "Allocated buffer %d\n", index);
 | 
			
		||||
 | 
			
		||||
	dmabuf = CALLOC_STRUCT(r300_dma_buffer);
 | 
			
		||||
	dmabuf->buf = &rmesa->radeon.radeonScreen->buffers->list[index];
 | 
			
		||||
	dmabuf->refcount = 1;
 | 
			
		||||
 | 
			
		||||
	rmesa->dma.current.buf = dmabuf;
 | 
			
		||||
	rmesa->dma.current.address = dmabuf->buf->address;
 | 
			
		||||
	rmesa->dma.current.end = dmabuf->buf->total;
 | 
			
		||||
	rmesa->dma.current.start = 0;
 | 
			
		||||
	rmesa->dma.current.ptr = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void r300ReleaseDmaRegion(r300ContextPtr rmesa,
 | 
			
		||||
			  struct r300_dma_region *region, const char *caller)
 | 
			
		||||
{
 | 
			
		||||
	if (RADEON_DEBUG & DEBUG_IOCTL)
 | 
			
		||||
		fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
 | 
			
		||||
 | 
			
		||||
	if (!region->buf)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (rmesa->dma.flush)
 | 
			
		||||
		rmesa->dma.flush(rmesa);
 | 
			
		||||
 | 
			
		||||
	if (--region->buf->refcount == 0) {
 | 
			
		||||
		drm_radeon_cmd_header_t *cmd;
 | 
			
		||||
 | 
			
		||||
		if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
 | 
			
		||||
			fprintf(stderr, "%s -- DISCARD BUF %d\n", __FUNCTION__,
 | 
			
		||||
				region->buf->buf->idx);
 | 
			
		||||
 | 
			
		||||
		cmd =
 | 
			
		||||
		    (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa,
 | 
			
		||||
								sizeof(*cmd),
 | 
			
		||||
								__FUNCTION__);
 | 
			
		||||
		cmd->dma.cmd_type = RADEON_CMD_DMA_DISCARD;
 | 
			
		||||
		cmd->dma.buf_idx = region->buf->buf->idx;
 | 
			
		||||
		FREE(region->buf);
 | 
			
		||||
		rmesa->dma.nr_released_bufs++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	region->buf = 0;
 | 
			
		||||
	region->start = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 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 r300AllocDmaRegion(r300ContextPtr rmesa,
 | 
			
		||||
			struct r300_dma_region *region,
 | 
			
		||||
			int bytes, int alignment)
 | 
			
		||||
{
 | 
			
		||||
	if (RADEON_DEBUG & DEBUG_IOCTL)
 | 
			
		||||
		fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
 | 
			
		||||
 | 
			
		||||
	if (rmesa->dma.flush)
 | 
			
		||||
		rmesa->dma.flush(rmesa);
 | 
			
		||||
 | 
			
		||||
	if (region->buf)
 | 
			
		||||
		r300ReleaseDmaRegion(rmesa, region, __FUNCTION__);
 | 
			
		||||
 | 
			
		||||
	alignment--;
 | 
			
		||||
	rmesa->dma.current.start = rmesa->dma.current.ptr =
 | 
			
		||||
	    (rmesa->dma.current.ptr + alignment) & ~alignment;
 | 
			
		||||
 | 
			
		||||
	if (rmesa->dma.current.ptr + bytes > rmesa->dma.current.end)
 | 
			
		||||
		r300RefillCurrentDmaRegion(rmesa);
 | 
			
		||||
 | 
			
		||||
	region->start = rmesa->dma.current.start;
 | 
			
		||||
	region->ptr = rmesa->dma.current.start;
 | 
			
		||||
	region->end = rmesa->dma.current.start + bytes;
 | 
			
		||||
	region->address = rmesa->dma.current.address;
 | 
			
		||||
	region->buf = rmesa->dma.current.buf;
 | 
			
		||||
	region->buf->refcount++;
 | 
			
		||||
 | 
			
		||||
	rmesa->dma.current.ptr += bytes;	/* bug - if alignment > 7 */
 | 
			
		||||
	rmesa->dma.current.start =
 | 
			
		||||
	    rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7;
 | 
			
		||||
 | 
			
		||||
	assert(rmesa->dma.current.ptr <= rmesa->dma.current.end);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Called via glXGetMemoryOffsetMESA() */
 | 
			
		||||
GLuint r300GetMemoryOffsetMESA(__DRInativeDisplay * dpy, int scrn,
 | 
			
		||||
			       const GLvoid * pointer)
 | 
			
		||||
{
 | 
			
		||||
	GET_CURRENT_CONTEXT(ctx);
 | 
			
		||||
	r300ContextPtr rmesa;
 | 
			
		||||
	GLuint card_offset;
 | 
			
		||||
 | 
			
		||||
	if (!ctx || !(rmesa = R300_CONTEXT(ctx))) {
 | 
			
		||||
		fprintf(stderr, "%s: no context\n", __FUNCTION__);
 | 
			
		||||
		return ~0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!r300IsGartMemory(rmesa, pointer, 0))
 | 
			
		||||
		return ~0;
 | 
			
		||||
 | 
			
		||||
	if (rmesa->radeon.dri.drmMinor < 6)
 | 
			
		||||
		return ~0;
 | 
			
		||||
 | 
			
		||||
	card_offset = r300GartOffsetFromVirtual(rmesa, pointer);
 | 
			
		||||
 | 
			
		||||
	return card_offset - rmesa->radeon.radeonScreen->gart_base;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLboolean r300IsGartMemory(r300ContextPtr rmesa, const GLvoid * pointer,
 | 
			
		||||
			   GLint size)
 | 
			
		||||
{
 | 
			
		||||
	int offset =
 | 
			
		||||
	    (char *)pointer - (char *)rmesa->radeon.radeonScreen->gartTextures.map;
 | 
			
		||||
	int valid = (size >= 0 && offset >= 0
 | 
			
		||||
		     && offset + size < rmesa->radeon.radeonScreen->gartTextures.size);
 | 
			
		||||
 | 
			
		||||
	if (RADEON_DEBUG & DEBUG_IOCTL)
 | 
			
		||||
		fprintf(stderr, "r300IsGartMemory( %p ) : %d\n", pointer,
 | 
			
		||||
			valid);
 | 
			
		||||
 | 
			
		||||
	return valid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLuint r300GartOffsetFromVirtual(r300ContextPtr rmesa, const GLvoid * pointer)
 | 
			
		||||
{
 | 
			
		||||
	int offset =
 | 
			
		||||
	    (char *)pointer - (char *)rmesa->radeon.radeonScreen->gartTextures.map;
 | 
			
		||||
 | 
			
		||||
	fprintf(stderr, "offset=%08x\n", offset);
 | 
			
		||||
 | 
			
		||||
	if (offset < 0 || offset > rmesa->radeon.radeonScreen->gartTextures.size)
 | 
			
		||||
		return ~0;
 | 
			
		||||
	else
 | 
			
		||||
		return rmesa->radeon.radeonScreen->gart_texture_offset + offset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void r300InitIoctlFuncs(struct dd_function_table *functions)
 | 
			
		||||
{
 | 
			
		||||
	functions->Clear = r300Clear;
 | 
			
		||||
 
 | 
			
		||||
@@ -36,6 +36,18 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#ifndef __R300_IOCTL_H__
 | 
			
		||||
#define __R300_IOCTL_H__
 | 
			
		||||
 | 
			
		||||
#include "r300_context.h"
 | 
			
		||||
#include "radeon_drm.h"
 | 
			
		||||
 | 
			
		||||
extern GLuint r300GetMemoryOffsetMESA(__DRInativeDisplay * dpy, int scrn,
 | 
			
		||||
				      const GLvoid * pointer);
 | 
			
		||||
 | 
			
		||||
extern GLboolean r300IsGartMemory(r300ContextPtr rmesa, const GLvoid * pointer,
 | 
			
		||||
				  GLint size);
 | 
			
		||||
 | 
			
		||||
extern GLuint r300GartOffsetFromVirtual(r300ContextPtr rmesa,
 | 
			
		||||
					const GLvoid * pointer);
 | 
			
		||||
 | 
			
		||||
extern void r300Flush(GLcontext * ctx);
 | 
			
		||||
extern void r300InitIoctlFuncs(struct dd_function_table *functions);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -458,12 +458,14 @@ static void r300_render_tex_primitive(r300ContextPtr rmesa,
 | 
			
		||||
       	
 | 
			
		||||
   type=r300_get_primitive_type(rmesa, ctx, start, end, prim);
 | 
			
		||||
		
 | 
			
		||||
   		#if 1
 | 
			
		||||
		fprintf(stderr,"ObjPtr: size=%d stride=%d\n", 
 | 
			
		||||
			VB->ObjPtr->size, VB->ObjPtr->stride);
 | 
			
		||||
		fprintf(stderr,"ColorPtr[0]: size=%d stride=%d\n", 
 | 
			
		||||
			VB->ColorPtr[0]->size, VB->ColorPtr[0]->stride);
 | 
			
		||||
		fprintf(stderr,"TexCoordPtr[0]: size=%d stride=%d\n", 
 | 
			
		||||
			VB->TexCoordPtr[0]->size, VB->TexCoordPtr[0]->stride);
 | 
			
		||||
		#endif
 | 
			
		||||
   
 | 
			
		||||
   if(type<0)return;
 | 
			
		||||
 | 
			
		||||
@@ -508,16 +510,21 @@ static GLboolean r300_run_tex_render(GLcontext *ctx,
 | 
			
		||||
   AOS_DATA vb_arrays[3];
 | 
			
		||||
   /* Only do 2d textures */
 | 
			
		||||
   struct gl_texture_object *to=ctx->Texture.Unit[0].Current2D;
 | 
			
		||||
   radeonScreenPtr rsp=rmesa->radeon.radeonScreen;
 | 
			
		||||
   r300TexObjPtr t=to->DriverData;
 | 
			
		||||
   LOCAL_VARS
 | 
			
		||||
	
 | 
			
		||||
   
 | 
			
		||||
   /* Update texture state - needs to be done only when actually changed..
 | 
			
		||||
      All the time for now.. */
 | 
			
		||||
   r300UpdateTextureState(ctx);
 | 
			
		||||
   
 | 
			
		||||
   /* Flush state - make sure command buffer is nice and large */
 | 
			
		||||
   r300Flush(ctx);
 | 
			
		||||
   
 | 
			
		||||
   //fprintf(stderr, "You can enable texture drawing in %s:%s \n", __FILE__, __FUNCTION__);
 | 
			
		||||
   //return GL_TRUE;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	if (RADEON_DEBUG == DEBUG_PRIMS)
 | 
			
		||||
		fprintf(stderr, "%s\n", __FUNCTION__);
 | 
			
		||||
 | 
			
		||||
@@ -549,8 +556,6 @@ static GLboolean r300_run_tex_render(GLcontext *ctx,
 | 
			
		||||
   vb_arrays[2].ncomponents=4;
 | 
			
		||||
   vb_arrays[2].reg=REG_TEX0;
 | 
			
		||||
 | 
			
		||||
   /* Fill texture with some random data */
 | 
			
		||||
   for(i=0;i<100000;i++)((int *)(rsp->gartTextures.map))[i]=rand();
 | 
			
		||||
     
 | 
			
		||||
   /* needed before starting 3d operation .. */
 | 
			
		||||
   reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
 | 
			
		||||
@@ -578,8 +583,16 @@ static GLboolean r300_run_tex_render(GLcontext *ctx,
 | 
			
		||||
   SINGLE_TEXTURE_PIPELINE.vertex_shader.unknown2.body.f[2]=1.0;
 | 
			
		||||
   SINGLE_TEXTURE_PIPELINE.vertex_shader.unknown2.body.f[3]=0.0;
 | 
			
		||||
 | 
			
		||||
   /* Put it in the beginning of texture memory */
 | 
			
		||||
   SINGLE_TEXTURE_PIPELINE.texture_unit[0].offset=rsp->gartTextures.handle;
 | 
			
		||||
   /* Use actual texture offset */
 | 
			
		||||
   
 | 
			
		||||
   SINGLE_TEXTURE_PIPELINE.texture_unit[0].offset=rmesa->radeon.radeonScreen->fbLocation+t->offset;
 | 
			
		||||
   #if 0
 | 
			
		||||
   SINGLE_TEXTURE_PIPELINE.texture_unit[0].format=t->format;
 | 
			
		||||
   SINGLE_TEXTURE_PIPELINE.texture_unit[0].size=t->size;
 | 
			
		||||
   #endif
 | 
			
		||||
   SINGLE_TEXTURE_PIPELINE.texture_unit[0].filter=t->filter;
 | 
			
		||||
   SINGLE_TEXTURE_PIPELINE.texture_unit[0].unknown1=t->pitch; /* Unknown 1 is pitch ! */
 | 
			
		||||
   SINGLE_TEXTURE_PIPELINE.texture_unit[0].filter=t->filter;
 | 
			
		||||
   
 | 
			
		||||
   
 | 
			
		||||
   /* Upload texture, a hack, really  we can do a lot better */
 | 
			
		||||
@@ -644,6 +657,7 @@ reg_start(R300_RS_INTERP_0,7);
 | 
			
		||||
   reg_start(0x4f18,0);
 | 
			
		||||
	e32(0x00000003);
 | 
			
		||||
         
 | 
			
		||||
//   exit(-1);
 | 
			
		||||
   fprintf(stderr, "\n");
 | 
			
		||||
   return GL_FALSE;
 | 
			
		||||
}
 | 
			
		||||
@@ -671,7 +685,7 @@ static GLboolean r300_run_render(GLcontext *ctx,
 | 
			
		||||
        if(ctx->Texture.Unit[0].Enabled)
 | 
			
		||||
        	return r300_run_tex_render(ctx, stage);
 | 
			
		||||
		else
 | 
			
		||||
        	return r300_run_flat_render(ctx, stage);
 | 
			
		||||
        	return r300_run_vb_flat_render(ctx, stage);
 | 
			
		||||
   #else
 | 
			
		||||
	return GL_TRUE;
 | 
			
		||||
   #endif
 | 
			
		||||
 
 | 
			
		||||
@@ -547,6 +547,17 @@ void r300ResetHwState(r300ContextPtr r300)
 | 
			
		||||
	r300->hw.vps.cmd[R300_VPS_ZERO_1] = 0;
 | 
			
		||||
	r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0);
 | 
			
		||||
	r300->hw.vps.cmd[R300_VPS_ZERO_3] = 0;
 | 
			
		||||
	
 | 
			
		||||
	/* Initialize texture units */
 | 
			
		||||
	for(i=0;i<r300->radeon.glCtx->Const.MaxTextureUnits;i++){
 | 
			
		||||
		r300->hw.tex.filter.cmd[R300_TEX_VALUE_0+i]=0x0;
 | 
			
		||||
		r300->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+i]=0x0;
 | 
			
		||||
		r300->hw.tex.size.cmd[R300_TEX_VALUE_0+i]=0x0;
 | 
			
		||||
		r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=0x0;
 | 
			
		||||
		r300->hw.tex.offset.cmd[R300_TEX_VALUE_0+i]=0x0;
 | 
			
		||||
		r300->hw.tex.unknown4.cmd[R300_TEX_VALUE_0+i]=0x0;
 | 
			
		||||
		r300->hw.tex.unknown5.cmd[R300_TEX_VALUE_0+i]=0x0;
 | 
			
		||||
		}
 | 
			
		||||
//END: TODO
 | 
			
		||||
	
 | 
			
		||||
	r300->hw.all_dirty = GL_TRUE;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1055
									
								
								src/mesa/drivers/dri/r300/r300_tex.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1055
									
								
								src/mesa/drivers/dri/r300/r300_tex.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										51
									
								
								src/mesa/drivers/dri/r300/r300_tex.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/mesa/drivers/dri/r300/r300_tex.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
/* $XFree86: xc/lib/GL/mesa/src/drv/r300/r300_tex.h,v 1.1 2002/10/30 12:51:53 alanh Exp $ */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
 | 
			
		||||
 | 
			
		||||
The Weather Channel (TM) 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 the rights to use, copy, modify, merge, publish,
 | 
			
		||||
distribute, sublicense, 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 NONINFRINGEMENT.
 | 
			
		||||
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
 | 
			
		||||
 | 
			
		||||
**************************************************************************/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Authors:
 | 
			
		||||
 *   Keith Whitwell <keith@tungstengraphics.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __r300_TEX_H__
 | 
			
		||||
#define __r300_TEX_H__
 | 
			
		||||
 | 
			
		||||
#ifdef GLX_DIRECT_RENDERING
 | 
			
		||||
 | 
			
		||||
extern void r300UpdateTextureState(GLcontext * ctx);
 | 
			
		||||
 | 
			
		||||
extern int r300UploadTexImages(r300ContextPtr rmesa, r300TexObjPtr t,
 | 
			
		||||
			       GLuint face);
 | 
			
		||||
 | 
			
		||||
extern void r300DestroyTexObj(r300ContextPtr rmesa, r300TexObjPtr t);
 | 
			
		||||
 | 
			
		||||
extern void r300InitTextureFuncs(struct dd_function_table *functions);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
#endif				/* __r300_TEX_H__ */
 | 
			
		||||
							
								
								
									
										490
									
								
								src/mesa/drivers/dri/r300/r300_texmem.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										490
									
								
								src/mesa/drivers/dri/r300/r300_texmem.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,490 @@
 | 
			
		||||
/* $XFree86: xc/lib/GL/mesa/src/drv/r300/r300_texmem.c,v 1.5 2002/12/17 00:32:56 dawes Exp $ */
 | 
			
		||||
/**************************************************************************
 | 
			
		||||
 | 
			
		||||
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 "glheader.h"
 | 
			
		||||
#include "imports.h"
 | 
			
		||||
#include "context.h"
 | 
			
		||||
#include "colormac.h"
 | 
			
		||||
#include "macros.h"
 | 
			
		||||
#include "simple_list.h"
 | 
			
		||||
#include "radeon_reg.h"		/* gets definition for usleep */
 | 
			
		||||
#include "r300_context.h"
 | 
			
		||||
#include "r300_state.h"
 | 
			
		||||
#include "radeon_ioctl.h"
 | 
			
		||||
/*
 | 
			
		||||
#include "r300_swtcl.h"
 | 
			
		||||
*/
 | 
			
		||||
#include "r300_tex.h"
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>		/* for usleep() */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Destroy any device-dependent state associated with the texture.  This may
 | 
			
		||||
 * include NULLing out hardware state that points to the texture.
 | 
			
		||||
 */
 | 
			
		||||
void r300DestroyTexObj(r300ContextPtr rmesa, r300TexObjPtr t)
 | 
			
		||||
{
 | 
			
		||||
	if (RADEON_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;
 | 
			
		||||
				/* This code below is meant to shorten state
 | 
			
		||||
				   pushed to the hardware by not programming 
 | 
			
		||||
				   unneeded units.
 | 
			
		||||
				   
 | 
			
		||||
				   This does not appear to be worthwhile on R300 */
 | 
			
		||||
				#if 0
 | 
			
		||||
				remove_from_list(&rmesa->hw.tex[i]);
 | 
			
		||||
				make_empty_list(&rmesa->hw.tex[i]);
 | 
			
		||||
				remove_from_list(&rmesa->hw.cube[i]);
 | 
			
		||||
				make_empty_list(&rmesa->hw.cube[i]);
 | 
			
		||||
				#endif
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------
 | 
			
		||||
 * Texture image conversions
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static void r300UploadGARTClientSubImage(r300ContextPtr rmesa,
 | 
			
		||||
					 r300TexObjPtr 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 = r300GartOffsetFromVirtual(rmesa, texImage->Data);
 | 
			
		||||
 | 
			
		||||
	assert(srcOffset != ~0);
 | 
			
		||||
 | 
			
		||||
	/* Don't currently need to cope with small pitches?
 | 
			
		||||
	 */
 | 
			
		||||
	width = texImage->Width;
 | 
			
		||||
	height = texImage->Height;
 | 
			
		||||
 | 
			
		||||
	r300EmitWait(rmesa, RADEON_WAIT_3D);
 | 
			
		||||
 | 
			
		||||
	r300EmitBlit(rmesa, blit_format,
 | 
			
		||||
		     srcPitch,
 | 
			
		||||
		     srcOffset,
 | 
			
		||||
		     dstPitch,
 | 
			
		||||
		     t->bufAddr,
 | 
			
		||||
		     x,
 | 
			
		||||
		     y,
 | 
			
		||||
		     t->image[0][hwlevel].x + x,
 | 
			
		||||
		     t->image[0][hwlevel].y + y, width, height);
 | 
			
		||||
 | 
			
		||||
	r300EmitWait(rmesa, RADEON_WAIT_2D);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void r300UploadRectSubImage(r300ContextPtr rmesa,
 | 
			
		||||
				   r300TexObjPtr 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->pitch + 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.
 | 
			
		||||
		 */
 | 
			
		||||
		t->offset =
 | 
			
		||||
		    r300GartOffsetFromVirtual(rmesa, texImage->Data);
 | 
			
		||||
		t->pitch =
 | 
			
		||||
		    texImage->RowStride * texFormat->TexelBytes - 32;
 | 
			
		||||
 | 
			
		||||
		if (RADEON_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;
 | 
			
		||||
		r300EmitBlit(rmesa,
 | 
			
		||||
			     blit_format,
 | 
			
		||||
			     srcPitch,
 | 
			
		||||
			     r300GartOffsetFromVirtual(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 r300_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));
 | 
			
		||||
			r300AllocDmaRegion(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;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			r300EmitWait(rmesa, RADEON_WAIT_3D);
 | 
			
		||||
 | 
			
		||||
			/* Blit to framebuffer
 | 
			
		||||
			 */
 | 
			
		||||
			r300EmitBlit(rmesa,
 | 
			
		||||
				     blit_format,
 | 
			
		||||
				     dstPitch, GET_START(®ion),
 | 
			
		||||
				     dstPitch, t->bufAddr,
 | 
			
		||||
				     0, 0, 0, done, width, lines);
 | 
			
		||||
 | 
			
		||||
			r300EmitWait(rmesa, RADEON_WAIT_2D);
 | 
			
		||||
 | 
			
		||||
			r300ReleaseDmaRegion(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(r300ContextPtr rmesa, r300TexObjPtr 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 (RADEON_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 (RADEON_DEBUG & DEBUG_TEXTURE)
 | 
			
		||||
			fprintf(stderr, "%s: texImage %d is NULL!\n",
 | 
			
		||||
				__FUNCTION__, level);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (!texImage->Data) {
 | 
			
		||||
		if (RADEON_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 (RADEON_DEBUG & DEBUG_TEXTURE)
 | 
			
		||||
			fprintf(stderr, "%s: image data is rectangular\n",
 | 
			
		||||
				__FUNCTION__);
 | 
			
		||||
		r300UploadRectSubImage(rmesa, t, texImage, x, y, width, height);
 | 
			
		||||
		return;
 | 
			
		||||
	} else if (texImage->IsClientData) {
 | 
			
		||||
		if (RADEON_DEBUG & DEBUG_TEXTURE)
 | 
			
		||||
			fprintf(stderr,
 | 
			
		||||
				"%s: image data is in GART client storage\n",
 | 
			
		||||
				__FUNCTION__);
 | 
			
		||||
		r300UploadGARTClientSubImage(rmesa, t, texImage, hwlevel, x, y,
 | 
			
		||||
					     width, height);
 | 
			
		||||
		return;
 | 
			
		||||
	} else if (RADEON_DEBUG & DEBUG_TEXTURE)
 | 
			
		||||
		fprintf(stderr, "%s: image data is in normal memory\n",
 | 
			
		||||
			__FUNCTION__);
 | 
			
		||||
 | 
			
		||||
	imageWidth = texImage->Width;
 | 
			
		||||
	imageHeight = texImage->Height;
 | 
			
		||||
 | 
			
		||||
	offset = t->bufAddr;
 | 
			
		||||
 | 
			
		||||
	if (RADEON_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)
 | 
			
		||||
	 */
 | 
			
		||||
	tex.offset = offset;
 | 
			
		||||
	tex.pitch = BLIT_WIDTH_BYTES / 64;
 | 
			
		||||
	tex.format = R200_TXFORMAT_I8;	/* any 1-byte texel format */
 | 
			
		||||
	if (texImage->TexFormat->TexelBytes) {
 | 
			
		||||
		tex.width = imageWidth * texImage->TexFormat->TexelBytes;	/* in bytes */
 | 
			
		||||
		tex.height = imageHeight;
 | 
			
		||||
	} else {
 | 
			
		||||
		tex.width = imageWidth;	/* compressed */
 | 
			
		||||
		tex.height = imageHeight;
 | 
			
		||||
		if (tex.height < 4)
 | 
			
		||||
			tex.height = 4;
 | 
			
		||||
	}
 | 
			
		||||
	tex.image = &tmp;
 | 
			
		||||
 | 
			
		||||
	/* copy (x,y,width,height,data) */
 | 
			
		||||
	memcpy(&tmp, &t->image[face][hwlevel], sizeof(tmp));
 | 
			
		||||
 | 
			
		||||
	LOCK_HARDWARE(&rmesa->radeon);
 | 
			
		||||
	do {
 | 
			
		||||
		ret = drmCommandWriteRead(rmesa->radeon.dri.fd, DRM_RADEON_TEXTURE,
 | 
			
		||||
					  &tex, sizeof(drm_radeon_texture_t));
 | 
			
		||||
		if (ret) {
 | 
			
		||||
			if (RADEON_DEBUG & DEBUG_IOCTL)
 | 
			
		||||
				fprintf(stderr,
 | 
			
		||||
					"DRM_RADEON_TEXTURE:  again!\n");
 | 
			
		||||
			usleep(1);
 | 
			
		||||
		}
 | 
			
		||||
	} while (ret && errno == 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 r300UploadTexImages(r300ContextPtr rmesa, r300TexObjPtr t, GLuint face)
 | 
			
		||||
{
 | 
			
		||||
	const int numLevels = t->base.lastLevel - t->base.firstLevel + 1;
 | 
			
		||||
 | 
			
		||||
	if (RADEON_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)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (RADEON_DEBUG & DEBUG_SYNC) {
 | 
			
		||||
		fprintf(stderr, "%s: Syncing\n", __FUNCTION__);
 | 
			
		||||
		radeonFinish(rmesa->radeon.glCtx);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	LOCK_HARDWARE(&rmesa->radeon);
 | 
			
		||||
 | 
			
		||||
	if (t->base.memBlock == NULL) {
 | 
			
		||||
		int heap;
 | 
			
		||||
 | 
			
		||||
		heap = driAllocateTexture(rmesa->texture_heaps, rmesa->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->offset = t->bufAddr;
 | 
			
		||||
 | 
			
		||||
		/* Mark this texobj as dirty on all units:
 | 
			
		||||
		 */
 | 
			
		||||
		t->dirty_state = 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 (RADEON_DEBUG & DEBUG_SYNC) {
 | 
			
		||||
		fprintf(stderr, "%s: Syncing\n", __FUNCTION__);
 | 
			
		||||
		radeonFinish(rmesa->radeon.glCtx);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1390
									
								
								src/mesa/drivers/dri/r300/r300_texstate.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1390
									
								
								src/mesa/drivers/dri/r300/r300_texstate.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user