From abacebe06d9f3d2fe1b7d256bd86cddbfa592a85 Mon Sep 17 00:00:00 2001 From: marha Date: Sat, 17 Dec 2011 13:43:14 +0100 Subject: libX11 libxtrans mesa xserver git update 17 dec 2011 --- mesalib/src/mesa/drivers/common/meta.c | 47 +- mesalib/src/mesa/main/api_validate.c | 34 ++ mesalib/src/mesa/main/api_validate.h | 10 + mesalib/src/mesa/main/dd.h | 3 +- mesalib/src/mesa/main/dlist.c | 22 +- mesalib/src/mesa/main/fbobject.c | 20 +- mesalib/src/mesa/main/format_unpack.c | 8 + mesalib/src/mesa/main/mipmap.c | 128 +++-- mesalib/src/mesa/main/mipmap.h | 6 + mesalib/src/mesa/main/mtypes.h | 2 + mesalib/src/mesa/main/texformat.c | 2 + mesalib/src/mesa/main/texgetimage.c | 8 + mesalib/src/mesa/main/teximage.c | 11 +- mesalib/src/mesa/main/teximage.h | 4 + mesalib/src/mesa/main/transformfeedback.c | 61 +-- mesalib/src/mesa/main/transformfeedback.h | 6 +- mesalib/src/mesa/main/varray.h | 7 + mesalib/src/mesa/main/vtxfmt.c | 1 + mesalib/src/mesa/program/prog_parameter_layout.c | 1 + .../src/mesa/state_tracker/st_atom_pixeltransfer.c | 1 + .../src/mesa/state_tracker/st_atom_rasterizer.c | 7 +- mesalib/src/mesa/state_tracker/st_cb_bitmap.c | 3 + mesalib/src/mesa/state_tracker/st_cb_clear.c | 3 + mesalib/src/mesa/state_tracker/st_cb_drawpixels.c | 3 + mesalib/src/mesa/state_tracker/st_cb_drawtex.c | 3 + mesalib/src/mesa/state_tracker/st_cb_rasterpos.c | 545 +++++++++++---------- mesalib/src/mesa/state_tracker/st_cb_xformfb.c | 331 ++++++++----- mesalib/src/mesa/state_tracker/st_cb_xformfb.h | 114 +++-- mesalib/src/mesa/state_tracker/st_draw.c | 14 +- mesalib/src/mesa/state_tracker/st_draw.h | 184 +++---- mesalib/src/mesa/state_tracker/st_draw_feedback.c | 3 +- mesalib/src/mesa/state_tracker/st_extensions.c | 15 + mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 27 + mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.h | 6 + mesalib/src/mesa/state_tracker/st_program.c | 12 + mesalib/src/mesa/swrast/s_blit.c | 10 +- mesalib/src/mesa/swrast/s_drawpix.c | 6 +- mesalib/src/mesa/tnl/t_draw.c | 3 +- mesalib/src/mesa/tnl/tnl.h | 207 ++++---- mesalib/src/mesa/vbo/vbo.h | 4 +- mesalib/src/mesa/vbo/vbo_context.h | 1 + mesalib/src/mesa/vbo/vbo_exec_array.c | 93 +++- mesalib/src/mesa/vbo/vbo_exec_draw.c | 3 +- mesalib/src/mesa/vbo/vbo_rebase.c | 3 +- mesalib/src/mesa/vbo/vbo_save_api.c | 11 + mesalib/src/mesa/vbo/vbo_save_draw.c | 3 +- mesalib/src/mesa/vbo/vbo_split_copy.c | 3 +- mesalib/src/mesa/vbo/vbo_split_inplace.c | 3 +- 48 files changed, 1178 insertions(+), 824 deletions(-) (limited to 'mesalib/src/mesa') 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 - */ - - -#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 + */ + + +#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 - */ - -#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 + */ + +#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 @@ -998,6 +998,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) { @@ -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 ) ©->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; -- cgit v1.2.3