diff options
author | Dave Airlie <airlied@redhat.com> | 2009-02-12 21:16:39 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-02-12 21:16:39 +1000 |
commit | 1090d206de011a67d236d8c4ae32d2d42b2f6337 (patch) | |
tree | 2f8dd5c189701b54c3e3153f4cf6739761f9b6e7 /src/mesa/drivers/dri/radeon | |
parent | f3f1f7dc20484a60b1325e60e0c9bb994ab591f1 (diff) |
radeon/r200/r300: another big merge upheavel.
This merges lots of the hw state atom emission and firevertices code.
it also removes a lot of the extra radeon crap from r300
and merge scissor
Diffstat (limited to 'src/mesa/drivers/dri/radeon')
-rw-r--r-- | src/mesa/drivers/dri/radeon/common_cmdbuf.h | 14 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/common_context.h | 27 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/common_misc.c | 155 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/common_misc.h | 5 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_context.c | 46 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_context.h | 24 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_ioctl.c | 202 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_ioctl.h | 14 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_screen.c | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_state.c | 26 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_state_init.c | 12 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_swtcl.c | 12 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_tcl.c | 8 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_tex.c | 2 |
14 files changed, 227 insertions, 322 deletions
diff --git a/src/mesa/drivers/dri/radeon/common_cmdbuf.h b/src/mesa/drivers/dri/radeon/common_cmdbuf.h index 071e29ee02..5526934209 100644 --- a/src/mesa/drivers/dri/radeon/common_cmdbuf.h +++ b/src/mesa/drivers/dri/radeon/common_cmdbuf.h @@ -1,10 +1,12 @@ #ifndef COMMON_CMDBUF_H #define COMMON_CMDBUF_H +#include "radeon_cs.h" + void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller); int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller); int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller); -void rcommonInitCmdBuf(radeonContextPtr rmesa, int max_state_size); +void rcommonInitCmdBuf(radeonContextPtr rmesa); void rcommonDestroyCmdBuf(radeonContextPtr rmesa); void rcommonBeginBatch(radeonContextPtr rmesa, @@ -128,4 +130,14 @@ void rcommonBeginBatch(radeonContextPtr rmesa, /** Write a 32 bit float to the ring; requires 1 dword. */ #define OUT_BATCH_FLOAT32(f) \ OUT_BATCH(radeonPackFloat32((f))); + + +/* Fire the buffered vertices no matter what. + */ +static INLINE void radeon_firevertices(radeonContextPtr radeon) +{ + if (radeon->cmdbuf.cs->cdw || radeon->dma.flush ) + radeonFlush(radeon->glCtx); +} + #endif diff --git a/src/mesa/drivers/dri/radeon/common_context.h b/src/mesa/drivers/dri/radeon/common_context.h index 618e74d458..c3a445e0d2 100644 --- a/src/mesa/drivers/dri/radeon/common_context.h +++ b/src/mesa/drivers/dri/radeon/common_context.h @@ -111,6 +111,13 @@ struct radeon_state_atom { void (*emit) (GLcontext *, struct radeon_state_atom *atom); }; +struct radeon_hw_state { + /* Head of the linked list of state atoms. */ + struct radeon_state_atom atomlist; + int max_state_size; /* Number of bytes necessary for a full state emit. */ + GLboolean is_dirty, all_dirty; +}; + /* Texture related */ typedef struct _radeon_texture_image radeon_texture_image; @@ -206,17 +213,6 @@ struct radeon_dma_buffer { drmBufPtr buf; }; -/* A retained region, eg vertices for indexed vertices. - */ -struct radeon_dma_region { - struct radeon_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 radeon_aos { struct radeon_bo *bo; /** Buffer object where vertex data is stored */ int offset; /** Offset into buffer object, in bytes */ @@ -388,6 +384,7 @@ struct radeon_context { float initialMaxAnisotropy; struct radeon_dma dma; + struct radeon_hw_state hw; /* Rasterization and vertex state: */ GLuint TclFallback; @@ -434,13 +431,11 @@ struct radeon_context { struct { void (*get_lock)(radeonContextPtr radeon); void (*update_viewport_offset)(GLcontext *ctx); - void (*flush)(GLcontext *ctx); - void (*set_all_dirty)(GLcontext *ctx); void (*update_draw_buffer)(GLcontext *ctx); void (*emit_cs_header)(struct radeon_cs *cs, radeonContextPtr rmesa); - void (*emit_state)(radeonContextPtr rmesa); - void (*flush_vertices)(radeonContextPtr rmesa); void (*swtcl_flush)(GLcontext *ctx, uint32_t offset); + void (*pre_emit_atoms)(radeonContextPtr rmesa); + void (*pre_emit_state)(radeonContextPtr rmesa); } vtbl; }; @@ -502,4 +497,6 @@ extern int RADEON_DEBUG; #define RADEON_DEBUG 0 #endif +#include "common_misc.h" +#include "common_cmdbuf.h" #endif diff --git a/src/mesa/drivers/dri/radeon/common_misc.c b/src/mesa/drivers/dri/radeon/common_misc.c index 9456f2a438..12536b1672 100644 --- a/src/mesa/drivers/dri/radeon/common_misc.c +++ b/src/mesa/drivers/dri/radeon/common_misc.c @@ -42,6 +42,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/colormac.h" #include "main/light.h" #include "main/framebuffer.h" +#include "main/simple_list.h" #include "swrast/swrast.h" #include "vbo/vbo.h" @@ -81,6 +82,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. int RADEON_DEBUG = (0); #endif +#define DEBUG_CMDBUF 0 + /* ============================================================= * Scissoring */ @@ -215,6 +218,21 @@ void radeonUpdateScissor( GLcontext *ctx ) } } +/* ============================================================= + * Scissoring + */ + +void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + if (ctx->Scissor.Enabled) { + /* We don't pipeline cliprect changes */ + radeon_firevertices(radeon); + radeonUpdateScissor(ctx); + } +} + + /* ================================================================ * SwapBuffers with client-side throttling */ @@ -367,7 +385,7 @@ void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void *) rmesa->glCtx ); } - rmesa->vtbl.flush(rmesa->glCtx); + radeon_firevertices(rmesa); LOCK_HARDWARE( rmesa ); /* Throttle the frame rate -- only allow one pending swap buffers @@ -437,7 +455,7 @@ void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, } rmesa->swap_ust = ust; - rmesa->vtbl.set_all_dirty(rmesa->glCtx); + rmesa->hw.all_dirty = GL_TRUE; } } @@ -465,7 +483,7 @@ void radeonPageFlip( __DRIdrawablePrivate *dPriv ) rmesa->sarea->pfCurrentPage); } - rmesa->vtbl.flush(rmesa->glCtx); + radeon_firevertices(rmesa); LOCK_HARDWARE( rmesa ); @@ -516,16 +534,111 @@ void radeonPageFlip( __DRIdrawablePrivate *dPriv ) rmesa->vtbl.update_draw_buffer(rmesa->glCtx); } +void radeonFlush(GLcontext *ctx) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (radeon->dma.flush) + radeon->dma.flush( ctx ); + + radeonEmitState(radeon); + + if (radeon->cmdbuf.cs->cdw) + rcommonFlushCmdBuf(radeon, __FUNCTION__); +} + +static INLINE void radeonEmitAtoms(radeonContextPtr radeon, GLboolean dirty) +{ + BATCH_LOCALS(radeon); + struct radeon_state_atom *atom; + int dwords; + + if (radeon->vtbl.pre_emit_atoms) + radeon->vtbl.pre_emit_atoms(radeon); + + /* Emit actual atoms */ + foreach(atom, &radeon->hw.atomlist) { + if ((atom->dirty || radeon->hw.all_dirty) == dirty) { + dwords = (*atom->check) (radeon->glCtx, atom); + if (dwords) { + if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) { + radeon_print_state_atom(atom); + } + if (atom->emit) { + (*atom->emit)(radeon->glCtx, atom); + } else { + BEGIN_BATCH_NO_AUTOSTATE(dwords); + OUT_BATCH_TABLE(atom->cmd, dwords); + END_BATCH(); + } + atom->dirty = GL_FALSE; + } else { + if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) { + fprintf(stderr, " skip state %s\n", + atom->name); + } + } + } + } + + COMMIT_BATCH(); +} + +void radeonEmitState(radeonContextPtr radeon) +{ + if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS)) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (radeon->vtbl.pre_emit_state) + radeon->vtbl.pre_emit_state(radeon); + + /* this code used to return here but now it emits zbs */ + if (radeon->cmdbuf.cs->cdw && !radeon->hw.is_dirty && !radeon->hw.all_dirty) + return; + + /* To avoid going across the entire set of states multiple times, just check + * for enough space for the case of emitting all state, and inline the + * radeonAllocCmdBuf code here without all the checks. + */ + rcommonEnsureCmdBufSpace(radeon, radeon->hw.max_state_size, __FUNCTION__); + + /* We always always emit zbs, this is due to a bug found by keithw in + the hardware and rediscovered after Erics changes by me. + if you ever touch this code make sure you emit zbs otherwise + you get tcl lockups on at least M7/7500 class of chips - airlied */ + /* special r100 case */ + // rmesa->hw.zbs.dirty=1; + + if (!radeon->cmdbuf.cs->cdw) { + if (RADEON_DEBUG & DEBUG_STATE) + fprintf(stderr, "Begin reemit state\n"); + + radeonEmitAtoms(radeon, GL_FALSE); + } + + if (RADEON_DEBUG & DEBUG_STATE) + fprintf(stderr, "Begin dirty state\n"); + + radeonEmitAtoms(radeon, GL_TRUE); + radeon->hw.is_dirty = GL_FALSE; + radeon->hw.all_dirty = GL_FALSE; + +} + /* Make sure all commands have been sent to the hardware and have * completed processing. */ -void radeon_common_finish(GLcontext * ctx) +void radeonFinish(GLcontext * ctx) { radeonContextPtr radeon = RADEON_CONTEXT(ctx); struct gl_framebuffer *fb = ctx->DrawBuffer; int i; + radeonFlush(ctx); + if (radeon->radeonScreen->kernel_mm) { for (i = 0; i < fb->_NumColorDrawBuffers; i++) { struct radeon_renderbuffer *rrb; @@ -611,7 +724,7 @@ int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller) rmesa->cmdbuf.flushing = 1; if (rmesa->cmdbuf.cs->cdw) { ret = radeon_cs_emit(rmesa->cmdbuf.cs); - rmesa->vtbl.set_all_dirty(rmesa->glCtx); + rmesa->hw.all_dirty = GL_TRUE; } radeon_cs_erase(rmesa->cmdbuf.cs); rmesa->cmdbuf.flushing = 0; @@ -650,20 +763,18 @@ void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *ca } } -void rcommonInitCmdBuf(radeonContextPtr rmesa, int max_state_size) +void rcommonInitCmdBuf(radeonContextPtr rmesa) { GLuint size; /* Initialize command buffer */ size = 256 * driQueryOptioni(&rmesa->optionCache, "command_buffer_size"); - if (size < 2 * max_state_size) { - size = 2 * max_state_size + 65535; + if (size < 2 * rmesa->hw.max_state_size) { + size = 2 * rmesa->hw.max_state_size + 65535; } if (size > 64 * 256) size = 64 * 256; - size = 64 * 1024 / 4; - if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) { fprintf(stderr, "sizeof(drm_r300_cmd_header_t)=%zd\n", sizeof(drm_r300_cmd_header_t)); @@ -671,7 +782,7 @@ void rcommonInitCmdBuf(radeonContextPtr rmesa, int max_state_size) sizeof(drm_radeon_cmd_buffer_t)); fprintf(stderr, "Allocating %d bytes command buffer (max state is %d bytes)\n", - size * 4, max_state_size * 4); + size * 4, rmesa->hw.max_state_size * 4); } if (rmesa->radeonScreen->kernel_mm) { @@ -725,7 +836,7 @@ void rcommonBeginBatch(radeonContextPtr rmesa, int n, if (!rmesa->cmdbuf.cs->cdw && dostate) { if (RADEON_DEBUG & DEBUG_IOCTL) fprintf(stderr, "Reemit state after flush (from %s)\n", function); - rmesa->vtbl.emit_state(rmesa); + radeonEmitState(rmesa); } radeon_cs_begin(rmesa->cmdbuf.cs, n, file, function, line); } @@ -927,6 +1038,20 @@ void radeonCleanupContext(radeonContextPtr radeon) } } +/* Force the context `c' to be unbound from its buffer. + */ +GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv) +{ + radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate; + + if (RADEON_DEBUG & DEBUG_DRI) + fprintf(stderr, "%s ctx %p\n", __FUNCTION__, + radeon->glCtx); + + return GL_TRUE; +} + + static void radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon, GLframebuffer *draw) @@ -1810,7 +1935,7 @@ static void radeon_teximage( radeonTexObj* t = radeon_tex_obj(texObj); radeon_texture_image* image = get_radeon_texture_image(texImage); - rmesa->vtbl.flush_vertices(rmesa); + radeon_firevertices(rmesa); t->validated = GL_FALSE; @@ -1968,7 +2093,7 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, int level, radeonTexObj* t = radeon_tex_obj(texObj); radeon_texture_image* image = get_radeon_texture_image(texImage); - rmesa->vtbl.flush_vertices(rmesa); + radeon_firevertices(rmesa); t->validated = GL_FALSE; pixels = _mesa_validate_pbo_teximage(ctx, dims, @@ -2373,7 +2498,7 @@ void radeonSpanRenderStart(GLcontext * ctx) radeonContextPtr rmesa = RADEON_CONTEXT(ctx); int i; - rmesa->vtbl.flush_vertices(rmesa); + radeon_firevertices(rmesa); for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { if (ctx->Texture.Unit[i]._ReallyEnabled) diff --git a/src/mesa/drivers/dri/radeon/common_misc.h b/src/mesa/drivers/dri/radeon/common_misc.h index 80b34aa6bd..ebf287a031 100644 --- a/src/mesa/drivers/dri/radeon/common_misc.h +++ b/src/mesa/drivers/dri/radeon/common_misc.h @@ -6,6 +6,7 @@ void radeonRecalcScissorRects(radeonContextPtr radeon); void radeonSetCliprects(radeonContextPtr radeon); void radeonUpdateScissor( GLcontext *ctx ); +void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h); void radeonWaitForIdleLocked(radeonContextPtr radeon); extern uint32_t radeonGetAge(radeonContextPtr radeon); @@ -26,6 +27,7 @@ GLboolean radeonInitContext(radeonContextPtr radeon, void *sharedContextPrivate); void radeonCleanupContext(radeonContextPtr radeon); +GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv); void radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable); GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, __DRIdrawablePrivate * driDrawPriv, @@ -132,6 +134,9 @@ void rcommon_flush_last_swtcl_prim(GLcontext *ctx); void *rcommonAllocDmaLowVerts(radeonContextPtr rmesa, int nverts, int vsize); +void radeonFlush(GLcontext *ctx); +void radeonFinish(GLcontext * ctx); +void radeonEmitState(radeonContextPtr radeon); static inline struct radeon_renderbuffer *radeon_get_depthbuffer(radeonContextPtr rmesa) { diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index 6fa01f4ded..b25f036c44 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -215,29 +215,17 @@ static void r100_get_lock(radeonContextPtr radeon) } } -static void r100_vtbl_flush(GLcontext *ctx) -{ - RADEON_FIREVERTICES(R100_CONTEXT(ctx)); -} - -static void r100_vtbl_set_all_dirty(GLcontext *ctx) -{ - r100ContextPtr rmesa = R100_CONTEXT(ctx); - rmesa->hw.all_dirty = GL_TRUE; -} - static void r100_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmesa) { } -static void r100_vtbl_emit_state(radeonContextPtr rmesa) +static void r100_vtbl_pre_emit_state(radeonContextPtr radeon) { - radeonEmitState((r100ContextPtr)rmesa); -} - -static void r100_vtbl_flush_vertices(radeonContextPtr rmesa) -{ - RADEON_FIREVERTICES(((r100ContextPtr)rmesa)); + r100ContextPtr rmesa = (r100ContextPtr)radeon; + + /* r100 always needs to emit ZBS to avoid TCL lockups */ + rmesa->hw.zbs.dirty = 1; + radeon->hw.is_dirty = 1; } @@ -245,13 +233,10 @@ static void r100_init_vtbl(radeonContextPtr radeon) { radeon->vtbl.get_lock = r100_get_lock; radeon->vtbl.update_viewport_offset = radeonUpdateViewportOffset; - radeon->vtbl.flush = r100_vtbl_flush; - radeon->vtbl.set_all_dirty = r100_vtbl_set_all_dirty; radeon->vtbl.update_draw_buffer = radeonUpdateDrawBuffer; radeon->vtbl.emit_cs_header = r100_vtbl_emit_cs_header; - radeon->vtbl.emit_state = r100_vtbl_emit_state; radeon->vtbl.swtcl_flush = r100_swtcl_flush; - radeon->vtbl.flush_vertices = r100_vtbl_flush_vertices; + radeon->vtbl.pre_emit_state = r100_vtbl_pre_emit_state; } /* Create the device specific context. @@ -344,7 +329,7 @@ radeonCreateContext( const __GLcontextModes *glVisual, DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16; rmesa->radeon.swtcl.RenderIndex = ~0; - rmesa->hw.all_dirty = GL_TRUE; + rmesa->radeon.hw.all_dirty = GL_TRUE; /* Set the maximum texture size small enough that we can guarentee that * all texture units can bind a maximal texture and have all of them in @@ -503,7 +488,7 @@ void radeonDestroyContext( __DRIcontextPrivate *driContextPriv ) /* check if we're deleting the currently bound context */ if (rmesa == current) { - RADEON_FIREVERTICES( rmesa ); + radeon_firevertices(&rmesa->radeon); _mesa_make_current(NULL, NULL, NULL); } @@ -553,16 +538,3 @@ void radeonDestroyContext( __DRIcontextPrivate *driContextPriv ) } } - -/* Force the context `c' to be unbound from its buffer. - */ -GLboolean -radeonUnbindContext( __DRIcontextPrivate *driContextPriv ) -{ - r100ContextPtr rmesa = (r100ContextPtr) driContextPriv->driverPrivate; - - if (RADEON_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *) rmesa->radeon.glCtx); - - return GL_TRUE; -} diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h index 358095a2b9..d05e47f16e 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_context.h @@ -296,10 +296,7 @@ struct radeon_texture_state { #define SHN_SHININESS 1 #define SHN_STATE_SIZE 2 -struct radeon_hw_state { - /* Head of the linked list of state atoms. */ - struct radeon_state_atom atomlist; - +struct r100_hw_state { /* Hardware state, stored as cmdbuf commands: * -- Need to doublebuffer for * - eliding noop statechange loops? (except line stipple count) @@ -324,8 +321,6 @@ struct radeon_hw_state { struct radeon_state_atom glt; struct radeon_state_atom txr[3]; /* for NPOT */ - int max_state_size; /* Number of bytes necessary for a full state emit. */ - GLboolean is_dirty, all_dirty; }; @@ -354,14 +349,6 @@ struct radeon_tcl_info { struct radeon_bo *indexed_bo; -// struct radeon_dma_region indexed_verts; - struct radeon_dma_region obj; - struct radeon_dma_region rgba; - struct radeon_dma_region spec; - struct radeon_dma_region fog; - struct radeon_dma_region tex[RADEON_MAX_TEXTURE_UNITS]; - struct radeon_dma_region norm; - int elt_cmd_offset; /** Offset into the cmdbuf */ int elt_cmd_start; int elt_used; @@ -391,8 +378,6 @@ struct r100_swtcl_info { GLuint specoffset; GLboolean needproj; - - struct radeon_dma_region indexed_verts; }; @@ -411,17 +396,13 @@ struct r100_context { /* Driver and hardware state management */ - struct radeon_hw_state hw; + struct r100_hw_state hw; struct r100_state state; /* Vertex buffers */ struct radeon_ioctl ioctl; struct radeon_store store; - /* A full state emit as of the first state emit in the main store, in case - * the context is lost. - */ - struct radeon_store backup_store; /* TCL stuff */ @@ -455,7 +436,6 @@ struct r100_context { GLuint c_textureBytes; GLuint c_vertexBuffers; - GLboolean save_on_next_emit; }; #define R100_CONTEXT(ctx) ((r100ContextPtr)(ctx->DriverCtx)) diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index 45d750dbf4..d0cd9ce7a6 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -59,60 +59,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define RADEON_TIMEOUT 512 #define RADEON_IDLE_RETRY 16 -#define DEBUG_CMDBUF 1 - -static void radeonSaveHwState( r100ContextPtr rmesa ) -{ - struct radeon_state_atom *atom; - char * dest = rmesa->backup_store.cmd_buf; - - if (RADEON_DEBUG & DEBUG_STATE) - fprintf(stderr, "%s\n", __FUNCTION__); - - rmesa->backup_store.cmd_used = 0; - - foreach( atom, &rmesa->hw.atomlist ) { - if ( atom->check( rmesa->radeon.glCtx, 0 ) ) { - int size = atom->cmd_size * 4; - memcpy( dest, atom->cmd, size); - dest += size; - rmesa->backup_store.cmd_used += size; - if (RADEON_DEBUG & DEBUG_STATE) - radeon_print_state_atom( atom ); - } - } - - assert( rmesa->backup_store.cmd_used <= RADEON_CMD_BUF_SZ ); - if (RADEON_DEBUG & DEBUG_STATE) - fprintf(stderr, "Returning to radeonEmitState\n"); -} - -/* At this point we were in FlushCmdBufLocked but we had lost our context, so - * we need to unwire our current cmdbuf, hook the one with the saved state in - * it, flush it, and then put the current one back. This is so commands at the - * start of a cmdbuf can rely on the state being kept from the previous one. - */ -static void radeonBackUpAndEmitLostStateLocked( r100ContextPtr rmesa ) -{ - GLuint nr_released_bufs; - struct radeon_store saved_store; - - if (rmesa->backup_store.cmd_used == 0) - return; - - if (RADEON_DEBUG & DEBUG_STATE) - fprintf(stderr, "Emitting backup state on lost context\n"); - - rmesa->radeon.lost_context = GL_FALSE; - - nr_released_bufs = rmesa->radeon.dma.nr_released_bufs; - saved_store = rmesa->store; - rmesa->radeon.dma.nr_released_bufs = 0; - rmesa->store = rmesa->backup_store; - rcommonFlushCmdBufLocked( &rmesa->radeon, __FUNCTION__ ); - rmesa->radeon.dma.nr_released_bufs = nr_released_bufs; - rmesa->store = saved_store; -} /* ============================================================= * Kernel command buffer handling @@ -125,107 +71,33 @@ void radeonSetUpAtomList( r100ContextPtr rmesa ) { int i, mtu = rmesa->radeon.glCtx->Const.MaxTextureUnits; - make_empty_list(&rmesa->hw.atomlist); - rmesa->hw.atomlist.name = "atom-list"; + make_empty_list(&rmesa->radeon.hw.atomlist); + rmesa->radeon.hw.atomlist.name = "atom-list"; - insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.ctx); - insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.set); - insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.lin); - insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.msk); - insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.vpt); - insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.tcl); - insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.msc); + insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.ctx); + insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.set); + insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.lin); + insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.msk); + insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.vpt); + insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.tcl); + insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.msc); for (i = 0; i < mtu; ++i) { - insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.tex[i]); - insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.txr[i]); - insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.cube[i]); + insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.tex[i]); + insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.txr[i]); + insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.cube[i]); } - insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.zbs); - insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.mtl); + insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.zbs); + insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.mtl); for (i = 0; i < 3 + mtu; ++i) - insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.mat[i]); + insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.mat[i]); for (i = 0; i < 8; ++i) - insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.lit[i]); + insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.lit[i]); for (i = 0; i < 6; ++i) - insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.ucp[i]); - insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.eye); - insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.grd); - insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.fog); - insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.glt); -} - -static INLINE void radeonEmitAtoms(r100ContextPtr r100, GLboolean dirty) -{ - BATCH_LOCALS(&r100->radeon); - struct radeon_state_atom *atom; - int dwords; - - /* Emit actual atoms */ - foreach(atom, &r100->hw.atomlist) { - if ((atom->dirty || r100->hw.all_dirty) == dirty) { - dwords = (*atom->check) (r100->radeon.glCtx, atom); - if (dwords) { - if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) { - radeon_print_state_atom(atom); - } - if (atom->emit) { - (*atom->emit)(r100->radeon.glCtx, atom); - } else { - BEGIN_BATCH_NO_AUTOSTATE(dwords); - OUT_BATCH_TABLE(atom->cmd, dwords); - END_BATCH(); - } - atom->dirty = GL_FALSE; - } else { - if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) { - fprintf(stderr, " skip state %s\n", - atom->name); - } - } - } - } - - COMMIT_BATCH(); -} - -void radeonEmitState( r100ContextPtr rmesa ) -{ - if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS)) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (rmesa->save_on_next_emit) { - radeonSaveHwState(rmesa); - rmesa->save_on_next_emit = GL_FALSE; - } - - /* this code used to return here but now it emits zbs */ - - /* To avoid going across the entire set of states multiple times, just check - * for enough space for the case of emitting all state, and inline the - * radeonAllocCmdBuf code here without all the checks. - */ - rcommonEnsureCmdBufSpace(&rmesa->radeon, rmesa->hw.max_state_size, __FUNCTION__); - - /* We always always emit zbs, this is due to a bug found by keithw in - the hardware and rediscovered after Erics changes by me. - if you ever touch this code make sure you emit zbs otherwise - you get tcl lockups on at least M7/7500 class of chips - airlied */ - rmesa->hw.zbs.dirty=1; - - if (!rmesa->radeon.cmdbuf.cs->cdw) { - if (RADEON_DEBUG & DEBUG_STATE) - fprintf(stderr, "Begin reemit state\n"); - - radeonEmitAtoms(rmesa, GL_FALSE); - } - - if (RADEON_DEBUG & DEBUG_STATE) - fprintf(stderr, "Begin dirty state\n"); - - radeonEmitAtoms(rmesa, GL_TRUE); - rmesa->hw.is_dirty = GL_FALSE; - rmesa->hw.all_dirty = GL_FALSE; - + insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.ucp[i]); + insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.eye); + insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.grd); + insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.fog); + insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.glt); } /* Fire a section of the retained (indexed_verts) buffer as a regular @@ -240,7 +112,7 @@ extern void radeonEmitVbufPrim( r100ContextPtr rmesa, assert(!(primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND)); - radeonEmitState( rmesa ); + radeonEmitState(&rmesa->radeon); #if RADEON_OLD_PACKETS BEGIN_BATCH(8); @@ -318,7 +190,7 @@ GLushort *radeonAllocEltsOpenEnded( r100ContextPtr rmesa, assert((primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND)); - radeonEmitState( rmesa ); + radeonEmitState(&rmesa->radeon); rmesa->tcl.elt_cmd_start = rmesa->radeon.cmdbuf.cs->cdw; @@ -679,35 +551,9 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask ) } UNLOCK_HARDWARE( &rmesa->radeon ); - rmesa->hw.all_dirty = GL_TRUE; -} - -void radeonFlush( GLcontext *ctx ) -{ - r100ContextPtr rmesa = R100_CONTEXT( ctx ); - - if (RADEON_DEBUG & DEBUG_IOCTL) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (rmesa->radeon.dma.flush) - rmesa->radeon.dma.flush( ctx ); - - radeonEmitState( rmesa ); - - if (rmesa->radeon.cmdbuf.cs->cdw) - rcommonFlushCmdBuf( &rmesa->radeon, __FUNCTION__ ); -} - -/* Make sure all commands have been sent to the hardware and have - * completed processing. - */ -void radeonFinish( GLcontext *ctx ) -{ - radeonFlush( ctx ); - radeon_common_finish(ctx); + rmesa->radeon.hw.all_dirty = GL_TRUE; } - void radeonInitIoctlFuncs( GLcontext *ctx ) { ctx->Driver.Clear = radeonClear; diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.h b/src/mesa/drivers/dri/radeon/radeon_ioctl.h index 4e93804646..6d616bf804 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.h +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.h @@ -40,7 +40,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_lock.h" #include "radeon_cs_legacy.h" -extern void radeonEmitState( r100ContextPtr rmesa ); extern void radeonEmitVertexAOS( r100ContextPtr rmesa, GLuint vertex_size, struct radeon_bo *bo, @@ -104,7 +103,7 @@ do { \ do { \ RADEON_NEWPRIM( rmesa ); \ rmesa->hw.ATOM.dirty = GL_TRUE; \ - rmesa->hw.is_dirty = GL_TRUE; \ + rmesa->radeon.hw.is_dirty = GL_TRUE; \ } while (0) #define RADEON_DB_STATE( ATOM ) \ @@ -118,7 +117,7 @@ static INLINE int RADEON_DB_STATECHANGE(r100ContextPtr rmesa, GLuint *tmp; RADEON_NEWPRIM( rmesa ); atom->dirty = GL_TRUE; - rmesa->hw.is_dirty = GL_TRUE; + rmesa->radeon.hw.is_dirty = GL_TRUE; tmp = atom->cmd; atom->cmd = atom->lastcmd; atom->lastcmd = tmp; @@ -128,15 +127,6 @@ static INLINE int RADEON_DB_STATECHANGE(r100ContextPtr rmesa, return 0; } -/* Fire the buffered vertices no matter what. - */ -#define RADEON_FIREVERTICES( rmesa ) \ -do { \ - if (rmesa->radeon.cmdbuf.cs->cdw || rmesa->radeon.dma.flush ) { \ - radeonFlush( rmesa->radeon.glCtx ); \ - } \ -} while (0) - /* Command lengths. Note that any time you ensure ELTS_BUFSZ or VBUF_BUFSZ * are available, you will also be adding an rmesa->state.max_state_size because * r200EmitState is called from within r200EmitVbufPrim and r200FlushElts. diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 497582ee23..7397218fb6 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -1523,7 +1523,7 @@ const struct __DriverAPIRec driDriverAPI = { .DestroyBuffer = radeonDestroyBuffer, .SwapBuffers = radeonSwapBuffers, .MakeCurrent = radeonMakeCurrent, - .UnbindContext = r200UnbindContext, + .UnbindContext = radeonUnbindContext, .GetSwapInfo = getSwapInfo, .GetDrawableMSC = driDrawableGetMSC32, .WaitForMSC = driWaitForMSC32, diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index 1d683e5b3a..a9ec1d51c7 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -47,6 +47,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast_setup/swrast_setup.h" #include "radeon_context.h" +#include "common_cmdbuf.h" #include "radeon_ioctl.h" #include "radeon_state.h" #include "radeon_tcl.h" @@ -406,23 +407,6 @@ static void radeonFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) } } - -/* ============================================================= - * Scissoring - */ -static void radeonScissor( GLcontext *ctx, - GLint x, GLint y, GLsizei w, GLsizei h ) -{ - r100ContextPtr rmesa = R100_CONTEXT(ctx); - - if ( ctx->Scissor.Enabled ) { - RADEON_FIREVERTICES( rmesa ); /* don't pipeline cliprect changes */ - radeonUpdateScissor( ctx ); - } - -} - - /* ============================================================= * Culling */ @@ -567,7 +551,7 @@ static void radeonPolygonStipple( GLcontext *ctx, const GLubyte *mask ) /* TODO: push this into cmd mechanism */ - RADEON_FIREVERTICES( rmesa ); + radeon_firevertices(&rmesa->radeon); LOCK_HARDWARE( &rmesa->radeon ); /* FIXME: Use window x,y offsets into stipple RAM. @@ -1415,7 +1399,7 @@ void radeonUpdateWindow( GLcontext *ctx ) float_ui32_type sz = { v[MAT_SZ] * rmesa->radeon.state.depth.scale }; float_ui32_type tz = { v[MAT_TZ] * rmesa->radeon.state.depth.scale }; - RADEON_FIREVERTICES( rmesa ); + radeon_firevertices(&rmesa->radeon); RADEON_STATECHANGE( rmesa, vpt ); rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = sx.ui32; @@ -1561,7 +1545,7 @@ static void radeonDrawBuffer( GLcontext *ctx, GLenum mode ) fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr( mode )); - RADEON_FIREVERTICES(rmesa); /* don't pipeline cliprect changes */ + radeon_firevertices(&rmesa->radeon); /* don't pipeline cliprect changes */ if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) { /* 0 (GL_NONE) buffers or multiple color drawing buffers */ @@ -1843,7 +1827,7 @@ static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state ) } case GL_SCISSOR_TEST: - RADEON_FIREVERTICES( rmesa ); + radeon_firevertices(&rmesa->radeon); rmesa->radeon.state.scissor.enabled = state; radeonUpdateScissor( ctx ); break; diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c index f12d9bdb50..1cfb539e71 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state_init.c +++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c @@ -171,8 +171,8 @@ void radeonPrintDirty( r100ContextPtr rmesa, const char *msg ) fprintf(stderr, msg); fprintf(stderr, ": "); - foreach(l, &rmesa->hw.atomlist) { - if (l->dirty || rmesa->hw.all_dirty) + foreach(l, &rmesa->radeon.hw.atomlist) { + if (l->dirty || rmesa->radeon.hw.all_dirty) fprintf(stderr, "%s, ", l->name); } @@ -512,7 +512,7 @@ void radeonInitState( r100ContextPtr rmesa ) drawPitch = rmesa->radeon.radeonScreen->frontPitch; } - rmesa->hw.max_state_size = 0; + rmesa->radeon.hw.max_state_size = 0; #define ALLOC_STATE_IDX( ATOM, CHK, SZ, NM, FLAG, IDX ) \ do { \ @@ -524,7 +524,7 @@ void radeonInitState( r100ContextPtr rmesa ) rmesa->hw.ATOM.check = check_##CHK; \ rmesa->hw.ATOM.dirty = GL_TRUE; \ rmesa->hw.ATOM.idx = IDX; \ - rmesa->hw.max_state_size += SZ * sizeof(int); \ + rmesa->radeon.hw.max_state_size += SZ * sizeof(int); \ } while (0) #define ALLOC_STATE( ATOM, CHK, SZ, NM, FLAG ) \ @@ -932,7 +932,7 @@ void radeonInitState( r100ContextPtr rmesa ) rmesa->hw.eye.cmd[EYE_Z] = IEEE_ONE; rmesa->hw.eye.cmd[EYE_RESCALE_FACTOR] = IEEE_ONE; - rmesa->hw.all_dirty = GL_TRUE; + rmesa->radeon.hw.all_dirty = GL_TRUE; - rcommonInitCmdBuf(&rmesa->radeon, rmesa->hw.max_state_size); + rcommonInitCmdBuf(&rmesa->radeon); } diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.c b/src/mesa/drivers/dri/radeon/radeon_swtcl.c index 615621dd98..995ab2099e 100644 --- a/src/mesa/drivers/dri/radeon/radeon_swtcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.c @@ -285,11 +285,11 @@ void r100_swtcl_flush(GLcontext *ctx, uint32_t current_offset) r100ContextPtr rmesa = R100_CONTEXT(ctx); rcommonEnsureCmdBufSpace(&rmesa->radeon, - rmesa->hw.max_state_size + (12*sizeof(int)), + rmesa->radeon.hw.max_state_size + (12*sizeof(int)), __FUNCTION__); - radeonEmitState(rmesa); + radeonEmitState(&rmesa->radeon); radeonEmitVertexAOS( rmesa, rmesa->radeon.swtcl.vertex_size, rmesa->radeon.dma.current, @@ -372,9 +372,6 @@ static GLboolean radeon_run_render( GLcontext *ctx, tnl_render_func *tab = TAG(render_tab_verts); GLuint i; - if (rmesa->swtcl.indexed_verts.buf) - RELEASE_ELT_VERTS(); - if (rmesa->radeon.swtcl.RenderIndex != 0 || !radeon_dma_validate_render( ctx, VB )) return GL_TRUE; @@ -750,7 +747,7 @@ void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) if (mode) { rmesa->radeon.Fallback |= bit; if (oldfallback == 0) { - RADEON_FIREVERTICES( rmesa ); + radeon_firevertices(&rmesa->radeon); TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_RASTER, GL_TRUE ); _swsetup_Wakeup( ctx ); rmesa->radeon.swtcl.RenderIndex = ~0; @@ -831,7 +828,4 @@ void radeonDestroySwtcl( GLcontext *ctx ) { r100ContextPtr rmesa = R100_CONTEXT(ctx); - // if (rmesa->swtcl.indexed_verts.buf) - // radeonReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, - // __FUNCTION__ ); } diff --git a/src/mesa/drivers/dri/radeon/radeon_tcl.c b/src/mesa/drivers/dri/radeon/radeon_tcl.c index daa88f43c7..7281800ce2 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_tcl.c @@ -126,7 +126,7 @@ static GLboolean discrete_prim[0x10] = { #define RESET_STIPPLE() do { \ RADEON_STATECHANGE( rmesa, lin ); \ - radeonEmitState( rmesa ); \ + radeonEmitState(&rmesa->radeon); \ } while (0) #define AUTO_STIPPLE( mode ) do { \ @@ -137,7 +137,7 @@ static GLboolean discrete_prim[0x10] = { else \ rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] &= \ ~RADEON_LINE_PATTERN_AUTO_RESET; \ - radeonEmitState( rmesa ); \ + radeonEmitState(&rmesa->radeon); \ } while (0) @@ -149,7 +149,7 @@ static GLushort *radeonAllocElts( r100ContextPtr rmesa, GLuint nr ) if (rmesa->radeon.dma.flush) rmesa->radeon.dma.flush( rmesa->radeon.glCtx ); - rcommonEnsureCmdBufSpace(&rmesa->radeon, rmesa->hw.max_state_size + ELTS_BUFSZ(nr) + + rcommonEnsureCmdBufSpace(&rmesa->radeon, rmesa->radeon.hw.max_state_size + ELTS_BUFSZ(nr) + AOS_BUFSZ(rmesa->tcl.nr_aos_components), __FUNCTION__); radeonEmitAOS( rmesa, @@ -178,7 +178,7 @@ static void radeonEmitPrim( GLcontext *ctx, rcommonEnsureCmdBufSpace( &rmesa->radeon, AOS_BUFSZ(rmesa->tcl.nr_aos_components) + - rmesa->hw.max_state_size + VBUF_BUFSZ, __FUNCTION__ ); + rmesa->radeon.hw.max_state_size + VBUF_BUFSZ, __FUNCTION__ ); radeonEmitAOS( rmesa, rmesa->tcl.nr_aos_components, diff --git a/src/mesa/drivers/dri/radeon/radeon_tex.c b/src/mesa/drivers/dri/radeon/radeon_tex.c index a916b63a27..e1b988bf4d 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tex.c +++ b/src/mesa/drivers/dri/radeon/radeon_tex.c @@ -381,7 +381,7 @@ static void radeonDeleteTexture( GLcontext *ctx, } if ( rmesa ) { - RADEON_FIREVERTICES( rmesa ); + radeon_firevertices(&rmesa->radeon); 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; |