summaryrefslogtreecommitdiff
path: root/src/mesa/state_tracker
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/state_tracker')
-rw-r--r--src/mesa/state_tracker/st_atom_shader.c57
-rw-r--r--src/mesa/state_tracker/st_cb_accum.c242
-rw-r--r--src/mesa/state_tracker/st_cb_bufferobjects.c10
-rw-r--r--src/mesa/state_tracker/st_cb_clear.c18
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c30
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c145
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.h13
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.c13
-rw-r--r--src/mesa/state_tracker/st_extensions.c1
-rw-r--r--src/mesa/state_tracker/st_format.c14
-rw-r--r--src/mesa/state_tracker/st_format.h4
-rw-r--r--src/mesa/state_tracker/st_framebuffer.c17
-rw-r--r--src/mesa/state_tracker/st_program.c63
13 files changed, 313 insertions, 314 deletions
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
index fc1ff5be04..ee649be885 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -175,11 +175,12 @@ find_translated_vp(struct st_context *st,
/* See if we need to translate vertex program to TGSI form */
if (xvp->serialNo != stvp->serialNo) {
- GLuint outAttr, dummySlot;
+ GLuint outAttr;
const GLbitfield outputsWritten = stvp->Base.Base.OutputsWritten;
GLuint numVpOuts = 0;
GLboolean emitPntSize = GL_FALSE, emitBFC0 = GL_FALSE, emitBFC1 = GL_FALSE;
- GLint maxGeneric;
+ GLbitfield usedGenerics = 0x0;
+ GLbitfield usedOutputSlots = 0x0;
/* Compute mapping of vertex program outputs to slots, which depends
* on the fragment program's input->slot mapping.
@@ -192,10 +193,12 @@ find_translated_vp(struct st_context *st,
if (outAttr == VERT_RESULT_HPOS) {
/* always put xformed position into slot zero */
- xvp->output_to_slot[VERT_RESULT_HPOS] = 0;
+ GLuint slot = 0;
+ xvp->output_to_slot[VERT_RESULT_HPOS] = slot;
xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_POSITION;
xvp->output_to_semantic_index[outAttr] = 0;
numVpOuts++;
+ usedOutputSlots |= (1 << slot);
}
else if (outputsWritten & (1 << outAttr)) {
/* see if the frag prog wants this vert output */
@@ -209,6 +212,12 @@ find_translated_vp(struct st_context *st,
xvp->output_to_semantic_name[outAttr] = stfp->input_semantic_name[fpInSlot];
xvp->output_to_semantic_index[outAttr] = stfp->input_semantic_index[fpInSlot];
numVpOuts++;
+ usedOutputSlots |= (1 << vpOutSlot);
+ }
+ else {
+#if 0 /*debug*/
+ printf("VP output %d not used by FP\n", outAttr);
+#endif
}
}
else if (outAttr == VERT_RESULT_PSIZ)
@@ -226,45 +235,49 @@ find_translated_vp(struct st_context *st,
/* must do these last */
if (emitPntSize) {
- xvp->output_to_slot[VERT_RESULT_PSIZ] = numVpOuts++;
+ GLuint slot = numVpOuts++;
+ xvp->output_to_slot[VERT_RESULT_PSIZ] = slot;
xvp->output_to_semantic_name[VERT_RESULT_PSIZ] = TGSI_SEMANTIC_PSIZE;
xvp->output_to_semantic_index[VERT_RESULT_PSIZ] = 0;
+ usedOutputSlots |= (1 << slot);
}
if (emitBFC0) {
- xvp->output_to_slot[VERT_RESULT_BFC0] = numVpOuts++;
+ GLuint slot = numVpOuts++;
+ xvp->output_to_slot[VERT_RESULT_BFC0] = slot;
xvp->output_to_semantic_name[VERT_RESULT_BFC0] = TGSI_SEMANTIC_COLOR;
xvp->output_to_semantic_index[VERT_RESULT_BFC0] = 0;
+ usedOutputSlots |= (1 << slot);
}
if (emitBFC1) {
- xvp->output_to_slot[VERT_RESULT_BFC1] = numVpOuts++;
- xvp->output_to_semantic_name[VERT_RESULT_BFC0] = TGSI_SEMANTIC_COLOR;
- xvp->output_to_semantic_index[VERT_RESULT_BFC0] = 1;
+ GLuint slot = numVpOuts++;
+ xvp->output_to_slot[VERT_RESULT_BFC1] = slot;
+ xvp->output_to_semantic_name[VERT_RESULT_BFC1] = TGSI_SEMANTIC_COLOR;
+ xvp->output_to_semantic_index[VERT_RESULT_BFC1] = 1;
+ usedOutputSlots |= (1 << slot);
}
- /* Unneeded vertex program outputs will go to this slot.
- * We could use this info to do dead code elimination in the
- * vertex program.
- */
- dummySlot = numVpOuts;
-
- /* find max GENERIC slot index */
- maxGeneric = -1;
+ /* build usedGenerics mask */
+ usedGenerics = 0x0;
for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
if (xvp->output_to_semantic_name[outAttr] == TGSI_SEMANTIC_GENERIC) {
- maxGeneric = MAX2(maxGeneric,
- xvp->output_to_semantic_index[outAttr]);
+ usedGenerics |= (1 << xvp->output_to_semantic_index[outAttr]);
}
}
- /* Map vert program outputs that aren't used to the dummy slot
- * (and an unused generic attribute slot).
+ /* For each vertex program output that doesn't match up to a fragment
+ * program input, map the vertex program output to a free slot and
+ * free generic attribute.
*/
for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
if (outputsWritten & (1 << outAttr)) {
if (xvp->output_to_slot[outAttr] == UNUSED) {
- xvp->output_to_slot[outAttr] = dummySlot;
+ GLint freeGeneric = _mesa_ffs(~usedGenerics) - 1;
+ GLint freeSlot = _mesa_ffs(~usedOutputSlots) - 1;
+ usedGenerics |= (1 << freeGeneric);
+ usedOutputSlots |= (1 << freeSlot);
+ xvp->output_to_slot[outAttr] = freeSlot;
xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_GENERIC;
- xvp->output_to_semantic_index[outAttr] = maxGeneric + 1;
+ xvp->output_to_semantic_index[outAttr] = freeGeneric;
}
}
diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c
index 7f793cf08d..95181578f6 100644
--- a/src/mesa/state_tracker/st_cb_accum.c
+++ b/src/mesa/state_tracker/st_cb_accum.c
@@ -48,10 +48,6 @@
#include "util/u_tile.h"
-#define UNCLAMPED_FLOAT_TO_SHORT(us, f) \
- us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) )
-
-
/**
* For hardware that supports deep color buffers, we could accelerate
* most/all the accum operations with blending/texturing.
@@ -59,74 +55,20 @@
*/
-/**
- * Wrapper for pipe_get_tile_rgba(). Do format/cpp override to make the
- * tile util function think the surface is 16bit/channel, even if it's not.
- * See also: st_renderbuffer_alloc_storage()
- */
-static void
-acc_get_tile_rgba(struct pipe_context *pipe, struct pipe_transfer *acc_pt,
- uint x, uint y, uint w, uint h, float *p)
-{
- const enum pipe_format f = acc_pt->format;
- const struct pipe_format_block b = acc_pt->block;
-
- acc_pt->format = DEFAULT_ACCUM_PIPE_FORMAT;
- acc_pt->block.size = 8;
- acc_pt->block.width = 1;
- acc_pt->block.height = 1;
-
- pipe_get_tile_rgba(acc_pt, x, y, w, h, p);
-
- acc_pt->format = f;
- acc_pt->block = b;
-}
-
-
-/**
- * Wrapper for pipe_put_tile_rgba(). Do format/cpp override to make the
- * tile util function think the surface is 16bit/channel, even if it's not.
- * See also: st_renderbuffer_alloc_storage()
- */
-static void
-acc_put_tile_rgba(struct pipe_context *pipe, struct pipe_transfer *acc_pt,
- uint x, uint y, uint w, uint h, const float *p)
-{
- enum pipe_format f = acc_pt->format;
- const struct pipe_format_block b = acc_pt->block;
-
- acc_pt->format = DEFAULT_ACCUM_PIPE_FORMAT;
- acc_pt->block.size = 8;
- acc_pt->block.width = 1;
- acc_pt->block.height = 1;
-
- pipe_put_tile_rgba(acc_pt, x, y, w, h, p);
-
- acc_pt->format = f;
- acc_pt->block = b;
-}
-
-
-
void
st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
{
struct st_renderbuffer *acc_strb = st_renderbuffer(rb);
- struct pipe_transfer *acc_pt;
- struct pipe_screen *screen = ctx->st->pipe->screen;
const GLint xpos = ctx->DrawBuffer->_Xmin;
const GLint ypos = ctx->DrawBuffer->_Ymin;
const GLint width = ctx->DrawBuffer->_Xmax - xpos;
const GLint height = ctx->DrawBuffer->_Ymax - ypos;
- GLubyte *map;
-
- acc_pt = st_cond_flush_get_tex_transfer(st_context(ctx), acc_strb->texture,
- 0, 0, 0,
- PIPE_TRANSFER_WRITE, xpos, ypos,
- width, height);
- map = screen->transfer_map(screen, acc_pt);
+ size_t stride = acc_strb->stride;
+ GLubyte *data = acc_strb->data;
- /* note acc_strb->format might not equal acc_pt->format */
+ if(!data)
+ return;
+
switch (acc_strb->format) {
case PIPE_FORMAT_R16G16B16A16_SNORM:
{
@@ -136,7 +78,7 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
GLshort a = FLOAT_TO_SHORT(ctx->Accum.ClearColor[3]);
int i, j;
for (i = 0; i < height; i++) {
- GLshort *dst = (GLshort *) (map + i * acc_pt->stride + xpos * 8);
+ GLshort *dst = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
for (j = 0; j < width; j++) {
dst[0] = r;
dst[1] = g;
@@ -150,9 +92,6 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
default:
_mesa_problem(ctx, "unexpected format in st_clear_accum_buffer()");
}
-
- screen->transfer_unmap(screen, acc_pt);
- screen->tex_transfer_destroy(acc_pt);
}
@@ -162,27 +101,18 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias,
GLint xpos, GLint ypos, GLint width, GLint height,
struct st_renderbuffer *acc_strb)
{
- struct pipe_screen *screen = ctx->st->pipe->screen;
- struct pipe_transfer *acc_pt;
- GLubyte *map;
-
- acc_pt = st_cond_flush_get_tex_transfer(st_context(ctx), acc_strb->texture,
- 0, 0, 0,
- PIPE_TRANSFER_READ_WRITE,
- xpos, ypos,
- width, height);
- map = screen->transfer_map(screen, acc_pt);
+ size_t stride = acc_strb->stride;
+ GLubyte *data = acc_strb->data;
- /* note acc_strb->format might not equal acc_pt->format */
switch (acc_strb->format) {
case PIPE_FORMAT_R16G16B16A16_SNORM:
{
int i, j;
for (i = 0; i < height; i++) {
- GLshort *acc = (GLshort *) (map + (ypos + i) * acc_pt->stride + xpos * 8);
+ GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
for (j = 0; j < width * 4; j++) {
- float val = SHORT_TO_FLOAT(acc[j]) * scale + bias;
- acc[j] = FLOAT_TO_SHORT(val);
+ float val = SHORT_TO_FLOAT(*acc) * scale + bias;
+ *acc++ = FLOAT_TO_SHORT(val);
}
}
}
@@ -190,9 +120,6 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias,
default:
_mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
}
-
- screen->transfer_unmap(screen, acc_pt);
- screen->tex_transfer_destroy(acc_pt);
}
@@ -204,39 +131,39 @@ accum_accum(struct st_context *st, GLfloat value,
{
struct pipe_context *pipe = st->pipe;
struct pipe_screen *screen = pipe->screen;
- struct pipe_transfer *acc_trans, *color_trans;
- GLfloat *colorBuf, *accBuf;
- GLint i;
-
- acc_trans = st_cond_flush_get_tex_transfer(st, acc_strb->texture, 0, 0, 0,
- PIPE_TRANSFER_READ, xpos, ypos,
- width, height);
+ struct pipe_transfer *color_trans;
+ size_t stride = acc_strb->stride;
+ GLubyte *data = acc_strb->data;
+ GLfloat *buf;
color_trans = st_cond_flush_get_tex_transfer(st, color_strb->texture,
0, 0, 0,
PIPE_TRANSFER_READ, xpos, ypos,
width, height);
- colorBuf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
- accBuf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
+ buf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
- pipe_get_tile_rgba(color_trans, 0, 0, width, height, colorBuf);
- acc_get_tile_rgba(pipe, acc_trans, 0, 0, width, height, accBuf);
+ pipe_get_tile_rgba(color_trans, 0, 0, width, height, buf);
- for (i = 0; i < 4 * width * height; i++) {
- accBuf[i] = accBuf[i] + colorBuf[i] * value;
+ switch (acc_strb->format) {
+ case PIPE_FORMAT_R16G16B16A16_SNORM:
+ {
+ const GLfloat *color = buf;
+ int i, j;
+ for (i = 0; i < height; i++) {
+ GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
+ for (j = 0; j < width * 4; j++) {
+ float val = *color++ * value;
+ *acc++ += FLOAT_TO_SHORT(val);
+ }
+ }
+ }
+ break;
+ default:
+ _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
}
- screen->tex_transfer_destroy(acc_trans);
- acc_trans = st_no_flush_get_tex_transfer(st, acc_strb->texture, 0, 0, 0,
- PIPE_TRANSFER_WRITE, xpos, ypos,
- width, height);
-
- acc_put_tile_rgba(pipe, acc_trans, 0, 0, width, height, accBuf);
-
- _mesa_free(colorBuf);
- _mesa_free(accBuf);
- screen->tex_transfer_destroy(acc_trans);
+ _mesa_free(buf);
screen->tex_transfer_destroy(color_trans);
}
@@ -249,13 +176,10 @@ accum_load(struct st_context *st, GLfloat value,
{
struct pipe_context *pipe = st->pipe;
struct pipe_screen *screen = pipe->screen;
- struct pipe_transfer *acc_trans, *color_trans;
+ struct pipe_transfer *color_trans;
+ size_t stride = acc_strb->stride;
+ GLubyte *data = acc_strb->data;
GLfloat *buf;
- GLint i;
-
- acc_trans = st_cond_flush_get_tex_transfer(st, acc_strb->texture, 0, 0, 0,
- PIPE_TRANSFER_WRITE, xpos, ypos,
- width, height);
color_trans = st_cond_flush_get_tex_transfer(st, color_strb->texture,
0, 0, 0,
@@ -266,14 +190,25 @@ accum_load(struct st_context *st, GLfloat value,
pipe_get_tile_rgba(color_trans, 0, 0, width, height, buf);
- for (i = 0; i < 4 * width * height; i++) {
- buf[i] = buf[i] * value;
+ switch (acc_strb->format) {
+ case PIPE_FORMAT_R16G16B16A16_SNORM:
+ {
+ const GLfloat *color = buf;
+ int i, j;
+ for (i = 0; i < height; i++) {
+ GLshort *acc = (GLshort *) (data + (ypos + i) * stride + xpos * 8);
+ for (j = 0; j < width * 4; j++) {
+ float val = *color++ * value;
+ *acc++ = FLOAT_TO_SHORT(val);
+ }
+ }
+ }
+ break;
+ default:
+ _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
}
- acc_put_tile_rgba(pipe, acc_trans, 0, 0, width, height, buf);
-
_mesa_free(buf);
- screen->tex_transfer_destroy(acc_trans);
screen->tex_transfer_destroy(color_trans);
}
@@ -287,48 +222,58 @@ accum_return(GLcontext *ctx, GLfloat value,
struct pipe_context *pipe = ctx->st->pipe;
struct pipe_screen *screen = pipe->screen;
const GLubyte *colormask = ctx->Color.ColorMask;
- struct pipe_transfer *acc_trans, *color_trans;
- GLfloat *abuf, *cbuf = NULL;
- GLint i, ch;
-
- abuf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
+ enum pipe_transfer_usage usage;
+ struct pipe_transfer *color_trans;
+ size_t stride = acc_strb->stride;
+ const GLubyte *data = acc_strb->data;
+ GLfloat *buf;
- acc_trans = st_cond_flush_get_tex_transfer(st_context(ctx),
- acc_strb->texture, 0, 0, 0,
- PIPE_TRANSFER_READ, xpos, ypos,
- width, height);
+ buf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
+ if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3])
+ usage = PIPE_TRANSFER_READ_WRITE;
+ else
+ usage = PIPE_TRANSFER_WRITE;
+
color_trans = st_cond_flush_get_tex_transfer(st_context(ctx),
color_strb->texture, 0, 0, 0,
- PIPE_TRANSFER_READ_WRITE,
+ usage,
xpos, ypos,
width, height);
- acc_get_tile_rgba(pipe, acc_trans, 0, 0, width, height, abuf);
-
- if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3]) {
- cbuf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
- pipe_get_tile_rgba(color_trans, 0, 0, width, height, cbuf);
- }
+ if (usage != PIPE_TRANSFER_WRITE)
+ pipe_get_tile_rgba(color_trans, 0, 0, width, height, buf);
- for (i = 0; i < width * height; i++) {
- for (ch = 0; ch < 4; ch++) {
- if (colormask[ch]) {
- GLfloat val = abuf[i * 4 + ch] * value;
- abuf[i * 4 + ch] = CLAMP(val, 0.0f, 1.0f);
- }
- else {
- abuf[i * 4 + ch] = cbuf[i * 4 + ch];
+ switch (acc_strb->format) {
+ case PIPE_FORMAT_R16G16B16A16_SNORM:
+ {
+ GLfloat *color = buf;
+ int i, j, ch;
+ for (i = 0; i < height; i++) {
+ const GLshort *acc = (const GLshort *) (data + (ypos + i) * stride + xpos * 8);
+ for (j = 0; j < width; j++) {
+ for (ch = 0; ch < 4; ch++) {
+ if (colormask[ch]) {
+ GLfloat val = SHORT_TO_FLOAT(*acc * value);
+ *color = CLAMP(val, 0.0f, 1.0f);
+ }
+ else {
+ /* No change */
+ }
+ ++acc;
+ ++color;
+ }
+ }
}
}
+ break;
+ default:
+ _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
}
- pipe_put_tile_rgba(color_trans, 0, 0, width, height, abuf);
+ pipe_put_tile_rgba(color_trans, 0, 0, width, height, buf);
- _mesa_free(abuf);
- if (cbuf)
- _mesa_free(cbuf);
- screen->tex_transfer_destroy(acc_trans);
+ _mesa_free(buf);
screen->tex_transfer_destroy(color_trans);
}
@@ -347,6 +292,9 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value)
const GLint width = ctx->DrawBuffer->_Xmax - xpos;
const GLint height = ctx->DrawBuffer->_Ymax - ypos;
+ if(!acc_strb->data)
+ return;
+
/* make sure color bufs aren't cached */
st_flush( st, PIPE_FLUSH_RENDER_CACHE, NULL );
diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c
index f140641d7e..7021d73208 100644
--- a/src/mesa/state_tracker/st_cb_bufferobjects.c
+++ b/src/mesa/state_tracker/st_cb_bufferobjects.c
@@ -245,11 +245,10 @@ st_bufferobj_map_range(GLcontext *ctx, GLenum target,
assert(offset < obj->Size);
assert(offset + length <= obj->Size);
- map = obj->Pointer = pipe_buffer_map_range(pipe->screen, st_obj->buffer,
- offset, length, flags);
- if (obj->Pointer) {
- obj->Offset = 0;
- obj->Length = obj->Size;
+ map = obj->Pointer = pipe_buffer_map_range(pipe->screen, st_obj->buffer, offset, length, flags);
+ if(obj->Pointer) {
+ obj->Offset = offset;
+ obj->Length = length;
map += offset;
}
@@ -268,7 +267,6 @@ st_bufferobj_flush_mapped_range(GLcontext *ctx, GLenum target,
/* Subrange is relative to mapped range */
assert(offset >= 0);
assert(length >= 0);
- assert(offset < obj->Length);
assert(offset + length <= obj->Length);
pipe_buffer_flush_mapped_range(pipe->screen, st_obj->buffer,
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index 880e83108c..668acbccb8 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -103,20 +103,6 @@ st_destroy_clear(struct st_context *st)
}
-static GLboolean
-is_depth_stencil_format(enum pipe_format pipeFormat)
-{
- switch (pipeFormat) {
- case PIPE_FORMAT_S8Z24_UNORM:
- case PIPE_FORMAT_Z24S8_UNORM:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-
/**
* Draw a screen-aligned quadrilateral.
* Coords are window coords with y=0=bottom. These will be passed
@@ -331,7 +317,7 @@ static INLINE GLboolean
check_clear_depth_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
{
const struct st_renderbuffer *strb = st_renderbuffer(rb);
- const GLboolean isDS = is_depth_stencil_format(strb->surface->format);
+ const GLboolean isDS = pf_is_depth_and_stencil(strb->surface->format);
if (ctx->Scissor.Enabled)
return TRUE;
@@ -351,7 +337,7 @@ static INLINE GLboolean
check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
{
const struct st_renderbuffer *strb = st_renderbuffer(rb);
- const GLboolean isDS = is_depth_stencil_format(strb->surface->format);
+ const GLboolean isDS = pf_is_depth_and_stencil(strb->surface->format);
const GLuint stencilMax = (1 << rb->StencilBits) - 1;
const GLboolean maskStencil
= (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 89725cfe8d..2027b713ce 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -630,6 +630,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
struct pipe_context *pipe = st->pipe;
struct pipe_screen *screen = pipe->screen;
struct st_renderbuffer *strb;
+ enum pipe_transfer_usage usage;
struct pipe_transfer *pt;
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
GLint skipPixels;
@@ -642,8 +643,14 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
y = ctx->DrawBuffer->Height - y - height;
}
+ if(format != GL_DEPTH_STENCIL &&
+ pf_get_component_bits( strb->format, PIPE_FORMAT_COMP_Z ) != 0)
+ usage = PIPE_TRANSFER_READ_WRITE;
+ else
+ usage = PIPE_TRANSFER_WRITE;
+
pt = st_cond_flush_get_tex_transfer(st_context(ctx), strb->texture, 0, 0, 0,
- PIPE_TRANSFER_WRITE, x, y,
+ usage, x, y,
width, height);
stmap = screen->transfer_map(screen, pt);
@@ -694,6 +701,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
case PIPE_FORMAT_S8_UNORM:
{
ubyte *dest = stmap + spanY * pt->stride + spanX;
+ assert(usage == PIPE_TRANSFER_WRITE);
memcpy(dest, sValues, spanWidth);
}
break;
@@ -701,6 +709,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
if (format == GL_DEPTH_STENCIL) {
uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4);
GLint k;
+ assert(usage == PIPE_TRANSFER_WRITE);
for (k = 0; k < spanWidth; k++) {
dest[k] = zValues[k] | (sValues[k] << 24);
}
@@ -708,6 +717,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
else {
uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4);
GLint k;
+ assert(usage == PIPE_TRANSFER_READ_WRITE);
for (k = 0; k < spanWidth; k++) {
dest[k] = (dest[k] & 0xffffff) | (sValues[k] << 24);
}
@@ -717,13 +727,15 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
if (format == GL_DEPTH_STENCIL) {
uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4);
GLint k;
+ assert(usage == PIPE_TRANSFER_WRITE);
for (k = 0; k < spanWidth; k++) {
- dest[k] = zValues[k] | (sValues[k] << 24);
+ dest[k] = (zValues[k] << 8) | (sValues[k] & 0xff);
}
}
else {
uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4);
GLint k;
+ assert(usage == PIPE_TRANSFER_READ_WRITE);
for (k = 0; k < spanWidth; k++) {
dest[k] = (dest[k] & 0xffffff00) | (sValues[k] & 0xff);
}
@@ -757,7 +769,6 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
struct st_vertex_program *stvp;
struct st_context *st = ctx->st;
struct pipe_surface *ps;
- GLuint bufferFormat;
const GLfloat *color;
if (format == GL_STENCIL_INDEX ||
@@ -785,8 +796,6 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
color = NULL;
}
- bufferFormat = ps->format;
-
/* draw with textured quad */
{
struct pipe_texture *pt
@@ -811,6 +820,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
{
struct st_renderbuffer *rbDraw = st_renderbuffer(ctx->DrawBuffer->_StencilBuffer);
struct pipe_screen *screen = ctx->st->pipe->screen;
+ enum pipe_transfer_usage usage;
struct pipe_transfer *ptDraw;
ubyte *drawMap;
ubyte *buffer;
@@ -827,9 +837,14 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
GL_STENCIL_INDEX, GL_UNSIGNED_BYTE,
&ctx->DefaultPacking, buffer);
+ if(pf_get_component_bits( rbDraw->format, PIPE_FORMAT_COMP_Z ) != 0)
+ usage = PIPE_TRANSFER_READ_WRITE;
+ else
+ usage = PIPE_TRANSFER_WRITE;
+
ptDraw = st_cond_flush_get_tex_transfer(st_context(ctx),
rbDraw->texture, 0, 0, 0,
- PIPE_TRANSFER_WRITE, dstx, dsty,
+ usage, dstx, dsty,
width, height);
assert(ptDraw->block.width == 1);
@@ -859,6 +874,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
{
uint *dst4 = (uint *) dst;
int j;
+ assert(usage == PIPE_TRANSFER_READ_WRITE);
for (j = 0; j < width; j++) {
*dst4 = (*dst4 & 0xffffff) | (src[j] << 24);
dst4++;
@@ -869,6 +885,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
{
uint *dst4 = (uint *) dst;
int j;
+ assert(usage == PIPE_TRANSFER_READ_WRITE);
for (j = 0; j < width; j++) {
*dst4 = (*dst4 & 0xffffff00) | (src[j] & 0xff);
dst4++;
@@ -876,6 +893,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
}
break;
case PIPE_FORMAT_S8_UNORM:
+ assert(usage == PIPE_TRANSFER_WRITE);
memcpy(dst, src, width);
break;
default:
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index c249f3b357..ecdb988033 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -88,93 +88,92 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
{
struct pipe_context *pipe = ctx->st->pipe;
struct st_renderbuffer *strb = st_renderbuffer(rb);
- struct pipe_texture template;
- unsigned surface_usage;
-
- /* Free the old surface and texture
- */
- pipe_surface_reference( &strb->surface, NULL );
- pipe_texture_reference( &strb->texture, NULL );
-
- /* Setup new texture template.
- */
- memset(&template, 0, sizeof(template));
- template.target = PIPE_TEXTURE_2D;
- if (strb->format != PIPE_FORMAT_NONE) {
- template.format = strb->format;
- }
- else {
- template.format = st_choose_renderbuffer_format(pipe, internalFormat);
- }
- pf_get_block(template.format, &template.block);
- template.width[0] = width;
- template.height[0] = height;
- template.depth[0] = 1;
- template.last_level = 0;
- template.nr_samples = rb->NumSamples;
- if (pf_is_depth_stencil(template.format)) {
- template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
- }
- else {
- template.tex_usage = (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_RENDER_TARGET);
- }
+ enum pipe_format format;
+ if (strb->format != PIPE_FORMAT_NONE)
+ format = strb->format;
+ else
+ format = st_choose_renderbuffer_format(pipe, internalFormat);
+
/* init renderbuffer fields */
strb->Base.Width = width;
strb->Base.Height = height;
- init_renderbuffer_bits(strb, template.format);
+ init_renderbuffer_bits(strb, format);
strb->defined = GL_FALSE; /* undefined contents now */
- /* Probably need dedicated flags for surface usage too:
- */
- surface_usage = (PIPE_BUFFER_USAGE_GPU_READ |
- PIPE_BUFFER_USAGE_GPU_WRITE);
-#if 0
- PIPE_BUFFER_USAGE_CPU_READ |
- PIPE_BUFFER_USAGE_CPU_WRITE);
-#endif
+ if(strb->software) {
+ struct pipe_format_block block;
+ size_t size;
+
+ _mesa_free(strb->data);
- strb->texture = pipe->screen->texture_create( pipe->screen,
- &template );
+ assert(strb->format != PIPE_FORMAT_NONE);
+ pf_get_block(strb->format, &block);
+
+ strb->stride = pf_get_stride(&block, width);
+ size = pf_get_2d_size(&block, strb->stride, height);
+
+ strb->data = _mesa_malloc(size);
+
+ return strb->data != NULL;
+ }
+ else {
+ struct pipe_texture template;
+ unsigned surface_usage;
+
+ /* Free the old surface and texture
+ */
+ pipe_surface_reference( &strb->surface, NULL );
+ pipe_texture_reference( &strb->texture, NULL );
- /* Special path for accum buffers.
- *
- * Try a different surface format. Since accum buffers are s/w
- * only for now, the surface pixel format doesn't really matter,
- * only that the buffer is large enough.
- */
- if (!strb->texture && template.format == DEFAULT_ACCUM_PIPE_FORMAT)
- {
- /* Actually, just setting this usage value should be sufficient
- * to tell the driver to go ahead and allocate the buffer, even
- * if HW doesn't support the format.
+ /* Setup new texture template.
+ */
+ memset(&template, 0, sizeof(template));
+ template.target = PIPE_TEXTURE_2D;
+ template.format = format;
+ pf_get_block(format, &template.block);
+ template.width[0] = width;
+ template.height[0] = height;
+ template.depth[0] = 1;
+ template.last_level = 0;
+ template.nr_samples = rb->NumSamples;
+ if (pf_is_depth_stencil(format)) {
+ template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
+ }
+ else {
+ template.tex_usage = (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_RENDER_TARGET);
+ }
+
+ /* Probably need dedicated flags for surface usage too:
*/
- template.tex_usage = 0;
- surface_usage = (PIPE_BUFFER_USAGE_CPU_READ |
+ surface_usage = (PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+#if 0
+ PIPE_BUFFER_USAGE_CPU_READ |
PIPE_BUFFER_USAGE_CPU_WRITE);
+#endif
strb->texture = pipe->screen->texture_create( pipe->screen,
&template );
- }
+ if (!strb->texture)
+ return FALSE;
- if (!strb->texture)
- return FALSE;
+ strb->surface = pipe->screen->get_tex_surface( pipe->screen,
+ strb->texture,
+ 0, 0, 0,
+ surface_usage );
- strb->surface = pipe->screen->get_tex_surface( pipe->screen,
- strb->texture,
- 0, 0, 0,
- surface_usage );
+ assert(strb->surface->texture);
+ assert(strb->surface->format);
+ assert(strb->surface->width == width);
+ assert(strb->surface->height == height);
- assert(strb->surface->texture);
- assert(strb->surface->format);
- assert(strb->surface->width == width);
- assert(strb->surface->height == height);
-
- return strb->surface != NULL;
+ return strb->surface != NULL;
+ }
}
@@ -188,6 +187,7 @@ st_renderbuffer_delete(struct gl_renderbuffer *rb)
ASSERT(strb);
pipe_surface_reference(&strb->surface, NULL);
pipe_texture_reference(&strb->texture, NULL);
+ _mesa_free(strb->data);
_mesa_free(strb);
}
@@ -244,7 +244,7 @@ st_new_renderbuffer(GLcontext *ctx, GLuint name)
* renderbuffer). The window system code determines the format.
*/
struct gl_renderbuffer *
-st_new_renderbuffer_fb(enum pipe_format format, int samples)
+st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw)
{
struct st_renderbuffer *strb;
@@ -258,7 +258,8 @@ st_new_renderbuffer_fb(enum pipe_format format, int samples)
strb->Base.ClassID = 0x4242; /* just a unique value */
strb->Base.NumSamples = samples;
strb->format = format;
-
+ strb->software = sw;
+
switch (format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
case PIPE_FORMAT_B8G8R8A8_UNORM:
@@ -289,7 +290,7 @@ st_new_renderbuffer_fb(enum pipe_format format, int samples)
strb->Base.InternalFormat = GL_STENCIL_INDEX8_EXT;
strb->Base._BaseFormat = GL_STENCIL_INDEX;
break;
- case DEFAULT_ACCUM_PIPE_FORMAT: /*PIPE_FORMAT_R16G16B16A16_SNORM*/
+ case PIPE_FORMAT_R16G16B16A16_SNORM:
strb->Base.InternalFormat = GL_RGBA16;
strb->Base._BaseFormat = GL_RGBA;
break;
@@ -536,7 +537,7 @@ check_create_front_buffer(GLcontext *ctx, struct gl_framebuffer *fb,
samples = back->Base.NumSamples;
/* create front renderbuffer */
- front = st_new_renderbuffer_fb(colorFormat, samples);
+ front = st_new_renderbuffer_fb(colorFormat, samples, FALSE);
_mesa_add_renderbuffer(fb, frontIndex, front);
/* alloc texture/surface for new front buffer */
diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h
index fd77d0a95b..bea6eb89c3 100644
--- a/src/mesa/state_tracker/st_cb_fbo.h
+++ b/src/mesa/state_tracker/st_cb_fbo.h
@@ -30,10 +30,6 @@
#define ST_CB_FBO_H
-#define DEFAULT_ACCUM_PIPE_FORMAT PIPE_FORMAT_R16G16B16A16_SNORM
-
-
-
/**
* Derived renderbuffer class. Just need to add a pointer to the
* pipe surface.
@@ -46,6 +42,13 @@ struct st_renderbuffer
enum pipe_format format; /** preferred format, or PIPE_FORMAT_NONE */
GLboolean defined; /**< defined contents? */
+ /**
+ * Used only when hardware accumulation buffers are not supported.
+ */
+ boolean software;
+ size_t stride;
+ void *data;
+
struct st_texture_object *rtt; /**< GL render to texture's texture */
int rtt_level, rtt_face, rtt_slice;
@@ -63,7 +66,7 @@ st_renderbuffer(struct gl_renderbuffer *rb)
extern struct gl_renderbuffer *
-st_new_renderbuffer_fb(enum pipe_format format, int samples);
+st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw);
extern void
st_init_fbo_functions(struct dd_function_table *functions);
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
index 7a4bbf5ce3..ccf1a0b563 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -112,7 +112,7 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
case PIPE_FORMAT_S8Z24_UNORM:
if (format == GL_DEPTH_STENCIL) {
const uint *src = (uint *) (stmap + srcY * pt->stride);
- const GLfloat scale = 1.0 / (0xffffff);
+ const GLfloat scale = 1.0f / (0xffffff);
GLint k;
for (k = 0; k < width; k++) {
sValues[k] = src[k] >> 24;
@@ -130,7 +130,7 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
case PIPE_FORMAT_Z24S8_UNORM:
if (format == GL_DEPTH_STENCIL) {
const uint *src = (uint *) (stmap + srcY * pt->stride);
- const GLfloat scale = 1.0 / (0xffffff);
+ const GLfloat scale = 1.0f / (0xffffff);
GLint k;
for (k = 0; k < width; k++) {
sValues[k] = src[k] & 0xff;
@@ -445,11 +445,16 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
}
}
else {
- /* untested, but simple: */
+ /* XXX: unreachable code -- should be before st_read_stencil_pixels */
assert(format == GL_DEPTH_STENCIL_EXT);
for (i = 0; i < height; i++) {
+ GLuint *zshort = (GLuint *)dst;
pipe_get_tile_raw(trans, 0, y, width, 1, dst, 0);
y += yStep;
+ /* Reverse into 24/8 */
+ for (j = 0; j < width; j++) {
+ zshort[j] = (zshort[j] << 8) | (zshort[j] >> 24);
+ }
dst += dstStride;
}
}
@@ -472,7 +477,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
}
}
else {
- /* untested, but simple: */
+ /* XXX: unreachable code -- should be before st_read_stencil_pixels */
assert(format == GL_DEPTH_STENCIL_EXT);
for (i = 0; i < height; i++) {
pipe_get_tile_raw(trans, 0, y, width, 1, dst, 0);
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index dc65b8b5f5..8f63819e63 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -175,6 +175,7 @@ void st_init_extensions(struct st_context *st)
ctx->Extensions.NV_blend_square = GL_TRUE;
ctx->Extensions.NV_texgen_reflection = GL_TRUE;
+ ctx->Extensions.NV_texture_env_combine4 = GL_TRUE;
ctx->Extensions.SGI_color_matrix = GL_TRUE;
ctx->Extensions.SGIS_generate_mipmap = GL_TRUE;
diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
index d507e3e58d..b243c249e3 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -392,7 +392,7 @@ default_depth_format(struct pipe_screen *screen,
* or PIPE_TEXTURE_USAGE_SAMPLER
*/
enum pipe_format
-st_choose_format(struct pipe_context *pipe, GLint internalFormat,
+st_choose_format(struct pipe_context *pipe, GLenum internalFormat,
enum pipe_texture_target target, unsigned tex_usage)
{
struct pipe_screen *screen = pipe->screen;
@@ -594,9 +594,13 @@ st_choose_format(struct pipe_context *pipe, GLint internalFormat,
static GLboolean
-is_stencil_format(GLenum format)
+is_depth_or_stencil_format(GLenum internalFormat)
{
- switch (format) {
+ switch (internalFormat) {
+ case GL_DEPTH_COMPONENT:
+ case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH_COMPONENT24:
+ case GL_DEPTH_COMPONENT32:
case GL_STENCIL_INDEX:
case GL_STENCIL_INDEX1_EXT:
case GL_STENCIL_INDEX4_EXT:
@@ -614,10 +618,10 @@ is_stencil_format(GLenum format)
* Called by FBO code to choose a PIPE_FORMAT_ for drawing surfaces.
*/
enum pipe_format
-st_choose_renderbuffer_format(struct pipe_context *pipe, GLint internalFormat)
+st_choose_renderbuffer_format(struct pipe_context *pipe, GLenum internalFormat)
{
uint usage;
- if (is_stencil_format(internalFormat))
+ if (is_depth_or_stencil_format(internalFormat))
usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
else
usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h
index 7bbbe2d570..9d9e02fe9b 100644
--- a/src/mesa/state_tracker/st_format.h
+++ b/src/mesa/state_tracker/st_format.h
@@ -64,11 +64,11 @@ st_mesa_format_to_pipe_format(GLuint mesaFormat);
extern enum pipe_format
-st_choose_format(struct pipe_context *pipe, GLint internalFormat,
+st_choose_format(struct pipe_context *pipe, GLenum internalFormat,
enum pipe_texture_target target, unsigned tex_usage);
extern enum pipe_format
-st_choose_renderbuffer_format(struct pipe_context *pipe, GLint internalFormat);
+st_choose_renderbuffer_format(struct pipe_context *pipe, GLenum internalFormat);
extern const struct gl_texture_format *
diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c
index ef800291cc..7072cbe62c 100644
--- a/src/mesa/state_tracker/st_framebuffer.c
+++ b/src/mesa/state_tracker/st_framebuffer.c
@@ -60,7 +60,7 @@ st_create_framebuffer( const __GLcontextModes *visual,
if (visual->doubleBufferMode) {
struct gl_renderbuffer *rb
- = st_new_renderbuffer_fb(colorFormat, samples);
+ = st_new_renderbuffer_fb(colorFormat, samples, FALSE);
_mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb);
}
else {
@@ -69,14 +69,14 @@ st_create_framebuffer( const __GLcontextModes *visual,
* See check_create_front_buffers().
*/
struct gl_renderbuffer *rb
- = st_new_renderbuffer_fb(colorFormat, samples);
+ = st_new_renderbuffer_fb(colorFormat, samples, FALSE);
_mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb);
}
if (depthFormat == stencilFormat && depthFormat != PIPE_FORMAT_NONE) {
/* combined depth/stencil buffer */
struct gl_renderbuffer *depthStencilRb
- = st_new_renderbuffer_fb(depthFormat, samples);
+ = st_new_renderbuffer_fb(depthFormat, samples, FALSE);
/* note: bind RB to two attachment points */
_mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthStencilRb);
_mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, depthStencilRb);
@@ -87,34 +87,35 @@ st_create_framebuffer( const __GLcontextModes *visual,
if (visual->depthBits == 32) {
/* 32-bit depth buffer */
struct gl_renderbuffer *depthRb
- = st_new_renderbuffer_fb(depthFormat, samples);
+ = st_new_renderbuffer_fb(depthFormat, samples, FALSE);
_mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb);
}
else if (visual->depthBits == 24) {
/* 24-bit depth buffer, ignore stencil bits */
struct gl_renderbuffer *depthRb
- = st_new_renderbuffer_fb(depthFormat, samples);
+ = st_new_renderbuffer_fb(depthFormat, samples, FALSE);
_mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb);
}
else if (visual->depthBits > 0) {
/* 16-bit depth buffer */
struct gl_renderbuffer *depthRb
- = st_new_renderbuffer_fb(depthFormat, samples);
+ = st_new_renderbuffer_fb(depthFormat, samples, FALSE);
_mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb);
}
if (visual->stencilBits > 0) {
/* 8-bit stencil */
struct gl_renderbuffer *stencilRb
- = st_new_renderbuffer_fb(stencilFormat, samples);
+ = st_new_renderbuffer_fb(stencilFormat, samples, FALSE);
_mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, stencilRb);
}
}
if (visual->accumRedBits > 0) {
/* 16-bit/channel accum */
+ /* TODO: query the pipe screen for accumulation buffer format support */
struct gl_renderbuffer *accumRb
- = st_new_renderbuffer_fb(DEFAULT_ACCUM_PIPE_FORMAT, 0); /* XXX accum isn't multisampled right? */
+ = st_new_renderbuffer_fb(PIPE_FORMAT_R16G16B16A16_SNORM, 0, TRUE);
_mesa_add_renderbuffer(&stfb->Base, BUFFER_ACCUM, accumRb);
}
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index 34926101ed..263dcc03b5 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -55,20 +55,6 @@
#define TGSI_DEBUG 0
-/** XXX we should use the version of this from u_memory.h but including
- * that header causes symbol collisions.
- */
-static INLINE void *
-mem_dup(const void *src, uint size)
-{
- void *dup = _mesa_malloc(size);
- if (dup)
- _mesa_memcpy(dup, src, size);
- return dup;
-}
-
-
-
/**
* Translate a Mesa vertex shader into a TGSI shader.
* \param outputMapping to map vertex program output registers (VERT_RESULT_x)
@@ -84,7 +70,7 @@ st_translate_vertex_program(struct st_context *st,
const ubyte *outputSemanticIndex)
{
struct pipe_context *pipe = st->pipe;
- struct tgsi_token tokens[ST_MAX_SHADER_TOKENS];
+ struct tgsi_token *tokens;
GLuint defaultOutputMapping[VERT_RESULT_MAX];
struct pipe_shader_state vs;
GLuint attr, i;
@@ -102,6 +88,13 @@ st_translate_vertex_program(struct st_context *st,
GLbitfield input_flags[MAX_PROGRAM_INPUTS];
GLbitfield output_flags[MAX_PROGRAM_OUTPUTS];
+ tokens = (struct tgsi_token *)MALLOC(ST_MAX_SHADER_TOKENS * sizeof *tokens);
+ if(!tokens) {
+ /* FIXME: propagate error to the caller */
+ assert(0);
+ return;
+ }
+
memset(&vs, 0, sizeof(vs));
memset(input_flags, 0, sizeof(input_flags));
memset(output_flags, 0, sizeof(output_flags));
@@ -297,9 +290,6 @@ st_translate_vertex_program(struct st_context *st,
}
}
- assert(vs_output_semantic_name[0] == TGSI_SEMANTIC_POSITION);
-
-
if (outputMapping) {
/* find max output slot referenced to compute vs_num_outputs */
GLuint maxSlot = 0;
@@ -313,6 +303,26 @@ st_translate_vertex_program(struct st_context *st,
outputMapping = defaultOutputMapping;
}
+#if 0 /* debug */
+ {
+ GLuint i;
+ printf("outputMapping? %d\n", outputMapping ? 1 : 0);
+ if (outputMapping) {
+ printf("attr -> slot\n");
+ for (i = 0; i < 16; i++) {
+ printf(" %2d %3d\n", i, outputMapping[i]);
+ }
+ }
+ printf("slot sem_name sem_index\n");
+ for (i = 0; i < vs_num_outputs; i++) {
+ printf(" %2d %d %d\n",
+ i,
+ vs_output_semantic_name[i],
+ vs_output_semantic_index[i]);
+ }
+ }
+#endif
+
/* free old shader state, if any */
if (stvp->state.tokens) {
_mesa_free((void *) stvp->state.tokens);
@@ -347,7 +357,9 @@ st_translate_vertex_program(struct st_context *st,
assert(num_tokens < ST_MAX_SHADER_TOKENS);
vs.tokens = (struct tgsi_token *)
- mem_dup(tokens, num_tokens * sizeof(tokens[0]));
+ _mesa_realloc(tokens,
+ ST_MAX_SHADER_TOKENS * sizeof *tokens,
+ num_tokens * sizeof *tokens);
stvp->num_inputs = vs_num_inputs;
stvp->state = vs; /* struct copy */
@@ -375,7 +387,7 @@ st_translate_fragment_program(struct st_context *st,
const GLuint inputMapping[])
{
struct pipe_context *pipe = st->pipe;
- struct tgsi_token tokens[ST_MAX_SHADER_TOKENS];
+ struct tgsi_token *tokens;
GLuint outputMapping[FRAG_RESULT_MAX];
GLuint defaultInputMapping[FRAG_ATTRIB_MAX];
struct pipe_shader_state fs;
@@ -395,6 +407,13 @@ st_translate_fragment_program(struct st_context *st,
GLbitfield input_flags[MAX_PROGRAM_INPUTS];
GLbitfield output_flags[MAX_PROGRAM_OUTPUTS];
+ tokens = (struct tgsi_token *)MALLOC(ST_MAX_SHADER_TOKENS * sizeof *tokens);
+ if(!tokens) {
+ /* FIXME: propagate error to the caller */
+ assert(0);
+ return;
+ }
+
memset(&fs, 0, sizeof(fs));
memset(input_flags, 0, sizeof(input_flags));
memset(output_flags, 0, sizeof(output_flags));
@@ -536,7 +555,9 @@ st_translate_fragment_program(struct st_context *st,
assert(num_tokens < ST_MAX_SHADER_TOKENS);
fs.tokens = (struct tgsi_token *)
- mem_dup(tokens, num_tokens * sizeof(tokens[0]));
+ _mesa_realloc(tokens,
+ ST_MAX_SHADER_TOKENS * sizeof *tokens,
+ num_tokens * sizeof *tokens);
stfp->state = fs; /* struct copy */
stfp->driver_shader = pipe->create_fs_state(pipe, &fs);