aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa')
-rw-r--r--mesalib/src/mesa/drivers/common/meta.c47
-rw-r--r--mesalib/src/mesa/main/api_validate.c34
-rw-r--r--mesalib/src/mesa/main/api_validate.h10
-rw-r--r--mesalib/src/mesa/main/dd.h3
-rw-r--r--mesalib/src/mesa/main/dlist.c22
-rw-r--r--mesalib/src/mesa/main/fbobject.c20
-rw-r--r--mesalib/src/mesa/main/format_unpack.c8
-rw-r--r--mesalib/src/mesa/main/mipmap.c128
-rw-r--r--mesalib/src/mesa/main/mipmap.h6
-rw-r--r--mesalib/src/mesa/main/mtypes.h2
-rw-r--r--mesalib/src/mesa/main/texformat.c2
-rw-r--r--mesalib/src/mesa/main/texgetimage.c8
-rw-r--r--mesalib/src/mesa/main/teximage.c11
-rw-r--r--mesalib/src/mesa/main/teximage.h4
-rw-r--r--mesalib/src/mesa/main/transformfeedback.c61
-rw-r--r--mesalib/src/mesa/main/transformfeedback.h6
-rw-r--r--mesalib/src/mesa/main/varray.h7
-rw-r--r--mesalib/src/mesa/main/vtxfmt.c1
-rw-r--r--mesalib/src/mesa/program/prog_parameter_layout.c1
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_pixeltransfer.c1
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_rasterizer.c7
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_bitmap.c3
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_clear.c3
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_drawpixels.c3
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_drawtex.c3
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_rasterpos.c545
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_xformfb.c331
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_xformfb.h114
-rw-r--r--mesalib/src/mesa/state_tracker/st_draw.c14
-rw-r--r--mesalib/src/mesa/state_tracker/st_draw.h184
-rw-r--r--mesalib/src/mesa/state_tracker/st_draw_feedback.c3
-rw-r--r--mesalib/src/mesa/state_tracker/st_extensions.c15
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp27
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h6
-rw-r--r--mesalib/src/mesa/state_tracker/st_program.c12
-rw-r--r--mesalib/src/mesa/swrast/s_blit.c10
-rw-r--r--mesalib/src/mesa/swrast/s_drawpix.c6
-rw-r--r--mesalib/src/mesa/tnl/t_draw.c3
-rw-r--r--mesalib/src/mesa/tnl/tnl.h207
-rw-r--r--mesalib/src/mesa/vbo/vbo.h4
-rw-r--r--mesalib/src/mesa/vbo/vbo_context.h1
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_array.c93
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_draw.c3
-rw-r--r--mesalib/src/mesa/vbo/vbo_rebase.c3
-rw-r--r--mesalib/src/mesa/vbo/vbo_save_api.c11
-rw-r--r--mesalib/src/mesa/vbo/vbo_save_draw.c3
-rw-r--r--mesalib/src/mesa/vbo/vbo_split_copy.c3
-rw-r--r--mesalib/src/mesa/vbo/vbo_split_inplace.c3
48 files changed, 1178 insertions, 824 deletions
diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c
index 259041f67..1683c85e9 100644
--- a/mesalib/src/mesa/drivers/common/meta.c
+++ b/mesalib/src/mesa/drivers/common/meta.c
@@ -2943,43 +2943,20 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
break;
}
- /* Set MaxLevel large enough to hold the new level when we allocate it */
+ /* Allocate storage for the destination mipmap image(s) */
+
+ /* Set MaxLevel large enough to hold the new level when we allocate it */
_mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, dstLevel);
- /* Create empty dest image */
- if (target == GL_TEXTURE_1D) {
- _mesa_TexImage1D(target, dstLevel, srcImage->InternalFormat,
- dstWidth, border,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- }
- else if (target == GL_TEXTURE_3D) {
- _mesa_TexImage3D(target, dstLevel, srcImage->InternalFormat,
- dstWidth, dstHeight, dstDepth, border,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- }
- else {
- /* 2D or cube */
- _mesa_TexImage2D(faceTarget, dstLevel, srcImage->InternalFormat,
- dstWidth, dstHeight, border,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-
- if (target == GL_TEXTURE_CUBE_MAP) {
- /* If texturing from a cube, we need to make sure all src faces
- * have been defined (even if we're not sampling from them.)
- * Otherwise the texture object will be 'incomplete' and
- * texturing from it will not be allowed.
- */
- GLuint face;
- for (face = 0; face < 6; face++) {
- if (!texObj->Image[face][srcLevel] ||
- texObj->Image[face][srcLevel]->Width != srcWidth) {
- _mesa_TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
- srcLevel, srcImage->InternalFormat,
- srcWidth, srcHeight, border,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- }
- }
- }
+ if (!_mesa_prepare_mipmap_level(ctx, texObj, dstLevel,
+ dstWidth, dstHeight, dstDepth,
+ srcImage->Border,
+ srcImage->InternalFormat,
+ srcImage->TexFormat)) {
+ /* All done. We either ran out of memory or we would go beyond the
+ * last valid level of an immutable texture if we continued.
+ */
+ break;
}
/* limit minification to src level */
diff --git a/mesalib/src/mesa/main/api_validate.c b/mesalib/src/mesa/main/api_validate.c
index efdecb212..945f12752 100644
--- a/mesalib/src/mesa/main/api_validate.c
+++ b/mesalib/src/mesa/main/api_validate.c
@@ -474,3 +474,37 @@ _mesa_validate_DrawElementsInstanced(struct gl_context *ctx,
return GL_TRUE;
}
+
+
+#if FEATURE_EXT_transform_feedback
+
+GLboolean
+_mesa_validate_DrawTransformFeedback(struct gl_context *ctx,
+ GLenum mode,
+ struct gl_transform_feedback_object *obj)
+{
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+
+ if (!_mesa_valid_prim_mode(ctx, mode)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glDrawTransformFeedback(mode)");
+ return GL_FALSE;
+ }
+
+ if (!obj) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glDrawTransformFeedback(name)");
+ return GL_FALSE;
+ }
+
+ if (!obj->EndedAnytime) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawTransformFeedback");
+ return GL_FALSE;
+ }
+
+ if (!check_valid_to_render(ctx, "glDrawTransformFeedback")) {
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+#endif
diff --git a/mesalib/src/mesa/main/api_validate.h b/mesalib/src/mesa/main/api_validate.h
index 7d6a66012..f4948424c 100644
--- a/mesalib/src/mesa/main/api_validate.h
+++ b/mesalib/src/mesa/main/api_validate.h
@@ -29,9 +29,11 @@
#include "glheader.h"
+#include "mfeatures.h"
struct gl_buffer_object;
struct gl_context;
+struct gl_transform_feedback_object;
extern GLuint
@@ -70,5 +72,13 @@ _mesa_validate_DrawElementsInstanced(struct gl_context *ctx,
const GLvoid *indices, GLsizei primcount,
GLint basevertex);
+#if FEATURE_EXT_transform_feedback
+
+extern GLboolean
+_mesa_validate_DrawTransformFeedback(struct gl_context *ctx,
+ GLenum mode,
+ struct gl_transform_feedback_object *obj);
+
+#endif
#endif
diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h
index d6f70d1c4..01cfff8ab 100644
--- a/mesalib/src/mesa/main/dd.h
+++ b/mesalib/src/mesa/main/dd.h
@@ -964,8 +964,6 @@ struct dd_function_table {
struct gl_transform_feedback_object *obj);
void (*ResumeTransformFeedback)(struct gl_context *ctx,
struct gl_transform_feedback_object *obj);
- void (*DrawTransformFeedback)(struct gl_context *ctx, GLenum mode,
- struct gl_transform_feedback_object *obj);
/**
* \name GL_NV_texture_barrier interface
@@ -1194,6 +1192,7 @@ typedef struct {
void (GLAPIENTRYP DrawElementsInstancedBaseVertex)(GLenum mode, GLsizei count,
GLenum type, const GLvoid *indices,
GLsizei primcount, GLint basevertex);
+ void (GLAPIENTRYP DrawTransformFeedback)(GLenum mode, GLuint name);
/*@}*/
/**
diff --git a/mesalib/src/mesa/main/dlist.c b/mesalib/src/mesa/main/dlist.c
index e1acc8028..b3edae0e6 100644
--- a/mesalib/src/mesa/main/dlist.c
+++ b/mesalib/src/mesa/main/dlist.c
@@ -1422,7 +1422,7 @@ save_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
}
}
if (ctx->ExecuteFlag) {
- /*CALL_ClearBufferiv(ctx->Exec, (buffer, drawbuffer, value));*/
+ CALL_ClearBufferiv(ctx->Exec, (buffer, drawbuffer, value));
}
}
@@ -1450,7 +1450,7 @@ save_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
}
}
if (ctx->ExecuteFlag) {
- /*CALL_ClearBufferuiv(ctx->Exec, (buffer, drawbuffer, value));*/
+ CALL_ClearBufferuiv(ctx->Exec, (buffer, drawbuffer, value));
}
}
@@ -1478,7 +1478,7 @@ save_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
}
}
if (ctx->ExecuteFlag) {
- /*CALL_ClearBufferuiv(ctx->Exec, (buffer, drawbuffer, value));*/
+ CALL_ClearBufferfv(ctx->Exec, (buffer, drawbuffer, value));
}
}
@@ -1498,7 +1498,7 @@ save_ClearBufferfi(GLenum buffer, GLint drawbuffer,
n[4].i = stencil;
}
if (ctx->ExecuteFlag) {
- /*CALL_ClearBufferfi(ctx->Exec, (buffer, drawbuffer, depth, stencil));*/
+ CALL_ClearBufferfi(ctx->Exec, (buffer, drawbuffer, depth, stencil));
}
}
@@ -7545,36 +7545,36 @@ execute_list(struct gl_context *ctx, GLuint list)
break;
case OPCODE_CLEAR_BUFFER_IV:
{
- /*GLint value[4];
+ GLint value[4];
value[0] = n[3].i;
value[1] = n[4].i;
value[2] = n[5].i;
value[3] = n[6].i;
- CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value));*/
+ CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value));
}
break;
case OPCODE_CLEAR_BUFFER_UIV:
{
- /*GLuint value[4];
+ GLuint value[4];
value[0] = n[3].ui;
value[1] = n[4].ui;
value[2] = n[5].ui;
value[3] = n[6].ui;
- CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value));*/
+ CALL_ClearBufferuiv(ctx->Exec, (n[1].e, n[2].i, value));
}
break;
case OPCODE_CLEAR_BUFFER_FV:
{
- /*GLfloat value[4];
+ GLfloat value[4];
value[0] = n[3].f;
value[1] = n[4].f;
value[2] = n[5].f;
value[3] = n[6].f;
- CALL_ClearBufferfv(ctx->Exec, (n[1].e, n[2].i, value));*/
+ CALL_ClearBufferfv(ctx->Exec, (n[1].e, n[2].i, value));
}
break;
case OPCODE_CLEAR_BUFFER_FI:
- /*CALL_ClearBufferfi(ctx->Exec, (n[1].e, n[2].i, n[3].f, n[4].i));*/
+ CALL_ClearBufferfi(ctx->Exec, (n[1].e, n[2].i, n[3].f, n[4].i));
break;
case OPCODE_CLEAR_COLOR:
CALL_ClearColor(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c
index 611a6d0b0..912170aba 100644
--- a/mesalib/src/mesa/main/fbobject.c
+++ b/mesalib/src/mesa/main/fbobject.c
@@ -819,7 +819,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
fbo_incomplete("width or height mismatch", -1);
return;
}
- /* check that all color buffer have same format */
+ /* check that all color buffers are the same format */
if (intFormat != GL_NONE && f != intFormat) {
fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT;
fbo_incomplete("format mismatch", -1);
@@ -831,8 +831,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
fbo_incomplete("inconsistant number of samples", i);
return;
- }
-
+ }
}
}
@@ -1273,7 +1272,7 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat)
case GL_RG32I:
return ctx->Extensions.ARB_texture_rg &&
ctx->Extensions.EXT_texture_integer ? GL_RG : 0;
-
+
case GL_INTENSITY8I_EXT:
case GL_INTENSITY8UI_EXT:
case GL_INTENSITY16I_EXT:
@@ -1820,7 +1819,7 @@ _mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers)
/* bind default */
ASSERT(fb->RefCount >= 2);
_mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
- }
+ }
}
/* remove from hash table immediately, to free the ID */
@@ -1897,6 +1896,7 @@ _mesa_CheckFramebufferStatusEXT(GLenum target)
return buffer->_Status;
}
+
/**
* Replicate the src attachment point. Used by framebuffer_texture() when
* the same texture is attached at GL_DEPTH_ATTACHMENT and
@@ -1911,7 +1911,7 @@ reuse_framebuffer_texture_attachment(struct gl_framebuffer *fb,
struct gl_renderbuffer_attachment *src_att = &fb->Attachment[src];
assert(src_att->Texture != NULL);
- assert (src_att->Renderbuffer != NULL);
+ assert(src_att->Renderbuffer != NULL);
_mesa_reference_texobj(&dst_att->Texture, src_att->Texture);
_mesa_reference_renderbuffer(&dst_att->Renderbuffer, src_att->Renderbuffer);
@@ -1921,6 +1921,7 @@ reuse_framebuffer_texture_attachment(struct gl_framebuffer *fb,
dst_att->Zoffset = src_att->Zoffset;
}
+
/**
* Common code called by glFramebufferTexture1D/2D/3DEXT().
*/
@@ -1949,7 +1950,6 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
return;
}
-
/* The textarget, level, and zoffset parameters are only validated if
* texture is non-zero.
*/
@@ -2002,7 +2002,7 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
}
}
- if ((level < 0) ||
+ if ((level < 0) ||
(level >= _mesa_max_texture_levels(ctx, texObj->Target))) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glFramebufferTexture%sEXT(level)", caller);
@@ -2031,7 +2031,7 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
reuse_framebuffer_texture_attachment(fb, BUFFER_DEPTH,
BUFFER_STENCIL);
} else if (attachment == GL_STENCIL_ATTACHMENT &&
- texObj== fb->Attachment[BUFFER_DEPTH].Texture) {
+ texObj == fb->Attachment[BUFFER_DEPTH].Texture) {
/* As above, but with depth and stencil juxtasposed. */
reuse_framebuffer_texture_attachment(fb, BUFFER_STENCIL,
BUFFER_DEPTH);
@@ -2797,6 +2797,7 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
}
#endif /* FEATURE_EXT_framebuffer_blit */
+
#if FEATURE_ARB_geometry_shader4
void GLAPIENTRY
_mesa_FramebufferTextureARB(GLenum target, GLenum attachment,
@@ -2808,6 +2809,7 @@ _mesa_FramebufferTextureARB(GLenum target, GLenum attachment,
"not implemented!");
}
+
void GLAPIENTRY
_mesa_FramebufferTextureFaceARB(GLenum target, GLenum attachment,
GLuint texture, GLint level, GLenum face)
diff --git a/mesalib/src/mesa/main/format_unpack.c b/mesalib/src/mesa/main/format_unpack.c
index 4f23f3dec..32d198ce8 100644
--- a/mesalib/src/mesa/main/format_unpack.c
+++ b/mesalib/src/mesa/main/format_unpack.c
@@ -1822,6 +1822,10 @@ unpack_float_z_Z32X24S8(GLuint n, const void *src, GLfloat *dst)
+/**
+ * Unpack Z values.
+ * The returned values will always be in the range [0.0, 1.0].
+ */
void
_mesa_unpack_float_z_row(gl_format format, GLuint n,
const void *src, GLfloat *dst)
@@ -1901,6 +1905,10 @@ unpack_uint_z_Z32(const void *src, GLuint *dst, GLuint n)
}
+/**
+ * Unpack Z values.
+ * The returned values will always be in the range [0, 0xffffffff].
+ */
void
_mesa_unpack_uint_z_row(gl_format format, GLuint n,
const void *src, GLuint *dst)
diff --git a/mesalib/src/mesa/main/mipmap.c b/mesalib/src/mesa/main/mipmap.c
index fd6e582ec..867cb22e2 100644
--- a/mesalib/src/mesa/main/mipmap.c
+++ b/mesalib/src/mesa/main/mipmap.c
@@ -1803,6 +1803,81 @@ next_mipmap_level_size(GLenum target, GLint border,
}
}
+
+/**
+ * Helper function for mipmap generation.
+ * Make sure the specified destination mipmap level is the right size/format
+ * for mipmap generation. If not, (re) allocate it.
+ * \return GL_TRUE if successful, GL_FALSE if mipmap generation should stop
+ */
+GLboolean
+_mesa_prepare_mipmap_level(struct gl_context *ctx,
+ struct gl_texture_object *texObj, GLuint level,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLsizei border, GLenum intFormat, gl_format format)
+{
+ const GLuint numFaces = texObj->Target == GL_TEXTURE_CUBE_MAP ? 6 : 1;
+ GLuint face;
+
+ if (texObj->Immutable) {
+ /* The texture was created with glTexStorage() so the number/size of
+ * mipmap levels is fixed and the storage for all images is already
+ * allocated.
+ */
+ if (!texObj->Image[0][level]) {
+ /* No more levels to create - we're done */
+ return GL_FALSE;
+ }
+ else {
+ /* Nothing to do - the texture memory must have already been
+ * allocated to the right size so we're all set.
+ */
+ return GL_TRUE;
+ }
+ }
+
+ for (face = 0; face < numFaces; face++) {
+ struct gl_texture_image *dstImage;
+ GLenum target;
+
+ if (numFaces == 1)
+ target = texObj->Target;
+ else
+ target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
+
+ dstImage = _mesa_get_tex_image(ctx, texObj, target, level);
+ if (!dstImage) {
+ /* out of memory */
+ return GL_FALSE;
+ }
+
+ if (dstImage->Width != width ||
+ dstImage->Height != height ||
+ dstImage->Depth != depth ||
+ dstImage->Border != border ||
+ dstImage->InternalFormat != intFormat ||
+ dstImage->TexFormat != format) {
+ /* need to (re)allocate image */
+ ctx->Driver.FreeTextureImageBuffer(ctx, dstImage);
+
+ _mesa_init_teximage_fields(ctx, target, dstImage,
+ width, height, depth,
+ border, intFormat, format);
+
+ ctx->Driver.AllocTextureImageBuffer(ctx, dstImage,
+ format, width, height, depth);
+
+ /* in case the mipmap level is part of an FBO: */
+ _mesa_update_fbo_texture(ctx, texObj, face, level);
+
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ }
+
+ return GL_TRUE;
+}
+
+
static void
generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
struct gl_texture_object *texObj,
@@ -1841,31 +1916,20 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
if (!nextLevel)
return;
- /* get dest gl_texture_image */
- dstImage = _mesa_get_tex_image(ctx, texObj, target, level + 1);
- if (!dstImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
+ if (!_mesa_prepare_mipmap_level(ctx, texObj, level + 1,
+ dstWidth, dstHeight, dstDepth,
+ border, srcImage->InternalFormat,
+ srcImage->TexFormat)) {
return;
}
- /* Free old image data */
- ctx->Driver.FreeTextureImageBuffer(ctx, dstImage);
-
- _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight,
- dstDepth, border, srcImage->InternalFormat,
- srcImage->TexFormat);
-
- /* Alloc storage for new texture image */
- if (!ctx->Driver.AllocTextureImageBuffer(ctx, dstImage,
- dstImage->TexFormat,
- dstWidth, dstHeight,
- dstDepth)) {
+ /* get dest gl_texture_image */
+ dstImage = _mesa_get_tex_image(ctx, texObj, target, level + 1);
+ if (!dstImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
return;
}
- ASSERT(dstImage->TexFormat);
-
if (target == GL_TEXTURE_1D_ARRAY) {
srcDepth = srcHeight;
dstDepth = dstHeight;
@@ -2052,9 +2116,7 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target,
return;
}
- /* Free old image data */
- ctx->Driver.FreeTextureImageBuffer(ctx, dstImage);
-
+ /* rescale src image to dest image */
_mesa_generate_mipmap_level(target, temp_datatype, components, border,
srcWidth, srcHeight, srcDepth,
(const GLubyte **) &temp_src,
@@ -2062,19 +2124,19 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target,
dstWidth, dstHeight, dstDepth,
&temp_dst, temp_dst_stride);
- /* initialize new image */
- _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight,
- dstDepth, border, srcImage->InternalFormat,
- srcImage->TexFormat);
-
- /* Free old dest texture image buffer */
- ctx->Driver.FreeTextureImageBuffer(ctx, dstImage);
+ if (!_mesa_prepare_mipmap_level(ctx, texObj, level + 1,
+ dstWidth, dstHeight, dstDepth,
+ border, srcImage->InternalFormat,
+ srcImage->TexFormat)) {
+ return;
+ }
- ctx->Driver.TexImage2D(ctx, target, level + 1,
- srcImage->InternalFormat,
- dstWidth, dstHeight, border,
- temp_base_format, temp_datatype,
- temp_dst, &ctx->DefaultPacking, texObj, dstImage);
+ /* The image space was allocated above so use glTexSubImage now */
+ ctx->Driver.TexSubImage2D(ctx, target, level + 1,
+ 0, 0, dstWidth, dstHeight,
+ temp_base_format, temp_datatype,
+ temp_dst, &ctx->DefaultPacking,
+ texObj, dstImage);
/* swap src and dest pointers */
{
diff --git a/mesalib/src/mesa/main/mipmap.h b/mesalib/src/mesa/main/mipmap.h
index 1fb9146a1..072794cb6 100644
--- a/mesalib/src/mesa/main/mipmap.h
+++ b/mesalib/src/mesa/main/mipmap.h
@@ -41,6 +41,12 @@ _mesa_generate_mipmap_level(GLenum target,
GLint dstRowStride);
+extern GLboolean
+_mesa_prepare_mipmap_level(struct gl_context *ctx,
+ struct gl_texture_object *texObj, GLuint level,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLsizei border, GLenum intFormat, gl_format format);
+
extern void
_mesa_generate_mipmap(struct gl_context *ctx, GLenum target,
struct gl_texture_object *texObj);
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index 193434976..0e29dc0dc 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -2355,6 +2355,8 @@ struct gl_transform_feedback_object
GLint RefCount;
GLboolean Active; /**< Is transform feedback enabled? */
GLboolean Paused; /**< Is transform feedback paused? */
+ GLboolean EndedAnytime; /**< Has EndTransformFeedback been called
+ at least once? */
/** The feedback buffers */
GLuint BufferNames[MAX_FEEDBACK_ATTRIBS];
diff --git a/mesalib/src/mesa/main/texformat.c b/mesalib/src/mesa/main/texformat.c
index c776b4160..7e60541c3 100644
--- a/mesalib/src/mesa/main/texformat.c
+++ b/mesalib/src/mesa/main/texformat.c
@@ -118,6 +118,8 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat,
break;
case GL_R3_G3_B2:
RETURN_IF_SUPPORTED(MESA_FORMAT_RGB332);
+ RETURN_IF_SUPPORTED(MESA_FORMAT_RGB565);
+ RETURN_IF_SUPPORTED(MESA_FORMAT_RGB565_REV);
RETURN_IF_SUPPORTED(MESA_FORMAT_RGB888);
RETURN_IF_SUPPORTED(MESA_FORMAT_XRGB8888);
RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB8888);
diff --git a/mesalib/src/mesa/main/texgetimage.c b/mesalib/src/mesa/main/texgetimage.c
index ae0d51fbb..3f2418729 100644
--- a/mesalib/src/mesa/main/texgetimage.c
+++ b/mesalib/src/mesa/main/texgetimage.c
@@ -708,6 +708,14 @@ getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level,
return GL_TRUE;
}
+ if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
+ /*GL_INVALID_OPERATION is generated by a format/type
+ * mismatch (see the 1.2 spec page 94, sec 3.6.4.)
+ */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(target)");
+ return GL_TRUE;
+ }
+
baseFormat = _mesa_get_format_base_format(texImage->TexFormat);
/* Make sure the requested image format is compatible with the
diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c
index 8a002b675..eccc0fd39 100644
--- a/mesalib/src/mesa/main/teximage.c
+++ b/mesalib/src/mesa/main/teximage.c
@@ -2205,9 +2205,10 @@ check_rtt_cb(GLuint key, void *data, void *userData)
* in size or format since that effects FBO completeness.
* Any FBOs rendering into the texture must be re-validated.
*/
-static void
-update_fbo_texture(struct gl_context *ctx, struct gl_texture_object *texObj,
- GLuint face, GLuint level)
+void
+_mesa_update_fbo_texture(struct gl_context *ctx,
+ struct gl_texture_object *texObj,
+ GLuint face, GLuint level)
{
/* Only check this texture if it's been marked as RenderToTexture */
if (texObj->_RenderToTexture) {
@@ -2502,7 +2503,7 @@ teximage(struct gl_context *ctx, GLuint dims,
check_gen_mipmap(ctx, target, texObj, level);
- update_fbo_texture(ctx, texObj, face, level);
+ _mesa_update_fbo_texture(ctx, texObj, face, level);
/* state update */
texObj->_Complete = GL_FALSE;
@@ -2844,7 +2845,7 @@ copyteximage(struct gl_context *ctx, GLuint dims,
check_gen_mipmap(ctx, target, texObj, level);
- update_fbo_texture(ctx, texObj, face, level);
+ _mesa_update_fbo_texture(ctx, texObj, face, level);
/* state update */
texObj->_Complete = GL_FALSE;
diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h
index 9cc7d5a54..d756646ce 100644
--- a/mesalib/src/mesa/main/teximage.h
+++ b/mesalib/src/mesa/main/teximage.h
@@ -80,6 +80,10 @@ _mesa_choose_texture_format(struct gl_context *ctx,
GLenum target, GLint level,
GLenum internalFormat, GLenum format, GLenum type);
+extern void
+_mesa_update_fbo_texture(struct gl_context *ctx,
+ struct gl_texture_object *texObj,
+ GLuint face, GLuint level);
extern void
_mesa_clear_texture_image(struct gl_context *ctx,
diff --git a/mesalib/src/mesa/main/transformfeedback.c b/mesalib/src/mesa/main/transformfeedback.c
index 799245d4e..824f66a35 100644
--- a/mesalib/src/mesa/main/transformfeedback.c
+++ b/mesalib/src/mesa/main/transformfeedback.c
@@ -294,18 +294,6 @@ resume_transform_feedback(struct gl_context *ctx,
/* nop */
}
-/** Default fallback for ctx->Driver.DrawTransformFeedback() */
-static void
-draw_transform_feedback(struct gl_context *ctx, GLenum mode,
- struct gl_transform_feedback_object *obj)
-{
- /* XXX to do */
- /*
- * Get number of vertices in obj's feedback buffer.
- * Call ctx->Exec.DrawArrays(mode, 0, count);
- */
-}
-
/**
* Plug in default device driver functions for transform feedback.
@@ -320,7 +308,6 @@ _mesa_init_transform_feedback_functions(struct dd_function_table *driver)
driver->EndTransformFeedback = end_transform_feedback;
driver->PauseTransformFeedback = pause_transform_feedback;
driver->ResumeTransformFeedback = resume_transform_feedback;
- driver->DrawTransformFeedback = draw_transform_feedback;
}
@@ -342,7 +329,6 @@ _mesa_init_transform_feedback_dispatch(struct _glapi_table *disp)
SET_IsTransformFeedback(disp, _mesa_IsTransformFeedback);
SET_PauseTransformFeedback(disp, _mesa_PauseTransformFeedback);
SET_ResumeTransformFeedback(disp, _mesa_ResumeTransformFeedback);
- SET_DrawTransformFeedback(disp, _mesa_DrawTransformFeedback);
}
@@ -401,6 +387,7 @@ _mesa_EndTransformFeedback(void)
FLUSH_VERTICES(ctx, _NEW_TRANSFORM_FEEDBACK);
ctx->TransformFeedback.CurrentObject->Active = GL_FALSE;
+ ctx->TransformFeedback.CurrentObject->EndedAnytime = GL_TRUE;
assert(ctx->Driver.EndTransformFeedback);
ctx->Driver.EndTransformFeedback(ctx, obj);
@@ -714,8 +701,8 @@ _mesa_GetTransformFeedbackVarying(GLuint program, GLuint index,
-static struct gl_transform_feedback_object *
-lookup_transform_feedback_object(struct gl_context *ctx, GLuint name)
+struct gl_transform_feedback_object *
+_mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name)
{
if (name == 0) {
return ctx->TransformFeedback.DefaultObject;
@@ -780,7 +767,7 @@ _mesa_IsTransformFeedback(GLuint name)
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
- if (name && lookup_transform_feedback_object(ctx, name))
+ if (name && _mesa_lookup_transform_feedback_object(ctx, name))
return GL_TRUE;
else
return GL_FALSE;
@@ -809,7 +796,7 @@ _mesa_BindTransformFeedback(GLenum target, GLuint name)
return;
}
- obj = lookup_transform_feedback_object(ctx, name);
+ obj = _mesa_lookup_transform_feedback_object(ctx, name);
if (!obj) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glBindTransformFeedback(name=%u)", name);
@@ -844,7 +831,7 @@ _mesa_DeleteTransformFeedbacks(GLsizei n, const GLuint *names)
for (i = 0; i < n; i++) {
if (names[i] > 0) {
struct gl_transform_feedback_object *obj
- = lookup_transform_feedback_object(ctx, names[i]);
+ = _mesa_lookup_transform_feedback_object(ctx, names[i]);
if (obj) {
if (obj->Active) {
_mesa_error(ctx, GL_INVALID_OPERATION,
@@ -912,40 +899,4 @@ _mesa_ResumeTransformFeedback(void)
ctx->Driver.ResumeTransformFeedback(ctx, obj);
}
-
-/**
- * Draw the vertex data in a transform feedback object.
- * \param mode GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc.
- * \param name the transform feedback object
- * The number of vertices comes from the transform feedback object.
- * User still has to setup of the vertex attribute info with
- * glVertexPointer, glColorPointer, etc.
- * Part of GL_ARB_transform_feedback2.
- */
-void GLAPIENTRY
-_mesa_DrawTransformFeedback(GLenum mode, GLuint name)
-{
- GET_CURRENT_CONTEXT(ctx);
- struct gl_transform_feedback_object *obj =
- lookup_transform_feedback_object(ctx, name);
-
- if (mode > GL_POLYGON) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glDrawTransformFeedback(mode=0x%x)", mode);
- return;
- }
- if (!obj) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glDrawTransformFeedback(name = %u)", name);
- return;
- }
-
- /* XXX check if EndTransformFeedback has never been called while
- * the object was bound
- */
-
- assert(ctx->Driver.DrawTransformFeedback);
- ctx->Driver.DrawTransformFeedback(ctx, mode, obj);
-}
-
#endif /* FEATURE_EXT_transform_feedback */
diff --git a/mesalib/src/mesa/main/transformfeedback.h b/mesalib/src/mesa/main/transformfeedback.h
index 9447effa9..8a6672d58 100644
--- a/mesalib/src/mesa/main/transformfeedback.h
+++ b/mesalib/src/mesa/main/transformfeedback.h
@@ -87,6 +87,9 @@ _mesa_GetTransformFeedbackVarying(GLuint program, GLuint index,
/*** GL_ARB_transform_feedback2 ***/
+struct gl_transform_feedback_object *
+_mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name);
+
extern void GLAPIENTRY
_mesa_GenTransformFeedbacks(GLsizei n, GLuint *names);
@@ -105,9 +108,6 @@ _mesa_PauseTransformFeedback(void);
extern void GLAPIENTRY
_mesa_ResumeTransformFeedback(void);
-extern void GLAPIENTRY
-_mesa_DrawTransformFeedback(GLenum mode, GLuint name);
-
#else /* FEATURE_EXT_transform_feedback */
static inline GLboolean
diff --git a/mesalib/src/mesa/main/varray.h b/mesalib/src/mesa/main/varray.h
index 6fcc0a336..b6041bd78 100644
--- a/mesalib/src/mesa/main/varray.h
+++ b/mesalib/src/mesa/main/varray.h
@@ -245,6 +245,13 @@ _mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
const GLvoid *indices,
GLint basevertex);
+#if FEATURE_EXT_transform_feedback
+
+extern void GLAPIENTRY
+_mesa_DrawTransformFeedback(GLenum mode, GLuint name);
+
+#endif
+
extern void GLAPIENTRY
_mesa_PrimitiveRestartIndex(GLuint index);
diff --git a/mesalib/src/mesa/main/vtxfmt.c b/mesalib/src/mesa/main/vtxfmt.c
index 03735d779..f3cca937d 100644
--- a/mesalib/src/mesa/main/vtxfmt.c
+++ b/mesalib/src/mesa/main/vtxfmt.c
@@ -107,6 +107,7 @@ install_vtxfmt( struct _glapi_table *tab, const GLvertexformat *vfmt )
SET_DrawArraysInstancedARB(tab, vfmt->DrawArraysInstanced);
SET_DrawElementsInstancedARB(tab, vfmt->DrawElementsInstanced);
SET_DrawElementsInstancedBaseVertex(tab, vfmt->DrawElementsInstancedBaseVertex);
+ SET_DrawTransformFeedback(tab, vfmt->DrawTransformFeedback);
/* GL_NV_vertex_program */
SET_VertexAttrib1fNV(tab, vfmt->VertexAttrib1fNV);
diff --git a/mesalib/src/mesa/program/prog_parameter_layout.c b/mesalib/src/mesa/program/prog_parameter_layout.c
index 28fca3b92..e4f2db3b3 100644
--- a/mesalib/src/mesa/program/prog_parameter_layout.c
+++ b/mesalib/src/mesa/program/prog_parameter_layout.c
@@ -138,6 +138,7 @@ _mesa_layout_parameters(struct asm_parser_state *state)
inst->SrcReg[i].Symbol->param_binding_length);
if (new_begin < 0) {
+ _mesa_free_parameter_list(layout);
return GL_FALSE;
}
diff --git a/mesalib/src/mesa/state_tracker/st_atom_pixeltransfer.c b/mesalib/src/mesa/state_tracker/st_atom_pixeltransfer.c
index afca60976..fb1e4092c 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_pixeltransfer.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_pixeltransfer.c
@@ -266,6 +266,7 @@ get_pixel_transfer_program(struct gl_context *ctx, const struct state_key *key)
if (!fp->Base.Instructions) {
_mesa_error(ctx, GL_OUT_OF_MEMORY,
"generating pixel transfer program");
+ _mesa_free_parameter_list(params);
return NULL;
}
diff --git a/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c b/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c
index 250cbb226..4aa0b4e2a 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c
@@ -256,9 +256,11 @@ static void update_raster_state( struct st_context *st )
/* _NEW_FRAG_CLAMP */
raster->clamp_fragment_color = ctx->Color._ClampFragmentColor;
-
raster->gl_rasterization_rules = 1;
+ /* _NEW_TRANSFORM */
+ raster->rasterizer_discard = ctx->TransformFeedback.RasterDiscard;
+
cso_set_rasterizer(st->cso_context, raster);
}
@@ -273,7 +275,8 @@ const struct st_tracked_state st_update_rasterizer = {
_NEW_POLYGON |
_NEW_PROGRAM |
_NEW_SCISSOR |
- _NEW_FRAG_CLAMP), /* mesa state dependencies*/
+ _NEW_FRAG_CLAMP |
+ _NEW_TRANSFORM), /* mesa state dependencies*/
ST_NEW_VERTEX_PROGRAM, /* state tracker dependencies */
},
update_raster_state /* update function */
diff --git a/mesalib/src/mesa/state_tracker/st_cb_bitmap.c b/mesalib/src/mesa/state_tracker/st_cb_bitmap.c
index fa37be0b6..af33bcf86 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_bitmap.c
@@ -483,6 +483,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
cso_save_fragment_sampler_views(cso);
cso_save_viewport(cso);
cso_save_fragment_shader(cso);
+ cso_save_stream_outputs(cso);
cso_save_vertex_shader(cso);
cso_save_geometry_shader(cso);
cso_save_vertex_elements(cso);
@@ -542,6 +543,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
}
cso_set_vertex_elements(cso, 3, st->velems_util_draw);
+ cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
/* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */
z = z * 2.0f - 1.0f;
@@ -568,6 +570,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
cso_restore_geometry_shader(cso);
cso_restore_vertex_elements(cso);
cso_restore_vertex_buffers(cso);
+ cso_restore_stream_outputs(cso);
}
diff --git a/mesalib/src/mesa/state_tracker/st_cb_clear.c b/mesalib/src/mesa/state_tracker/st_cb_clear.c
index 61d98aeb9..23700eeb7 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_clear.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_clear.c
@@ -250,6 +250,7 @@ clear_with_quad(struct gl_context *ctx,
cso_save_viewport(st->cso_context);
cso_save_clip(st->cso_context);
cso_save_fragment_shader(st->cso_context);
+ cso_save_stream_outputs(st->cso_context);
cso_save_vertex_shader(st->cso_context);
cso_save_geometry_shader(st->cso_context);
cso_save_vertex_elements(st->cso_context);
@@ -306,6 +307,7 @@ clear_with_quad(struct gl_context *ctx,
}
cso_set_vertex_elements(st->cso_context, 2, st->velems_util_draw);
+ cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
cso_set_rasterizer(st->cso_context, &st->clear.raster);
@@ -350,6 +352,7 @@ clear_with_quad(struct gl_context *ctx,
cso_restore_geometry_shader(st->cso_context);
cso_restore_vertex_elements(st->cso_context);
cso_restore_vertex_buffers(st->cso_context);
+ cso_restore_stream_outputs(st->cso_context);
}
diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c
index 65b444552..318ba7d06 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -671,6 +671,7 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
cso_save_samplers(cso);
cso_save_fragment_sampler_views(cso);
cso_save_fragment_shader(cso);
+ cso_save_stream_outputs(cso);
cso_save_vertex_shader(cso);
cso_save_geometry_shader(cso);
cso_save_vertex_elements(cso);
@@ -761,6 +762,7 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
}
cso_set_vertex_elements(cso, 3, st->velems_util_draw);
+ cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
/* texture state: */
cso_set_fragment_sampler_views(cso, num_sampler_view, sv);
@@ -796,6 +798,7 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
cso_restore_geometry_shader(cso);
cso_restore_vertex_elements(cso);
cso_restore_vertex_buffers(cso);
+ cso_restore_stream_outputs(cso);
if (write_stencil) {
cso_restore_depth_stencil_alpha(cso);
cso_restore_blend(cso);
diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawtex.c b/mesalib/src/mesa/state_tracker/st_cb_drawtex.c
index 332b0d1b6..6144eb99c 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_drawtex.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_drawtex.c
@@ -227,6 +227,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
cso_save_viewport(cso);
+ cso_save_stream_outputs(cso);
cso_save_vertex_shader(cso);
cso_save_geometry_shader(cso);
cso_save_vertex_elements(cso);
@@ -246,6 +247,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
velements[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
}
cso_set_vertex_elements(cso, numAttribs, velements);
+ cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
/* viewport state: viewport matching window dims */
{
@@ -281,6 +283,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
cso_restore_geometry_shader(cso);
cso_restore_vertex_elements(cso);
cso_restore_vertex_buffers(cso);
+ cso_restore_stream_outputs(cso);
}
diff --git a/mesalib/src/mesa/state_tracker/st_cb_rasterpos.c b/mesalib/src/mesa/state_tracker/st_cb_rasterpos.c
index 2e9eb7265..2c21dc9a7 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_rasterpos.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_rasterpos.c
@@ -1,272 +1,273 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * 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, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/**
- * glRasterPos implementation. Basically render a GL_POINT with our
- * private draw module. Plug in a special "rasterpos" stage at the end
- * of the 'draw' pipeline to capture the results and update the current
- * raster pos attributes.
- *
- * Authors:
- * Brian Paul
- */
-
-
-#include "main/imports.h"
-#include "main/macros.h"
-#include "main/mfeatures.h"
-#include "main/feedback.h"
-
-#include "st_context.h"
-#include "st_atom.h"
-#include "st_draw.h"
-#include "st_cb_rasterpos.h"
-#include "draw/draw_context.h"
-#include "draw/draw_pipe.h"
-#include "vbo/vbo.h"
-
-
-#if FEATURE_rastpos
-
-/**
- * Our special drawing pipeline stage (replaces rasterization).
- */
-struct rastpos_stage
-{
- struct draw_stage stage; /**< Base class */
- struct gl_context *ctx; /**< Rendering context */
-
- /* vertex attrib info we can setup once and re-use */
- struct gl_client_array array[VERT_ATTRIB_MAX];
- const struct gl_client_array *arrays[VERT_ATTRIB_MAX];
- struct _mesa_prim prim;
-};
-
-
-static INLINE struct rastpos_stage *
-rastpos_stage( struct draw_stage *stage )
-{
- return (struct rastpos_stage *) stage;
-}
-
-static void
-rastpos_flush( struct draw_stage *stage, unsigned flags )
-{
- /* no-op */
-}
-
-static void
-rastpos_reset_stipple_counter( struct draw_stage *stage )
-{
- /* no-op */
-}
-
-static void
-rastpos_tri( struct draw_stage *stage, struct prim_header *prim )
-{
- /* should never get here */
- assert(0);
-}
-
-static void
-rastpos_line( struct draw_stage *stage, struct prim_header *prim )
-{
- /* should never get here */
- assert(0);
-}
-
-static void
-rastpos_destroy(struct draw_stage *stage)
-{
- free(stage);
-}
-
-
-/**
- * Update a raster pos attribute from the vertex result if it's present,
- * else copy the current attrib.
- */
-static void
-update_attrib(struct gl_context *ctx, const GLuint *outputMapping,
- const struct vertex_header *vert,
- GLfloat *dest,
- GLuint result, GLuint defaultAttrib)
-{
- const GLfloat *src;
- const GLuint k = outputMapping[result];
- if (k != ~0U)
- src = vert->data[k];
- else
- src = ctx->Current.Attrib[defaultAttrib];
- COPY_4V(dest, src);
-}
-
-
-/**
- * Normally, this function would render a GL_POINT.
- */
-static void
-rastpos_point(struct draw_stage *stage, struct prim_header *prim)
-{
- struct rastpos_stage *rs = rastpos_stage(stage);
- struct gl_context *ctx = rs->ctx;
- struct st_context *st = st_context(ctx);
- const GLfloat height = (GLfloat) ctx->DrawBuffer->Height;
- const GLuint *outputMapping = st->vertex_result_to_slot;
- const GLfloat *pos;
- GLuint i;
-
- /* if we get here, we didn't get clipped */
- ctx->Current.RasterPosValid = GL_TRUE;
-
- /* update raster pos */
- pos = prim->v[0]->data[0];
- ctx->Current.RasterPos[0] = pos[0];
- if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP)
- ctx->Current.RasterPos[1] = height - pos[1]; /* invert Y */
- else
- ctx->Current.RasterPos[1] = pos[1];
- ctx->Current.RasterPos[2] = pos[2];
- ctx->Current.RasterPos[3] = pos[3];
-
- /* update other raster attribs */
- update_attrib(ctx, outputMapping, prim->v[0],
- ctx->Current.RasterColor,
- VERT_RESULT_COL0, VERT_ATTRIB_COLOR0);
-
- update_attrib(ctx, outputMapping, prim->v[0],
- ctx->Current.RasterSecondaryColor,
- VERT_RESULT_COL1, VERT_ATTRIB_COLOR1);
-
- for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
- update_attrib(ctx, outputMapping, prim->v[0],
- ctx->Current.RasterTexCoords[i],
- VERT_RESULT_TEX0 + i, VERT_ATTRIB_TEX0 + i);
- }
-
- if (ctx->RenderMode == GL_SELECT) {
- _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
- }
-}
-
-
-/**
- * Create rasterpos "drawing" stage.
- */
-static struct rastpos_stage *
-new_draw_rastpos_stage(struct gl_context *ctx, struct draw_context *draw)
-{
- struct rastpos_stage *rs = ST_CALLOC_STRUCT(rastpos_stage);
- GLuint i;
-
- rs->stage.draw = draw;
- rs->stage.next = NULL;
- rs->stage.point = rastpos_point;
- rs->stage.line = rastpos_line;
- rs->stage.tri = rastpos_tri;
- rs->stage.flush = rastpos_flush;
- rs->stage.destroy = rastpos_destroy;
- rs->stage.reset_stipple_counter = rastpos_reset_stipple_counter;
- rs->stage.destroy = rastpos_destroy;
- rs->ctx = ctx;
-
- for (i = 0; i < Elements(rs->array); i++) {
- rs->array[i].Size = 4;
- rs->array[i].Type = GL_FLOAT;
- rs->array[i].Format = GL_RGBA;
- rs->array[i].Stride = 0;
- rs->array[i].StrideB = 0;
- rs->array[i].Ptr = (GLubyte *) ctx->Current.Attrib[i];
- rs->array[i].Enabled = GL_TRUE;
- rs->array[i].Normalized = GL_TRUE;
- rs->array[i].BufferObj = NULL;
- rs->arrays[i] = &rs->array[i];
- }
-
- rs->prim.mode = GL_POINTS;
- rs->prim.indexed = 0;
- rs->prim.begin = 1;
- rs->prim.end = 1;
- rs->prim.weak = 0;
- rs->prim.start = 0;
- rs->prim.count = 1;
-
- return rs;
-}
-
-
-static void
-st_RasterPos(struct gl_context *ctx, const GLfloat v[4])
-{
- struct st_context *st = st_context(ctx);
- struct draw_context *draw = st->draw;
- struct rastpos_stage *rs;
-
- if (st->rastpos_stage) {
- /* get rastpos stage info */
- rs = rastpos_stage(st->rastpos_stage);
- }
- else {
- /* create rastpos draw stage */
- rs = new_draw_rastpos_stage(ctx, draw);
- st->rastpos_stage = &rs->stage;
- }
-
- /* plug our rastpos stage into the draw module */
- draw_set_rasterize_stage(st->draw, st->rastpos_stage);
-
- /* make sure everything's up to date */
- st_validate_state(st);
-
- /* This will get set only if rastpos_point(), above, gets called */
- ctx->Current.RasterPosValid = GL_FALSE;
-
- /* All vertex attribs but position were previously initialized above.
- * Just plug in position pointer now.
- */
- rs->array[0].Ptr = (GLubyte *) v;
-
- /* draw the point */
- st_feedback_draw_vbo(ctx, rs->arrays, &rs->prim, 1, NULL, GL_TRUE, 0, 1);
-
- /* restore draw's rasterization stage depending on rendermode */
- if (ctx->RenderMode == GL_FEEDBACK) {
- draw_set_rasterize_stage(draw, st->feedback_stage);
- }
- else if (ctx->RenderMode == GL_SELECT) {
- draw_set_rasterize_stage(draw, st->selection_stage);
- }
-}
-
-
-
-void st_init_rasterpos_functions(struct dd_function_table *functions)
-{
- functions->RasterPos = st_RasterPos;
-}
-
-#endif /* FEATURE_rastpos */
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * 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, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * glRasterPos implementation. Basically render a GL_POINT with our
+ * private draw module. Plug in a special "rasterpos" stage at the end
+ * of the 'draw' pipeline to capture the results and update the current
+ * raster pos attributes.
+ *
+ * Authors:
+ * Brian Paul
+ */
+
+
+#include "main/imports.h"
+#include "main/macros.h"
+#include "main/mfeatures.h"
+#include "main/feedback.h"
+
+#include "st_context.h"
+#include "st_atom.h"
+#include "st_draw.h"
+#include "st_cb_rasterpos.h"
+#include "draw/draw_context.h"
+#include "draw/draw_pipe.h"
+#include "vbo/vbo.h"
+
+
+#if FEATURE_rastpos
+
+/**
+ * Our special drawing pipeline stage (replaces rasterization).
+ */
+struct rastpos_stage
+{
+ struct draw_stage stage; /**< Base class */
+ struct gl_context *ctx; /**< Rendering context */
+
+ /* vertex attrib info we can setup once and re-use */
+ struct gl_client_array array[VERT_ATTRIB_MAX];
+ const struct gl_client_array *arrays[VERT_ATTRIB_MAX];
+ struct _mesa_prim prim;
+};
+
+
+static INLINE struct rastpos_stage *
+rastpos_stage( struct draw_stage *stage )
+{
+ return (struct rastpos_stage *) stage;
+}
+
+static void
+rastpos_flush( struct draw_stage *stage, unsigned flags )
+{
+ /* no-op */
+}
+
+static void
+rastpos_reset_stipple_counter( struct draw_stage *stage )
+{
+ /* no-op */
+}
+
+static void
+rastpos_tri( struct draw_stage *stage, struct prim_header *prim )
+{
+ /* should never get here */
+ assert(0);
+}
+
+static void
+rastpos_line( struct draw_stage *stage, struct prim_header *prim )
+{
+ /* should never get here */
+ assert(0);
+}
+
+static void
+rastpos_destroy(struct draw_stage *stage)
+{
+ free(stage);
+}
+
+
+/**
+ * Update a raster pos attribute from the vertex result if it's present,
+ * else copy the current attrib.
+ */
+static void
+update_attrib(struct gl_context *ctx, const GLuint *outputMapping,
+ const struct vertex_header *vert,
+ GLfloat *dest,
+ GLuint result, GLuint defaultAttrib)
+{
+ const GLfloat *src;
+ const GLuint k = outputMapping[result];
+ if (k != ~0U)
+ src = vert->data[k];
+ else
+ src = ctx->Current.Attrib[defaultAttrib];
+ COPY_4V(dest, src);
+}
+
+
+/**
+ * Normally, this function would render a GL_POINT.
+ */
+static void
+rastpos_point(struct draw_stage *stage, struct prim_header *prim)
+{
+ struct rastpos_stage *rs = rastpos_stage(stage);
+ struct gl_context *ctx = rs->ctx;
+ struct st_context *st = st_context(ctx);
+ const GLfloat height = (GLfloat) ctx->DrawBuffer->Height;
+ const GLuint *outputMapping = st->vertex_result_to_slot;
+ const GLfloat *pos;
+ GLuint i;
+
+ /* if we get here, we didn't get clipped */
+ ctx->Current.RasterPosValid = GL_TRUE;
+
+ /* update raster pos */
+ pos = prim->v[0]->data[0];
+ ctx->Current.RasterPos[0] = pos[0];
+ if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP)
+ ctx->Current.RasterPos[1] = height - pos[1]; /* invert Y */
+ else
+ ctx->Current.RasterPos[1] = pos[1];
+ ctx->Current.RasterPos[2] = pos[2];
+ ctx->Current.RasterPos[3] = pos[3];
+
+ /* update other raster attribs */
+ update_attrib(ctx, outputMapping, prim->v[0],
+ ctx->Current.RasterColor,
+ VERT_RESULT_COL0, VERT_ATTRIB_COLOR0);
+
+ update_attrib(ctx, outputMapping, prim->v[0],
+ ctx->Current.RasterSecondaryColor,
+ VERT_RESULT_COL1, VERT_ATTRIB_COLOR1);
+
+ for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
+ update_attrib(ctx, outputMapping, prim->v[0],
+ ctx->Current.RasterTexCoords[i],
+ VERT_RESULT_TEX0 + i, VERT_ATTRIB_TEX0 + i);
+ }
+
+ if (ctx->RenderMode == GL_SELECT) {
+ _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
+ }
+}
+
+
+/**
+ * Create rasterpos "drawing" stage.
+ */
+static struct rastpos_stage *
+new_draw_rastpos_stage(struct gl_context *ctx, struct draw_context *draw)
+{
+ struct rastpos_stage *rs = ST_CALLOC_STRUCT(rastpos_stage);
+ GLuint i;
+
+ rs->stage.draw = draw;
+ rs->stage.next = NULL;
+ rs->stage.point = rastpos_point;
+ rs->stage.line = rastpos_line;
+ rs->stage.tri = rastpos_tri;
+ rs->stage.flush = rastpos_flush;
+ rs->stage.destroy = rastpos_destroy;
+ rs->stage.reset_stipple_counter = rastpos_reset_stipple_counter;
+ rs->stage.destroy = rastpos_destroy;
+ rs->ctx = ctx;
+
+ for (i = 0; i < Elements(rs->array); i++) {
+ rs->array[i].Size = 4;
+ rs->array[i].Type = GL_FLOAT;
+ rs->array[i].Format = GL_RGBA;
+ rs->array[i].Stride = 0;
+ rs->array[i].StrideB = 0;
+ rs->array[i].Ptr = (GLubyte *) ctx->Current.Attrib[i];
+ rs->array[i].Enabled = GL_TRUE;
+ rs->array[i].Normalized = GL_TRUE;
+ rs->array[i].BufferObj = NULL;
+ rs->arrays[i] = &rs->array[i];
+ }
+
+ rs->prim.mode = GL_POINTS;
+ rs->prim.indexed = 0;
+ rs->prim.begin = 1;
+ rs->prim.end = 1;
+ rs->prim.weak = 0;
+ rs->prim.start = 0;
+ rs->prim.count = 1;
+
+ return rs;
+}
+
+
+static void
+st_RasterPos(struct gl_context *ctx, const GLfloat v[4])
+{
+ struct st_context *st = st_context(ctx);
+ struct draw_context *draw = st->draw;
+ struct rastpos_stage *rs;
+
+ if (st->rastpos_stage) {
+ /* get rastpos stage info */
+ rs = rastpos_stage(st->rastpos_stage);
+ }
+ else {
+ /* create rastpos draw stage */
+ rs = new_draw_rastpos_stage(ctx, draw);
+ st->rastpos_stage = &rs->stage;
+ }
+
+ /* plug our rastpos stage into the draw module */
+ draw_set_rasterize_stage(st->draw, st->rastpos_stage);
+
+ /* make sure everything's up to date */
+ st_validate_state(st);
+
+ /* This will get set only if rastpos_point(), above, gets called */
+ ctx->Current.RasterPosValid = GL_FALSE;
+
+ /* All vertex attribs but position were previously initialized above.
+ * Just plug in position pointer now.
+ */
+ rs->array[0].Ptr = (GLubyte *) v;
+
+ /* draw the point */
+ st_feedback_draw_vbo(ctx, rs->arrays, &rs->prim, 1, NULL, GL_TRUE, 0, 1,
+ NULL);
+
+ /* restore draw's rasterization stage depending on rendermode */
+ if (ctx->RenderMode == GL_FEEDBACK) {
+ draw_set_rasterize_stage(draw, st->feedback_stage);
+ }
+ else if (ctx->RenderMode == GL_SELECT) {
+ draw_set_rasterize_stage(draw, st->selection_stage);
+ }
+}
+
+
+
+void st_init_rasterpos_functions(struct dd_function_table *functions)
+{
+ functions->RasterPos = st_RasterPos;
+}
+
+#endif /* FEATURE_rastpos */
diff --git a/mesalib/src/mesa/state_tracker/st_cb_xformfb.c b/mesalib/src/mesa/state_tracker/st_cb_xformfb.c
index 378b4822b..2fc28dc24 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_xformfb.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_xformfb.c
@@ -1,134 +1,197 @@
-/**************************************************************************
- *
- * Copyright 2010 VMware, Inc.
- * All Rights Reserved.
- *
- * 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, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-
-/**
- * Transform feedback functions.
- *
- * \author Brian Paul
- */
-
-
-#include "main/imports.h"
-#include "main/context.h"
-#include "main/mfeatures.h"
-#include "main/transformfeedback.h"
-
-#include "st_cb_xformfb.h"
-
-
-#if FEATURE_EXT_transform_feedback
-
-#if 0
-static struct gl_transform_feedback_object *
-st_new_transform_feedback(struct gl_context *ctx, GLuint name)
-{
- struct gl_transform_feedback_object *obj;
- obj = CALLOC_STRUCT(gl_transform_feedback_object);
- if (obj) {
- obj->Name = name;
- obj->RefCount = 1;
- }
- return obj;
-}
-#endif
-
-#if 0
-static void
-st_delete_transform_feedback(struct gl_context *ctx,
- struct gl_transform_feedback_object *obj)
-{
- GLuint i;
-
- for (i = 0; i < Elements(obj->Buffers); i++) {
- _mesa_reference_buffer_object(ctx, &obj->Buffers[i], NULL);
- }
-
- free(obj);
-}
-#endif
-
-
-static void
-st_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
- struct gl_transform_feedback_object *obj)
-{
- /* to-do */
-}
-
-
-static void
-st_end_transform_feedback(struct gl_context *ctx,
- struct gl_transform_feedback_object *obj)
-{
- /* to-do */
-}
-
-
-static void
-st_pause_transform_feedback(struct gl_context *ctx,
- struct gl_transform_feedback_object *obj)
-{
- /* to-do */
-}
-
-
-static void
-st_resume_transform_feedback(struct gl_context *ctx,
- struct gl_transform_feedback_object *obj)
-{
- /* to-do */
-}
-
-
-static void
-st_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
- struct gl_transform_feedback_object *obj)
-{
- /* XXX to do */
- /*
- * Get number of vertices in obj's feedback buffer.
- * Call ctx->Exec.DrawArrays(mode, 0, count);
- */
-}
-
-
-void
-st_init_xformfb_functions(struct dd_function_table *functions)
-{
- /* let core Mesa plug in its functions */
- _mesa_init_transform_feedback_functions(functions);
-
- /* then override a few: */
- functions->BeginTransformFeedback = st_begin_transform_feedback;
- functions->EndTransformFeedback = st_end_transform_feedback;
- functions->PauseTransformFeedback = st_pause_transform_feedback;
- functions->ResumeTransformFeedback = st_resume_transform_feedback;
- functions->DrawTransformFeedback = st_draw_transform_feedback;
-}
-
-#endif /* FEATURE_EXT_transform_feedback */
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * 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, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+/**
+ * Transform feedback functions.
+ *
+ * \author Brian Paul
+ * Marek Olšák
+ */
+
+
+#include "main/bufferobj.h"
+#include "main/context.h"
+#include "main/mfeatures.h"
+#include "main/transformfeedback.h"
+
+#include "st_cb_bufferobjects.h"
+#include "st_cb_xformfb.h"
+#include "st_context.h"
+
+#include "pipe/p_context.h"
+#include "util/u_draw.h"
+#include "util/u_inlines.h"
+#include "cso_cache/cso_context.h"
+
+#if FEATURE_EXT_transform_feedback
+
+struct st_transform_feedback_object {
+ struct gl_transform_feedback_object base;
+
+ unsigned num_targets;
+ struct pipe_stream_output_target *targets[PIPE_MAX_SO_BUFFERS];
+};
+
+
+static struct gl_transform_feedback_object *
+st_new_transform_feedback(struct gl_context *ctx, GLuint name)
+{
+ struct st_transform_feedback_object *obj;
+
+ obj = CALLOC_STRUCT(st_transform_feedback_object);
+ if (!obj)
+ return NULL;
+
+ obj->base.Name = name;
+ obj->base.RefCount = 1;
+ return &obj->base;
+}
+
+
+static void
+st_delete_transform_feedback(struct gl_context *ctx,
+ struct gl_transform_feedback_object *obj)
+{
+ struct st_transform_feedback_object *sobj =
+ (struct st_transform_feedback_object*)obj;
+ unsigned i;
+
+ /* Unreference targets. */
+ for (i = 0; i < sobj->num_targets; i++) {
+ pipe_so_target_reference(&sobj->targets[i], NULL);
+ }
+
+ for (i = 0; i < Elements(sobj->base.Buffers); i++) {
+ _mesa_reference_buffer_object(ctx, &sobj->base.Buffers[i], NULL);
+ }
+
+ free(obj);
+}
+
+
+/* XXX Do we really need the mode? */
+static void
+st_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
+ struct gl_transform_feedback_object *obj)
+{
+ struct st_context *st = st_context(ctx);
+ struct pipe_context *pipe = st->pipe;
+ struct st_transform_feedback_object *sobj =
+ (struct st_transform_feedback_object*)obj;
+ unsigned i, max_num_targets;
+
+ max_num_targets = MIN2(Elements(sobj->base.Buffers),
+ Elements(sobj->targets));
+
+ /* Convert the transform feedback state into the gallium representation. */
+ for (i = 0; i < max_num_targets; i++) {
+ struct st_buffer_object *bo = st_buffer_object(sobj->base.Buffers[i]);
+
+ if (bo) {
+ /* Check whether we need to recreate the target. */
+ if (!sobj->targets[i] ||
+ sobj->targets[i]->buffer != bo->buffer ||
+ sobj->targets[i]->buffer_offset != sobj->base.Offset[i] ||
+ sobj->targets[i]->buffer_size != sobj->base.Size[i]) {
+ /* Create a new target. */
+ struct pipe_stream_output_target *so_target =
+ pipe->create_stream_output_target(pipe, bo->buffer,
+ sobj->base.Offset[i],
+ sobj->base.Size[i]);
+
+ pipe_so_target_reference(&sobj->targets[i], NULL);
+ sobj->targets[i] = so_target;
+ }
+
+ sobj->num_targets = i+1;
+ } else {
+ pipe_so_target_reference(&sobj->targets[i], NULL);
+ }
+ }
+
+ /* Start writing at the beginning of each target. */
+ cso_set_stream_outputs(st->cso_context, sobj->num_targets, sobj->targets,
+ 0);
+}
+
+
+static void
+st_stop_transform_feedback(struct gl_context *ctx,
+ struct gl_transform_feedback_object *obj)
+{
+ struct st_context *st = st_context(ctx);
+ cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
+}
+
+
+static void
+st_resume_transform_feedback(struct gl_context *ctx,
+ struct gl_transform_feedback_object *obj)
+{
+ struct st_context *st = st_context(ctx);
+ struct st_transform_feedback_object *sobj =
+ (struct st_transform_feedback_object*)obj;
+
+ cso_set_stream_outputs(st->cso_context, sobj->num_targets, sobj->targets,
+ ~0);
+}
+
+/* Set count_from_stream_output to any stream output target
+ * from the transform feedback object. */
+void
+st_transform_feedback_draw_init(struct gl_transform_feedback_object *obj,
+ struct pipe_draw_info *out)
+{
+ struct st_transform_feedback_object *sobj =
+ (struct st_transform_feedback_object*)obj;
+ unsigned i;
+
+ for (i = 0; i < Elements(sobj->targets); i++) {
+ if (sobj->targets[i]) {
+ out->count_from_stream_output = sobj->targets[i];
+ return;
+ }
+ }
+
+ assert(0);
+ out->count_from_stream_output = NULL;
+}
+
+
+void
+st_init_xformfb_functions(struct dd_function_table *functions)
+{
+ functions->NewTransformFeedback = st_new_transform_feedback;
+ functions->DeleteTransformFeedback = st_delete_transform_feedback;
+ functions->BeginTransformFeedback = st_begin_transform_feedback;
+ functions->EndTransformFeedback = st_stop_transform_feedback;
+ functions->PauseTransformFeedback = st_stop_transform_feedback;
+ functions->ResumeTransformFeedback = st_resume_transform_feedback;
+}
+
+#endif /* FEATURE_EXT_transform_feedback */
diff --git a/mesalib/src/mesa/state_tracker/st_cb_xformfb.h b/mesalib/src/mesa/state_tracker/st_cb_xformfb.h
index e07f500ce..c5261b39b 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_xformfb.h
+++ b/mesalib/src/mesa/state_tracker/st_cb_xformfb.h
@@ -1,51 +1,63 @@
-/**************************************************************************
- *
- * Copyright 2010 VMware, Inc.
- * All Rights Reserved.
- *
- * 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, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-#ifndef ST_CB_XFORMFB_H
-#define ST_CB_XFORMFB_H
-
-
-#include "main/compiler.h"
-#include "main/mfeatures.h"
-
-struct dd_function_table;
-
-#if FEATURE_EXT_transform_feedback
-
-extern void
-st_init_xformfb_functions(struct dd_function_table *functions);
-
-#else
-
-static INLINE void
-st_init_xformfb_functions(struct dd_function_table *functions)
-{
-}
-
-#endif /* FEATURE_EXT_transform_feedback */
-
-#endif /* ST_CB_XFORMFB_H */
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * 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, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef ST_CB_XFORMFB_H
+#define ST_CB_XFORMFB_H
+
+
+#include "main/compiler.h"
+#include "main/mfeatures.h"
+
+struct dd_function_table;
+struct gl_transform_feedback_object;
+struct pipe_draw_info;
+
+#if FEATURE_EXT_transform_feedback
+
+extern void
+st_init_xformfb_functions(struct dd_function_table *functions);
+
+extern void
+st_transform_feedback_draw_init(struct gl_transform_feedback_object *obj,
+ struct pipe_draw_info *out);
+
+#else
+
+static INLINE void
+st_init_xformfb_functions(struct dd_function_table *functions)
+{
+}
+
+static INLINE void
+st_transform_feedback_draw_init(struct gl_transform_feedback_object *obj,
+ struct pipe_draw_info *out)
+{
+}
+
+#endif /* FEATURE_EXT_transform_feedback */
+
+#endif /* ST_CB_XFORMFB_H */
diff --git a/mesalib/src/mesa/state_tracker/st_draw.c b/mesalib/src/mesa/state_tracker/st_draw.c
index fd1c8ee48..87a997865 100644
--- a/mesalib/src/mesa/state_tracker/st_draw.c
+++ b/mesalib/src/mesa/state_tracker/st_draw.c
@@ -51,6 +51,7 @@
#include "st_context.h"
#include "st_atom.h"
#include "st_cb_bufferobjects.h"
+#include "st_cb_xformfb.h"
#include "st_draw.h"
#include "st_program.h"
@@ -926,7 +927,8 @@ st_draw_vbo(struct gl_context *ctx,
const struct _mesa_index_buffer *ib,
GLboolean index_bounds_valid,
GLuint min_index,
- GLuint max_index)
+ GLuint max_index,
+ struct gl_transform_feedback_object *tfb_vertcount)
{
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
@@ -1032,6 +1034,11 @@ st_draw_vbo(struct gl_context *ctx,
info.restart_index = ctx->Array.RestartIndex;
}
+ /* Set info.count_from_stream_output. */
+ if (tfb_vertcount) {
+ st_transform_feedback_draw_init(tfb_vertcount, &info);
+ }
+
/* do actual drawing */
for (i = 0; i < nr_prims; i++) {
info.mode = translate_prim( ctx, prims[i].mode );
@@ -1044,7 +1051,10 @@ st_draw_vbo(struct gl_context *ctx,
info.max_index = info.start + info.count - 1;
}
- if (info.primitive_restart) {
+ if (info.count_from_stream_output) {
+ pipe->draw_vbo(pipe, &info);
+ }
+ else if (info.primitive_restart) {
if (st->sw_primitive_restart) {
/* Handle primitive restart for drivers that doesn't support it */
handle_fallback_primitive_restart(pipe, ib, &ibuffer, &info);
diff --git a/mesalib/src/mesa/state_tracker/st_draw.h b/mesalib/src/mesa/state_tracker/st_draw.h
index 23e1c7821..2623cdbb1 100644
--- a/mesalib/src/mesa/state_tracker/st_draw.h
+++ b/mesalib/src/mesa/state_tracker/st_draw.h
@@ -1,91 +1,93 @@
-/**************************************************************************
- *
- * Copyright 2004 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * 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, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
- /*
- * Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
- */
-
-
-#ifndef ST_DRAW_H
-#define ST_DRAW_H
-
-#include "main/compiler.h"
-#include "main/glheader.h"
-
-struct _mesa_index_buffer;
-struct _mesa_prim;
-struct gl_client_array;
-struct gl_context;
-struct st_context;
-
-void st_init_draw( struct st_context *st );
-
-void st_destroy_draw( struct st_context *st );
-
-extern void
-st_draw_vbo(struct gl_context *ctx,
- const struct gl_client_array **arrays,
- const struct _mesa_prim *prims,
- GLuint nr_prims,
- const struct _mesa_index_buffer *ib,
- GLboolean index_bounds_valid,
- GLuint min_index,
- GLuint max_index);
-
-extern void
-st_feedback_draw_vbo(struct gl_context *ctx,
- const struct gl_client_array **arrays,
- const struct _mesa_prim *prims,
- GLuint nr_prims,
- const struct _mesa_index_buffer *ib,
- GLboolean index_bounds_valid,
- GLuint min_index,
- GLuint max_index);
-
-/* Internal function:
- */
-extern enum pipe_format
-st_pipe_vertex_format(GLenum type, GLuint size, GLenum format,
- GLboolean normalized);
-
-
-/**
- * When drawing with VBOs, the addresses specified with
- * glVertex/Color/TexCoordPointer() are really offsets into the VBO, not real
- * addresses. At some point we need to convert those pointers to offsets.
- * This function is basically a cast wrapper to avoid warnings when building
- * in 64-bit mode.
- */
-static INLINE unsigned
-pointer_to_offset(const void *ptr)
-{
- return (unsigned) (((unsigned long) ptr) & 0xffffffffUL);
-}
-
-
-#endif
+/**************************************************************************
+ *
+ * Copyright 2004 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * 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, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+ /*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+
+#ifndef ST_DRAW_H
+#define ST_DRAW_H
+
+#include "main/compiler.h"
+#include "main/glheader.h"
+
+struct _mesa_index_buffer;
+struct _mesa_prim;
+struct gl_client_array;
+struct gl_context;
+struct st_context;
+
+void st_init_draw( struct st_context *st );
+
+void st_destroy_draw( struct st_context *st );
+
+extern void
+st_draw_vbo(struct gl_context *ctx,
+ const struct gl_client_array **arrays,
+ const struct _mesa_prim *prims,
+ GLuint nr_prims,
+ const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
+ GLuint min_index,
+ GLuint max_index,
+ struct gl_transform_feedback_object *tfb_vertcount);
+
+extern void
+st_feedback_draw_vbo(struct gl_context *ctx,
+ const struct gl_client_array **arrays,
+ const struct _mesa_prim *prims,
+ GLuint nr_prims,
+ const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
+ GLuint min_index,
+ GLuint max_index,
+ struct gl_transform_feedback_object *tfb_vertcount);
+
+/* Internal function:
+ */
+extern enum pipe_format
+st_pipe_vertex_format(GLenum type, GLuint size, GLenum format,
+ GLboolean normalized);
+
+
+/**
+ * When drawing with VBOs, the addresses specified with
+ * glVertex/Color/TexCoordPointer() are really offsets into the VBO, not real
+ * addresses. At some point we need to convert those pointers to offsets.
+ * This function is basically a cast wrapper to avoid warnings when building
+ * in 64-bit mode.
+ */
+static INLINE unsigned
+pointer_to_offset(const void *ptr)
+{
+ return (unsigned) (((unsigned long) ptr) & 0xffffffffUL);
+}
+
+
+#endif
diff --git a/mesalib/src/mesa/state_tracker/st_draw_feedback.c b/mesalib/src/mesa/state_tracker/st_draw_feedback.c
index a7e6a0f1b..4c1e67495 100644
--- a/mesalib/src/mesa/state_tracker/st_draw_feedback.c
+++ b/mesalib/src/mesa/state_tracker/st_draw_feedback.c
@@ -97,7 +97,8 @@ st_feedback_draw_vbo(struct gl_context *ctx,
const struct _mesa_index_buffer *ib,
GLboolean index_bounds_valid,
GLuint min_index,
- GLuint max_index)
+ GLuint max_index,
+ struct gl_transform_feedback_object *tfb_vertcount)
{
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c
index 457d5d62a..47a178b8b 100644
--- a/mesalib/src/mesa/state_tracker/st_extensions.c
+++ b/mesalib/src/mesa/state_tracker/st_extensions.c
@@ -221,6 +221,13 @@ void st_init_limits(struct st_context *st)
c->UniformBooleanTrue = ~0;
+ c->MaxTransformFeedbackSeparateAttribs =
+ screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_ATTRIBS);
+ c->MaxTransformFeedbackSeparateComponents =
+ screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS);
+ c->MaxTransformFeedbackInterleavedComponents =
+ screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS);
+
c->StripTextureBorder = GL_TRUE;
c->GLSLSkipStrictMaxUniformLimitCheck =
@@ -682,4 +689,12 @@ void st_init_extensions(struct st_context *st)
PIPE_BIND_SAMPLER_VIEW))
ctx->Extensions.ARB_texture_rgb10_a2ui = GL_TRUE;
+ if (screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0) {
+ ctx->Extensions.EXT_transform_feedback = GL_TRUE;
+
+ if (screen->get_param(screen,
+ PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME) != 0) {
+ ctx->Extensions.ARB_transform_feedback2 = GL_TRUE;
+ }
+ }
}
diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 9ef65c8fd..b929806ad 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -5095,4 +5095,31 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
return GL_TRUE;
}
+void
+st_translate_stream_output_info(struct glsl_to_tgsi_visitor *glsl_to_tgsi,
+ const GLuint outputMapping[],
+ struct pipe_stream_output_info *so)
+{
+ static unsigned comps_to_mask[] = {
+ 0,
+ TGSI_WRITEMASK_X,
+ TGSI_WRITEMASK_XY,
+ TGSI_WRITEMASK_XYZ,
+ TGSI_WRITEMASK_XYZW
+ };
+ unsigned i;
+ struct gl_transform_feedback_info *info =
+ &glsl_to_tgsi->shader_program->LinkedTransformFeedback;
+
+ for (i = 0; i < info->NumOutputs; i++) {
+ assert(info->Outputs[i].NumComponents < Elements(comps_to_mask));
+ so->output[i].register_index =
+ outputMapping[info->Outputs[i].OutputRegister];
+ so->output[i].register_mask =
+ comps_to_mask[info->Outputs[i].NumComponents];
+ so->output[i].output_buffer = info->Outputs[i].OutputBuffer;
+ }
+ so->num_outputs = info->NumOutputs;
+}
+
} /* extern "C" */
diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h
index fafe52e31..1f71f33fd 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h
@@ -66,6 +66,12 @@ st_new_shader_program(struct gl_context *ctx, GLuint name);
GLboolean st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog);
+void
+st_translate_stream_output_info(struct glsl_to_tgsi_visitor *glsl_to_tgsi,
+ const GLuint outputMapping[],
+ struct pipe_stream_output_info *so);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/mesalib/src/mesa/state_tracker/st_program.c b/mesalib/src/mesa/state_tracker/st_program.c
index 04d3ef60f..b83c56165 100644
--- a/mesalib/src/mesa/state_tracker/st_program.c
+++ b/mesalib/src/mesa/state_tracker/st_program.c
@@ -367,6 +367,12 @@ st_translate_vertex_program(struct st_context *st,
ureg_destroy( ureg );
+ if (stvp->glsl_to_tgsi) {
+ st_translate_stream_output_info(stvp->glsl_to_tgsi,
+ stvp->result_to_output,
+ &vpv->tgsi.stream_output);
+ }
+
vpv->driver_shader = pipe->create_vs_state(pipe, &vpv->tgsi);
if (ST_DEBUG & DEBUG_TGSI) {
@@ -994,6 +1000,12 @@ st_translate_geometry_program(struct st_context *st,
stgp->tgsi.tokens = ureg_get_tokens( ureg, NULL );
ureg_destroy( ureg );
+ if (stgp->glsl_to_tgsi) {
+ st_translate_stream_output_info(stgp->glsl_to_tgsi,
+ outputMapping,
+ &stgp->tgsi.stream_output);
+ }
+
/* fill in new variant */
gpv->driver_shader = pipe->create_gs_state(pipe, &stgp->tgsi);
gpv->key = *key;
diff --git a/mesalib/src/mesa/swrast/s_blit.c b/mesalib/src/mesa/swrast/s_blit.c
index 2817ec12f..803ad2e89 100644
--- a/mesalib/src/mesa/swrast/s_blit.c
+++ b/mesalib/src/mesa/swrast/s_blit.c
@@ -478,7 +478,15 @@ simple_blit(struct gl_context *ctx,
ASSERT(srcX1 - srcX0 == dstX1 - dstX0);
ASSERT(srcY1 - srcY0 == dstY1 - dstY0);
- /* determine if copy should be bottom-to-top or top-to-bottom */
+ /* From the GL_ARB_framebuffer_object spec:
+ *
+ * "If the source and destination buffers are identical, and the source
+ * and destination rectangles overlap, the result of the blit operation
+ * is undefined."
+ *
+ * However, we provide the expected result anyway by flipping the order of
+ * the memcpy of rows.
+ */
if (srcY0 > dstY0) {
/* src above dst: copy bottom-to-top */
yStep = 1;
diff --git a/mesalib/src/mesa/swrast/s_drawpix.c b/mesalib/src/mesa/swrast/s_drawpix.c
index b6c433753..7259881c1 100644
--- a/mesalib/src/mesa/swrast/s_drawpix.c
+++ b/mesalib/src/mesa/swrast/s_drawpix.c
@@ -625,7 +625,8 @@ draw_depth_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,
GL_DEPTH_STENCIL_EXT, type, i, 0);
if (ctx->Depth.Mask) {
- if (!scaleOrBias && ctx->DrawBuffer->Visual.depthBits == 24) {
+ if (!scaleOrBias && ctx->DrawBuffer->Visual.depthBits == 24 &&
+ type == GL_UNSIGNED_INT_24_8) {
/* fast path 24-bit zbuffer */
GLuint zValues[MAX_WIDTH];
GLint j;
@@ -639,7 +640,8 @@ draw_depth_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,
else
depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues,NULL);
}
- else if (!scaleOrBias && ctx->DrawBuffer->Visual.depthBits == 16) {
+ else if (!scaleOrBias && ctx->DrawBuffer->Visual.depthBits == 16 &&
+ type == GL_UNSIGNED_INT_24_8) {
/* fast path 16-bit zbuffer */
GLushort zValues[MAX_WIDTH];
GLint j;
diff --git a/mesalib/src/mesa/tnl/t_draw.c b/mesalib/src/mesa/tnl/t_draw.c
index 03424d7a4..83ded1949 100644
--- a/mesalib/src/mesa/tnl/t_draw.c
+++ b/mesalib/src/mesa/tnl/t_draw.c
@@ -430,7 +430,8 @@ void _tnl_vbo_draw_prims(struct gl_context *ctx,
const struct _mesa_index_buffer *ib,
GLboolean index_bounds_valid,
GLuint min_index,
- GLuint max_index)
+ GLuint max_index,
+ struct gl_transform_feedback_object *tfb_vertcount)
{
if (!index_bounds_valid)
vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
diff --git a/mesalib/src/mesa/tnl/tnl.h b/mesalib/src/mesa/tnl/tnl.h
index 3ca0c5ebb..d3889811e 100644
--- a/mesalib/src/mesa/tnl/tnl.h
+++ b/mesalib/src/mesa/tnl/tnl.h
@@ -1,103 +1,104 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.1
- *
- * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
- *
- * 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 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
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#ifndef _TNL_H
-#define _TNL_H
-
-#include "main/glheader.h"
-
-struct gl_client_array;
-struct gl_context;
-struct gl_program;
-
-
-/* These are the public-access functions exported from tnl. (A few
- * more are currently hooked into dispatch directly by the module
- * itself.)
- */
-extern GLboolean
-_tnl_CreateContext( struct gl_context *ctx );
-
-extern void
-_tnl_DestroyContext( struct gl_context *ctx );
-
-extern void
-_tnl_InvalidateState( struct gl_context *ctx, GLuint new_state );
-
-/* Functions to revive the tnl module after being unhooked from
- * dispatch and/or driver callbacks.
- */
-
-extern void
-_tnl_wakeup( struct gl_context *ctx );
-
-/* Driver configuration options:
- */
-extern void
-_tnl_need_projected_coords( struct gl_context *ctx, GLboolean flag );
-
-
-/* Control whether T&L does per-vertex fog
- */
-extern void
-_tnl_allow_vertex_fog( struct gl_context *ctx, GLboolean value );
-
-extern void
-_tnl_allow_pixel_fog( struct gl_context *ctx, GLboolean value );
-
-extern GLboolean
-_tnl_program_string(struct gl_context *ctx, GLenum target, struct gl_program *program);
-
-struct _mesa_prim;
-struct _mesa_index_buffer;
-
-void
-_tnl_draw_prims( struct gl_context *ctx,
- const struct gl_client_array *arrays[],
- const struct _mesa_prim *prim,
- GLuint nr_prims,
- const struct _mesa_index_buffer *ib,
- GLuint min_index,
- GLuint max_index);
-
-void
-_tnl_vbo_draw_prims( struct gl_context *ctx,
- const struct gl_client_array *arrays[],
- const struct _mesa_prim *prim,
- GLuint nr_prims,
- const struct _mesa_index_buffer *ib,
- GLboolean index_bounds_valid,
- GLuint min_index,
- GLuint max_index);
-
-extern void
-_mesa_load_tracked_matrices(struct gl_context *ctx);
-
-extern void
-_tnl_RasterPos(struct gl_context *ctx, const GLfloat vObj[4]);
-
-#endif
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.1
+ *
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ *
+ * 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 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
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef _TNL_H
+#define _TNL_H
+
+#include "main/glheader.h"
+
+struct gl_client_array;
+struct gl_context;
+struct gl_program;
+
+
+/* These are the public-access functions exported from tnl. (A few
+ * more are currently hooked into dispatch directly by the module
+ * itself.)
+ */
+extern GLboolean
+_tnl_CreateContext( struct gl_context *ctx );
+
+extern void
+_tnl_DestroyContext( struct gl_context *ctx );
+
+extern void
+_tnl_InvalidateState( struct gl_context *ctx, GLuint new_state );
+
+/* Functions to revive the tnl module after being unhooked from
+ * dispatch and/or driver callbacks.
+ */
+
+extern void
+_tnl_wakeup( struct gl_context *ctx );
+
+/* Driver configuration options:
+ */
+extern void
+_tnl_need_projected_coords( struct gl_context *ctx, GLboolean flag );
+
+
+/* Control whether T&L does per-vertex fog
+ */
+extern void
+_tnl_allow_vertex_fog( struct gl_context *ctx, GLboolean value );
+
+extern void
+_tnl_allow_pixel_fog( struct gl_context *ctx, GLboolean value );
+
+extern GLboolean
+_tnl_program_string(struct gl_context *ctx, GLenum target, struct gl_program *program);
+
+struct _mesa_prim;
+struct _mesa_index_buffer;
+
+void
+_tnl_draw_prims( struct gl_context *ctx,
+ const struct gl_client_array *arrays[],
+ const struct _mesa_prim *prim,
+ GLuint nr_prims,
+ const struct _mesa_index_buffer *ib,
+ GLuint min_index,
+ GLuint max_index);
+
+void
+_tnl_vbo_draw_prims( struct gl_context *ctx,
+ const struct gl_client_array *arrays[],
+ const struct _mesa_prim *prim,
+ GLuint nr_prims,
+ const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
+ GLuint min_index,
+ GLuint max_index,
+ struct gl_transform_feedback_object *tfb_vertcount );
+
+extern void
+_mesa_load_tracked_matrices(struct gl_context *ctx);
+
+extern void
+_tnl_RasterPos(struct gl_context *ctx, const GLfloat vObj[4]);
+
+#endif
diff --git a/mesalib/src/mesa/vbo/vbo.h b/mesalib/src/mesa/vbo/vbo.h
index 9fbb07f3d..f357657af 100644
--- a/mesalib/src/mesa/vbo/vbo.h
+++ b/mesalib/src/mesa/vbo/vbo.h
@@ -36,6 +36,7 @@
struct gl_client_array;
struct gl_context;
+struct gl_transform_feedback_object;
struct _mesa_prim {
GLuint mode:8; /**< GL_POINTS, GL_LINES, GL_QUAD_STRIP, etc */
@@ -77,7 +78,8 @@ typedef void (*vbo_draw_func)( struct gl_context *ctx,
const struct _mesa_index_buffer *ib,
GLboolean index_bounds_valid,
GLuint min_index,
- GLuint max_index );
+ GLuint max_index,
+ struct gl_transform_feedback_object *tfb_vertcount );
diff --git a/mesalib/src/mesa/vbo/vbo_context.h b/mesalib/src/mesa/vbo/vbo_context.h
index ef8a2a2b6..1a1cc928b 100644
--- a/mesalib/src/mesa/vbo/vbo_context.h
+++ b/mesalib/src/mesa/vbo/vbo_context.h
@@ -67,6 +67,7 @@ struct vbo_context {
struct gl_client_array *generic_currval;
struct gl_client_array *mat_currval;
+ /** Map VERT_ATTRIB_x to VBO_ATTRIB_y */
GLuint map_vp_none[VERT_ATTRIB_MAX];
GLuint map_vp_arb[VERT_ATTRIB_MAX];
diff --git a/mesalib/src/mesa/vbo/vbo_exec_array.c b/mesalib/src/mesa/vbo/vbo_exec_array.c
index 97221a54d..a6e41e9c5 100644
--- a/mesalib/src/mesa/vbo/vbo_exec_array.c
+++ b/mesalib/src/mesa/vbo/vbo_exec_array.c
@@ -34,6 +34,7 @@
#include "main/bufferobj.h"
#include "main/enums.h"
#include "main/macros.h"
+#include "main/transformfeedback.h"
#include "vbo_context.h"
@@ -608,7 +609,7 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
/* draw one or two prims */
check_buffers_are_unmapped(exec->array.inputs);
vbo->draw_prims(ctx, exec->array.inputs, prim, primCount, NULL,
- GL_TRUE, start, start + count - 1);
+ GL_TRUE, start, start + count - 1, NULL);
}
}
else {
@@ -618,7 +619,8 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
check_buffers_are_unmapped(exec->array.inputs);
vbo->draw_prims(ctx, exec->array.inputs, prim, 1, NULL,
- GL_TRUE, start, start + count - 1);
+ GL_TRUE, start, start + count - 1,
+ NULL);
}
}
@@ -824,7 +826,7 @@ vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,
check_buffers_are_unmapped(exec->array.inputs);
vbo->draw_prims( ctx, exec->array.inputs, prim, 1, &ib,
- index_bounds_valid, start, end );
+ index_bounds_valid, start, end, NULL );
}
@@ -1168,7 +1170,7 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
check_buffers_are_unmapped(exec->array.inputs);
vbo->draw_prims(ctx, exec->array.inputs, prim, primcount, &ib,
- GL_FALSE, ~0, ~0);
+ GL_FALSE, ~0, ~0, NULL);
} else {
/* render one prim at a time */
for (i = 0; i < primcount; i++) {
@@ -1193,7 +1195,7 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
check_buffers_are_unmapped(exec->array.inputs);
vbo->draw_prims(ctx, exec->array.inputs, prim, 1, &ib,
- GL_FALSE, ~0, ~0);
+ GL_FALSE, ~0, ~0, NULL);
}
}
@@ -1245,6 +1247,76 @@ vbo_exec_MultiDrawElementsBaseVertex(GLenum mode,
basevertex);
}
+#if FEATURE_EXT_transform_feedback
+
+static void
+vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
+ struct gl_transform_feedback_object *obj,
+ GLuint numInstances)
+{
+ struct vbo_context *vbo = vbo_context(ctx);
+ struct vbo_exec_context *exec = &vbo->exec;
+ struct _mesa_prim prim[2];
+
+ vbo_bind_arrays(ctx);
+
+ /* Again... because we may have changed the bitmask of per-vertex varying
+ * attributes. If we regenerate the fixed-function vertex program now
+ * we may be able to prune down the number of vertex attributes which we
+ * need in the shader.
+ */
+ if (ctx->NewState)
+ _mesa_update_state(ctx);
+
+ /* init most fields to zero */
+ memset(prim, 0, sizeof(prim));
+ prim[0].begin = 1;
+ prim[0].end = 1;
+ prim[0].mode = mode;
+ prim[0].num_instances = numInstances;
+
+ /* Maybe we should do some primitive splitting for primitive restart
+ * (like in DrawArrays), but we have no way to know how many vertices
+ * will be rendered. */
+
+ check_buffers_are_unmapped(exec->array.inputs);
+ vbo->draw_prims(ctx, exec->array.inputs, prim, 1, NULL,
+ GL_TRUE, 0, 0, obj);
+}
+
+/**
+ * Like DrawArrays, but take the count from a transform feedback object.
+ * \param mode GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc.
+ * \param name the transform feedback object
+ * User still has to setup of the vertex attribute info with
+ * glVertexPointer, glColorPointer, etc.
+ * Part of GL_ARB_transform_feedback2.
+ */
+static void GLAPIENTRY
+vbo_exec_DrawTransformFeedback(GLenum mode, GLuint name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_transform_feedback_object *obj =
+ _mesa_lookup_transform_feedback_object(ctx, name);
+
+ if (MESA_VERBOSE & VERBOSE_DRAW)
+ _mesa_debug(ctx, "glDrawTransformFeedback(%s, %d)\n",
+ _mesa_lookup_enum_by_nr(mode), name);
+
+ if (!_mesa_validate_DrawTransformFeedback(ctx, mode, obj)) {
+ return;
+ }
+
+ FLUSH_CURRENT(ctx, 0);
+
+ if (!_mesa_valid_to_render(ctx, "glDrawTransformFeedback")) {
+ return;
+ }
+
+ vbo_draw_transform_feedback(ctx, mode, obj, 1);
+}
+
+#endif
/**
* Plug in the immediate-mode vertex array drawing commands into the
@@ -1263,6 +1335,7 @@ vbo_exec_array_init( struct vbo_exec_context *exec )
exec->vtxfmt.DrawArraysInstanced = vbo_exec_DrawArraysInstanced;
exec->vtxfmt.DrawElementsInstanced = vbo_exec_DrawElementsInstanced;
exec->vtxfmt.DrawElementsInstancedBaseVertex = vbo_exec_DrawElementsInstancedBaseVertex;
+ exec->vtxfmt.DrawTransformFeedback = vbo_exec_DrawTransformFeedback;
}
@@ -1338,3 +1411,13 @@ _mesa_MultiDrawElementsBaseVertex(GLenum mode,
vbo_exec_MultiDrawElementsBaseVertex(mode, count, type, indices,
primcount, basevertex);
}
+
+#if FEATURE_EXT_transform_feedback
+
+void GLAPIENTRY
+_mesa_DrawTransformFeedback(GLenum mode, GLuint name)
+{
+ vbo_exec_DrawTransformFeedback(mode, name);
+}
+
+#endif
diff --git a/mesalib/src/mesa/vbo/vbo_exec_draw.c b/mesalib/src/mesa/vbo/vbo_exec_draw.c
index 4962b54e1..dd5363beb 100644
--- a/mesalib/src/mesa/vbo/vbo_exec_draw.c
+++ b/mesalib/src/mesa/vbo/vbo_exec_draw.c
@@ -411,7 +411,8 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec, GLboolean keepUnmapped)
NULL,
GL_TRUE,
0,
- exec->vtx.vert_count - 1);
+ exec->vtx.vert_count - 1,
+ NULL);
/* If using a real VBO, get new storage -- unless asked not to.
*/
diff --git a/mesalib/src/mesa/vbo/vbo_rebase.c b/mesalib/src/mesa/vbo/vbo_rebase.c
index 97c8d1297..597a8f469 100644
--- a/mesalib/src/mesa/vbo/vbo_rebase.c
+++ b/mesalib/src/mesa/vbo/vbo_rebase.c
@@ -233,7 +233,8 @@ void vbo_rebase_prims( struct gl_context *ctx,
ib,
GL_TRUE,
0,
- max_index - min_index );
+ max_index - min_index,
+ NULL );
if (tmp_indices)
free(tmp_indices);
diff --git a/mesalib/src/mesa/vbo/vbo_save_api.c b/mesalib/src/mesa/vbo/vbo_save_api.c
index 9d8bada04..952136747 100644
--- a/mesalib/src/mesa/vbo/vbo_save_api.c
+++ b/mesalib/src/mesa/vbo/vbo_save_api.c
@@ -999,6 +999,16 @@ _save_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count,
static void GLAPIENTRY
+_save_DrawTransformFeedback(GLenum mode, GLuint name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ (void) mode;
+ (void) name;
+ _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glDrawTransformFeedback");
+}
+
+
+static void GLAPIENTRY
_save_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
{
GET_CURRENT_CONTEXT(ctx);
@@ -1347,6 +1357,7 @@ _save_vtxfmt_init(struct gl_context *ctx)
vfmt->DrawRangeElements = _save_DrawRangeElements;
vfmt->DrawElementsBaseVertex = _save_DrawElementsBaseVertex;
vfmt->DrawRangeElementsBaseVertex = _save_DrawRangeElementsBaseVertex;
+ vfmt->DrawTransformFeedback = _save_DrawTransformFeedback;
vfmt->MultiDrawElementsEXT = _save_MultiDrawElements;
vfmt->MultiDrawElementsBaseVertex = _save_MultiDrawElementsBaseVertex;
}
diff --git a/mesalib/src/mesa/vbo/vbo_save_draw.c b/mesalib/src/mesa/vbo/vbo_save_draw.c
index 0773786b3..fa93ca48f 100644
--- a/mesalib/src/mesa/vbo/vbo_save_draw.c
+++ b/mesalib/src/mesa/vbo/vbo_save_draw.c
@@ -299,7 +299,8 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data)
NULL,
GL_TRUE,
0, /* Node is a VBO, so this is ok */
- node->count - 1);
+ node->count - 1,
+ NULL);
}
}
diff --git a/mesalib/src/mesa/vbo/vbo_split_copy.c b/mesalib/src/mesa/vbo/vbo_split_copy.c
index 4dcf71ef5..b53293c31 100644
--- a/mesalib/src/mesa/vbo/vbo_split_copy.c
+++ b/mesalib/src/mesa/vbo/vbo_split_copy.c
@@ -196,7 +196,8 @@ flush( struct copy_context *copy )
&copy->dstib,
GL_TRUE,
0,
- copy->dstbuf_nr - 1 );
+ copy->dstbuf_nr - 1,
+ NULL );
/* Reset all pointers:
*/
diff --git a/mesalib/src/mesa/vbo/vbo_split_inplace.c b/mesalib/src/mesa/vbo/vbo_split_inplace.c
index f6aa576b6..9e596f668 100644
--- a/mesalib/src/mesa/vbo/vbo_split_inplace.c
+++ b/mesalib/src/mesa/vbo/vbo_split_inplace.c
@@ -89,7 +89,8 @@ static void flush_vertex( struct split_context *split )
split->ib ? &ib : NULL,
!split->ib,
split->min_index,
- split->max_index);
+ split->max_index,
+ NULL);
split->dstprim_nr = 0;
split->min_index = ~0;