Merge branch 'master' of ssh://git.freedesktop.org/git/mesa/mesa into r600_state_predict

Conflicts:
	src/mesa/drivers/dri/r300/r300_cmdbuf.c
	src/mesa/drivers/dri/radeon/radeon_cmdbuf.h
This commit is contained in:
Pauli Nieminen
2009-08-24 00:57:05 +03:00
52 changed files with 14093 additions and 8468 deletions
+52 -21
View File
@@ -44,14 +44,6 @@
#include "util/u_memory.h"
static void
dri_copy_to_front(__DRIdrawablePrivate * dPriv,
struct pipe_surface *from,
int x, int y, unsigned w, unsigned h)
{
/* TODO send a message to the Xserver to copy to the real front buffer */
}
static struct pipe_surface *
dri_surface_from_handle(struct drm_api *api,
struct pipe_screen *screen,
@@ -95,6 +87,35 @@ dri_surface_from_handle(struct drm_api *api,
return surface;
}
/**
* Pixmaps have will have the same name of fake front and front.
*/
static boolean
dri2_check_if_pixmap(__DRIbuffer *buffers, int count)
{
boolean found = FALSE;
boolean is_pixmap = FALSE;
unsigned name;
int i;
for (i = 0; i < count; i++) {
switch (buffers[i].attachment) {
case __DRI_BUFFER_FRONT_LEFT:
case __DRI_BUFFER_FAKE_FRONT_LEFT:
if (found) {
is_pixmap = buffers[i].name == name;
} else {
name = buffers[i].name;
found = TRUE;
}
default:
continue;
}
}
return is_pixmap;
}
/**
* This will be called a drawable is known to have been resized.
*/
@@ -153,15 +174,15 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv)
memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * count);
}
drawable->is_pixmap = dri2_check_if_pixmap(buffers, count);
for (i = 0; i < count; i++) {
enum pipe_format format = 0;
int index = 0;
switch (buffers[i].attachment) {
case __DRI_BUFFER_FRONT_LEFT:
index = ST_SURFACE_FRONT_LEFT;
format = drawable->color_format;
break;
continue;
case __DRI_BUFFER_FAKE_FRONT_LEFT:
index = ST_SURFACE_FRONT_LEFT;
format = drawable->color_format;
@@ -233,8 +254,25 @@ dri_flush_frontbuffer(struct pipe_screen *screen,
struct pipe_surface *surf, void *context_private)
{
struct dri_context *ctx = (struct dri_context *)context_private;
struct dri_drawable *drawable = dri_drawable(ctx->dPriv);
__DRIdrawable *dri_drawable = ctx->dPriv;
__DRIscreen *dri_screen = ctx->sPriv;
dri_copy_to_front(ctx->dPriv, surf, 0, 0, surf->width, surf->height);
/* XXX Does this function get called with DRI1? */
if (ctx->dPriv == NULL) {
debug_printf("%s: no drawable bound to context\n", __func__);
return;
}
#if 0
/* TODO if rendering to pixmaps is slow enable this code. */
if (drawable->is_pixmap)
return;
#endif
(*dri_screen->dri2.loader->flushFrontBuffer)(dri_drawable,
dri_drawable->loaderPrivate);
}
/**
@@ -259,26 +297,20 @@ dri_create_buffer(__DRIscreenPrivate * sPriv,
drawable->color_format = (visual->redBits == 8) ?
PIPE_FORMAT_A8R8G8B8_UNORM : PIPE_FORMAT_R5G6B5_UNORM;
debug_printf("Red bits is %d\n", visual->redBits);
switch(visual->depthBits) {
default:
case 0:
debug_printf("Depth buffer 0.\n");
drawable->depth_format = PIPE_FORMAT_NONE;
break;
case 16:
debug_printf("Depth buffer 16.\n");
drawable->depth_format = PIPE_FORMAT_Z16_UNORM;
break;
case 24:
if (visual->stencilBits == 0) {
debug_printf("Depth buffer 24. Stencil 0.\n");
drawable->depth_format = (screen->d_depth_bits_last) ?
PIPE_FORMAT_X8Z24_UNORM:
PIPE_FORMAT_Z24X8_UNORM;
} else {
debug_printf("Combined depth stencil 24 / 8.\n");
drawable->depth_format = (screen->sd_depth_bits_last) ?
PIPE_FORMAT_S8Z24_UNORM:
PIPE_FORMAT_Z24S8_UNORM;
@@ -312,12 +344,11 @@ dri_create_buffer(__DRIscreenPrivate * sPriv,
dPriv->driverPrivate = (void *)drawable;
/* setup dri2 buffers information */
/* TODO incase of double buffer visual, delay fake creation */
i = 0;
drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
#if 0
/* TODO incase of double buffer visual, delay fake creation */
drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
#endif
if (visual->doubleBufferMode)
drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
if (visual->depthBits)
@@ -46,6 +46,8 @@ struct dri_drawable
unsigned attachments[8];
unsigned num_attachments;
boolean is_pixmap;
__DRIbuffer old[8];
unsigned old_num;
unsigned old_w;
@@ -97,6 +97,11 @@ driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
tex = ms->screen->texture_create(ms->screen, &template);
depth = tex;
} else if (attachments[i] == DRI2BufferFakeFrontLeft &&
pDraw->type == DRAWABLE_PIXMAP) {
pPixmap = (PixmapPtr) pDraw;
pPixmap->refcnt++;
tex = xorg_exa_get_texture(pPixmap);
} else {
pPixmap = (*pScreen->CreatePixmap)(pScreen, pDraw->width,
pDraw->height,
@@ -171,12 +176,53 @@ driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
GCPtr gc;
RegionPtr copy_clip;
/*
* In driCreateBuffers we dewrap windows into the
* backing pixmaps in order to get to the texture.
* We need to use the real drawable in CopyArea
* so that cliprects and offsets are correct.
*/
src_pixmap = src_priv->pPixmap;
dst_pixmap = dst_priv->pPixmap;
if (pSrcBuffer->attachment == DRI2BufferFrontLeft)
src_pixmap = (PixmapPtr)pDraw;
if (pDestBuffer->attachment == DRI2BufferFrontLeft)
dst_pixmap = (PixmapPtr)pDraw;
/*
* The clients implements glXWaitX with a copy front to fake and then
* waiting on the server to signal its completion of it. While
* glXWaitGL is a client side flush and a copy from fake to front.
* This is how it is done in the DRI2 protocol, how ever depending
* which type of drawables the server does things a bit differently
* then what the protocol says as the fake and front are the same.
*
* for pixmaps glXWaitX is a server flush.
* for pixmaps glXWaitGL is a client flush.
* for windows glXWaitX is a copy from front to fake then a server flush.
* for windows glXWaitGL is a client flush then a copy from fake to front.
*
* XXX in the windows case this code always flushes but that isn't a
* must in the glXWaitGL case but we don't know if this is a glXWaitGL
* or a glFlush/glFinish call.
*/
if (dst_pixmap == src_pixmap) {
/* pixmap glXWaitX */
if (pSrcBuffer->attachment == DRI2BufferFrontLeft &&
pDestBuffer->attachment == DRI2BufferFakeFrontLeft) {
ms->ctx->flush(ms->ctx, PIPE_FLUSH_SWAPBUFFERS, NULL);
return;
}
/* pixmap glXWaitGL */
if (pDestBuffer->attachment == DRI2BufferFrontLeft &&
pSrcBuffer->attachment == DRI2BufferFakeFrontLeft) {
return;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"copying between the same pixmap\n");
}
}
gc = GetScratchGC(pDraw->depth, pScreen);
copy_clip = REGION_CREATE(pScreen, NULL, 0);
REGION_COPY(pScreen, copy_clip, pRegion);
@@ -57,9 +57,6 @@ intel_be_batch_flush(struct i915_winsys *sws,
struct intel_be_context *intel = intel_be_context(sws);
struct intel_be_fence **f = (struct intel_be_fence **)fence;
if (fence && *fence)
assert(0);
intel_be_batchbuffer_flush(intel->batch, f);
}
+5 -5
View File
@@ -159,7 +159,7 @@ dri2DestroyDrawable(__GLXDRIdrawable * pdraw)
const __DRIcoreExtension *core = pdraw->psc->core;
(*core->destroyDrawable) (pdraw->driDrawable);
DRI2DestroyDrawable(pdraw->psc->dpy, pdraw->drawable);
DRI2DestroyDrawable(pdraw->psc->dpy, pdraw->xDrawable);
Xfree(pdraw);
}
@@ -189,7 +189,7 @@ dri2CreateDrawable(__GLXscreenConfigs * psc,
config->driConfig, pdraw);
if (!pdraw->base.driDrawable) {
DRI2DestroyDrawable(psc->dpy, drawable);
DRI2DestroyDrawable(psc->dpy, xDrawable);
Xfree(pdraw);
return NULL;
}
@@ -221,7 +221,7 @@ dri2CopySubBuffer(__GLXDRIdrawable * pdraw,
region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
/* should get a fence ID back from here at some point */
DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region,
DRI2CopyRegion(pdraw->psc->dpy, pdraw->xDrawable, region,
DRI2BufferFrontLeft, DRI2BufferBackLeft);
XFixesDestroyRegion(pdraw->psc->dpy, region);
@@ -261,7 +261,7 @@ dri2WaitX(__GLXDRIdrawable * pdraw)
#endif
region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region,
DRI2CopyRegion(pdraw->psc->dpy, pdraw->xDrawable, region,
DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
XFixesDestroyRegion(pdraw->psc->dpy, region);
}
@@ -287,7 +287,7 @@ dri2WaitGL(__GLXDRIdrawable * pdraw)
#endif
region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region,
DRI2CopyRegion(pdraw->psc->dpy, pdraw->xDrawable, region,
DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
XFixesDestroyRegion(pdraw->psc->dpy, region);
}
+6 -6
View File
@@ -1960,7 +1960,7 @@ __glXBeginFrameTrackingMESA(Display * dpy, GLXDrawable drawable)
{
int status = GLX_BAD_CONTEXT;
#ifdef __DRI_FRAME_TRACKING
int screen;
int screen = 0;
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
__GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
@@ -1979,7 +1979,7 @@ __glXEndFrameTrackingMESA(Display * dpy, GLXDrawable drawable)
{
int status = GLX_BAD_CONTEXT;
#ifdef __DRI_FRAME_TRACKING
int screen;
int screen = 0;
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
__GLXscreenConfigs *psc = GetGLXScreenConfigs(dpy, screen);
@@ -1999,7 +1999,7 @@ __glXGetFrameUsageMESA(Display * dpy, GLXDrawable drawable, GLfloat * usage)
{
int status = GLX_BAD_CONTEXT;
#ifdef __DRI_FRAME_TRACKING
int screen;
int screen = 0;
__GLXDRIdrawable *const pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
__GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
@@ -2029,7 +2029,7 @@ __glXQueryFrameTrackingMESA(Display * dpy, GLXDrawable drawable,
{
int status = GLX_BAD_CONTEXT;
#ifdef __DRI_FRAME_TRACKING
int screen;
int screen = 0;
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
__GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
@@ -2213,7 +2213,7 @@ PUBLIC GLXFBConfigSGIX
glXGetFBConfigFromVisualSGIX(Display * dpy, XVisualInfo * vis)
{
__GLXdisplayPrivate *priv;
__GLXscreenConfigs *psc;
__GLXscreenConfigs *psc = NULL;
if ((GetGLXPrivScreenConfig(dpy, vis->screen, &priv, &psc) != Success)
&& __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit)
@@ -2432,7 +2432,7 @@ __glXWaitForMscOML(Display * dpy, GLXDrawable drawable,
int64_t * msc, int64_t * sbc)
{
#ifdef __DRI_MEDIA_STREAM_COUNTER
int screen;
int screen = 0;
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
__GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
int ret;
+5 -3
View File
@@ -588,17 +588,19 @@ static void emit_dph( struct brw_compile *p,
const struct brw_reg *arg0,
const struct brw_reg *arg1 )
{
const int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
if (!(mask & WRITEMASK_XYZW))
return; /* Do not emit dead code */
assert((mask & WRITEMASK_XYZW) == WRITEMASK_X);
assert(is_power_of_two(mask & WRITEMASK_XYZW));
brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]);
brw_MAC(p, brw_null_reg(), arg0[1], arg1[1]);
brw_MAC(p, dst[0], arg0[2], arg1[2]);
brw_MAC(p, dst[dst_chan], arg0[2], arg1[2]);
brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
brw_ADD(p, dst[0], dst[0], arg1[3]);
brw_ADD(p, dst[dst_chan], dst[dst_chan], arg1[3]);
brw_set_saturate(p, 0);
}
+2 -2
View File
@@ -105,7 +105,7 @@ void emit_vpu(GLcontext *ctx, struct radeon_state_atom * atom)
ndw -= 5;
OUT_BATCH_REGVAL(R300_VAP_PVS_VECTOR_INDX_REG, addr);
OUT_BATCH(CP_PACKET0(R300_VAP_PVS_UPLOAD_DATA, ndw-1) | RADEON_ONE_REG_WR);
OUT_BATCH_TABLE(atom->cmd + 1, ndw);
OUT_BATCH_TABLE(&atom->cmd[1], ndw);
OUT_BATCH_REGVAL(R300_VAP_PVS_STATE_FLUSH_REG, 0);
END_BATCH();
}
@@ -134,7 +134,7 @@ void emit_r500fp(GLcontext *ctx, struct radeon_state_atom * atom)
OUT_BATCH(addr);
ndw-=3;
OUT_BATCH(CP_PACKET0(R500_GA_US_VECTOR_DATA, ndw-1) | RADEON_ONE_REG_WR);
OUT_BATCH_TABLE(atom->cmd + 1, ndw);
OUT_BATCH_TABLE(&atom->cmd[1], ndw);
END_BATCH();
}
+3 -3
View File
@@ -109,11 +109,11 @@ static void r300FixupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer
#if MESA_BIG_ENDIAN
} else { /* if (mesa_ind_buf->type == GL_UNSIGNED_SHORT) */
GLuint size;
GLushort *in = (GLushort *)src_ptr;
size = sizeof(GLushort) * ((mesa_ind_buf->count + 1) & ~1);
GLuint size = sizeof(GLushort) * ((mesa_ind_buf->count + 1) & ~1);
radeonAllocDmaRegion(&r300->radeon, &r300->ind_buf.bo, &r300->ind_buf.bo_offet, size, 4);
radeonAllocDmaRegion(&r300->radeon, &r300->ind_buf.bo,
&r300->ind_buf.bo_offset, size, 4);
assert(r300->ind_buf.bo->ptr != NULL);
out = (GLuint *)ADD_POINTERS(r300->ind_buf.bo->ptr, r300->ind_buf.bo_offset);
+1 -1
View File
@@ -390,7 +390,7 @@ void r300RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim)
GLuint first, incr, offset = 0;
if (!split_prim_inplace(prim & PRIM_MODE_MASK, &first, &incr) &&
num_verts > 65500) {
num_verts > 65535) {
WARN_ONCE("Fixme: can't handle spliting prim %d\n", prim);
return;
}
+1 -1
View File
@@ -322,7 +322,7 @@ static int r600_cs_emit(struct radeon_cs *cs)
struct drm_radeon_cs_chunk cs_chunk[2];
uint32_t length_dw_reloc_chunk;
uint64_t chunk_ptrs[2];
uint32_t reloc_chunk[128];
uint32_t reloc_chunk[256];
int r;
int retry = 0;
+7 -1
View File
@@ -185,7 +185,13 @@ static void r600_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmes
static void r600_vtbl_pre_emit_atoms(radeonContextPtr radeon)
{
/* to be enabled */
context_t *context = (context_t *)radeon;
/* always emit CB base to prevent
* lock ups on some chips.
*/
R600_STATECHANGE(context, cb_target);
r700Start3D(context);
}
static void r600_fallback(GLcontext *ctx, GLuint bit, GLboolean mode)
+22 -14
View File
@@ -55,10 +55,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
struct r600_context;
typedef struct r600_context context_t;
extern GLboolean r700SendPSState(context_t *context);
extern GLboolean r700SendVSState(context_t *context);
extern GLboolean r700SendFSState(context_t *context);
#include "main/mm.h"
/************ DMA BUFFERS **************/
@@ -115,17 +111,37 @@ enum
struct r600_hw_state {
struct radeon_state_atom sq;
struct radeon_state_atom db;
struct radeon_state_atom stencil;
struct radeon_state_atom db_target;
struct radeon_state_atom sc;
struct radeon_state_atom scissor;
struct radeon_state_atom aa;
struct radeon_state_atom cl;
struct radeon_state_atom gb;
struct radeon_state_atom ucp;
struct radeon_state_atom su;
struct radeon_state_atom poly;
struct radeon_state_atom cb;
struct radeon_state_atom clrcmp;
struct radeon_state_atom blnd;
struct radeon_state_atom blnd_clr;
struct radeon_state_atom cb_target;
struct radeon_state_atom sx;
struct radeon_state_atom vgt;
struct radeon_state_atom spi;
struct radeon_state_atom vpt;
struct radeon_state_atom fs;
struct radeon_state_atom vs;
struct radeon_state_atom ps;
struct radeon_state_atom vs_consts;
struct radeon_state_atom ps_consts;
struct radeon_state_atom vtx;
struct radeon_state_atom tx;
struct radeon_state_atom tx_smplr;
struct radeon_state_atom tx_brdr_clr;
};
/**
@@ -168,22 +184,14 @@ do { \
r600->radeon.hw.is_dirty = GL_TRUE; \
} while(0)
extern GLboolean r700SendTextureState(context_t *context);
extern GLboolean r700SyncSurf(context_t *context,
struct radeon_bo *pbo,
uint32_t read_domain,
uint32_t write_domain,
uint32_t sync_type);
extern int r700SetupStreams(GLcontext * ctx);
extern void r700SetupVTXConstants(GLcontext * ctx,
unsigned int nStreamID,
void * pAos,
unsigned int size, /* number of elements in vector */
unsigned int stride,
unsigned int Count); /* number of vectors in stream */
extern void r700SetupStreams(GLcontext * ctx);
extern void r700Start3D(context_t *context);
extern void r600InitAtoms(context_t *context);
#define RADEON_D_CAPTURE 0
+26 -24
View File
@@ -51,53 +51,55 @@ void r600EmitCacheFlush(context_t *rmesa)
{
}
GLboolean r600EmitShader(GLcontext * ctx,
GLboolean r600EmitShader(GLcontext * ctx,
void ** shaderbo,
GLvoid * data,
GLvoid * data,
int sizeinDWORD,
char * szShaderUsage)
char * szShaderUsage)
{
radeonContextPtr radeonctx = RADEON_CONTEXT(ctx);
struct radeon_bo * pbo;
uint32_t *out;
radeonContextPtr radeonctx = RADEON_CONTEXT(ctx);
struct radeon_bo * pbo;
uint32_t *out;
shader_again_alloc:
pbo = radeon_bo_open(radeonctx->radeonScreen->bom,
0,
sizeinDWORD * 4,
256,
RADEON_GEM_DOMAIN_GTT,
0);
pbo = radeon_bo_open(radeonctx->radeonScreen->bom,
0,
sizeinDWORD * 4,
256,
RADEON_GEM_DOMAIN_GTT,
0);
if (!pbo) {
rcommonFlushCmdBuf(radeonctx, __FUNCTION__);
goto shader_again_alloc;
}
radeon_cs_space_add_persistent_bo(radeonctx->cmdbuf.cs,
pbo,
RADEON_GEM_DOMAIN_GTT, 0);
if (radeon_cs_space_check_with_bo(radeonctx->cmdbuf.cs,
pbo,
RADEON_GEM_DOMAIN_GTT, 0))
RADEON_GEM_DOMAIN_GTT, 0)) {
fprintf(stderr,"failure to revalidate BOs - badness\n");
return GL_FALSE;
}
radeon_bo_map(pbo, 1);
radeon_bo_ref(pbo);
out = (uint32_t*)(pbo->ptr);
out = (uint32_t*)(pbo->ptr);
memcpy(out, data, sizeinDWORD * 4);
memcpy(out, data, sizeinDWORD * 4);
radeon_bo_unmap(pbo);
radeon_bo_unmap(pbo);
*shaderbo = (void*)pbo;
*shaderbo = (void*)pbo;
return GL_TRUE;
return GL_TRUE;
}
GLboolean r600DeleteShader(GLcontext * ctx,
void * shaderbo)
GLboolean r600DeleteShader(GLcontext * ctx,
void * shaderbo)
{
struct radeon_bo * pbo = (struct radeon_bo *)shaderbo;
@@ -60,6 +60,10 @@ void r600UpdateTextureState(GLcontext * ctx)
struct radeon_tex_obj *t;
GLuint unit;
R600_STATECHANGE(context, tx);
R600_STATECHANGE(context, tx_smplr);
R600_STATECHANGE(context, tx_brdr_clr);
for (unit = 0; unit < R700_MAX_TEXTURE_UNITS; unit++) {
texUnit = &ctx->Texture.Unit[unit];
t = radeon_tex_obj(ctx->Texture.Unit[unit]._Current);
+378 -169
View File
@@ -41,75 +41,102 @@
#include "radeon_mipmap_tree.h"
GLboolean r700SendTextureState(context_t *context)
static void r700SendTexState(GLcontext *ctx, struct radeon_state_atom *atom)
{
unsigned int i;
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
struct radeon_bo *bo = NULL;
BATCH_LOCALS(&context->radeon);
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
struct radeon_bo *bo = NULL;
unsigned int i;
BATCH_LOCALS(&context->radeon);
for (i=0; i<R700_TEXTURE_NUMBERUNITS; i++) {
radeonTexObj *t = r700->textures[i];
if (t) {
if (!t->image_override)
bo = t->mt->bo;
else
bo = t->bo;
if (bo) {
for (i = 0; i < R700_TEXTURE_NUMBERUNITS; i++) {
radeonTexObj *t = r700->textures[i];
if (t) {
if (!t->image_override)
bo = t->mt->bo;
else
bo = t->bo;
if (bo) {
r700SyncSurf(context, bo,
RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM,
0, TC_ACTION_ENA_bit);
r700SyncSurf(context, bo,
RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM,
0, TC_ACTION_ENA_bit);
BEGIN_BATCH_NO_AUTOSTATE(9 + 4);
R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, 7));
R600_OUT_BATCH(i * 7);
R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE0);
R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE1);
R600_OUT_BATCH(0); /* r700->textures[i]->SQ_TEX_RESOURCE2 */
R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE3);
R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE4);
R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE5);
R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE6);
R600_OUT_BATCH_RELOC(r700->textures[i]->SQ_TEX_RESOURCE2,
bo,
0,
RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
R600_OUT_BATCH_RELOC(r700->textures[i]->SQ_TEX_RESOURCE3,
bo,
r700->textures[i]->SQ_TEX_RESOURCE3,
RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
END_BATCH();
BEGIN_BATCH_NO_AUTOSTATE(5);
R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_SAMPLER, 3));
R600_OUT_BATCH(i * 3);
R600_OUT_BATCH(r700->textures[i]->SQ_TEX_SAMPLER0);
R600_OUT_BATCH(r700->textures[i]->SQ_TEX_SAMPLER1);
R600_OUT_BATCH(r700->textures[i]->SQ_TEX_SAMPLER2);
END_BATCH();
BEGIN_BATCH_NO_AUTOSTATE(2 + 4);
R600_OUT_BATCH_REGSEQ((TD_PS_SAMPLER0_BORDER_RED + (i * 16)), 4);
R600_OUT_BATCH(r700->textures[i]->TD_PS_SAMPLER0_BORDER_RED);
R600_OUT_BATCH(r700->textures[i]->TD_PS_SAMPLER0_BORDER_GREEN);
R600_OUT_BATCH(r700->textures[i]->TD_PS_SAMPLER0_BORDER_BLUE);
R600_OUT_BATCH(r700->textures[i]->TD_PS_SAMPLER0_BORDER_ALPHA);
END_BATCH();
COMMIT_BATCH();
}
}
}
return GL_TRUE;
BEGIN_BATCH_NO_AUTOSTATE(9 + 4);
R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, 7));
R600_OUT_BATCH(i * 7);
R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE0);
R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE1);
R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE2);
R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE3);
R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE4);
R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE5);
R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE6);
R600_OUT_BATCH_RELOC(r700->textures[i]->SQ_TEX_RESOURCE2,
bo,
0,
RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
R600_OUT_BATCH_RELOC(r700->textures[i]->SQ_TEX_RESOURCE3,
bo,
r700->textures[i]->SQ_TEX_RESOURCE3,
RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
END_BATCH();
COMMIT_BATCH();
}
}
}
}
void r700SetupVTXConstants(GLcontext * ctx,
unsigned int nStreamID,
void * pAos,
unsigned int size, /* number of elements in vector */
unsigned int stride,
unsigned int count) /* number of vectors in stream */
static void r700SendTexSamplerState(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
unsigned int i;
BATCH_LOCALS(&context->radeon);
for (i = 0; i < R700_TEXTURE_NUMBERUNITS; i++) {
radeonTexObj *t = r700->textures[i];
if (t) {
BEGIN_BATCH_NO_AUTOSTATE(5);
R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_SAMPLER, 3));
R600_OUT_BATCH(i * 3);
R600_OUT_BATCH(r700->textures[i]->SQ_TEX_SAMPLER0);
R600_OUT_BATCH(r700->textures[i]->SQ_TEX_SAMPLER1);
R600_OUT_BATCH(r700->textures[i]->SQ_TEX_SAMPLER2);
END_BATCH();
COMMIT_BATCH();
}
}
}
static void r700SendTexBorderColorState(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
unsigned int i;
BATCH_LOCALS(&context->radeon);
for (i = 0; i < R700_TEXTURE_NUMBERUNITS; i++) {
radeonTexObj *t = r700->textures[i];
if (t) {
BEGIN_BATCH_NO_AUTOSTATE(2 + 4);
R600_OUT_BATCH_REGSEQ((TD_PS_SAMPLER0_BORDER_RED + (i * 16)), 4);
R600_OUT_BATCH(r700->textures[i]->TD_PS_SAMPLER0_BORDER_RED);
R600_OUT_BATCH(r700->textures[i]->TD_PS_SAMPLER0_BORDER_GREEN);
R600_OUT_BATCH(r700->textures[i]->TD_PS_SAMPLER0_BORDER_BLUE);
R600_OUT_BATCH(r700->textures[i]->TD_PS_SAMPLER0_BORDER_ALPHA);
END_BATCH();
COMMIT_BATCH();
}
}
}
static void r700SetupVTXConstants(GLcontext * ctx,
unsigned int nStreamID,
void * pAos,
unsigned int size, /* number of elements in vector */
unsigned int stride,
unsigned int count) /* number of vectors in stream */
{
context_t *context = R700_CONTEXT(ctx);
struct radeon_aos * paos = (struct radeon_aos *)pAos;
@@ -127,6 +154,7 @@ void r700SetupVTXConstants(GLcontext * ctx,
if ((context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV610) ||
(context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV620) ||
(context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RS780) ||
(context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RS880) ||
(context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV710))
r700SyncSurf(context, paos->bo, RADEON_GEM_DOMAIN_GTT, 0, TC_ACTION_ENA_bit);
else
@@ -169,19 +197,38 @@ void r700SetupVTXConstants(GLcontext * ctx,
}
int r700SetupStreams(GLcontext * ctx)
void r700SetupStreams(GLcontext *ctx)
{
context_t *context = R700_CONTEXT(ctx);
BATCH_LOCALS(&context->radeon);
struct r700_vertex_program *vpc
= (struct r700_vertex_program *)ctx->VertexProgram._Current;
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *vb = &tnl->vb;
unsigned int i, j = 0;
R600_STATECHANGE(context, vtx);
for(i=0; i<VERT_ATTRIB_MAX; i++) {
if(vpc->mesa_program.Base.InputsRead & (1 << i)) {
rcommon_emit_vector(ctx,
&context->radeon.tcl.aos[j],
vb->AttribPtr[i]->data,
vb->AttribPtr[i]->size,
vb->AttribPtr[i]->stride,
vb->Count);
j++;
}
}
context->radeon.tcl.aos_count = j;
}
static void r700SendVTXState(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
struct r700_vertex_program *vpc
= (struct r700_vertex_program *)ctx->VertexProgram._Current;
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *vb = &tnl->vb;
unsigned int unBit;
unsigned int i, j = 0;
BATCH_LOCALS(&context->radeon);
BEGIN_BATCH_NO_AUTOSTATE(6);
R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, 1));
@@ -194,31 +241,18 @@ int r700SetupStreams(GLcontext * ctx)
END_BATCH();
COMMIT_BATCH();
for(i=0; i<VERT_ATTRIB_MAX; i++)
{
unBit = 1 << i;
if(vpc->mesa_program.Base.InputsRead & unBit)
{
rcommon_emit_vector(ctx,
&context->radeon.tcl.aos[j],
vb->AttribPtr[i]->data,
vb->AttribPtr[i]->size,
vb->AttribPtr[i]->stride,
vb->Count);
/* currently aos are packed */
r700SetupVTXConstants(ctx,
i,
(void*)(&context->radeon.tcl.aos[j]),
(unsigned int)context->radeon.tcl.aos[j].components,
(unsigned int)context->radeon.tcl.aos[j].stride * 4,
(unsigned int)context->radeon.tcl.aos[j].count);
j++;
}
}
context->radeon.tcl.aos_count = j;
return R600_FALLBACK_NONE;
for(i=0; i<VERT_ATTRIB_MAX; i++) {
if(vpc->mesa_program.Base.InputsRead & (1 << i)) {
/* currently aos are packed */
r700SetupVTXConstants(ctx,
i,
(void*)(&context->radeon.tcl.aos[j]),
(unsigned int)context->radeon.tcl.aos[j].components,
(unsigned int)context->radeon.tcl.aos[j].stride * 4,
(unsigned int)context->radeon.tcl.aos[j].count);
j++;
}
}
}
static void r700SendDepthTargetState(GLcontext *ctx, struct radeon_state_atom *atom)
@@ -309,8 +343,9 @@ static void r700SendRenderTargetState(GLcontext *ctx, struct radeon_state_atom *
}
GLboolean r700SendPSState(context_t *context)
static void r700SendPSState(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
struct radeon_bo * pbo;
BATCH_LOCALS(&context->radeon);
@@ -318,7 +353,7 @@ GLboolean r700SendPSState(context_t *context)
pbo = (struct radeon_bo *)r700GetActiveFpShaderBo(GL_CONTEXT(context));
if (!pbo)
return GL_FALSE;
return;
r700SyncSurf(context, pbo, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit);
@@ -339,13 +374,11 @@ GLboolean r700SendPSState(context_t *context)
COMMIT_BATCH();
r700->ps.dirty = GL_FALSE;
return GL_TRUE;
}
GLboolean r700SendVSState(context_t *context)
static void r700SendVSState(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
struct radeon_bo * pbo;
BATCH_LOCALS(&context->radeon);
@@ -353,7 +386,7 @@ GLboolean r700SendVSState(context_t *context)
pbo = (struct radeon_bo *)r700GetActiveVpShaderBo(GL_CONTEXT(context));
if (!pbo)
return GL_FALSE;
return;
r700SyncSurf(context, pbo, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit);
@@ -372,14 +405,11 @@ GLboolean r700SendVSState(context_t *context)
END_BATCH();
COMMIT_BATCH();
r700->vs.dirty = GL_FALSE;
return GL_TRUE;
}
GLboolean r700SendFSState(context_t *context)
static void r700SendFSState(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
struct radeon_bo * pbo;
BATCH_LOCALS(&context->radeon);
@@ -396,7 +426,7 @@ GLboolean r700SendFSState(context_t *context)
/* XXX */
if (!pbo)
return GL_FALSE;
return;
r700SyncSurf(context, pbo, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit);
@@ -416,9 +446,6 @@ GLboolean r700SendFSState(context_t *context)
COMMIT_BATCH();
r700->fs.dirty = GL_FALSE;
return GL_TRUE;
}
static void r700SendViewportState(GLcontext *ctx, struct radeon_state_atom *atom)
@@ -650,17 +677,13 @@ static void r700SendDBState(GLcontext *ctx, struct radeon_state_atom *atom)
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
BATCH_LOCALS(&context->radeon);
BEGIN_BATCH_NO_AUTOSTATE(27);
BEGIN_BATCH_NO_AUTOSTATE(23);
R600_OUT_BATCH_REGVAL(DB_HTILE_DATA_BASE, r700->DB_HTILE_DATA_BASE.u32All);
R600_OUT_BATCH_REGSEQ(DB_STENCIL_CLEAR, 2);
R600_OUT_BATCH(r700->DB_STENCIL_CLEAR.u32All);
R600_OUT_BATCH(r700->DB_DEPTH_CLEAR.u32All);
R600_OUT_BATCH_REGSEQ(DB_STENCILREFMASK, 2);
R600_OUT_BATCH(r700->DB_STENCILREFMASK.u32All);
R600_OUT_BATCH(r700->DB_STENCILREFMASK_BF.u32All);
R600_OUT_BATCH_REGVAL(DB_DEPTH_CONTROL, r700->DB_DEPTH_CONTROL.u32All);
R600_OUT_BATCH_REGVAL(DB_SHADER_CONTROL, r700->DB_SHADER_CONTROL.u32All);
@@ -675,15 +698,28 @@ static void r700SendDBState(GLcontext *ctx, struct radeon_state_atom *atom)
COMMIT_BATCH();
}
static void r700SendStencilState(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
BATCH_LOCALS(&context->radeon);
BEGIN_BATCH_NO_AUTOSTATE(4);
R600_OUT_BATCH_REGSEQ(DB_STENCILREFMASK, 2);
R600_OUT_BATCH(r700->DB_STENCILREFMASK.u32All);
R600_OUT_BATCH(r700->DB_STENCILREFMASK_BF.u32All);
END_BATCH();
COMMIT_BATCH();
}
static void r700SendCBState(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
BATCH_LOCALS(&context->radeon);
unsigned int ui;
if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770) {
BEGIN_BATCH_NO_AUTOSTATE(14);
BEGIN_BATCH_NO_AUTOSTATE(11);
R600_OUT_BATCH_REGSEQ(CB_CLEAR_RED, 4);
R600_OUT_BATCH(r700->CB_CLEAR_RED_R6XX.u32All);
R600_OUT_BATCH(r700->CB_CLEAR_GREEN_R6XX.u32All);
@@ -693,31 +729,50 @@ static void r700SendCBState(GLcontext *ctx, struct radeon_state_atom *atom)
R600_OUT_BATCH(r700->CB_FOG_RED_R6XX.u32All);
R600_OUT_BATCH(r700->CB_FOG_GREEN_R6XX.u32All);
R600_OUT_BATCH(r700->CB_FOG_BLUE_R6XX.u32All);
/* R600 does not have per-MRT blend */
R600_OUT_BATCH_REGVAL(CB_BLEND_CONTROL, r700->CB_BLEND_CONTROL.u32All);
END_BATCH();
}
BEGIN_BATCH_NO_AUTOSTATE(22);
BEGIN_BATCH_NO_AUTOSTATE(7);
R600_OUT_BATCH_REGSEQ(CB_TARGET_MASK, 2);
R600_OUT_BATCH(r700->CB_TARGET_MASK.u32All);
R600_OUT_BATCH(r700->CB_SHADER_MASK.u32All);
R600_OUT_BATCH_REGSEQ(CB_BLEND_RED, 4);
R600_OUT_BATCH(r700->CB_BLEND_RED.u32All);
R600_OUT_BATCH(r700->CB_BLEND_GREEN.u32All);
R600_OUT_BATCH(r700->CB_BLEND_BLUE.u32All);
R600_OUT_BATCH(r700->CB_BLEND_ALPHA.u32All);
R600_OUT_BATCH_REGVAL(R7xx_CB_SHADER_CONTROL, r700->CB_SHADER_CONTROL.u32All);
R600_OUT_BATCH_REGVAL(CB_COLOR_CONTROL, r700->CB_COLOR_CONTROL.u32All);
END_BATCH();
COMMIT_BATCH();
}
static void r700SendCBCLRCMPState(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
BATCH_LOCALS(&context->radeon);
BEGIN_BATCH_NO_AUTOSTATE(6);
R600_OUT_BATCH_REGSEQ(CB_CLRCMP_CONTROL, 4);
R600_OUT_BATCH(r700->CB_CLRCMP_CONTROL.u32All);
R600_OUT_BATCH(r700->CB_CLRCMP_SRC.u32All);
R600_OUT_BATCH(r700->CB_CLRCMP_DST.u32All);
R600_OUT_BATCH(r700->CB_CLRCMP_MSK.u32All);
END_BATCH();
COMMIT_BATCH();
}
static void r700SendCBBlendState(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
BATCH_LOCALS(&context->radeon);
unsigned int ui;
if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770) {
BEGIN_BATCH_NO_AUTOSTATE(3);
R600_OUT_BATCH_REGVAL(CB_BLEND_CONTROL, r700->CB_BLEND_CONTROL.u32All);
END_BATCH();
}
BEGIN_BATCH_NO_AUTOSTATE(3);
R600_OUT_BATCH_REGVAL(CB_COLOR_CONTROL, r700->CB_COLOR_CONTROL.u32All);
END_BATCH();
if (context->radeon.radeonScreen->chip_family > CHIP_FAMILY_R600) {
for (ui = 0; ui < R700_MAX_RENDER_TARGETS; ui++) {
@@ -731,7 +786,22 @@ static void r700SendCBState(GLcontext *ctx, struct radeon_state_atom *atom)
}
COMMIT_BATCH();
}
static void r700SendCBBlendColorState(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
BATCH_LOCALS(&context->radeon);
BEGIN_BATCH_NO_AUTOSTATE(6);
R600_OUT_BATCH_REGSEQ(CB_BLEND_RED, 4);
R600_OUT_BATCH(r700->CB_BLEND_RED.u32All);
R600_OUT_BATCH(r700->CB_BLEND_GREEN.u32All);
R600_OUT_BATCH(r700->CB_BLEND_BLUE.u32All);
R600_OUT_BATCH(r700->CB_BLEND_ALPHA.u32All);
END_BATCH();
COMMIT_BATCH();
}
static void r700SendSUState(GLcontext *ctx, struct radeon_state_atom *atom)
@@ -740,25 +810,33 @@ static void r700SendSUState(GLcontext *ctx, struct radeon_state_atom *atom)
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
BATCH_LOCALS(&context->radeon);
BEGIN_BATCH_NO_AUTOSTATE(19);
BEGIN_BATCH_NO_AUTOSTATE(9);
R600_OUT_BATCH_REGVAL(PA_SU_SC_MODE_CNTL, r700->PA_SU_SC_MODE_CNTL.u32All);
R600_OUT_BATCH_REGSEQ(PA_SU_POINT_SIZE, 4);
R600_OUT_BATCH(r700->PA_SU_POINT_SIZE.u32All);
R600_OUT_BATCH(r700->PA_SU_POINT_MINMAX.u32All);
R600_OUT_BATCH(r700->PA_SU_LINE_CNTL.u32All);
R600_OUT_BATCH(r700->PA_SU_VTX_CNTL.u32All);
END_BATCH();
COMMIT_BATCH();
}
static void r700SendPolyState(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
BATCH_LOCALS(&context->radeon);
BEGIN_BATCH_NO_AUTOSTATE(10);
R600_OUT_BATCH_REGSEQ(PA_SU_POLY_OFFSET_DB_FMT_CNTL, 2);
R600_OUT_BATCH(r700->PA_SU_POLY_OFFSET_DB_FMT_CNTL.u32All);
R600_OUT_BATCH(r700->PA_SU_POLY_OFFSET_CLAMP.u32All);
R600_OUT_BATCH_REGSEQ(PA_SU_POLY_OFFSET_FRONT_SCALE, 4);
R600_OUT_BATCH(r700->PA_SU_POLY_OFFSET_FRONT_SCALE.u32All);
R600_OUT_BATCH(r700->PA_SU_POLY_OFFSET_FRONT_OFFSET.u32All);
R600_OUT_BATCH(r700->PA_SU_POLY_OFFSET_BACK_SCALE.u32All);
R600_OUT_BATCH(r700->PA_SU_POLY_OFFSET_BACK_OFFSET.u32All);
END_BATCH();
COMMIT_BATCH();
@@ -770,35 +848,43 @@ static void r700SendCLState(GLcontext *ctx, struct radeon_state_atom *atom)
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
BATCH_LOCALS(&context->radeon);
BEGIN_BATCH_NO_AUTOSTATE(18);
BEGIN_BATCH_NO_AUTOSTATE(12);
R600_OUT_BATCH_REGVAL(PA_CL_CLIP_CNTL, r700->PA_CL_CLIP_CNTL.u32All);
R600_OUT_BATCH_REGVAL(PA_CL_VTE_CNTL, r700->PA_CL_VTE_CNTL.u32All);
R600_OUT_BATCH_REGVAL(PA_CL_VS_OUT_CNTL, r700->PA_CL_VS_OUT_CNTL.u32All);
R600_OUT_BATCH_REGVAL(PA_CL_NANINF_CNTL, r700->PA_CL_NANINF_CNTL.u32All);
R600_OUT_BATCH_REGSEQ(PA_CL_GB_VERT_CLIP_ADJ, 4);
R600_OUT_BATCH(r700->PA_CL_GB_VERT_CLIP_ADJ.u32All);
R600_OUT_BATCH(r700->PA_CL_GB_VERT_DISC_ADJ.u32All);
R600_OUT_BATCH(r700->PA_CL_GB_HORZ_CLIP_ADJ.u32All);
R600_OUT_BATCH(r700->PA_CL_GB_HORZ_DISC_ADJ.u32All);
END_BATCH();
COMMIT_BATCH();
}
// XXX need to split this up
static void r700SendSCState(GLcontext *ctx, struct radeon_state_atom *atom)
static void r700SendGBState(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
BATCH_LOCALS(&context->radeon);
BEGIN_BATCH_NO_AUTOSTATE(47);
BEGIN_BATCH_NO_AUTOSTATE(6);
R600_OUT_BATCH_REGSEQ(PA_CL_GB_VERT_CLIP_ADJ, 4);
R600_OUT_BATCH(r700->PA_CL_GB_VERT_CLIP_ADJ.u32All);
R600_OUT_BATCH(r700->PA_CL_GB_VERT_DISC_ADJ.u32All);
R600_OUT_BATCH(r700->PA_CL_GB_HORZ_CLIP_ADJ.u32All);
R600_OUT_BATCH(r700->PA_CL_GB_HORZ_DISC_ADJ.u32All);
END_BATCH();
COMMIT_BATCH();
}
static void r700SendScissorState(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
BATCH_LOCALS(&context->radeon);
BEGIN_BATCH_NO_AUTOSTATE(22);
R600_OUT_BATCH_REGSEQ(PA_SC_SCREEN_SCISSOR_TL, 2);
R600_OUT_BATCH(r700->PA_SC_SCREEN_SCISSOR_TL.u32All);
R600_OUT_BATCH(r700->PA_SC_SCREEN_SCISSOR_BR.u32All);
R600_OUT_BATCH_REGSEQ(PA_SC_WINDOW_OFFSET, 13);
R600_OUT_BATCH_REGSEQ(PA_SC_WINDOW_OFFSET, 12);
R600_OUT_BATCH(r700->PA_SC_WINDOW_OFFSET.u32All);
R600_OUT_BATCH(r700->PA_SC_WINDOW_SCISSOR_TL.u32All);
R600_OUT_BATCH(r700->PA_SC_WINDOW_SCISSOR_BR.u32All);
@@ -811,21 +897,89 @@ static void r700SendSCState(GLcontext *ctx, struct radeon_state_atom *atom)
R600_OUT_BATCH(r700->PA_SC_CLIPRECT_2_BR.u32All);
R600_OUT_BATCH(r700->PA_SC_CLIPRECT_3_TL.u32All);
R600_OUT_BATCH(r700->PA_SC_CLIPRECT_3_BR.u32All);
R600_OUT_BATCH(r700->PA_SC_EDGERULE.u32All);
R600_OUT_BATCH_REGSEQ(PA_SC_GENERIC_SCISSOR_TL, 2);
R600_OUT_BATCH(r700->PA_SC_GENERIC_SCISSOR_TL.u32All);
R600_OUT_BATCH(r700->PA_SC_GENERIC_SCISSOR_BR.u32All);
END_BATCH();
COMMIT_BATCH();
}
static void r700SendSCState(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
BATCH_LOCALS(&context->radeon);
BEGIN_BATCH_NO_AUTOSTATE(15);
R600_OUT_BATCH_REGVAL(R7xx_PA_SC_EDGERULE, r700->PA_SC_EDGERULE.u32All);
R600_OUT_BATCH_REGVAL(PA_SC_LINE_STIPPLE, r700->PA_SC_LINE_STIPPLE.u32All);
R600_OUT_BATCH_REGVAL(PA_SC_MPASS_PS_CNTL, r700->PA_SC_MPASS_PS_CNTL.u32All);
R600_OUT_BATCH_REGVAL(PA_SC_MODE_CNTL, r700->PA_SC_MODE_CNTL.u32All);
R600_OUT_BATCH_REGVAL(PA_SC_LINE_CNTL, r700->PA_SC_LINE_CNTL.u32All);
END_BATCH();
COMMIT_BATCH();
}
static void r700SendAAState(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
BATCH_LOCALS(&context->radeon);
BEGIN_BATCH_NO_AUTOSTATE(12);
R600_OUT_BATCH_REGVAL(PA_SC_AA_CONFIG, r700->PA_SC_AA_CONFIG.u32All);
R600_OUT_BATCH_REGVAL(PA_SC_AA_SAMPLE_LOCS_MCTX, r700->PA_SC_AA_SAMPLE_LOCS_MCTX.u32All);
R600_OUT_BATCH_REGVAL(PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX, r700->PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX.u32All);
R600_OUT_BATCH_REGVAL(PA_SC_AA_MASK, r700->PA_SC_AA_MASK.u32All);
END_BATCH();
COMMIT_BATCH();
}
static void r700SendPSConsts(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
int i;
BATCH_LOCALS(&context->radeon);
if (r700->ps.num_consts == 0)
return;
BEGIN_BATCH_NO_AUTOSTATE(2 + (r700->ps.num_consts * 4));
R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_ALU_CONST, (r700->ps.num_consts * 4)));
/* assembler map const from very beginning. */
R600_OUT_BATCH(SQ_ALU_CONSTANT_PS_OFFSET * 4);
for (i = 0; i < r700->ps.num_consts; i++) {
R600_OUT_BATCH(r700->ps.consts[i][0].u32All);
R600_OUT_BATCH(r700->ps.consts[i][1].u32All);
R600_OUT_BATCH(r700->ps.consts[i][2].u32All);
R600_OUT_BATCH(r700->ps.consts[i][3].u32All);
}
END_BATCH();
COMMIT_BATCH();
}
static void r700SendVSConsts(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
int i;
BATCH_LOCALS(&context->radeon);
if (r700->vs.num_consts == 0)
return;
BEGIN_BATCH_NO_AUTOSTATE(2 + (r700->vs.num_consts * 4));
R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_ALU_CONST, (r700->vs.num_consts * 4)));
/* assembler map const from very beginning. */
R600_OUT_BATCH(SQ_ALU_CONSTANT_VS_OFFSET * 4);
for (i = 0; i < r700->vs.num_consts; i++) {
R600_OUT_BATCH(r700->vs.consts[i][0].u32All);
R600_OUT_BATCH(r700->vs.consts[i][1].u32All);
R600_OUT_BATCH(r700->vs.consts[i][2].u32All);
R600_OUT_BATCH(r700->vs.consts[i][3].u32All);
}
END_BATCH();
COMMIT_BATCH();
}
@@ -835,39 +989,94 @@ static int check_always(GLcontext *ctx, struct radeon_state_atom *atom)
return atom->cmd_size;
}
#define ALLOC_STATE( ATOM, SZ, EMIT ) \
static int check_vtx(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
return context->radeon.tcl.aos_count * 18;
}
static int check_tx(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
unsigned int i, count = 0;
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
for (i = 0; i < R700_TEXTURE_NUMBERUNITS; i++) {
radeonTexObj *t = r700->textures[i];
if (t)
count++;
}
return count * 31;
}
static int check_ps_consts(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
return 2 + (r700->ps.num_consts * 4);
}
static int check_vs_consts(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
return 2 + (r700->vs.num_consts * 4);
}
#define ALLOC_STATE( ATOM, CHK, SZ, EMIT ) \
do { \
context->atoms.ATOM.cmd_size = (SZ); \
context->atoms.ATOM.cmd = NULL; \
context->atoms.ATOM.name = #ATOM; \
context->atoms.ATOM.idx = 0; \
context->atoms.ATOM.check = check_always; \
context->atoms.ATOM.dirty = GL_FALSE; \
context->atoms.ATOM.emit = (EMIT); \
context->radeon.hw.max_state_size += (SZ); \
insert_at_tail(&context->radeon.hw.atomlist, &context->atoms.ATOM); \
context->atoms.ATOM.cmd_size = (SZ); \
context->atoms.ATOM.cmd = NULL; \
context->atoms.ATOM.name = #ATOM; \
context->atoms.ATOM.idx = 0; \
context->atoms.ATOM.check = check_##CHK; \
context->atoms.ATOM.dirty = GL_FALSE; \
context->atoms.ATOM.emit = (EMIT); \
context->radeon.hw.max_state_size += (SZ); \
insert_at_tail(&context->radeon.hw.atomlist, &context->atoms.ATOM); \
} while (0)
void r600InitAtoms(context_t *context)
{
context->radeon.hw.max_state_size = 10 + 5 + 14; /* start 3d, idle, cb/db flush */
/* Setup the atom linked list */
make_empty_list(&context->radeon.hw.atomlist);
context->radeon.hw.atomlist.name = "atom-list";
ALLOC_STATE(sq, 34, r700SendSQConfig);
ALLOC_STATE(db, 27, r700SendDBState);
ALLOC_STATE(db_target, 19, r700SendDepthTargetState);
ALLOC_STATE(sc, 47, r700SendSCState);
ALLOC_STATE(cl, 18, r700SendCLState);
ALLOC_STATE(ucp, 36, r700SendUCPState);
ALLOC_STATE(su, 19, r700SendSUState);
ALLOC_STATE(cb, 39, r700SendCBState);
ALLOC_STATE(cb_target, 32, r700SendRenderTargetState);
ALLOC_STATE(sx, 9, r700SendSXState);
ALLOC_STATE(vgt, 41, r700SendVGTState);
ALLOC_STATE(spi, (59 + R700_MAX_SHADER_EXPORTS), r700SendSPIState);
ALLOC_STATE(vpt, 16, r700SendViewportState);
ALLOC_STATE(sq, always, 34, r700SendSQConfig);
ALLOC_STATE(db, always, 23, r700SendDBState);
ALLOC_STATE(stencil, always, 4, r700SendStencilState);
ALLOC_STATE(db_target, always, 12, r700SendDepthTargetState);
ALLOC_STATE(sc, always, 15, r700SendSCState);
ALLOC_STATE(scissor, always, 22, r700SendScissorState);
ALLOC_STATE(aa, always, 12, r700SendAAState);
ALLOC_STATE(cl, always, 12, r700SendCLState);
ALLOC_STATE(gb, always, 6, r700SendGBState);
ALLOC_STATE(ucp, always, 36, r700SendUCPState);
ALLOC_STATE(su, always, 9, r700SendSUState);
ALLOC_STATE(poly, always, 10, r700SendPolyState);
ALLOC_STATE(cb, always, 18, r700SendCBState);
ALLOC_STATE(clrcmp, always, 6, r700SendCBCLRCMPState);
ALLOC_STATE(blnd, always, 30, r700SendCBBlendState);
ALLOC_STATE(blnd_clr, always, 6, r700SendCBBlendColorState);
ALLOC_STATE(cb_target, always, 25, r700SendRenderTargetState);
ALLOC_STATE(sx, always, 9, r700SendSXState);
ALLOC_STATE(vgt, always, 41, r700SendVGTState);
ALLOC_STATE(spi, always, (59 + R700_MAX_SHADER_EXPORTS), r700SendSPIState);
ALLOC_STATE(vpt, always, 16, r700SendViewportState);
ALLOC_STATE(fs, always, 18, r700SendFSState);
ALLOC_STATE(vs, always, 18, r700SendVSState);
ALLOC_STATE(ps, always, 21, r700SendPSState);
ALLOC_STATE(vs_consts, vs_consts, (2 + (R700_MAX_DX9_CONSTS * 4)), r700SendVSConsts);
ALLOC_STATE(ps_consts, ps_consts, (2 + (R700_MAX_DX9_CONSTS * 4)), r700SendPSConsts);
ALLOC_STATE(vtx, vtx, (VERT_ATTRIB_MAX * 18), r700SendVTXState);
ALLOC_STATE(tx, tx, (R700_TEXTURE_NUMBERUNITS * 20), r700SendTexState);
ALLOC_STATE(tx_smplr, tx, (R700_TEXTURE_NUMBERUNITS * 5), r700SendTexSamplerState);
ALLOC_STATE(tx_brdr_clr, tx, (R700_TEXTURE_NUMBERUNITS * 6), r700SendTexBorderColorState);
context->radeon.hw.is_dirty = GL_TRUE;
context->radeon.hw.all_dirty = GL_TRUE;
+5
View File
@@ -46,6 +46,7 @@
#define R700_MAX_VIEWPORTS 16
#define R700_MAX_SHADER_EXPORTS 32
#define R700_MAX_UCP 6
#define R700_MAX_DX9_CONSTS 256
/* Enum not show in r600_*.h */
@@ -224,6 +225,8 @@ typedef struct _PS_STATE_STRUCT
union UINT_FLOAT SQ_PGM_EXPORTS_PS ; /* 0xA215 */
union UINT_FLOAT SQ_PGM_CF_OFFSET_PS ; /* 0xA233 */
GLboolean dirty;
int num_consts;
union UINT_FLOAT consts[R700_MAX_DX9_CONSTS][4];
} PS_STATE_STRUCT;
typedef struct _VS_STATE_STRUCT
@@ -232,6 +235,8 @@ typedef struct _VS_STATE_STRUCT
union UINT_FLOAT SQ_PGM_RESOURCES_VS ; /* 0xA21A */
union UINT_FLOAT SQ_PGM_CF_OFFSET_VS ; /* 0xA234 */
GLboolean dirty;
int num_consts;
union UINT_FLOAT consts[R700_MAX_DX9_CONSTS][4];
} VS_STATE_STRUCT;
typedef struct _GS_STATE_STRUCT
+41 -33
View File
@@ -270,7 +270,6 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
BATCH_LOCALS(&context->radeon);
struct r700_fragment_program *fp = (struct r700_fragment_program *)
(ctx->FragmentProgram._Current);
r700_AssemblerBase *pAsm = &(fp->r700AsmCode);
@@ -280,6 +279,7 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx)
unsigned int ui, i;
unsigned int unNumOfReg;
unsigned int unBit;
GLuint exportCount;
if(GL_FALSE == fp->loaded)
{
@@ -305,8 +305,15 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx)
(context->chipobj.MemUse)(context, fp->shadercode.buf->id);
*/
R600_STATECHANGE(context, ps);
r700->ps.SQ_PGM_RESOURCES_PS.u32All = 0;
SETbit(r700->ps.SQ_PGM_RESOURCES_PS.u32All, PGM_RESOURCES__PRIME_CACHE_ON_DRAW_bit);
r700->ps.SQ_PGM_START_PS.u32All = 0; /* set from buffer obj */
R600_STATECHANGE(context, spi);
unNumOfReg = fp->r700Shader.nRegs + 1;
ui = (r700->SPI_PS_IN_CONTROL_0.u32All & NUM_INTERP_mask) / (1 << NUM_INTERP_shift);
@@ -323,8 +330,8 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx)
ui = (unNumOfReg < ui) ? ui : unNumOfReg;
SETfield(r700->ps.SQ_PGM_RESOURCES_PS.u32All, ui, NUM_GPRS_shift, NUM_GPRS_mask);
SETfield(r700->ps.SQ_PGM_RESOURCES_PS.u32All, ui, NUM_GPRS_shift, NUM_GPRS_mask);
CLEARbit(r700->ps.SQ_PGM_RESOURCES_PS.u32All, UNCACHED_FIRST_INST_bit);
if(fp->r700Shader.uStackSize) /* we don't use branch for now, it should be zero. */
@@ -336,6 +343,8 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx)
SETfield(r700->ps.SQ_PGM_EXPORTS_PS.u32All, fp->r700Shader.exportMode,
EXPORT_MODE_shift, EXPORT_MODE_mask);
R600_STATECHANGE(context, db);
if(fp->r700Shader.killIsUsed)
{
SETbit(r700->DB_SHADER_CONTROL.u32All, KILL_ENABLE_bit);
@@ -347,42 +356,13 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx)
if(fp->r700Shader.depthIsExported)
{
SETbit(r700->DB_SHADER_CONTROL.u32All, Z_EXPORT_ENABLE_bit);
SETbit(r700->DB_SHADER_CONTROL.u32All, Z_EXPORT_ENABLE_bit);
}
else
{
CLEARbit(r700->DB_SHADER_CONTROL.u32All, Z_EXPORT_ENABLE_bit);
}
/* sent out shader constants. */
paramList = fp->mesa_program.Base.Parameters;
if(NULL != paramList)
{
_mesa_load_state_parameters(ctx, paramList);
unNumParamData = paramList->NumParameters * 4;
BEGIN_BATCH_NO_AUTOSTATE(2 + unNumParamData);
R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_ALU_CONST, unNumParamData));
/* assembler map const from very beginning. */
R600_OUT_BATCH(SQ_ALU_CONSTANT_PS_OFFSET * 4);
unNumParamData = paramList->NumParameters;
for(ui=0; ui<unNumParamData; ui++)
{
R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][0])));
R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][1])));
R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][2])));
R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][3])));
}
END_BATCH();
COMMIT_BATCH();
}
// emit ps input map
unBit = 1 << FRAG_ATTRIB_WPOS;
if(mesa_fp->Base.InputsRead & unBit)
@@ -449,6 +429,34 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx)
}
}
R600_STATECHANGE(context, cb);
exportCount = (r700->ps.SQ_PGM_EXPORTS_PS.u32All & EXPORT_MODE_mask) / (1 << EXPORT_MODE_shift);
r700->CB_SHADER_CONTROL.u32All = (1 << exportCount) - 1;
/* sent out shader constants. */
paramList = fp->mesa_program.Base.Parameters;
if(NULL != paramList) {
_mesa_load_state_parameters(ctx, paramList);
if (paramList->NumParameters > R700_MAX_DX9_CONSTS)
return GL_FALSE;
R600_STATECHANGE(context, ps_consts);
r700->ps.num_consts = paramList->NumParameters;
unNumParamData = paramList->NumParameters;
for(ui=0; ui<unNumParamData; ui++) {
r700->ps.consts[ui][0].f32All = paramList->ParameterValues[ui][0];
r700->ps.consts[ui][1].f32All = paramList->ParameterValues[ui][1];
r700->ps.consts[ui][2].f32All = paramList->ParameterValues[ui][2];
r700->ps.consts[ui][3].f32All = paramList->ParameterValues[ui][3];
}
} else
r700->ps.num_consts = 0;
return GL_TRUE;
}
+7 -38
View File
@@ -55,7 +55,6 @@
void r700WaitForIdle(context_t *context);
void r700WaitForIdleClean(context_t *context);
void r700Start3D(context_t *context);
GLboolean r700SendTextureState(context_t *context);
static unsigned int r700PrimitiveType(int prim);
void r600UpdateTextureState(GLcontext * ctx);
@@ -116,39 +115,6 @@ void r700Start3D(context_t *context)
r700WaitForIdleClean(context);
}
static GLboolean r700SetupShaders(GLcontext * ctx)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
GLuint exportCount;
r700->ps.SQ_PGM_RESOURCES_PS.u32All = 0;
r700->vs.SQ_PGM_RESOURCES_VS.u32All = 0;
SETbit(r700->ps.SQ_PGM_RESOURCES_PS.u32All, PGM_RESOURCES__PRIME_CACHE_ON_DRAW_bit);
SETbit(r700->vs.SQ_PGM_RESOURCES_VS.u32All, PGM_RESOURCES__PRIME_CACHE_ON_DRAW_bit);
r700SetupVertexProgram(ctx);
r700SetupFragmentProgram(ctx);
exportCount = (r700->ps.SQ_PGM_EXPORTS_PS.u32All & EXPORT_MODE_mask) / (1 << EXPORT_MODE_shift);
r700->CB_SHADER_CONTROL.u32All = (1 << exportCount) - 1;
r600UpdateTextureState(ctx);
r700SendFSState(context); // FIXME just a place holder for now
r700SendPSState(context);
r700SendVSState(context);
r700SendTextureState(context);
r700SetupStreams(ctx);
return GL_TRUE;
}
GLboolean r700SyncSurf(context_t *context,
struct radeon_bo *pbo,
uint32_t read_domain,
@@ -333,7 +299,7 @@ static void r700RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim
}
static GLboolean r700RunRender(GLcontext * ctx,
struct tnl_pipeline_stage *stage)
struct tnl_pipeline_stage *stage)
{
context_t *context = R700_CONTEXT(ctx);
radeonContextPtr radeon = &context->radeon;
@@ -347,12 +313,15 @@ static GLboolean r700RunRender(GLcontext * ctx,
/* just an estimate, need to properly calculate this */
rcommonEnsureCmdBufSpace(&context->radeon,
radeon->hw.max_state_size + ind_count + 1000, __FUNCTION__);
radeon->hw.max_state_size + ind_count, __FUNCTION__);
r700Start3D(context);
r700UpdateShaders(ctx);
r700SetScissor(context);
r700SetupShaders(ctx);
r700SetupVertexProgram(ctx);
r700SetupFragmentProgram(ctx);
r600UpdateTextureState(ctx);
r700SetupStreams(ctx);
radeonEmitState(radeon);
/* richard test code */
+9 -9
View File
@@ -168,7 +168,6 @@ void r700UpdateViewportOffset(GLcontext * ctx) //------------------
void r700UpdateDrawBuffer(GLcontext * ctx) /* TODO */ //---------------------
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
R600_STATECHANGE(context, cb_target);
R600_STATECHANGE(context, db_target);
@@ -400,7 +399,7 @@ static void r700BlendColor(GLcontext * ctx, const GLfloat cf[4]) //-------------
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
R600_STATECHANGE(context, cb);
R600_STATECHANGE(context, blnd_clr);
r700->CB_BLEND_RED.f32All = cf[0];
r700->CB_BLEND_GREEN.f32All = cf[1];
@@ -470,7 +469,7 @@ static void r700SetBlendState(GLcontext * ctx)
int id = 0;
uint32_t blend_reg = 0, eqn, eqnA;
R600_STATECHANGE(context, cb);
R600_STATECHANGE(context, blnd);
if (RGBA_LOGICOP_ENABLED(ctx) || !ctx->Color.BlendEnabled) {
SETfield(blend_reg,
@@ -661,7 +660,7 @@ static void r700SetLogicOpState(GLcontext *ctx)
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&R700_CONTEXT(ctx)->hw);
R600_STATECHANGE(context, cb);
R600_STATECHANGE(context, blnd);
if (RGBA_LOGICOP_ENABLED(ctx))
SETfield(r700->CB_COLOR_CONTROL.u32All,
@@ -1024,7 +1023,7 @@ static void r700StencilFuncSeparate(GLcontext * ctx, GLenum face,
//fixme
//r300CatchStencilFallback(ctx);
R600_STATECHANGE(context, db);
R600_STATECHANGE(context, stencil);
//front
SETfield(r700->DB_STENCILREFMASK.u32All, ctx->Stencil.Ref[0],
@@ -1055,7 +1054,7 @@ static void r700StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask) /
//fixme
//r300CatchStencilFallback(ctx);
R600_STATECHANGE(context, db);
R600_STATECHANGE(context, stencil);
// front
SETfield(r700->DB_STENCILREFMASK.u32All, ctx->Stencil.WriteMask[0],
@@ -1215,7 +1214,7 @@ static void r700PolygonOffset(GLcontext * ctx, GLfloat factor, GLfloat units) //
factor *= 12.0;
R600_STATECHANGE(context, su);
R600_STATECHANGE(context, poly);
r700->PA_SU_POLY_OFFSET_FRONT_SCALE.f32All = factor;
r700->PA_SU_POLY_OFFSET_FRONT_OFFSET.f32All = constant;
@@ -1356,7 +1355,7 @@ void r700SetScissor(context_t *context) //---------------
y2 = rrb->dPriv->y + rrb->dPriv->h;
}
R600_STATECHANGE(context, sc);
R600_STATECHANGE(context, scissor);
/* window */
SETbit(r700->PA_SC_WINDOW_SCISSOR_TL.u32All, WINDOW_OFFSET_DISABLE_bit);
@@ -1422,7 +1421,6 @@ static void r700SetRenderTarget(context_t *context, int id)
rrb = radeon_get_colorbuffer(&context->radeon);
if (!rrb || !rrb->bo) {
fprintf(stderr, "no rrb\n");
return;
}
@@ -1579,6 +1577,7 @@ static void r700InitSQConfig(GLcontext * ctx)
case CHIP_FAMILY_RV610:
case CHIP_FAMILY_RV620:
case CHIP_FAMILY_RS780:
case CHIP_FAMILY_RS880:
default:
num_ps_gprs = 84;
num_vs_gprs = 36;
@@ -1661,6 +1660,7 @@ static void r700InitSQConfig(GLcontext * ctx)
if ((context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV610) ||
(context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV620) ||
(context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RS780) ||
(context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RS880) ||
(context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV710))
CLEARbit(r700->sq_config.SQ_CONFIG.u32All, VC_ENABLE_bit);
else
+28 -28
View File
@@ -336,7 +336,6 @@ GLboolean r700SetupVertexProgram(GLcontext * ctx)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
BATCH_LOCALS(&context->radeon);
struct r700_vertex_program *vp
= (struct r700_vertex_program *)ctx->VertexProgram._Current;
@@ -368,8 +367,14 @@ GLboolean r700SetupVertexProgram(GLcontext * ctx)
(context->chipobj.MemUse)(context, vp->shadercode.buf->id);
*/
r700->vs.SQ_PGM_START_VS.u32All = 0; /* set from buffer object. */
R600_STATECHANGE(context, vs);
R600_STATECHANGE(context, fs); /* hack */
r700->vs.SQ_PGM_RESOURCES_VS.u32All = 0;
SETbit(r700->vs.SQ_PGM_RESOURCES_VS.u32All, PGM_RESOURCES__PRIME_CACHE_ON_DRAW_bit);
r700->vs.SQ_PGM_START_VS.u32All = 0; /* set from buffer object. */
SETfield(r700->vs.SQ_PGM_RESOURCES_VS.u32All, vp->r700Shader.nRegs + 1,
NUM_GPRS_shift, NUM_GPRS_mask);
@@ -379,9 +384,12 @@ GLboolean r700SetupVertexProgram(GLcontext * ctx)
STACK_SIZE_shift, STACK_SIZE_mask);
}
SETfield(r700->SPI_VS_OUT_CONFIG.u32All, vp->r700Shader.nParamExports ? (vp->r700Shader.nParamExports - 1) : 0,
R600_STATECHANGE(context, spi);
SETfield(r700->SPI_VS_OUT_CONFIG.u32All,
vp->r700Shader.nParamExports ? (vp->r700Shader.nParamExports - 1) : 0,
VS_EXPORT_COUNT_shift, VS_EXPORT_COUNT_mask);
SETfield(r700->SPI_PS_IN_CONTROL_0.u32All, vp->r700Shader.nParamExports,
SETfield(r700->SPI_PS_IN_CONTROL_0.u32All, vp->r700Shader.nParamExports,
NUM_INTERP_shift, NUM_INTERP_mask);
/*
@@ -392,34 +400,26 @@ GLboolean r700SetupVertexProgram(GLcontext * ctx)
/* sent out shader constants. */
paramList = vp->mesa_program.Base.Parameters;
if(NULL != paramList)
{
_mesa_load_state_parameters(ctx, paramList);
if(NULL != paramList) {
_mesa_load_state_parameters(ctx, paramList);
unNumParamData = paramList->NumParameters * 4;
if (paramList->NumParameters > R700_MAX_DX9_CONSTS)
return GL_FALSE;
BEGIN_BATCH_NO_AUTOSTATE(unNumParamData + 2);
R600_STATECHANGE(context, vs_consts);
R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_ALU_CONST, unNumParamData));
/* assembler map const from very beginning. */
R600_OUT_BATCH(SQ_ALU_CONSTANT_VS_OFFSET * 4);
r700->vs.num_consts = paramList->NumParameters;
unNumParamData = paramList->NumParameters;
unNumParamData = paramList->NumParameters;
for(ui=0; ui<unNumParamData; ui++)
{
R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][0])));
R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][1])));
R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][2])));
R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][3])));
}
END_BATCH();
COMMIT_BATCH();
}
for(ui=0; ui<unNumParamData; ui++) {
r700->vs.consts[ui][0].f32All = paramList->ParameterValues[ui][0];
r700->vs.consts[ui][1].f32All = paramList->ParameterValues[ui][1];
r700->vs.consts[ui][2].f32All = paramList->ParameterValues[ui][2];
r700->vs.consts[ui][3].f32All = paramList->ParameterValues[ui][3];
}
} else
r700->vs.num_consts = 0;
return GL_TRUE;
}
@@ -73,6 +73,7 @@ struct radeon_bo_funcs {
uint32_t pitch);
int (*bo_get_tiling)(struct radeon_bo *bo, uint32_t *tiling_flags,
uint32_t *pitch);
int (*bo_is_busy)(struct radeon_bo *bo, uint32_t *domain);
};
struct radeon_bo_manager {
@@ -170,6 +171,15 @@ static inline int _radeon_bo_wait(struct radeon_bo *bo,
return bo->bom->funcs->bo_wait(bo);
}
static inline int _radeon_bo_is_busy(struct radeon_bo *bo,
uint32_t *domain,
const char *file,
const char *func,
int line)
{
return bo->bom->funcs->bo_is_busy(bo, domain);
}
static inline int radeon_bo_set_tiling(struct radeon_bo *bo,
uint32_t tiling_flags, uint32_t pitch)
{
@@ -203,5 +213,7 @@ static inline int radeon_bo_is_static(struct radeon_bo *bo)
_radeon_bo_debug(bo, opcode, __FILE__, __FUNCTION__, __LINE__)
#define radeon_bo_wait(bo) \
_radeon_bo_wait(bo, __FILE__, __func__, __LINE__)
#define radeon_bo_is_busy(bo, domain) \
_radeon_bo_is_busy(bo, domain, __FILE__, __func__, __LINE__)
#endif
@@ -542,6 +542,18 @@ static int bo_unmap(struct radeon_bo *bo)
return 0;
}
static int bo_is_busy(struct radeon_bo *bo, uint32_t *domain)
{
*domain = 0;
if (bo->domains & RADEON_GEM_DOMAIN_GTT)
*domain = RADEON_GEM_DOMAIN_GTT;
else
*domain = RADEON_GEM_DOMAIN_CPU;
if (legacy_is_pending(bo))
return -EBUSY;
else
return 0;
}
static int bo_is_static(struct radeon_bo *bo)
{
@@ -559,6 +571,7 @@ static struct radeon_bo_funcs bo_legacy_funcs = {
bo_is_static,
NULL,
NULL,
bo_is_busy
};
static int bo_vram_validate(struct radeon_bo *bo,
@@ -335,6 +335,12 @@
#define PCI_CHIP_RS780_9615 0x9615
#define PCI_CHIP_RS780_9616 0x9616
#define PCI_CHIP_RS880_9710 0x9710
#define PCI_CHIP_RS880_9711 0x9711
#define PCI_CHIP_RS880_9712 0x9712
#define PCI_CHIP_RS880_9713 0x9713
#define PCI_CHIP_RS880_9714 0x9714
#define PCI_CHIP_RV770_9440 0x9440
#define PCI_CHIP_RV770_9441 0x9441
#define PCI_CHIP_RV770_9442 0x9442
@@ -421,6 +427,7 @@ enum {
CHIP_FAMILY_RV620,
CHIP_FAMILY_RV635,
CHIP_FAMILY_RS780,
CHIP_FAMILY_RS880,
CHIP_FAMILY_RV770,
CHIP_FAMILY_RV730,
CHIP_FAMILY_RV710,
@@ -92,6 +92,7 @@ static const char* get_chip_family_name(int chip_family)
case CHIP_FAMILY_RV620: return "RV620";
case CHIP_FAMILY_RV635: return "RV635";
case CHIP_FAMILY_RS780: return "RS780";
case CHIP_FAMILY_RS880: return "RS880";
case CHIP_FAMILY_RV770: return "RV770";
case CHIP_FAMILY_RV730: return "RV730";
case CHIP_FAMILY_RV710: return "RV710";
@@ -201,6 +201,15 @@ static inline void radeon_cs_write_qword(struct radeon_cs *cs, uint64_t qword)
}
}
static inline void radeon_cs_write_table(struct radeon_cs *cs, void *data, uint32_t size)
{
memcpy(cs->packets + cs->cdw, data, size * 4);
cs->cdw += size;
if (cs->section) {
cs->section_cdw += size;
}
}
static inline void radeon_cs_space_set_flush(struct radeon_cs *cs, void (*fn)(void *), void *data)
{
cs->space_flush_fn = fn;
+8 -1
View File
@@ -30,6 +30,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#include <errno.h>
#include "radeon_common.h"
#include "main/simple_list.h"
@@ -302,7 +303,13 @@ void radeonReturnDmaRegion(radeonContextPtr rmesa, int return_bytes)
static int radeon_bo_is_idle(struct radeon_bo* bo)
{
return bo->cref == 1;
uint32_t domain;
int ret = radeon_bo_is_busy(bo, &domain);
if (ret == -EINVAL) {
WARN_ONCE("Your libdrm or kernel doesn't have support for busy query.\n"
"This may cause small performance drop for you.\n");
}
return ret != -EBUSY;
}
void radeonReleaseDmaRegions(radeonContextPtr rmesa)
+38 -21
View File
@@ -32,7 +32,19 @@
#define DDEBUG 0
#define PAGE_SIZE 4096
static int radeonQueryIsFlushed(GLcontext *ctx, struct gl_query_object *q)
{
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
struct radeon_query_object *tmp, *query = (struct radeon_query_object *)q;
foreach(tmp, &radeon->query.not_flushed_head) {
if (tmp == query) {
return 0;
}
}
return 1;
}
static void radeonQueryGetResult(GLcontext *ctx, struct gl_query_object *q)
{
@@ -86,22 +98,11 @@ static void radeonDeleteQuery(GLcontext *ctx, struct gl_query_object *q)
static void radeonWaitQuery(GLcontext *ctx, struct gl_query_object *q)
{
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
struct radeon_query_object *tmp, *query = (struct radeon_query_object *)q;
struct radeon_query_object *query = (struct radeon_query_object *)q;
/* If the cmdbuf with packets for this query hasn't been flushed yet, do it now */
{
GLboolean found = GL_FALSE;
foreach(tmp, &radeon->query.not_flushed_head) {
if (tmp == query) {
found = GL_TRUE;
break;
}
}
if (found)
ctx->Driver.Flush(ctx);
}
if (!radeonQueryIsFlushed(ctx, q))
ctx->Driver.Flush(ctx);
if (DDEBUG) fprintf(stderr, "%s: query id %d, bo %p, offset %d\n", __FUNCTION__, q->Id, query->bo, query->curr_offset);
@@ -124,7 +125,7 @@ static void radeonBeginQuery(GLcontext *ctx, struct gl_query_object *q)
radeon->dma.flush(radeon->glCtx);
if (!query->bo) {
query->bo = radeon_bo_open(radeon->radeonScreen->bom, 0, PAGE_SIZE, PAGE_SIZE, RADEON_GEM_DOMAIN_GTT, 0);
query->bo = radeon_bo_open(radeon->radeonScreen->bom, 0, RADEON_QUERY_PAGE_SIZE, RADEON_QUERY_PAGE_SIZE, RADEON_GEM_DOMAIN_GTT, 0);
}
query->curr_offset = 0;
@@ -168,16 +169,32 @@ static void radeonEndQuery(GLcontext *ctx, struct gl_query_object *q)
radeon->query.current = NULL;
}
/**
* TODO:
* should check if bo is idle, bo there's no interface to do it
* just wait for result now
*/
static void radeonCheckQuery(GLcontext *ctx, struct gl_query_object *q)
{
if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, q->Id);
#ifdef DRM_RADEON_GEM_BUSY
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
if (radeon->radeonScreen->kernel_mm) {
struct radeon_query_object *query = (struct radeon_query_object *)q;
uint32_t domain;
/* Need to perform a flush, as per ARB_occlusion_query spec */
if (!radeonQueryIsFlushed(ctx, q)) {
ctx->Driver.Flush(ctx);
}
if (radeon_bo_is_busy(query->bo, &domain) == 0) {
radeonQueryGetResult(ctx, q);
query->Base.Ready = GL_TRUE;
}
} else {
radeonWaitQuery(ctx, q);
}
#else
radeonWaitQuery(ctx, q);
#endif
}
void radeonInitQueryObjFunctions(struct dd_function_table *functions)
@@ -853,6 +853,14 @@ static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
screen->chip_family = CHIP_FAMILY_RS780;
screen->chip_flags = RADEON_CHIPSET_TCL;
break;
case PCI_CHIP_RS880_9710:
case PCI_CHIP_RS880_9711:
case PCI_CHIP_RS880_9712:
case PCI_CHIP_RS880_9713:
case PCI_CHIP_RS880_9714:
screen->chip_family = CHIP_FAMILY_RS880;
screen->chip_flags = RADEON_CHIPSET_TCL;
break;
case PCI_CHIP_RV770_9440:
case PCI_CHIP_RV770_9441:
@@ -876,7 +876,7 @@ void radeonInitState( r100ContextPtr rmesa )
rmesa->hw.glt.emit = vec_emit;
rmesa->hw.eye.emit = vec_emit;
for (i = 0; i <= 6; i++)
for (i = 0; i < 6; i++)
rmesa->hw.mat[i].emit = vec_emit;
for (i = 0; i < 8; i++)
+1
View File
@@ -0,0 +1 @@
program_parse.output
+7
View File
@@ -0,0 +1,7 @@
all: program_parse.tab.c lex.yy.c
program_parse.tab.c program_parse.tab.h: program_parse.y
bison -v -d $<
lex.yy.c: program_lexer.l
flex --never-interactive $<
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+163
View File
@@ -0,0 +1,163 @@
/*
* Copyright © 2008 Intel Corporation
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*/
/**
* \file hash_table.c
* \brief Implementation of a generic, opaque hash table data type.
*
* \author Ian Romanick <ian.d.romanick@intel.com>
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "main/imports.h"
#include "main/simple_list.h"
#include "hash_table.h"
struct node {
struct node *next;
struct node *prev;
};
struct hash_table {
hash_func_t hash;
hash_compare_func_t compare;
unsigned num_buckets;
struct node buckets[1];
};
struct hash_node {
struct node link;
const void *key;
void *data;
};
struct hash_table *
hash_table_ctor(unsigned num_buckets, hash_func_t hash,
hash_compare_func_t compare)
{
struct hash_table *ht;
unsigned i;
if (num_buckets < 16) {
num_buckets = 16;
}
ht = _mesa_malloc(sizeof(*ht) + ((num_buckets - 1)
* sizeof(ht->buckets[0])));
if (ht != NULL) {
ht->hash = hash;
ht->compare = compare;
ht->num_buckets = num_buckets;
for (i = 0; i < num_buckets; i++) {
make_empty_list(& ht->buckets[i]);
}
}
return ht;
}
void
hash_table_dtor(struct hash_table *ht)
{
hash_table_clear(ht);
_mesa_free(ht);
}
void
hash_table_clear(struct hash_table *ht)
{
struct node *node;
struct node *temp;
unsigned i;
for (i = 0; i < ht->num_buckets; i++) {
foreach_s(node, temp, & ht->buckets[i]) {
remove_from_list(node);
_mesa_free(node);
}
assert(is_empty_list(& ht->buckets[i]));
}
}
void *
hash_table_find(struct hash_table *ht, const void *key)
{
const unsigned hash_value = (*ht->hash)(key);
const unsigned bucket = hash_value % ht->num_buckets;
struct node *node;
foreach(node, & ht->buckets[bucket]) {
struct hash_node *hn = (struct hash_node *) node;
if ((*ht->compare)(hn->key, key) == 0) {
return hn->data;
}
}
return NULL;
}
void
hash_table_insert(struct hash_table *ht, void *data, const void *key)
{
const unsigned hash_value = (*ht->hash)(key);
const unsigned bucket = hash_value % ht->num_buckets;
struct hash_node *node;
node = _mesa_calloc(sizeof(*node));
node->data = data;
node->key = key;
insert_at_head(& ht->buckets[bucket], & node->link);
}
unsigned
hash_table_string_hash(const void *key)
{
const char *str = (const char *) key;
unsigned hash = 5381;
while (*str != '\0') {
hash = (hash * 33) + *str;
str++;
}
return hash;
}
+117
View File
@@ -0,0 +1,117 @@
/*
* Copyright © 2008 Intel Corporation
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*/
/**
* \file hash_table.h
* \brief Implementation of a generic, opaque hash table data type.
*
* \author Ian Romanick <ian.d.romanick@intel.com>
*/
#ifndef HASH_TABLE_H
#define HASH_TABLE_H
#include <string.h>
struct hash_table;
typedef unsigned (*hash_func_t)(const void *key);
typedef int (*hash_compare_func_t)(const void *key1, const void *key2);
/**
* Hash table constructor
*
* Creates a hash table with the specified number of buckets. The supplied
* \c hash and \c compare routines are used when adding elements to the table
* and when searching for elements in the table.
*
* \param num_buckets Number of buckets (bins) in the hash table.
* \param hash Function used to compute hash value of input keys.
* \param compare Function used to compare keys.
*/
extern struct hash_table *hash_table_ctor(unsigned num_buckets,
hash_func_t hash, hash_compare_func_t compare);
/**
* Release all memory associated with a hash table
*
* \warning
* This function cannot release memory occupied either by keys or data.
*/
extern void hash_table_dtor(struct hash_table *ht);
/**
* Flush all entries from a hash table
*
* \param ht Table to be cleared of its entries.
*/
extern void hash_table_clear(struct hash_table *ht);
/**
* Search a hash table for a specific element
*
* \param ht Table to be searched
* \param key Key of the desired element
*
* \return
* The \c data value supplied to \c hash_table_insert when the element with
* the matching key was added. If no matching key exists in the table,
* \c NULL is returned.
*/
extern void *hash_table_find(struct hash_table *ht, const void *key);
/**
* Add an element to a hash table
*/
extern void hash_table_insert(struct hash_table *ht, void *data,
const void *key);
/**
* Compute hash value of a string
*
* Computes the hash value of a string using the DJB2 algorithm developed by
* Professor Daniel J. Bernstein. It was published on comp.lang.c once upon
* a time. I was unable to find the original posting in the archives.
*
* \param key Pointer to a NUL terminated string to be hashed.
*
* \sa hash_table_string_compare
*/
extern unsigned hash_table_string_hash(const void *key);
/**
* Compare two strings used as keys
*
* This is just a macro wrapper around \c strcmp.
*
* \sa hash_table_string_hash
*/
#define hash_table_string_compare ((hash_compare_func_t) strcmp)
#endif /* HASH_TABLE_H */
File diff suppressed because it is too large Load Diff
+28
View File
@@ -44,6 +44,34 @@ _mesa_new_parameter_list(void)
}
struct gl_program_parameter_list *
_mesa_new_parameter_list_sized(unsigned size)
{
struct gl_program_parameter_list *p = _mesa_new_parameter_list();
if ((p != NULL) && (size != 0)) {
p->Size = size;
/* alloc arrays */
p->Parameters = (struct gl_program_parameter *)
_mesa_calloc(size * sizeof(struct gl_program_parameter));
p->ParameterValues = (GLfloat (*)[4])
_mesa_align_malloc(size * 4 *sizeof(GLfloat), 16);
if ((p->Parameters == NULL) || (p->ParameterValues == NULL)) {
_mesa_free(p->Parameters);
_mesa_align_free(p->ParameterValues);
_mesa_free(p);
p = NULL;
}
}
return p;
}
/**
* Free a parameter list and all its parameters
*/
+3
View File
@@ -84,6 +84,9 @@ struct gl_program_parameter_list
extern struct gl_program_parameter_list *
_mesa_new_parameter_list(void);
extern struct gl_program_parameter_list *
_mesa_new_parameter_list_sized(unsigned size);
extern void
_mesa_free_parameter_list(struct gl_program_parameter_list *paramList);
+213
View File
@@ -0,0 +1,213 @@
/*
* Copyright © 2009 Intel Corporation
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*/
/**
* \file prog_parameter_layout.c
* \brief Helper functions to layout storage for program parameters
*
* \author Ian Romanick <ian.d.romanick@intel.com>
*/
#include "main/mtypes.h"
#include "prog_parameter.h"
#include "prog_parameter_layout.h"
#include "prog_instruction.h"
#include "program_parser.h"
unsigned
_mesa_combine_swizzles(unsigned base, unsigned applied)
{
unsigned swiz = 0;
unsigned i;
for (i = 0; i < 4; i++) {
const unsigned s = GET_SWZ(applied, i);
swiz |= ((s <= SWIZZLE_W) ? GET_SWZ(base, s) : s) << (i * 3);
}
return swiz;
}
/**
* Copy indirect access array from one parameter list to another
*
* \param src Parameter array copied from
* \param dst Parameter array copied to
* \param first Index of first element in \c src to copy
* \param count Number of elements to copy
*
* \return
* The location in \c dst of the first element copied from \c src on
* success. -1 on failure.
*
* \warning
* This function assumes that there is already enough space available in
* \c dst to hold all of the elements that will be copied over.
*/
static int
copy_indirect_accessed_array(struct gl_program_parameter_list *src,
struct gl_program_parameter_list *dst,
unsigned first, unsigned count)
{
const int base = dst->NumParameters;
unsigned i;
unsigned j;
for (i = first; i < (first + count); i++) {
struct gl_program_parameter *curr = & src->Parameters[i];
if (curr->Type == PROGRAM_CONSTANT) {
j = dst->NumParameters;
} else {
for (j = 0; j < dst->NumParameters; j++) {
if (memcmp(dst->Parameters[j].StateIndexes, curr->StateIndexes,
sizeof(curr->StateIndexes)) == 0) {
return -1;
}
}
}
assert(j == dst->NumParameters);
memcpy(& dst->Parameters[j], curr,
sizeof(dst->Parameters[j]));
memcpy(dst->ParameterValues[j], src->ParameterValues[i],
sizeof(GLfloat) * 4);
curr->Name = NULL;
dst->NumParameters++;
}
return base;
}
int
_mesa_layout_parameters(struct asm_parser_state *state)
{
struct gl_program_parameter_list *layout;
struct asm_instruction *inst;
unsigned i;
layout =
_mesa_new_parameter_list_sized(state->prog->Parameters->NumParameters);
/* PASS 1: Move any parameters that are accessed indirectly from the
* original parameter list to the new parameter list.
*/
for (inst = state->inst_head; inst != NULL; inst = inst->next) {
for (i = 0; i < 3; i++) {
if (inst->SrcReg[i].Base.RelAddr) {
/* Only attempt to add the to the new parameter list once.
*/
if (!inst->SrcReg[i].Symbol->pass1_done) {
const int new_begin =
copy_indirect_accessed_array(state->prog->Parameters, layout,
inst->SrcReg[i].Symbol->param_binding_begin,
inst->SrcReg[i].Symbol->param_binding_length);
if (new_begin < 0) {
return 0;
}
inst->SrcReg[i].Symbol->param_binding_begin = new_begin;
inst->SrcReg[i].Symbol->pass1_done = 1;
}
/* Previously the Index was just the offset from the parameter
* array. Now that the base of the parameter array is known, the
* index can be updated to its actual value.
*/
inst->Base.SrcReg[i] = inst->SrcReg[i].Base;
inst->Base.SrcReg[i].Index +=
inst->SrcReg[i].Symbol->param_binding_begin;
}
}
}
/* PASS 2: Move any parameters that are not accessed indirectly from the
* original parameter list to the new parameter list.
*/
for (inst = state->inst_head; inst != NULL; inst = inst->next) {
for (i = 0; i < 3; i++) {
const struct gl_program_parameter *p;
const int idx = inst->SrcReg[i].Base.Index;
unsigned swizzle = SWIZZLE_NOOP;
/* All relative addressed operands were processed on the first
* pass. Just skip them here.
*/
if (inst->SrcReg[i].Base.RelAddr) {
continue;
}
if ((inst->SrcReg[i].Base.File <= PROGRAM_VARYING )
|| (inst->SrcReg[i].Base.File >= PROGRAM_WRITE_ONLY)) {
continue;
}
inst->Base.SrcReg[i] = inst->SrcReg[i].Base;
p = & state->prog->Parameters->Parameters[idx];
switch (p->Type) {
case PROGRAM_CONSTANT: {
const float *const v =
state->prog->Parameters->ParameterValues[idx];
inst->Base.SrcReg[i].Index =
_mesa_add_unnamed_constant(layout, v, p->Size, & swizzle);
inst->Base.SrcReg[i].Swizzle =
_mesa_combine_swizzles(swizzle, inst->Base.SrcReg[i].Swizzle);
break;
}
case PROGRAM_STATE_VAR:
inst->Base.SrcReg[i].Index =
_mesa_add_state_reference(layout, p->StateIndexes);
break;
default:
break;
}
inst->SrcReg[i].Base.File = p->Type;
inst->Base.SrcReg[i].File = p->Type;
}
}
_mesa_free_parameter_list(state->prog->Parameters);
state->prog->Parameters = layout;
return 1;
}
+41
View File
@@ -0,0 +1,41 @@
/*
* Copyright © 2009 Intel Corporation
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*/
/**
* \file prog_parameter_layout.h
* \brief Helper functions to layout storage for program parameters
*
* \author Ian Romanick <ian.d.romanick@intel.com>
*/
#pragma once
#ifndef PROG_PARAMETER_LAYOUT_H
#define PROG_PARAMETER_LAYOUT_H
extern unsigned _mesa_combine_swizzles(unsigned base, unsigned applied);
struct asm_parser_state;
extern int _mesa_layout_parameters(struct asm_parser_state *state);
#endif /* PROG_PARAMETER_LAYOUT_H */
+1 -1
View File
@@ -816,7 +816,7 @@ _mesa_fprint_program_opt(FILE *f,
void
_mesa_print_program(const struct gl_program *prog)
{
_mesa_fprint_program_opt(stdout, prog, PROG_PRINT_DEBUG, GL_TRUE);
_mesa_fprint_program_opt(stderr, prog, PROG_PRINT_DEBUG, GL_TRUE);
}
+488
View File
@@ -0,0 +1,488 @@
%{
/*
* Copyright © 2009 Intel Corporation
*
* 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "main/glheader.h"
#include "prog_instruction.h"
#include "program_parser.h"
#include "program_parse.tab.h"
#define require_ARB_vp (yyextra->mode == ARB_vertex)
#define require_ARB_fp (yyextra->mode == ARB_fragment)
#define require_shadow (yyextra->option.Shadow)
#define require_rect (yyextra->option.TexRect)
#define require_texarray (yyextra->option.TexArray)
#define return_token_or_IDENTIFIER(condition, token) \
do { \
if (condition) { \
return token; \
} else { \
yylval->string = strdup(yytext); \
return IDENTIFIER; \
} \
} while (0)
#define return_token_or_DOT(condition, token) \
do { \
if (condition) { \
return token; \
} else { \
yyless(1); \
return DOT; \
} \
} while (0)
#define return_opcode(condition, token, opcode, sat) \
do { \
if (condition) { \
yylval->temp_inst.Opcode = OPCODE_ ## opcode; \
yylval->temp_inst.SaturateMode = SATURATE_ ## sat; \
return token; \
} else { \
yylval->string = strdup(yytext); \
return IDENTIFIER; \
} \
} while (0)
#define SWIZZLE_INVAL MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \
SWIZZLE_NIL, SWIZZLE_NIL)
static unsigned
mask_from_char(char c)
{
switch (c) {
case 'x':
case 'r':
return WRITEMASK_X;
case 'y':
case 'g':
return WRITEMASK_Y;
case 'z':
case 'b':
return WRITEMASK_Z;
case 'w':
case 'a':
return WRITEMASK_W;
}
return 0;
}
static unsigned
swiz_from_char(char c)
{
switch (c) {
case 'x':
case 'r':
return SWIZZLE_X;
case 'y':
case 'g':
return SWIZZLE_Y;
case 'z':
case 'b':
return SWIZZLE_Z;
case 'w':
case 'a':
return SWIZZLE_W;
}
return 0;
}
#define YY_USER_ACTION \
do { \
yylloc->first_column = yylloc->last_column; \
yylloc->last_column += yyleng; \
if ((yylloc->first_line == 1) \
&& (yylloc->first_column == 1)) { \
yylloc->position = 1; \
} else { \
yylloc->position += yylloc->last_column - yylloc->first_column; \
} \
} while(0);
#define YY_EXTRA_TYPE struct asm_parser_state *
%}
num [0-9]+
exp [Ee][-+]?[0-9]+
frac "."[0-9]+
dot "."[ \t]*
%option bison-bridge bison-locations reentrant noyywrap
%%
"!!ARBvp1.0" { return ARBvp_10; }
"!!ARBfp1.0" { return ARBfp_10; }
ADDRESS {
yylval->integer = at_address;
return_token_or_IDENTIFIER(require_ARB_vp, ADDRESS);
}
ALIAS { return ALIAS; }
ATTRIB { return ATTRIB; }
END { return END; }
OPTION { return OPTION; }
OUTPUT { return OUTPUT; }
PARAM { return PARAM; }
TEMP { yylval->integer = at_temp; return TEMP; }
ABS { return_opcode( 1, VECTOR_OP, ABS, OFF); }
ABS_SAT { return_opcode(require_ARB_fp, VECTOR_OP, ABS, ZERO_ONE); }
ADD { return_opcode( 1, BIN_OP, ADD, OFF); }
ADD_SAT { return_opcode(require_ARB_fp, BIN_OP, ADD, ZERO_ONE); }
ARL { return_opcode(require_ARB_vp, ARL, ARL, OFF); }
CMP { return_opcode(require_ARB_fp, TRI_OP, CMP, OFF); }
CMP_SAT { return_opcode(require_ARB_fp, TRI_OP, CMP, ZERO_ONE); }
COS { return_opcode(require_ARB_fp, SCALAR_OP, COS, OFF); }
COS_SAT { return_opcode(require_ARB_fp, SCALAR_OP, COS, ZERO_ONE); }
DP3 { return_opcode( 1, BIN_OP, DP3, OFF); }
DP3_SAT { return_opcode(require_ARB_fp, BIN_OP, DP3, ZERO_ONE); }
DP4 { return_opcode( 1, BIN_OP, DP4, OFF); }
DP4_SAT { return_opcode(require_ARB_fp, BIN_OP, DP4, ZERO_ONE); }
DPH { return_opcode( 1, BIN_OP, DPH, OFF); }
DPH_SAT { return_opcode(require_ARB_fp, BIN_OP, DPH, ZERO_ONE); }
DST { return_opcode( 1, BIN_OP, DST, OFF); }
DST_SAT { return_opcode(require_ARB_fp, BIN_OP, DST, ZERO_ONE); }
EX2 { return_opcode( 1, SCALAR_OP, EX2, OFF); }
EX2_SAT { return_opcode(require_ARB_fp, SCALAR_OP, EX2, ZERO_ONE); }
EXP { return_opcode(require_ARB_vp, SCALAR_OP, EXP, OFF); }
FLR { return_opcode( 1, VECTOR_OP, FLR, OFF); }
FLR_SAT { return_opcode(require_ARB_fp, VECTOR_OP, FLR, ZERO_ONE); }
FRC { return_opcode( 1, VECTOR_OP, FRC, OFF); }
FRC_SAT { return_opcode(require_ARB_fp, VECTOR_OP, FRC, ZERO_ONE); }
KIL { return_opcode(require_ARB_fp, KIL, KIL, OFF); }
LIT { return_opcode( 1, VECTOR_OP, LIT, OFF); }
LIT_SAT { return_opcode(require_ARB_fp, VECTOR_OP, LIT, ZERO_ONE); }
LG2 { return_opcode( 1, SCALAR_OP, LG2, OFF); }
LG2_SAT { return_opcode(require_ARB_fp, SCALAR_OP, LG2, ZERO_ONE); }
LOG { return_opcode(require_ARB_vp, SCALAR_OP, LOG, OFF); }
LRP { return_opcode(require_ARB_fp, TRI_OP, LRP, OFF); }
LRP_SAT { return_opcode(require_ARB_fp, TRI_OP, LRP, ZERO_ONE); }
MAD { return_opcode( 1, TRI_OP, MAD, OFF); }
MAD_SAT { return_opcode(require_ARB_fp, TRI_OP, MAD, ZERO_ONE); }
MAX { return_opcode( 1, BIN_OP, MAX, OFF); }
MAX_SAT { return_opcode(require_ARB_fp, BIN_OP, MAX, ZERO_ONE); }
MIN { return_opcode( 1, BIN_OP, MIN, OFF); }
MIN_SAT { return_opcode(require_ARB_fp, BIN_OP, MIN, ZERO_ONE); }
MOV { return_opcode( 1, VECTOR_OP, MOV, OFF); }
MOV_SAT { return_opcode(require_ARB_fp, VECTOR_OP, MOV, ZERO_ONE); }
MUL { return_opcode( 1, BIN_OP, MUL, OFF); }
MUL_SAT { return_opcode(require_ARB_fp, BIN_OP, MUL, ZERO_ONE); }
POW { return_opcode( 1, BINSC_OP, POW, OFF); }
POW_SAT { return_opcode(require_ARB_fp, BINSC_OP, POW, ZERO_ONE); }
RCP { return_opcode( 1, SCALAR_OP, RCP, OFF); }
RCP_SAT { return_opcode(require_ARB_fp, SCALAR_OP, RCP, ZERO_ONE); }
RSQ { return_opcode( 1, SCALAR_OP, RSQ, OFF); }
RSQ_SAT { return_opcode(require_ARB_fp, SCALAR_OP, RSQ, ZERO_ONE); }
SCS { return_opcode(require_ARB_fp, SCALAR_OP, SCS, OFF); }
SCS_SAT { return_opcode(require_ARB_fp, SCALAR_OP, SCS, ZERO_ONE); }
SGE { return_opcode( 1, BIN_OP, SGE, OFF); }
SGE_SAT { return_opcode(require_ARB_fp, BIN_OP, SGE, ZERO_ONE); }
SIN { return_opcode(require_ARB_fp, SCALAR_OP, SIN, OFF); }
SIN_SAT { return_opcode(require_ARB_fp, SCALAR_OP, SIN, ZERO_ONE); }
SLT { return_opcode( 1, BIN_OP, SLT, OFF); }
SLT_SAT { return_opcode(require_ARB_fp, BIN_OP, SLT, ZERO_ONE); }
SUB { return_opcode( 1, BIN_OP, SUB, OFF); }
SUB_SAT { return_opcode(require_ARB_fp, BIN_OP, SUB, ZERO_ONE); }
SWZ { return_opcode( 1, SWZ, SWZ, OFF); }
SWZ_SAT { return_opcode(require_ARB_fp, SWZ, SWZ, ZERO_ONE); }
TEX { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, OFF); }
TEX_SAT { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, ZERO_ONE); }
TXB { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, OFF); }
TXB_SAT { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, ZERO_ONE); }
TXP { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, OFF); }
TXP_SAT { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, ZERO_ONE); }
XPD { return_opcode( 1, BIN_OP, XPD, OFF); }
XPD_SAT { return_opcode(require_ARB_fp, BIN_OP, XPD, ZERO_ONE); }
vertex { return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); }
fragment { return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); }
program { return PROGRAM; }
state { return STATE; }
result { return RESULT; }
{dot}ambient { return AMBIENT; }
{dot}attenuation { return ATTENUATION; }
{dot}back { return BACK; }
{dot}clip { return_token_or_DOT(require_ARB_vp, CLIP); }
{dot}color { return COLOR; }
{dot}depth { return_token_or_DOT(require_ARB_fp, DEPTH); }
{dot}diffuse { return DIFFUSE; }
{dot}direction { return DIRECTION; }
{dot}emission { return EMISSION; }
{dot}env { return ENV; }
{dot}eye { return EYE; }
{dot}fogcoord { return FOGCOORD; }
{dot}fog { return FOG; }
{dot}front { return FRONT; }
{dot}half { return HALF; }
{dot}inverse { return INVERSE; }
{dot}invtrans { return INVTRANS; }
{dot}light { return LIGHT; }
{dot}lightmodel { return LIGHTMODEL; }
{dot}lightprod { return LIGHTPROD; }
{dot}local { return LOCAL; }
{dot}material { return MATERIAL; }
{dot}program { return MAT_PROGRAM; }
{dot}matrix { return MATRIX; }
{dot}matrixindex { return_token_or_DOT(require_ARB_vp, MATRIXINDEX); }
{dot}modelview { return MODELVIEW; }
{dot}mvp { return MVP; }
{dot}normal { return_token_or_DOT(require_ARB_vp, NORMAL); }
{dot}object { return OBJECT; }
{dot}palette { return PALETTE; }
{dot}params { return PARAMS; }
{dot}plane { return PLANE; }
{dot}point { return_token_or_DOT(require_ARB_vp, POINT); }
{dot}pointsize { return_token_or_DOT(require_ARB_vp, POINTSIZE); }
{dot}position { return POSITION; }
{dot}primary { return PRIMARY; }
{dot}projection { return PROJECTION; }
{dot}range { return_token_or_DOT(require_ARB_fp, RANGE); }
{dot}row { return ROW; }
{dot}scenecolor { return SCENECOLOR; }
{dot}secondary { return SECONDARY; }
{dot}shininess { return SHININESS; }
{dot}size { return_token_or_DOT(require_ARB_vp, SIZE); }
{dot}specular { return SPECULAR; }
{dot}spot { return SPOT; }
{dot}texcoord { return TEXCOORD; }
{dot}texenv { return_token_or_DOT(require_ARB_fp, TEXENV); }
{dot}texgen { return_token_or_DOT(require_ARB_vp, TEXGEN); }
{dot}q { return_token_or_DOT(require_ARB_vp, TEXGEN_Q); }
{dot}s { return_token_or_DOT(require_ARB_vp, TEXGEN_S); }
{dot}t { return_token_or_DOT(require_ARB_vp, TEXGEN_T); }
{dot}texture { return TEXTURE; }
{dot}transpose { return TRANSPOSE; }
{dot}attrib { return_token_or_DOT(require_ARB_vp, VTXATTRIB); }
{dot}weight { return_token_or_DOT(require_ARB_vp, WEIGHT); }
texture { return_token_or_IDENTIFIER(require_ARB_fp, TEXTURE_UNIT); }
1D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_1D); }
2D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_2D); }
3D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_3D); }
CUBE { return_token_or_IDENTIFIER(require_ARB_fp, TEX_CUBE); }
RECT { return_token_or_IDENTIFIER(require_ARB_fp && require_rect, TEX_RECT); }
SHADOW1D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW1D); }
SHADOW2D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW2D); }
SHADOWRECT { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_rect, TEX_SHADOWRECT); }
ARRAY1D { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY1D); }
ARRAY2D { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY2D); }
ARRAYSHADOW1D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW1D); }
ARRAYSHADOW2D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); }
[_a-zA-Z$][_a-zA-Z0-9$]* {
yylval->string = strdup(yytext);
return IDENTIFIER;
}
".." { return DOT_DOT; }
{num} {
yylval->integer = strtol(yytext, NULL, 10);
return INTEGER;
}
{num}?{frac}{exp}? {
yylval->real = strtod(yytext, NULL);
return REAL;
}
{num}"."/[^.] {
yylval->real = strtod(yytext, NULL);
return REAL;
}
{num}{exp} {
yylval->real = strtod(yytext, NULL);
return REAL;
}
{num}"."{exp} {
yylval->real = strtod(yytext, NULL);
return REAL;
}
".xyzw" {
yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
yylval->swiz_mask.mask = WRITEMASK_XYZW;
return MASK4;
}
".xy"[zw] {
yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
yylval->swiz_mask.mask = WRITEMASK_XY
| mask_from_char(yytext[3]);
return MASK3;
}
".xzw" {
yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
yylval->swiz_mask.mask = WRITEMASK_XZW;
return MASK3;
}
".yzw" {
yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
yylval->swiz_mask.mask = WRITEMASK_YZW;
return MASK3;
}
".x"[yzw] {
yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
yylval->swiz_mask.mask = WRITEMASK_X
| mask_from_char(yytext[2]);
return MASK2;
}
".y"[zw] {
yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
yylval->swiz_mask.mask = WRITEMASK_Y
| mask_from_char(yytext[2]);
return MASK2;
}
".zw" {
yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
yylval->swiz_mask.mask = WRITEMASK_ZW;
return MASK2;
}
"."[xyzw] {
const unsigned s = swiz_from_char(yytext[1]);
yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
yylval->swiz_mask.mask = mask_from_char(yytext[1]);
return MASK1;
}
"."[xyzw]{4} {
yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
swiz_from_char(yytext[2]),
swiz_from_char(yytext[3]),
swiz_from_char(yytext[4]));
yylval->swiz_mask.mask = 0;
return SWIZZLE;
}
".rgba" {
yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
yylval->swiz_mask.mask = WRITEMASK_XYZW;
return_token_or_DOT(require_ARB_fp, MASK4);
}
".rg"[ba] {
yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
yylval->swiz_mask.mask = WRITEMASK_XY
| mask_from_char(yytext[3]);
return_token_or_DOT(require_ARB_fp, MASK3);
}
".rba" {
yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
yylval->swiz_mask.mask = WRITEMASK_XZW;
return_token_or_DOT(require_ARB_fp, MASK3);
}
".gba" {
yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
yylval->swiz_mask.mask = WRITEMASK_YZW;
return_token_or_DOT(require_ARB_fp, MASK3);
}
".r"[gba] {
yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
yylval->swiz_mask.mask = WRITEMASK_X
| mask_from_char(yytext[2]);
return_token_or_DOT(require_ARB_fp, MASK2);
}
".g"[ba] {
yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
yylval->swiz_mask.mask = WRITEMASK_Y
| mask_from_char(yytext[2]);
return_token_or_DOT(require_ARB_fp, MASK2);
}
".ba" {
yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
yylval->swiz_mask.mask = WRITEMASK_ZW;
return_token_or_DOT(require_ARB_fp, MASK2);
}
"."[gba] {
const unsigned s = swiz_from_char(yytext[1]);
yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
yylval->swiz_mask.mask = mask_from_char(yytext[1]);
return_token_or_DOT(require_ARB_fp, MASK1);
}
".r" {
if (require_ARB_vp) {
return TEXGEN_R;
} else {
yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X,
SWIZZLE_X, SWIZZLE_X);
yylval->swiz_mask.mask = WRITEMASK_X;
return MASK1;
}
}
"."[rgba]{4} {
yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
swiz_from_char(yytext[2]),
swiz_from_char(yytext[3]),
swiz_from_char(yytext[4]));
yylval->swiz_mask.mask = 0;
return_token_or_DOT(require_ARB_fp, SWIZZLE);
}
"." { return DOT; }
\n {
yylloc->first_line++;
yylloc->first_column = 1;
yylloc->last_line++;
yylloc->last_column = 1;
yylloc->position++;
}
[ \t\r]+ /* eat whitespace */ ;
#.*$ /* eat comments */ ;
. { return yytext[0]; }
%%
void
_mesa_program_lexer_ctor(void **scanner, struct asm_parser_state *state,
const char *string, size_t len)
{
yylex_init_extra(state, scanner);
yy_scan_bytes(string, len, *scanner);
}
void
_mesa_program_lexer_dtor(void *scanner)
{
yylex_destroy(scanner);
}
File diff suppressed because it is too large Load Diff
+207
View File
@@ -0,0 +1,207 @@
/* A Bison parser, made by GNU Bison 2.4.1. */
/* Skeleton interface for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
ARBvp_10 = 258,
ARBfp_10 = 259,
ADDRESS = 260,
ALIAS = 261,
ATTRIB = 262,
OPTION = 263,
OUTPUT = 264,
PARAM = 265,
TEMP = 266,
END = 267,
BIN_OP = 268,
BINSC_OP = 269,
SAMPLE_OP = 270,
SCALAR_OP = 271,
TRI_OP = 272,
VECTOR_OP = 273,
ARL = 274,
KIL = 275,
SWZ = 276,
INTEGER = 277,
REAL = 278,
AMBIENT = 279,
ATTENUATION = 280,
BACK = 281,
CLIP = 282,
COLOR = 283,
DEPTH = 284,
DIFFUSE = 285,
DIRECTION = 286,
EMISSION = 287,
ENV = 288,
EYE = 289,
FOG = 290,
FOGCOORD = 291,
FRAGMENT = 292,
FRONT = 293,
HALF = 294,
INVERSE = 295,
INVTRANS = 296,
LIGHT = 297,
LIGHTMODEL = 298,
LIGHTPROD = 299,
LOCAL = 300,
MATERIAL = 301,
MAT_PROGRAM = 302,
MATRIX = 303,
MATRIXINDEX = 304,
MODELVIEW = 305,
MVP = 306,
NORMAL = 307,
OBJECT = 308,
PALETTE = 309,
PARAMS = 310,
PLANE = 311,
POINT = 312,
POINTSIZE = 313,
POSITION = 314,
PRIMARY = 315,
PROGRAM = 316,
PROJECTION = 317,
RANGE = 318,
RESULT = 319,
ROW = 320,
SCENECOLOR = 321,
SECONDARY = 322,
SHININESS = 323,
SIZE = 324,
SPECULAR = 325,
SPOT = 326,
STATE = 327,
TEXCOORD = 328,
TEXENV = 329,
TEXGEN = 330,
TEXGEN_Q = 331,
TEXGEN_R = 332,
TEXGEN_S = 333,
TEXGEN_T = 334,
TEXTURE = 335,
TRANSPOSE = 336,
TEXTURE_UNIT = 337,
TEX_1D = 338,
TEX_2D = 339,
TEX_3D = 340,
TEX_CUBE = 341,
TEX_RECT = 342,
TEX_SHADOW1D = 343,
TEX_SHADOW2D = 344,
TEX_SHADOWRECT = 345,
TEX_ARRAY1D = 346,
TEX_ARRAY2D = 347,
TEX_ARRAYSHADOW1D = 348,
TEX_ARRAYSHADOW2D = 349,
VERTEX = 350,
VTXATTRIB = 351,
WEIGHT = 352,
IDENTIFIER = 353,
MASK4 = 354,
MASK3 = 355,
MASK2 = 356,
MASK1 = 357,
SWIZZLE = 358,
DOT_DOT = 359,
DOT = 360
};
#endif
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
{
/* Line 1676 of yacc.c */
#line 107 "program_parse.y"
struct asm_instruction *inst;
struct asm_symbol *sym;
struct asm_symbol temp_sym;
struct asm_swizzle_mask swiz_mask;
struct asm_src_register src_reg;
struct prog_dst_register dst_reg;
struct prog_instruction temp_inst;
char *string;
unsigned result;
unsigned attrib;
int integer;
float real;
unsigned state[5];
int negate;
struct asm_vector vector;
gl_inst_opcode opcode;
struct {
unsigned swz;
unsigned rgba_valid:1;
unsigned xyzw_valid:1;
unsigned negate:1;
} ext_swizzle;
/* Line 1676 of yacc.c */
#line 185 "program_parse.tab.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
#endif
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
typedef struct YYLTYPE
{
int first_line;
int first_column;
int last_line;
int last_column;
} YYLTYPE;
# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
# define YYLTYPE_IS_DECLARED 1
# define YYLTYPE_IS_TRIVIAL 1
#endif
File diff suppressed because it is too large Load Diff
+117
View File
@@ -0,0 +1,117 @@
/*
* Copyright © 2009 Intel Corporation
*
* 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <string.h>
#include "main/mtypes.h"
#include "prog_instruction.h"
#include "program_parser.h"
/**
* Extra assembly-level parser routines
*
* \author Ian Romanick <ian.d.romanick@intel.com>
*/
int
_mesa_ARBvp_parse_option(struct asm_parser_state *state, const char *option)
{
if (strcmp(option, "ARB_position_invariant") == 0) {
state->option.PositionInvariant = 1;
return 1;
}
return 0;
}
int
_mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option)
{
/* All of the options currently supported start with "ARB_". The code is
* currently structured with nested if-statements because eventually options
* that start with "NV_" will be supported. This structure will result in
* less churn when those options are added.
*/
if (strncmp(option, "ARB_", 4) == 0) {
/* Advance the pointer past the "ARB_" prefix.
*/
option += 4;
if (strncmp(option, "fog_", 4) == 0) {
option += 4;
if (state->option.Fog == OPTION_NONE) {
if (strcmp(option, "exp") == 0) {
state->option.Fog = OPTION_FOG_EXP;
return 1;
} else if (strcmp(option, "exp2") == 0) {
state->option.Fog = OPTION_FOG_EXP2;
return 1;
} else if (strcmp(option, "linear") == 0) {
state->option.Fog = OPTION_FOG_LINEAR;
return 1;
}
}
return 0;
} else if (strncmp(option, "precision_hint_", 15) == 0) {
option += 15;
if (state->option.PrecisionHint == OPTION_NONE) {
if (strcmp(option, "nicest") == 0) {
state->option.PrecisionHint = OPTION_NICEST;
return 1;
} else if (strcmp(option, "fastest") == 0) {
state->option.PrecisionHint = OPTION_FASTEST;
return 1;
}
}
return 0;
} else if (strcmp(option, "draw_buffers") == 0) {
/* Don't need to check extension availability because all Mesa-based
* drivers support GL_ARB_draw_buffers.
*/
state->option.DrawBuffers = 1;
return 1;
} else if (strcmp(option, "fragment_program_shadow") == 0) {
if (state->ctx->Extensions.ARB_fragment_program_shadow) {
state->option.Shadow = 1;
return 1;
}
}
} else if (strncmp(option, "MESA_", 5) == 0) {
option += 5;
if (strcmp(option, "texture_array") == 0) {
if (state->ctx->Extensions.MESA_texture_array) {
state->option.TexArray = 1;
return 1;
}
}
}
return 0;
}
+266
View File
@@ -0,0 +1,266 @@
/*
* Copyright © 2009 Intel Corporation
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*/
#pragma once
#include "main/config.h"
#ifndef MTYPES_H
struct __GLcontextRec;
typedef struct __GLcontextRec GLcontext;
#endif
enum asm_type {
at_none,
at_address,
at_attrib,
at_param,
at_temp,
at_output,
};
struct asm_symbol {
struct asm_symbol *next; /**< List linkage for freeing. */
const char *name;
enum asm_type type;
unsigned attrib_binding;
unsigned output_binding; /**< Output / result register number. */
/**
* One of PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM, or PROGRAM_ENV_PARAM.
*/
unsigned param_binding_type;
/**
* Offset into the program_parameter_list where the tokens representing our
* bound state (or constants) start.
*/
unsigned param_binding_begin;
/* This is how many entries in the the program_parameter_list we take up
* with our state tokens or constants. Note that this is _not_ the same as
* the number of param registers we eventually use.
*/
unsigned param_binding_length;
/**
* Index of the temp register assigned to this variable.
*/
unsigned temp_binding;
/**
* Flag whether or not a PARAM is an array
*/
unsigned param_is_array:1;
/**
* Flag whether or not a PARAM array is accessed indirectly
*/
unsigned param_accessed_indirectly:1;
/**
* \brief Is first pass of parameter layout done with this variable?
*
* The parameter layout routine operates in two passes. This flag tracks
* whether or not the first pass has handled this variable.
*
* \sa _mesa_layout_parameters
*/
unsigned pass1_done:1;
};
struct asm_vector {
unsigned count;
float data[4];
};
struct asm_swizzle_mask {
unsigned swizzle:12;
unsigned mask:4;
};
struct asm_src_register {
struct prog_src_register Base;
/**
* Symbol associated with indirect access to parameter arrays.
*
* If \c Base::RelAddr is 1, this will point to the symbol for the parameter
* that is being dereferenced. Further, \c Base::Index will be the offset
* from the address register being used.
*/
struct asm_symbol *Symbol;
};
struct asm_instruction {
struct prog_instruction Base;
struct asm_instruction *next;
struct asm_src_register SrcReg[3];
};
struct asm_parser_state {
GLcontext *ctx;
struct gl_program *prog;
/**
* Per-program target limits
*/
struct gl_program_constants *limits;
struct _mesa_symbol_table *st;
/**
* Linked list of symbols
*
* This list is \b only used when cleaning up compiler state and freeing
* memory.
*/
struct asm_symbol *sym;
/**
* State for the lexer.
*/
void *scanner;
/**
* Linked list of instructions generated during parsing.
*/
/*@{*/
struct asm_instruction *inst_head;
struct asm_instruction *inst_tail;
/*@}*/
/**
* Selected limits copied from gl_constants
*
* These are limits from the GL context, but various bits in the program
* must be validated against these values.
*/
/*@{*/
unsigned MaxTextureCoordUnits;
unsigned MaxTextureImageUnits;
unsigned MaxTextureUnits;
unsigned MaxClipPlanes;
unsigned MaxLights;
unsigned MaxProgramMatrices;
/*@}*/
/**
* Value to use in state vector accessors for environment and local
* parameters
*/
unsigned state_param_enum;
/**
* Input attributes bound to specific names
*
* This is only needed so that errors can be properly produced when
* multiple ATTRIB statements bind illegal combinations of vertex
* attributes.
*/
unsigned InputsBound;
enum {
invalid_mode = 0,
ARB_vertex,
ARB_fragment
} mode;
struct {
unsigned PositionInvariant:1;
unsigned Fog:2;
unsigned PrecisionHint:2;
unsigned DrawBuffers:1;
unsigned Shadow:1;
unsigned TexRect:1;
unsigned TexArray:1;
} option;
struct {
unsigned UsesKill:1;
} fragment;
};
#define OPTION_NONE 0
#define OPTION_FOG_EXP 1
#define OPTION_FOG_EXP2 2
#define OPTION_FOG_LINEAR 3
#define OPTION_NICEST 1
#define OPTION_FASTEST 2
typedef struct YYLTYPE {
int first_line;
int first_column;
int last_line;
int last_column;
int position;
} YYLTYPE;
#define YYLTYPE_IS_DECLARED 1
#define YYLTYPE_IS_TRIVIAL 1
extern GLboolean _mesa_parse_arb_program(GLcontext *ctx, GLenum target,
const GLubyte *str, GLsizei len, struct asm_parser_state *state);
/* From program_lexer.l. */
extern void _mesa_program_lexer_dtor(void *scanner);
extern void _mesa_program_lexer_ctor(void **scanner,
struct asm_parser_state *state, const char *string, size_t len);
/**
*\name From program_parse_extra.c
*/
/*@{*/
/**
* Parses and processes an option string to an ARB vertex program
*
* \return
* Non-zero on success, zero on failure.
*/
extern int _mesa_ARBvp_parse_option(struct asm_parser_state *state,
const char *option);
/**
* Parses and processes an option string to an ARB fragment program
*
* \return
* Non-zero on success, zero on failure.
*/
extern int _mesa_ARBfp_parse_option(struct asm_parser_state *state,
const char *option);
/*@}*/
+348
View File
@@ -0,0 +1,348 @@
/*
* Copyright © 2008 Intel Corporation
*
* 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include "symbol_table.h"
#include "hash_table.h"
struct symbol {
/**
* Link to the next symbol in the table with the same name
*
* The linked list of symbols with the same name is ordered by scope
* from inner-most to outer-most.
*/
struct symbol *next_with_same_name;
/**
* Link to the next symbol in the table with the same scope
*
* The linked list of symbols with the same scope is unordered. Symbols
* in this list my have unique names.
*/
struct symbol *next_with_same_scope;
/**
* Header information for the list of symbols with the same name.
*/
struct symbol_header *hdr;
/**
* Name space of the symbol
*
* Name space are arbitrary user assigned integers. No two symbols can
* exist in the same name space at the same scope level.
*/
int name_space;
/**
* Arbitrary user supplied data.
*/
void *data;
};
/**
*/
struct symbol_header {
/** Symbol name. */
const char *name;
/** Linked list of symbols with the same name. */
struct symbol *symbols;
};
/**
* Element of the scope stack.
*/
struct scope_level {
/** Link to next (inner) scope level. */
struct scope_level *next;
/** Linked list of symbols with the same scope. */
struct symbol *symbols;
};
/**
*
*/
struct _mesa_symbol_table {
/** Hash table containing all symbols in the symbol table. */
struct hash_table *ht;
/** Top of scope stack. */
struct scope_level *current_scope;
};
struct _mesa_symbol_table_iterator {
/**
* Name space of symbols returned by this iterator.
*/
int name_space;
/**
* Currently iterated symbol
*
* The next call to \c _mesa_symbol_table_iterator_get will return this
* value. It will also update this value to the value that should be
* returned by the next call.
*/
struct symbol *curr;
};
static void
check_symbol_table(struct _mesa_symbol_table *table)
{
#if 1
struct scope_level *scope;
for (scope = table->current_scope; scope != NULL; scope = scope->next) {
struct symbol *sym;
for (sym = scope->symbols
; sym != NULL
; sym = sym->next_with_same_name) {
const struct symbol_header *const hdr = sym->hdr;
struct symbol *sym2;
for (sym2 = hdr->symbols
; sym2 != NULL
; sym2 = sym2->next_with_same_name) {
assert(sym2->hdr == hdr);
}
}
}
#endif
}
void
_mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table)
{
struct scope_level *const scope = table->current_scope;
struct symbol *sym = scope->symbols;
table->current_scope = scope->next;
free(scope);
while (sym != NULL) {
struct symbol *const next = sym->next_with_same_scope;
struct symbol_header *const hdr = sym->hdr;
assert(hdr->symbols == sym);
hdr->symbols = sym->next_with_same_name;
free(sym);
sym = next;
}
check_symbol_table(table);
}
void
_mesa_symbol_table_push_scope(struct _mesa_symbol_table *table)
{
struct scope_level *const scope = calloc(1, sizeof(*scope));
scope->next = table->current_scope;
table->current_scope = scope;
}
static struct symbol_header *
find_symbol(struct _mesa_symbol_table *table, const char *name)
{
return (struct symbol_header *) hash_table_find(table->ht, name);
}
struct _mesa_symbol_table_iterator *
_mesa_symbol_table_iterator_ctor(struct _mesa_symbol_table *table,
int name_space, const char *name)
{
struct _mesa_symbol_table_iterator *iter = calloc(1, sizeof(*iter));
struct symbol_header *const hdr = find_symbol(table, name);
iter->name_space = name_space;
if (hdr != NULL) {
struct symbol *sym;
for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
assert(sym->hdr == hdr);
if ((name_space == -1) || (sym->name_space == name_space)) {
iter->curr = sym;
break;
}
}
}
return iter;
}
void
_mesa_symbol_table_iterator_dtor(struct _mesa_symbol_table_iterator *iter)
{
free(iter);
}
void *
_mesa_symbol_table_iterator_get(struct _mesa_symbol_table_iterator *iter)
{
return (iter->curr == NULL) ? NULL : iter->curr->data;
}
int
_mesa_symbol_table_iterator_next(struct _mesa_symbol_table_iterator *iter)
{
struct symbol_header *hdr;
if (iter->curr == NULL) {
return 0;
}
hdr = iter->curr->hdr;
iter->curr = iter->curr->next_with_same_name;
while (iter->curr != NULL) {
assert(iter->curr->hdr == hdr);
if ((iter->name_space == -1)
|| (iter->curr->name_space == iter->name_space)) {
return 1;
}
iter->curr = iter->curr->next_with_same_name;
}
return 0;
}
void *
_mesa_symbol_table_find_symbol(struct _mesa_symbol_table *table,
int name_space, const char *name)
{
struct symbol_header *const hdr = find_symbol(table, name);
if (hdr != NULL) {
struct symbol *sym;
for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
assert(sym->hdr == hdr);
if ((name_space == -1) || (sym->name_space == name_space)) {
return sym->data;
}
}
}
return NULL;
}
int
_mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table,
int name_space, const char *name,
void *declaration)
{
check_symbol_table(table);
struct symbol_header *hdr = find_symbol(table, name);
struct symbol *sym;
check_symbol_table(table);
if (hdr == NULL) {
hdr = calloc(1, sizeof(*hdr));
hdr->name = name;
hash_table_insert(table->ht, hdr, name);
}
check_symbol_table(table);
sym = calloc(1, sizeof(*sym));
sym->next_with_same_name = hdr->symbols;
sym->next_with_same_scope = table->current_scope->symbols;
sym->hdr = hdr;
sym->name_space = name_space;
sym->data = declaration;
assert(sym->hdr == hdr);
hdr->symbols = sym;
table->current_scope->symbols = sym;
check_symbol_table(table);
return 0;
}
struct _mesa_symbol_table *
_mesa_symbol_table_ctor(void)
{
struct _mesa_symbol_table *table = calloc(1, sizeof(*table));
if (table != NULL) {
table->ht = hash_table_ctor(32, hash_table_string_hash,
hash_table_string_compare);
_mesa_symbol_table_push_scope(table);
}
return table;
}
void
_mesa_symbol_table_dtor(struct _mesa_symbol_table *table)
{
while (table->current_scope != NULL) {
_mesa_symbol_table_pop_scope(table);
}
hash_table_dtor(table->ht);
free(table);
}
+55
View File
@@ -0,0 +1,55 @@
/*
* Copyright © 2008 Intel Corporation
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*/
#ifndef MESA_SYMBOL_TABLE_H
#define MESA_SYMBOL_TABLE_H
struct _mesa_symbol_table;
struct _mesa_symbol_table_iterator;
extern void _mesa_symbol_table_push_scope(struct _mesa_symbol_table *table);
extern void _mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table);
extern int _mesa_symbol_table_add_symbol(struct _mesa_symbol_table *symtab,
int name_space, const char *name, void *declaration);
extern void *_mesa_symbol_table_find_symbol(
struct _mesa_symbol_table *symtab, int name_space, const char *name);
extern struct _mesa_symbol_table *_mesa_symbol_table_ctor(void);
extern void _mesa_symbol_table_dtor(struct _mesa_symbol_table *);
extern struct _mesa_symbol_table_iterator *_mesa_symbol_table_iterator_ctor(
struct _mesa_symbol_table *table, int name_space, const char *name);
extern void _mesa_symbol_table_iterator_dtor(
struct _mesa_symbol_table_iterator *);
extern void *_mesa_symbol_table_iterator_get(
struct _mesa_symbol_table_iterator *iter);
extern int _mesa_symbol_table_iterator_next(
struct _mesa_symbol_table_iterator *iter);
#endif /* MESA_SYMBOL_TABLE_H */
+7 -1
View File
@@ -218,21 +218,27 @@ SHADER_SOURCES = \
shader/arbprogram.c \
shader/atifragshader.c \
shader/grammar/grammar_mesa.c \
shader/hash_table.c \
shader/lex.yy.c \
shader/nvfragparse.c \
shader/nvprogram.c \
shader/nvvertparse.c \
shader/program.c \
shader/program_parse.tab.c \
shader/program_parse_extra.c \
shader/prog_cache.c \
shader/prog_execute.c \
shader/prog_instruction.c \
shader/prog_noise.c \
shader/prog_optimize.c \
shader/prog_parameter.c \
shader/prog_parameter_layout.c \
shader/prog_print.c \
shader/prog_statevars.c \
shader/prog_uniform.c \
shader/programopt.c \
shader/shader_api.c \
shader/symbol_table.c \
shader/shader_api.c
SLANG_SOURCES = \
shader/slang/slang_builtin.c \