Port texture allocation code from R200.
Hook it up, so lesson06 displays red colored textures.
This commit is contained in:
parent
63fd67e561
commit
2fc9351ee7
|
@ -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"
|
||||
|
||||
|
@ -545,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,44 @@ 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
|
||||
|
@ -74,8 +112,8 @@ static __inline__ uint32_t r300PackFloat32(float fl)
|
|||
#define TEX_3 0x8
|
||||
#define TEX_4 0x10
|
||||
#define TEX_5 0x20
|
||||
#define TEX_6 0x20
|
||||
#define TEX_7 0x20
|
||||
#define TEX_6 0x40
|
||||
#define TEX_7 0x80
|
||||
#define TEX_ALL 0xff
|
||||
|
||||
typedef struct r300_tex_obj r300TexObj, *r300TexObjPtr;
|
||||
|
@ -114,6 +152,17 @@ struct r300_tex_obj {
|
|||
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.
|
||||
|
@ -402,6 +451,7 @@ struct r300_depthbuffer_state {
|
|||
|
||||
struct r300_state {
|
||||
struct r300_depthbuffer_state depth;
|
||||
struct r300_texture_state texture;
|
||||
};
|
||||
|
||||
|
||||
|
@ -419,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
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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__ */
|
|
@ -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;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue