diff options
Diffstat (limited to 'mesalib/src')
22 files changed, 1054 insertions, 651 deletions
diff --git a/mesalib/src/gallium/auxiliary/util/u_blit.c b/mesalib/src/gallium/auxiliary/util/u_blit.c index e5b97f720..9bd2ef52d 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blit.c +++ b/mesalib/src/gallium/auxiliary/util/u_blit.c @@ -419,7 +419,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, dstX0, dstY0, dst->u.tex.first_layer,/* dest */ src_tex, src_level, &src_box); - return; + return; } if (dst_format == dst->format) { @@ -444,6 +444,9 @@ util_blit_pixels_writemask(struct blit_state *ctx, src_tex->target != PIPE_TEXTURE_2D && src_tex->target != PIPE_TEXTURE_RECT)) { + /* Make a temporary texture which contains a copy of the source pixels. + * Then we'll sample from the temporary texture. + */ struct pipe_resource texTemp; struct pipe_resource *tex; struct pipe_sampler_view sv_templ; @@ -515,6 +518,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, pipe_resource_reference(&tex, NULL); } else { + /* Directly sample from the source resource/texture */ u_sampler_view_default_template(&sv_templ, src_tex, src_format); sampler_view = pipe->create_sampler_view(pipe, src_tex, &sv_templ); diff --git a/mesalib/src/glsl/TODO b/mesalib/src/glsl/TODO index eb73fc2e8..bd077a856 100644 --- a/mesalib/src/glsl/TODO +++ b/mesalib/src/glsl/TODO @@ -6,9 +6,6 @@ constant index values. For others it is more complicated. Perhaps these cases should be silently converted to uniforms? -- Implement support for ir_binop_dot in opt_algebraic.cpp. Perform - transformations such as "dot(v, vec3(0.0, 1.0, 0.0))" -> v.y. - - Track source locations throughout the IR. There are currently several places where we cannot emit line numbers for errors (and currently emit 0:0) because we've "lost" the line number information. This is particularly diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp index 69954998b..f81bfd1ab 100644 --- a/mesalib/src/glsl/ir.cpp +++ b/mesalib/src/glsl/ir.cpp @@ -46,6 +46,11 @@ bool ir_rvalue::is_negative_one() const return false; } +bool ir_rvalue::is_basis() const +{ + return false; +} + /** * Modify the swizzle make to move one component to another * @@ -1125,6 +1130,49 @@ ir_constant::is_negative_one() const return true; } +bool +ir_constant::is_basis() const +{ + if (!this->type->is_scalar() && !this->type->is_vector()) + return false; + + if (this->type->is_boolean()) + return false; + + unsigned ones = 0; + for (unsigned c = 0; c < this->type->vector_elements; c++) { + switch (this->type->base_type) { + case GLSL_TYPE_FLOAT: + if (this->value.f[c] == 1.0) + ones++; + else if (this->value.f[c] != 0.0) + return false; + break; + case GLSL_TYPE_INT: + if (this->value.i[c] == 1) + ones++; + else if (this->value.i[c] != 0) + return false; + break; + case GLSL_TYPE_UINT: + if (int(this->value.u[c]) == 1) + ones++; + else if (int(this->value.u[c]) != 0) + return false; + break; + default: + /* The only other base types are structures, arrays, samplers, and + * booleans. Samplers cannot be constants, and the others should + * have been filtered out above. + */ + assert(!"Should not get here."); + return false; + } + } + + return ones == 1; +} + ir_loop::ir_loop() { this->ir_type = ir_type_loop; diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h index a3f9f0588..55535b2f5 100644 --- a/mesalib/src/glsl/ir.h +++ b/mesalib/src/glsl/ir.h @@ -201,7 +201,8 @@ public: * for vector and scalar types that have all elements set to the value * zero (or \c false for booleans). * - * \sa ir_constant::has_value, ir_rvalue::is_one, ir_rvalue::is_negative_one + * \sa ir_constant::has_value, ir_rvalue::is_one, ir_rvalue::is_negative_one, + * ir_constant::is_basis */ virtual bool is_zero() const; @@ -213,7 +214,8 @@ public: * for vector and scalar types that have all elements set to the value * one (or \c true for booleans). * - * \sa ir_constant::has_value, ir_rvalue::is_zero, ir_rvalue::is_negative_one + * \sa ir_constant::has_value, ir_rvalue::is_zero, ir_rvalue::is_negative_one, + * ir_constant::is_basis */ virtual bool is_one() const; @@ -223,12 +225,27 @@ public: * The base implementation of this function always returns \c false. The * \c ir_constant class over-rides this function to return \c true \b only * for vector and scalar types that have all elements set to the value - * negative one. For boolean times, the result is always \c false. + * negative one. For boolean types, the result is always \c false. * * \sa ir_constant::has_value, ir_rvalue::is_zero, ir_rvalue::is_one + * ir_constant::is_basis */ virtual bool is_negative_one() const; + /** + * Determine if an r-value is a basis vector + * + * The base implementation of this function always returns \c false. The + * \c ir_constant class over-rides this function to return \c true \b only + * for vector and scalar types that have one element set to the value one, + * and the other elements set to the value zero. For boolean types, the + * result is always \c false. + * + * \sa ir_constant::has_value, ir_rvalue::is_zero, ir_rvalue::is_one, + * is_constant::is_negative_one + */ + virtual bool is_basis() const; + /** * Return a generic value of error_type. @@ -1743,13 +1760,14 @@ public: * Determine whether a constant has the same value as another constant * * \sa ir_constant::is_zero, ir_constant::is_one, - * ir_constant::is_negative_one + * ir_constant::is_negative_one, ir_constant::is_basis */ bool has_value(const ir_constant *) const; virtual bool is_zero() const; virtual bool is_one() const; virtual bool is_negative_one() const; + virtual bool is_basis() const; /** * Value of the constant. diff --git a/mesalib/src/glsl/opt_algebraic.cpp b/mesalib/src/glsl/opt_algebraic.cpp index d39761260..75948db16 100644 --- a/mesalib/src/glsl/opt_algebraic.cpp +++ b/mesalib/src/glsl/opt_algebraic.cpp @@ -84,6 +84,12 @@ is_vec_one(ir_constant *ir) return (ir == NULL) ? false : ir->is_one(); } +static inline bool +is_vec_basis(ir_constant *ir) +{ + return (ir == NULL) ? false : ir->is_basis(); +} + static void update_type(ir_expression *ir) { @@ -309,6 +315,31 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) } break; + case ir_binop_dot: + if (is_vec_zero(op_const[0]) || is_vec_zero(op_const[1])) { + this->progress = true; + return ir_constant::zero(mem_ctx, ir->type); + } + if (is_vec_basis(op_const[0])) { + this->progress = true; + unsigned component = 0; + for (unsigned c = 0; c < op_const[0]->type->vector_elements; c++) { + if (op_const[0]->value.f[c] == 1.0) + component = c; + } + return new(mem_ctx) ir_swizzle(ir->operands[1], component, 0, 0, 0, 1); + } + if (is_vec_basis(op_const[1])) { + this->progress = true; + unsigned component = 0; + for (unsigned c = 0; c < op_const[1]->type->vector_elements; c++) { + if (op_const[1]->value.f[c] == 1.0) + component = c; + } + return new(mem_ctx) ir_swizzle(ir->operands[0], component, 0, 0, 0, 1); + } + break; + case ir_binop_logic_and: /* FINISHME: Also simplify (a && a) to (a). */ if (is_vec_one(op_const[0])) { diff --git a/mesalib/src/mapi/glapi/gen/ARB_texture_storage.xml b/mesalib/src/mapi/glapi/gen/ARB_texture_storage.xml index 945467939..045913806 100644 --- a/mesalib/src/mapi/glapi/gen/ARB_texture_storage.xml +++ b/mesalib/src/mapi/glapi/gen/ARB_texture_storage.xml @@ -8,7 +8,7 @@ <category name="GL_ARB_texture_storage" number="117"> - <enum name="GL_TEXTURE_IMMUTABLE_FORMAT" value="0x912F"/> + <enum name="TEXTURE_IMMUTABLE_FORMAT" value="0x912F"/> <function name="TexStorage1D" offset="assign"> <param name="target" type="GLenum"/> diff --git a/mesalib/src/mapi/glapi/gen/GL3x.xml b/mesalib/src/mapi/glapi/gen/GL3x.xml index ab4900c3e..f3d782ca4 100644 --- a/mesalib/src/mapi/glapi/gen/GL3x.xml +++ b/mesalib/src/mapi/glapi/gen/GL3x.xml @@ -32,6 +32,8 @@ <enum name="MAX_ARRAY_TEXTURE_LAYERS" value="0x88FF"/> <enum name="MIN_PROGRAM_TEXEL_OFFSET" value="0x8904"/> <enum name="MAX_PROGRAM_TEXEL_OFFSET" value="0x8905"/> + <enum name="CLAMP_VERTEX_COLOR" value="0x891A"/> + <enum name="CLAMP_FRAGMENT_COLOR" value="0x891B"/> <enum name="CLAMP_READ_COLOR" value="0x891C"/> <enum name="FIXED_ONLY" value="0x891D"/> <enum name="MAX_VARYING_COMPONENTS" value="0x8B4B"/> @@ -474,8 +476,41 @@ <category name="3.1"> + <enum name="UNIFORM_BUFFER" value="0x8A11"/> + <enum name="UNIFORM_BUFFER_BINDING" value="0x8A28"/> + <enum name="UNIFORM_BUFFER_START" value="0x8A29"/> + <enum name="UNIFORM_BUFFER_SIZE" value="0x8A2A"/> + <enum name="MAX_VERTEX_UNIFORM_BLOCKS" value="0x8A2B"/> + <enum name="MAX_GEOMETRY_UNIFORM_BLOCKS" value="0x8A2C"/> + <enum name="MAX_FRAGMENT_UNIFORM_BLOCKS" value="0x8A2D"/> + <enum name="MAX_COMBINED_UNIFORM_BLOCKS" value="0x8A2E"/> + <enum name="MAX_UNIFORM_BUFFER_BINDINGS" value="0x8A2F"/> + <enum name="MAX_UNIFORM_BLOCK_SIZE" value="0x8A30"/> + <enum name="MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS" value="0x8A31"/> + <enum name="MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS" value="0x8A32"/> + <enum name="MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS" value="0x8A33"/> + <enum name="UNIFORM_BUFFER_OFFSET_ALIGNMENT" value="0x8A34"/> + <enum name="ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH" value="0x8A35"/> + <enum name="ACTIVE_UNIFORM_BLOCKS" value="0x8A36"/> + <enum name="UNIFORM_TYPE" value="0x8A37"/> + <enum name="UNIFORM_SIZE" value="0x8A38"/> + <enum name="UNIFORM_NAME_LENGTH" value="0x8A39"/> + <enum name="UNIFORM_BLOCK_INDEX" value="0x8A3A"/> + <enum name="UNIFORM_OFFSET" value="0x8A3B"/> + <enum name="UNIFORM_ARRAY_STRIDE" value="0x8A3C"/> + <enum name="UNIFORM_MATRIX_STRIDE" value="0x8A3D"/> + <enum name="UNIFORM_IS_ROW_MAJOR" value="0x8A3E"/> + <enum name="UNIFORM_BLOCK_BINDING" value="0x8A3F"/> + <enum name="UNIFORM_BLOCK_DATA_SIZE" value="0x8A40"/> + <enum name="UNIFORM_BLOCK_NAME_LENGTH" value="0x8A41"/> + <enum name="UNIFORM_BLOCK_ACTIVE_UNIFORMS" value="0x8A42"/> + <enum name="UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES" value="0x8A43"/> + <enum name="UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER" value="0x8A44"/> + <enum name="UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER" value="0x8A45"/> + <enum name="UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER" value="0x8A46"/> <enum name="SAMPLER_2D_RECT" value="0x8B63"/> <enum name="SAMPLER_2D_RECT_SHADOW" value="0x8B64"/> + <enum name="FRAMEBUFFER_SRGB" value="0x8DB9"/> <enum name="SAMPLER_BUFFER" value="0x8DC2"/> <enum name="INT_SAMPLER_2D_RECT" value="0x8DCD"/> <enum name="INT_SAMPLER_BUFFER" value="0x8DD0"/> @@ -583,6 +618,11 @@ <category name="3.3"> <!-- There are other new functions and tokens defined by other extensions --> + <enum name="TEXTURE_SWIZZLE_R" value="0x8E42"/> + <enum name="TEXTURE_SWIZZLE_G" value="0x8E43"/> + <enum name="TEXTURE_SWIZZLE_B" value="0x8E44"/> + <enum name="TEXTURE_SWIZZLE_A" value="0x8E45"/> + <enum name="TEXTURE_SWIZZLE_RGBA" value="0x8E46"/> <function name="VertexAttribDivisor" offset="assign"> <param name="index" type="GLuint"/> diff --git a/mesalib/src/mapi/glapi/gen/gl_API.xml b/mesalib/src/mapi/glapi/gen/gl_API.xml index a74577d1f..4bd0fc6b2 100644 --- a/mesalib/src/mapi/glapi/gen/gl_API.xml +++ b/mesalib/src/mapi/glapi/gen/gl_API.xml @@ -7965,7 +7965,12 @@ <xi:include href="ARB_blend_func_extended.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> <!-- 79. GL_ARB_explicit_attrib_location --> -<!-- 80. GL_ARB_occlusion_query2 --> + +<category name="GL_ARB_occlusion_query2" number="80"> + <enum name="ANY_SAMPLES_PASSED" count="1" value="0x8C2F"> + <size name="GetQueryiv" mode="get"/> + </enum> +</category> <xi:include href="ARB_sampler_objects.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> @@ -8614,37 +8619,37 @@ </category> <category name="GL_SGIS_pixel_texture" number="15"> - <function name="PixelTexGenParameteriSGIS" offset="assign" static_dispatch="false"> + <function name="PixelTexGenParameteriSGIS"> <param name="pname" type="GLenum"/> <param name="param" type="GLint"/> <glx ignore="true"/> </function> - <function name="PixelTexGenParameterivSGIS" offset="assign" static_dispatch="false"> + <function name="PixelTexGenParameterivSGIS"> <param name="pname" type="GLenum"/> <param name="params" type="const GLint *"/> <glx ignore="true"/> </function> - <function name="PixelTexGenParameterfSGIS" offset="assign" static_dispatch="false"> + <function name="PixelTexGenParameterfSGIS"> <param name="pname" type="GLenum"/> <param name="param" type="GLfloat"/> <glx ignore="true"/> </function> - <function name="PixelTexGenParameterfvSGIS" offset="assign" static_dispatch="false"> + <function name="PixelTexGenParameterfvSGIS"> <param name="pname" type="GLenum"/> <param name="params" type="const GLfloat *"/> <glx ignore="true"/> </function> - <function name="GetPixelTexGenParameterivSGIS" offset="assign" static_dispatch="false"> + <function name="GetPixelTexGenParameterivSGIS"> <param name="pname" type="GLenum"/> <param name="params" type="GLint *" output="true" variable_param="pname"/> <glx ignore="true"/> </function> - <function name="GetPixelTexGenParameterfvSGIS" offset="assign" static_dispatch="false"> + <function name="GetPixelTexGenParameterfvSGIS"> <param name="pname" type="GLenum"/> <param name="params" type="GLfloat *" output="true" variable_param="pname"/> <glx ignore="true"/> @@ -8787,6 +8792,15 @@ <!-- Extension number 29 is not listed in the extension registry. --> <category name="GL_EXT_vertex_array" number="30"> + <!-- These enums are part of the extension only. --> + <enum name="VERTEX_ARRAY_COUNT_EXT" value="0x807D"/> + <enum name="NORMAL_ARRAY_COUNT_EXT" value="0x8080"/> + <enum name="COLOR_ARRAY_COUNT_EXT" value="0x8084"/> + <enum name="INDEX_ARRAY_COUNT_EXT" value="0x8087"/> + <enum name="TEXTURE_COORD_ARRAY_COUNT_EXT" value="0x808B"/> + <enum name="EDGE_FLAG_ARRAY_COUNT_EXT" value="0x808D"/> + + <function name="ArrayElementEXT" alias="ArrayElement"> <param name="i" type="GLint"/> </function> @@ -9381,6 +9395,9 @@ </category> <category name="GL_EXT_compiled_vertex_array" number="97"> + <enum name="ARRAY_ELEMENT_LOCK_FIRST_EXT" value="0x81A8"/> + <enum name="ARRAY_ELEMENT_LOCK_COUNT_EXT" value="0x81A9"/> + <function name="LockArraysEXT" offset="assign"> <param name="first" type="GLint"/> <param name="count" type="GLsizei"/> @@ -10003,7 +10020,7 @@ </category> <category name="GL_SGIX_pixel_texture" number="160"> - <function name="PixelTexGenSGIX" offset="assign" static_dispatch="false"> + <function name="PixelTexGenSGIX"> <param name="mode" type="GLenum"/> <glx rop="2059" ignore="true"/> </function> @@ -10522,11 +10539,11 @@ </category> <category name="GL_NV_vertex_array_range" number="190"> - <function name="FlushVertexArrayRangeNV" offset="assign"> + <function name="FlushVertexArrayRangeNV"> <glx ignore="true"/> </function> - <function name="VertexArrayRangeNV" offset="assign"> + <function name="VertexArrayRangeNV"> <param name="length" type="GLsizei"/> <param name="pointer" type="const GLvoid *"/> <glx ignore="true"/> @@ -10534,31 +10551,31 @@ </category> <category name="GL_NV_register_combiners" number="191"> - <function name="CombinerParameterfvNV" offset="assign"> + <function name="CombinerParameterfvNV"> <param name="pname" type="GLenum"/> <param name="params" type="const GLfloat *" variable_param="pname"/> <glx rop="4137" ignore="true"/> </function> - <function name="CombinerParameterfNV" offset="assign"> + <function name="CombinerParameterfNV"> <param name="pname" type="GLenum"/> <param name="param" type="GLfloat"/> <glx rop="4136" ignore="true"/> </function> - <function name="CombinerParameterivNV" offset="assign"> + <function name="CombinerParameterivNV"> <param name="pname" type="GLenum"/> <param name="params" type="const GLint *" variable_param="pname"/> <glx rop="4139" ignore="true"/> </function> - <function name="CombinerParameteriNV" offset="assign"> + <function name="CombinerParameteriNV"> <param name="pname" type="GLenum"/> <param name="param" type="GLint"/> <glx rop="4138" ignore="true"/> </function> - <function name="CombinerInputNV" offset="assign"> + <function name="CombinerInputNV"> <param name="stage" type="GLenum"/> <param name="portion" type="GLenum"/> <param name="variable" type="GLenum"/> @@ -10568,7 +10585,7 @@ <glx rop="4140" ignore="true"/> </function> - <function name="CombinerOutputNV" offset="assign"> + <function name="CombinerOutputNV"> <param name="stage" type="GLenum"/> <param name="portion" type="GLenum"/> <param name="abOutput" type="GLenum"/> @@ -10582,7 +10599,7 @@ <glx rop="4141" ignore="true"/> </function> - <function name="FinalCombinerInputNV" offset="assign"> + <function name="FinalCombinerInputNV"> <param name="variable" type="GLenum"/> <param name="input" type="GLenum"/> <param name="mapping" type="GLenum"/> @@ -10590,7 +10607,7 @@ <glx rop="4142" ignore="true"/> </function> - <function name="GetCombinerInputParameterfvNV" offset="assign"> + <function name="GetCombinerInputParameterfvNV"> <param name="stage" type="GLenum"/> <param name="portion" type="GLenum"/> <param name="variable" type="GLenum"/> @@ -10599,7 +10616,7 @@ <glx vendorpriv="1270" ignore="true"/> </function> - <function name="GetCombinerInputParameterivNV" offset="assign"> + <function name="GetCombinerInputParameterivNV"> <param name="stage" type="GLenum"/> <param name="portion" type="GLenum"/> <param name="variable" type="GLenum"/> @@ -10608,7 +10625,7 @@ <glx vendorpriv="1271" ignore="true"/> </function> - <function name="GetCombinerOutputParameterfvNV" offset="assign"> + <function name="GetCombinerOutputParameterfvNV"> <param name="stage" type="GLenum"/> <param name="portion" type="GLenum"/> <param name="pname" type="GLenum"/> @@ -10616,7 +10633,7 @@ <glx vendorpriv="1272" ignore="true"/> </function> - <function name="GetCombinerOutputParameterivNV" offset="assign"> + <function name="GetCombinerOutputParameterivNV"> <param name="stage" type="GLenum"/> <param name="portion" type="GLenum"/> <param name="pname" type="GLenum"/> @@ -10624,14 +10641,14 @@ <glx vendorpriv="1273" ignore="true"/> </function> - <function name="GetFinalCombinerInputParameterfvNV" offset="assign"> + <function name="GetFinalCombinerInputParameterfvNV"> <param name="variable" type="GLenum"/> <param name="pname" type="GLenum"/> <param name="params" type="GLfloat *" output="true"/> <glx vendorpriv="1274" ignore="true"/> </function> - <function name="GetFinalCombinerInputParameterivNV" offset="assign"> + <function name="GetFinalCombinerInputParameterivNV"> <param name="variable" type="GLenum"/> <param name="pname" type="GLenum"/> <param name="params" type="GLint *" output="true"/> @@ -10654,7 +10671,7 @@ </category> <category name="GL_NV_texture_env_combine4" number="195"> - <enum name="COMBINE4" value="0x8503"/> + <enum name="COMBINE4_NV" value="0x8503"/> <enum name="SOURCE3_RGB_NV" count="1" value="0x8583"> <size name="TexEnvfv"/> <size name="TexEnviv"/> @@ -10988,43 +11005,43 @@ </category> <category name="GL_NV_fence" number="222"> - <function name="DeleteFencesNV" offset="assign" static_dispatch="false"> + <function name="DeleteFencesNV"> <param name="n" type="GLsizei"/> <param name="fences" type="const GLuint *"/> <glx ignore="true"/> </function> - <function name="GenFencesNV" offset="assign" static_dispatch="false"> + <function name="GenFencesNV"> <param name="n" type="GLsizei" counter="true"/> <param name="fences" type="GLuint *" output="true" count="n"/> <glx ignore="true"/> </function> - <function name="IsFenceNV" offset="assign" static_dispatch="false"> + <function name="IsFenceNV"> <param name="fence" type="GLuint"/> <return type="GLboolean"/> <glx ignore="true"/> </function> - <function name="TestFenceNV" offset="assign" static_dispatch="false"> + <function name="TestFenceNV"> <param name="fence" type="GLuint"/> <return type="GLboolean"/> <glx ignore="true"/> </function> - <function name="GetFenceivNV" offset="assign" static_dispatch="false"> + <function name="GetFenceivNV"> <param name="fence" type="GLuint"/> <param name="pname" type="GLenum"/> <param name="params" type="GLint *" output="true"/> <glx ignore="true"/> </function> - <function name="FinishFenceNV" offset="assign" static_dispatch="false"> + <function name="FinishFenceNV"> <param name="fence" type="GLuint"/> <glx ignore="true"/> </function> - <function name="SetFenceNV" offset="assign" static_dispatch="false"> + <function name="SetFenceNV"> <param name="fence" type="GLuint"/> <param name="condition" type="GLenum"/> <glx ignore="true"/> @@ -11776,6 +11793,117 @@ </category> <category name="GL_ATI_fragment_shader" number="245"> + <enum name="FRAGMENT_SHADER_ATI" value="0x8920"/> + <enum name="REG_0_ATI" value="0x8921"/> + <enum name="REG_1_ATI" value="0x8922"/> + <enum name="REG_2_ATI" value="0x8923"/> + <enum name="REG_3_ATI" value="0x8924"/> + <enum name="REG_4_ATI" value="0x8925"/> + <enum name="REG_5_ATI" value="0x8926"/> + + <!-- These values are not in the extension spec, but they are in glext.h --> + <enum name="REG_6_ATI" value="0x8927"/> + <enum name="REG_7_ATI" value="0x8928"/> + <enum name="REG_8_ATI" value="0x8929"/> + <enum name="REG_9_ATI" value="0x892A"/> + <enum name="REG_10_ATI" value="0x892B"/> + <enum name="REG_11_ATI" value="0x892C"/> + <enum name="REG_12_ATI" value="0x892D"/> + <enum name="REG_13_ATI" value="0x892E"/> + <enum name="REG_14_ATI" value="0x892F"/> + <enum name="REG_15_ATI" value="0x8930"/> + <enum name="REG_16_ATI" value="0x8931"/> + <enum name="REG_17_ATI" value="0x8932"/> + <enum name="REG_18_ATI" value="0x8933"/> + <enum name="REG_19_ATI" value="0x8934"/> + <enum name="REG_20_ATI" value="0x8935"/> + <enum name="REG_21_ATI" value="0x8936"/> + <enum name="REG_22_ATI" value="0x8937"/> + <enum name="REG_23_ATI" value="0x8938"/> + <enum name="REG_24_ATI" value="0x8939"/> + <enum name="REG_25_ATI" value="0x893A"/> + <enum name="REG_26_ATI" value="0x893B"/> + <enum name="REG_27_ATI" value="0x893C"/> + <enum name="REG_28_ATI" value="0x893D"/> + <enum name="REG_29_ATI" value="0x893E"/> + <enum name="REG_30_ATI" value="0x893F"/> + <enum name="REG_31_ATI" value="0x8940"/> + + <enum name="CON_0_ATI" value="0x8941"/> + <enum name="CON_1_ATI" value="0x8942"/> + <enum name="CON_2_ATI" value="0x8943"/> + <enum name="CON_3_ATI" value="0x8944"/> + <enum name="CON_4_ATI" value="0x8945"/> + <enum name="CON_5_ATI" value="0x8946"/> + <enum name="CON_6_ATI" value="0x8947"/> + <enum name="CON_7_ATI" value="0x8948"/> + + <!-- These values are not in the extension spec, but they are in glext.h --> + <enum name="CON_8_ATI" value="0x8949"/> + <enum name="CON_9_ATI" value="0x894A"/> + <enum name="CON_10_ATI" value="0x894B"/> + <enum name="CON_11_ATI" value="0x894C"/> + <enum name="CON_12_ATI" value="0x894D"/> + <enum name="CON_13_ATI" value="0x894E"/> + <enum name="CON_14_ATI" value="0x894F"/> + <enum name="CON_15_ATI" value="0x8950"/> + <enum name="CON_16_ATI" value="0x8951"/> + <enum name="CON_17_ATI" value="0x8952"/> + <enum name="CON_18_ATI" value="0x8953"/> + <enum name="CON_19_ATI" value="0x8954"/> + <enum name="CON_20_ATI" value="0x8955"/> + <enum name="CON_21_ATI" value="0x8956"/> + <enum name="CON_22_ATI" value="0x8957"/> + <enum name="CON_23_ATI" value="0x8958"/> + <enum name="CON_24_ATI" value="0x8959"/> + <enum name="CON_25_ATI" value="0x895A"/> + <enum name="CON_26_ATI" value="0x895B"/> + <enum name="CON_27_ATI" value="0x895C"/> + <enum name="CON_28_ATI" value="0x895D"/> + <enum name="CON_29_ATI" value="0x895E"/> + <enum name="CON_30_ATI" value="0x895F"/> + <enum name="CON_31_ATI" value="0x8960"/> + + <enum name="MOV_ATI" value="0x8961"/> + <enum name="ADD_ATI" value="0x8963"/> + <enum name="MUL_ATI" value="0x8964"/> + <enum name="SUB_ATI" value="0x8965"/> + <enum name="DOT3_ATI" value="0x8966"/> + <enum name="DOT4_ATI" value="0x8967"/> + <enum name="MAD_ATI" value="0x8968"/> + <enum name="LERP_ATI" value="0x8969"/> + <enum name="CND_ATI" value="0x896A"/> + <enum name="CND0_ATI" value="0x896B"/> + <enum name="DOT2_ADD_ATI" value="0x896C"/> + <enum name="SECONDARY_INTERPOLATOR_ATI" value="0x896D"/> + + <!-- + These values are not in the extension spec, but they are in glext.h. + However, the specification does say that they are deprecated. + --> + <enum name="NUM_FRAGMENT_REGISTERS_ATI" value="0x896E"/> + <enum name="NUM_FRAGMENT_CONSTANTS_ATI" value="0x896F"/> + <enum name="NUM_PASSES_ATI" value="0x8970"/> + <enum name="NUM_INSTRUCTIONS_PER_PASS_ATI" value="0x8971"/> + <enum name="NUM_INSTRUCTIONS_TOTAL_ATI" value="0x8972"/> + <enum name="NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI" value="0x8973"/> + <enum name="NUM_LOOPBACK_COMPONENTS_ATI" value="0x8974"/> + <enum name="COLOR_ALPHA_PAIRING_ATI" value="0x8975"/> + + <enum name="SWIZZLE_STR_ATI" value="0x8976"/> + <enum name="SWIZZLE_STQ_ATI" value="0x8977"/> + <enum name="SWIZZLE_STR_DR_ATI" value="0x8978"/> + <enum name="SWIZZLE_STQ_DQ_ATI" value="0x8979"/> + + <!-- These values are not in the extension spec, but they are in glext.h --> + <enum name="SWIZZLE_STRQ_ATI" value="0x897A"/> + <enum name="SWIZZLE_STRQ_DQ_ATI" value="0x897B"/> + + <!-- + The _BIT enums are not added because they just clutter enums.c with + redudndant garbage. There are a lot of enums with the value 0x00000001. + --> + <function name="GenFragmentShadersATI" offset="assign"> <return type="GLuint"/> <param name="range" type="GLuint"/> @@ -12030,6 +12158,13 @@ </category> <category name="GL_NV_fragment_program" number="282"> + <enum name="FRAGMENT_PROGRAM_NV" value="0x8870"/> + <enum name="MAX_TEXTURE_COORDS_NV" value="0x8871"/> + <enum name="MAX_TEXTURE_IMAGE_UNITS_NV" value="0x8872"/> + <enum name="FRAGMENT_PROGRAM_BINDING_NV" value="0x8873"/> + <enum name="MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV" value="0x8868"/> + <enum name="PROGRAM_ERROR_STRING_NV" value="0x8874"/> + <function name="ProgramNamedParameter4fNV" offset="assign" vectorequiv="ProgramNamedParameter4fvNV"> <param name="id" type="GLuint"/> <param name="len" type="GLsizei" counter="true"/> @@ -12236,8 +12371,19 @@ </function> </category> +<category name="GL_EXT_packed_float" number="328"> + <enum name="R11F_G11F_B10F_EXT" value="0x8C3A"/> + <enum name="UNSIGNED_INT_10F_11F_11F_REV" value="0x8C3B"/> + <enum name="RGBA_SIGNED_COMPONENTS_EXT" value="0x8C3C"/> +</category> + <xi:include href="EXT_texture_array.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> +<category name="GL_EXT_framebuffer_sRGB" number="337"> + <enum name="FRAMEBUFFER_SRGB_EXT" value="0x8DB9"/> + <enum name="FRAMEBUFFER_SRGB_CAPABLE_EXT" value="0x8DBA"/> +</category> + <category name="GL_APPLE_texture_range" number="367"> <enum name="TEXTURE_STORAGE_HINT_APPLE" count="1" value="0x85BC"> <size name="TexParameteriv"/> @@ -12264,12 +12410,12 @@ <enum name="TEXTURE_RANGE_POINTER_APPLE" count="1" value="0x85B8"> <size name="GetTexParameterPointervAPPLE" mode="get"/> </enum> - <function name="TextureRangeAPPLE" offset="assign" static_dispatch="false"> + <function name="TextureRangeAPPLE"> <param name="target" type="GLenum"/> <param name="length" type="GLsizei"/> <param name="pointer" type="GLvoid *"/> </function> - <function name="GetTexParameterPointervAPPLE" offset="assign" static_dispatch="false"> + <function name="GetTexParameterPointervAPPLE"> <param name="target" type="GLenum"/> <param name="pname" type="GLenum"/> <param name="params" type="GLvoid **"/> @@ -12279,6 +12425,12 @@ <xi:include href="EXT_separate_shader_objects.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> +<category name="GL_EXT_texture_sRGB_decode" number="402"> + <enum name="TEXTURE_SRGB_DECODE_EXT" value="0x8A48"/> + <enum name="DECODE_EXT" value="0x8A49"/> + <enum name="SKIP_DECODE_EXT" value="0x8A4A"/> +</category> + <!-- Unnumbered extensions sorted by name. --> <category name="GL_ATI_blend_equation_separate"> diff --git a/mesalib/src/mesa/Makefile b/mesalib/src/mesa/Makefile index 845b524e6..b0b461fdd 100644 --- a/mesalib/src/mesa/Makefile +++ b/mesalib/src/mesa/Makefile @@ -135,7 +135,7 @@ asm_subdirs: ###################################################################### # Dependency generation -depend: $(ALL_FILES) +depend: $(ALL_FILES) main/git_sha1.h @ echo "running $(MKDEP)" @ touch depend @$(MKDEP) $(MKDEP_OPTIONS) $(MESA_CPPFLAGS) \ diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c index 8d7e90126..be7141a58 100644 --- a/mesalib/src/mesa/drivers/common/meta.c +++ b/mesalib/src/mesa/drivers/common/meta.c @@ -319,6 +319,10 @@ struct gl_meta_state struct drawtex_state DrawTex; /**< For _mesa_meta_DrawTex() */ }; +static void meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit); +static void cleanup_temp_texture(struct gl_context *ctx, struct temp_texture *tex); +static void meta_glsl_clear_cleanup(struct gl_context *ctx, struct clear_state *clear); + static GLuint compile_shader_with_debug(struct gl_context *ctx, GLenum target, const GLcharARB *source) { @@ -335,12 +339,16 @@ compile_shader_with_debug(struct gl_context *ctx, GLenum target, const GLcharARB return shader; _mesa_GetShaderiv(shader, GL_INFO_LOG_LENGTH, &size); - if (size == 0) + if (size == 0) { + _mesa_DeleteObjectARB(shader); return 0; + } info = malloc(size); - if (!info) + if (!info) { + _mesa_DeleteObjectARB(shader); return 0; + } _mesa_GetProgramInfoLog(shader, size, NULL, info); _mesa_problem(ctx, @@ -349,6 +357,7 @@ compile_shader_with_debug(struct gl_context *ctx, GLenum target, const GLcharARB info, source); free(info); + _mesa_DeleteObjectARB(shader); return 0; } @@ -401,10 +410,15 @@ _mesa_meta_init(struct gl_context *ctx) void _mesa_meta_free(struct gl_context *ctx) { - /* Note: Any textures, VBOs, etc, that we allocate should get - * freed by the normal context destruction code. But this would be - * the place to free other meta data someday. - */ + GET_CURRENT_CONTEXT(old_context); + _mesa_make_current(ctx, NULL, NULL); + meta_glsl_blit_cleanup(ctx, &ctx->Meta->Blit); + meta_glsl_clear_cleanup(ctx, &ctx->Meta->Clear); + cleanup_temp_texture(ctx, &ctx->Meta->TempTex); + if (old_context) + _mesa_make_current(old_context, old_context->WinSysDrawBuffer, old_context->WinSysReadBuffer); + else + _mesa_make_current(NULL, NULL, NULL); free(ctx->Meta); ctx->Meta = NULL; } @@ -1068,6 +1082,15 @@ init_temp_texture(struct gl_context *ctx, struct temp_texture *tex) _mesa_GenTextures(1, &tex->TexObj); } +static void +cleanup_temp_texture(struct gl_context *ctx, struct temp_texture *tex) +{ + if (!tex->TexObj) + return; + _mesa_DeleteTextures(1, &tex->TexObj); + tex->TexObj = 0; +} + /** * Return pointer to temp_texture info for non-bitmap ops. @@ -1604,6 +1627,21 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx, } } +static void +meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit) +{ + if (blit->ArrayObj) { + _mesa_DeleteVertexArraysAPPLE(1, &blit->ArrayObj); + blit->ArrayObj = 0; + _mesa_DeleteBuffersARB(1, &blit->VBO); + blit->VBO = 0; + } + if (blit->DepthFP) { + _mesa_DeletePrograms(1, &blit->DepthFP); + blit->DepthFP = 0; + } +} + /** * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering. @@ -1786,7 +1824,9 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear) clear->ShaderProg = _mesa_CreateProgramObjectARB(); _mesa_AttachShader(clear->ShaderProg, fs); + _mesa_DeleteObjectARB(fs); _mesa_AttachShader(clear->ShaderProg, vs); + _mesa_DeleteObjectARB(vs); _mesa_BindAttribLocationARB(clear->ShaderProg, 0, "position"); _mesa_LinkProgramARB(clear->ShaderProg); @@ -1799,7 +1839,9 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear) clear->IntegerShaderProg = _mesa_CreateProgramObjectARB(); _mesa_AttachShader(clear->IntegerShaderProg, fs); + _mesa_DeleteObjectARB(fs); _mesa_AttachShader(clear->IntegerShaderProg, vs); + _mesa_DeleteObjectARB(vs); _mesa_BindAttribLocationARB(clear->IntegerShaderProg, 0, "position"); /* Note that user-defined out attributes get automatically assigned @@ -1814,6 +1856,24 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear) } } +static void +meta_glsl_clear_cleanup(struct gl_context *ctx, struct clear_state *clear) +{ + if (clear->ArrayObj == 0) + return; + _mesa_DeleteVertexArraysAPPLE(1, &clear->ArrayObj); + clear->ArrayObj = 0; + _mesa_DeleteBuffersARB(1, &clear->VBO); + clear->VBO = 0; + _mesa_DeleteObjectARB(clear->ShaderProg); + clear->ShaderProg = 0; + + if (clear->IntegerShaderProg) { + _mesa_DeleteObjectARB(clear->IntegerShaderProg); + clear->IntegerShaderProg = 0; + } +} + /** * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering. */ diff --git a/mesalib/src/mesa/drivers/windows/gdi/mesa.def b/mesalib/src/mesa/drivers/windows/gdi/mesa.def index d5c98801d..fec7bbac0 100644 --- a/mesalib/src/mesa/drivers/windows/gdi/mesa.def +++ b/mesalib/src/mesa/drivers/windows/gdi/mesa.def @@ -556,21 +556,6 @@ EXPORTS glFogCoorddvEXT glFogCoordPointerEXT glBlendFuncSeparateEXT - glFlushVertexArrayRangeNV - glVertexArrayRangeNV - glCombinerParameterfvNV - glCombinerParameterfNV - glCombinerParameterivNV - glCombinerParameteriNV - glCombinerInputNV - glCombinerOutputNV - glFinalCombinerInputNV - glGetCombinerInputParameterfvNV - glGetCombinerInputParameterivNV - glGetCombinerOutputParameterfvNV - glGetCombinerOutputParameterivNV - glGetFinalCombinerInputParameterfvNV - glGetFinalCombinerInputParameterivNV glResizeBuffersMESA glWindowPos2dMESA glWindowPos2dvMESA diff --git a/mesalib/src/mesa/main/shaderobj.c b/mesalib/src/mesa/main/shaderobj.c index 7eb6f0bda..16800ae5e 100644 --- a/mesalib/src/mesa/main/shaderobj.c +++ b/mesalib/src/mesa/main/shaderobj.c @@ -278,7 +278,9 @@ _mesa_clear_shader_program_data(struct gl_context *ctx, struct gl_shader_program *shProg) { if (shProg->UniformStorage) { - _mesa_uniform_detach_all_driver_storage(shProg->UniformStorage); + unsigned i; + for (i = 0; i < shProg->NumUserUniformStorage; ++i) + _mesa_uniform_detach_all_driver_storage(&shProg->UniformStorage[i]); ralloc_free(shProg->UniformStorage); shProg->NumUserUniformStorage = 0; shProg->UniformStorage = NULL; diff --git a/mesalib/src/mesa/program/hash_table.c b/mesalib/src/mesa/program/hash_table.c index dc8563a33..7dabadc50 100644 --- a/mesalib/src/mesa/program/hash_table.c +++ b/mesalib/src/mesa/program/hash_table.c @@ -149,7 +149,7 @@ hash_table_insert(struct hash_table *ht, void *data, const void *key) insert_at_head(& ht->buckets[bucket], & node->link); } -void +bool hash_table_replace(struct hash_table *ht, void *data, const void *key) { const unsigned hash_value = (*ht->hash)(key); @@ -162,7 +162,7 @@ hash_table_replace(struct hash_table *ht, void *data, const void *key) if ((*ht->compare)(hn->key, key) == 0) { hn->data = data; - return; + return true; } } @@ -172,6 +172,7 @@ hash_table_replace(struct hash_table *ht, void *data, const void *key) hn->key = key; insert_at_head(& ht->buckets[bucket], & hn->link); + return false; } void diff --git a/mesalib/src/mesa/program/hash_table.h b/mesalib/src/mesa/program/hash_table.h index bcf65df7d..e95fc4982 100644 --- a/mesalib/src/mesa/program/hash_table.h +++ b/mesalib/src/mesa/program/hash_table.h @@ -32,6 +32,7 @@ #define HASH_TABLE_H #include <string.h> +#include <stdbool.h> #include <stdlib.h> #include <stdint.h> #include <limits.h> @@ -114,6 +115,10 @@ extern void hash_table_insert(struct hash_table *ht, void *data, /** * Add an element to a hash table with replacement * + * \return + * 1 if it did replace the the value (in which case the old key is kept), 0 if + * it did not replace the value (in which case the new key is kept). + * * \warning * If \c key is already in the hash table, \c data will \b replace the most * recently inserted \c data (see the warning in \c hash_table_insert) for @@ -121,7 +126,7 @@ extern void hash_table_insert(struct hash_table *ht, void *data, * * \sa hash_table_insert */ -extern void hash_table_replace(struct hash_table *ht, void *data, +extern bool hash_table_replace(struct hash_table *ht, void *data, const void *key); /** @@ -219,6 +224,7 @@ public: */ void clear() { + hash_table_call_foreach(this->ht, delete_key, NULL); hash_table_clear(this->ht); } @@ -258,9 +264,12 @@ public: * because UINT_MAX+1 = 0. */ assert(value != UINT_MAX); - hash_table_replace(this->ht, - (void *) (intptr_t) (value + 1), - strdup(key)); + char *dup_key = strdup(key); + bool result = hash_table_replace(this->ht, + (void *) (intptr_t) (value + 1), + dup_key); + if (result) + free(dup_key); } private: diff --git a/mesalib/src/mesa/sources.mak b/mesalib/src/mesa/sources.mak index 608aa79ab..16b1c39c0 100644 --- a/mesalib/src/mesa/sources.mak +++ b/mesalib/src/mesa/sources.mak @@ -198,6 +198,7 @@ VBO_FILES = \ STATETRACKER_FILES = \ $(SRCDIR)/state_tracker/st_atom.c \ + $(SRCDIR)/state_tracker/st_atom_array.c \ $(SRCDIR)/state_tracker/st_atom_blend.c \ $(SRCDIR)/state_tracker/st_atom_clip.c \ $(SRCDIR)/state_tracker/st_atom_constbuf.c \ diff --git a/mesalib/src/mesa/state_tracker/st_atom.c b/mesalib/src/mesa/state_tracker/st_atom.c index d9cd4aab4..e6fc114f1 100644 --- a/mesalib/src/mesa/state_tracker/st_atom.c +++ b/mesalib/src/mesa/state_tracker/st_atom.c @@ -63,7 +63,10 @@ static const struct st_tracked_state *atoms[] = &st_update_vs_constants, &st_update_gs_constants, &st_update_fs_constants, - &st_update_pixel_transfer + &st_update_pixel_transfer, + + /* this must be done after the vertex program update */ + &st_update_array }; @@ -122,6 +125,22 @@ static void check_program_state( struct st_context *st ) st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM; } +static void check_attrib_edgeflag(struct st_context *st) +{ + const struct gl_client_array **arrays = st->ctx->Array._DrawArrays; + GLboolean vertDataEdgeFlags; + + if (!arrays) + return; + + vertDataEdgeFlags = arrays[VERT_ATTRIB_EDGEFLAG]->BufferObj && + arrays[VERT_ATTRIB_EDGEFLAG]->BufferObj->Name; + if (vertDataEdgeFlags != st->vertdata_edgeflags) { + st->vertdata_edgeflags = vertDataEdgeFlags; + st->dirty.st |= ST_NEW_EDGEFLAGS_DATA; + } +} + /*********************************************************************** * Update all derived state: @@ -132,6 +151,12 @@ void st_validate_state( struct st_context *st ) struct st_state_flags *state = &st->dirty; GLuint i; + /* Get Mesa driver state. */ + st->dirty.st |= st->ctx->NewDriverState; + st->ctx->NewDriverState = 0; + + check_attrib_edgeflag(st); + /* The bitmap cache is immune to pixel unpack changes. * Note that GLUT makes several calls to glPixelStore for each * bitmap char it draws so this is an important check. diff --git a/mesalib/src/mesa/state_tracker/st_atom.h b/mesalib/src/mesa/state_tracker/st_atom.h index 930a08444..703bc2ab3 100644 --- a/mesalib/src/mesa/state_tracker/st_atom.h +++ b/mesalib/src/mesa/state_tracker/st_atom.h @@ -46,6 +46,7 @@ void st_destroy_atoms( struct st_context *st ); void st_validate_state( struct st_context *st ); +extern const struct st_tracked_state st_update_array; extern const struct st_tracked_state st_update_framebuffer; extern const struct st_tracked_state st_update_clip; extern const struct st_tracked_state st_update_depth_stencil_alpha; @@ -70,4 +71,8 @@ extern const struct st_tracked_state st_update_pixel_transfer; GLuint st_compare_func_to_pipe(GLenum func); +enum pipe_format +st_pipe_vertex_format(GLenum type, GLuint size, GLenum format, + GLboolean normalized, GLboolean integer); + #endif diff --git a/mesalib/src/mesa/state_tracker/st_atom_array.c b/mesalib/src/mesa/state_tracker/st_atom_array.c new file mode 100644 index 000000000..d60b0d7a9 --- /dev/null +++ b/mesalib/src/mesa/state_tracker/st_atom_array.c @@ -0,0 +1,588 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2012 Marek Olšák <maraeo@gmail.com> + * 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 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. + * + **************************************************************************/ + +/* + * This converts the VBO's vertex attribute/array information into + * Gallium vertex state and binds it. + * + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + * Marek Olšák <maraeo@gmail.com> + */ + +#include "st_context.h" +#include "st_atom.h" +#include "st_cb_bufferobjects.h" +#include "st_draw.h" +#include "st_program.h" + +#include "cso_cache/cso_context.h" +#include "util/u_math.h" + +#include "main/bufferobj.h" +#include "main/image.h" + + +static GLuint double_types[4] = { + PIPE_FORMAT_R64_FLOAT, + PIPE_FORMAT_R64G64_FLOAT, + PIPE_FORMAT_R64G64B64_FLOAT, + PIPE_FORMAT_R64G64B64A64_FLOAT +}; + +static GLuint float_types[4] = { + PIPE_FORMAT_R32_FLOAT, + PIPE_FORMAT_R32G32_FLOAT, + PIPE_FORMAT_R32G32B32_FLOAT, + PIPE_FORMAT_R32G32B32A32_FLOAT +}; + +static GLuint half_float_types[4] = { + PIPE_FORMAT_R16_FLOAT, + PIPE_FORMAT_R16G16_FLOAT, + PIPE_FORMAT_R16G16B16_FLOAT, + PIPE_FORMAT_R16G16B16A16_FLOAT +}; + +static GLuint uint_types_norm[4] = { + PIPE_FORMAT_R32_UNORM, + PIPE_FORMAT_R32G32_UNORM, + PIPE_FORMAT_R32G32B32_UNORM, + PIPE_FORMAT_R32G32B32A32_UNORM +}; + +static GLuint uint_types_scale[4] = { + PIPE_FORMAT_R32_USCALED, + PIPE_FORMAT_R32G32_USCALED, + PIPE_FORMAT_R32G32B32_USCALED, + PIPE_FORMAT_R32G32B32A32_USCALED +}; + +static GLuint uint_types_int[4] = { + PIPE_FORMAT_R32_UINT, + PIPE_FORMAT_R32G32_UINT, + PIPE_FORMAT_R32G32B32_UINT, + PIPE_FORMAT_R32G32B32A32_UINT +}; + +static GLuint int_types_norm[4] = { + PIPE_FORMAT_R32_SNORM, + PIPE_FORMAT_R32G32_SNORM, + PIPE_FORMAT_R32G32B32_SNORM, + PIPE_FORMAT_R32G32B32A32_SNORM +}; + +static GLuint int_types_scale[4] = { + PIPE_FORMAT_R32_SSCALED, + PIPE_FORMAT_R32G32_SSCALED, + PIPE_FORMAT_R32G32B32_SSCALED, + PIPE_FORMAT_R32G32B32A32_SSCALED +}; + +static GLuint int_types_int[4] = { + PIPE_FORMAT_R32_SINT, + PIPE_FORMAT_R32G32_SINT, + PIPE_FORMAT_R32G32B32_SINT, + PIPE_FORMAT_R32G32B32A32_SINT +}; + +static GLuint ushort_types_norm[4] = { + PIPE_FORMAT_R16_UNORM, + PIPE_FORMAT_R16G16_UNORM, + PIPE_FORMAT_R16G16B16_UNORM, + PIPE_FORMAT_R16G16B16A16_UNORM +}; + +static GLuint ushort_types_scale[4] = { + PIPE_FORMAT_R16_USCALED, + PIPE_FORMAT_R16G16_USCALED, + PIPE_FORMAT_R16G16B16_USCALED, + PIPE_FORMAT_R16G16B16A16_USCALED +}; + +static GLuint ushort_types_int[4] = { + PIPE_FORMAT_R16_UINT, + PIPE_FORMAT_R16G16_UINT, + PIPE_FORMAT_R16G16B16_UINT, + PIPE_FORMAT_R16G16B16A16_UINT +}; + +static GLuint short_types_norm[4] = { + PIPE_FORMAT_R16_SNORM, + PIPE_FORMAT_R16G16_SNORM, + PIPE_FORMAT_R16G16B16_SNORM, + PIPE_FORMAT_R16G16B16A16_SNORM +}; + +static GLuint short_types_scale[4] = { + PIPE_FORMAT_R16_SSCALED, + PIPE_FORMAT_R16G16_SSCALED, + PIPE_FORMAT_R16G16B16_SSCALED, + PIPE_FORMAT_R16G16B16A16_SSCALED +}; + +static GLuint short_types_int[4] = { + PIPE_FORMAT_R16_SINT, + PIPE_FORMAT_R16G16_SINT, + PIPE_FORMAT_R16G16B16_SINT, + PIPE_FORMAT_R16G16B16A16_SINT +}; + +static GLuint ubyte_types_norm[4] = { + PIPE_FORMAT_R8_UNORM, + PIPE_FORMAT_R8G8_UNORM, + PIPE_FORMAT_R8G8B8_UNORM, + PIPE_FORMAT_R8G8B8A8_UNORM +}; + +static GLuint ubyte_types_scale[4] = { + PIPE_FORMAT_R8_USCALED, + PIPE_FORMAT_R8G8_USCALED, + PIPE_FORMAT_R8G8B8_USCALED, + PIPE_FORMAT_R8G8B8A8_USCALED +}; + +static GLuint ubyte_types_int[4] = { + PIPE_FORMAT_R8_UINT, + PIPE_FORMAT_R8G8_UINT, + PIPE_FORMAT_R8G8B8_UINT, + PIPE_FORMAT_R8G8B8A8_UINT +}; + +static GLuint byte_types_norm[4] = { + PIPE_FORMAT_R8_SNORM, + PIPE_FORMAT_R8G8_SNORM, + PIPE_FORMAT_R8G8B8_SNORM, + PIPE_FORMAT_R8G8B8A8_SNORM +}; + +static GLuint byte_types_scale[4] = { + PIPE_FORMAT_R8_SSCALED, + PIPE_FORMAT_R8G8_SSCALED, + PIPE_FORMAT_R8G8B8_SSCALED, + PIPE_FORMAT_R8G8B8A8_SSCALED +}; + +static GLuint byte_types_int[4] = { + PIPE_FORMAT_R8_SINT, + PIPE_FORMAT_R8G8_SINT, + PIPE_FORMAT_R8G8B8_SINT, + PIPE_FORMAT_R8G8B8A8_SINT +}; + +static GLuint fixed_types[4] = { + PIPE_FORMAT_R32_FIXED, + PIPE_FORMAT_R32G32_FIXED, + PIPE_FORMAT_R32G32B32_FIXED, + PIPE_FORMAT_R32G32B32A32_FIXED +}; + + +/** + * Return a PIPE_FORMAT_x for the given GL datatype and size. + */ +enum pipe_format +st_pipe_vertex_format(GLenum type, GLuint size, GLenum format, + GLboolean normalized, GLboolean integer) +{ + assert((type >= GL_BYTE && type <= GL_DOUBLE) || + type == GL_FIXED || type == GL_HALF_FLOAT || + type == GL_INT_2_10_10_10_REV || + type == GL_UNSIGNED_INT_2_10_10_10_REV); + assert(size >= 1); + assert(size <= 4); + assert(format == GL_RGBA || format == GL_BGRA); + + if (type == GL_INT_2_10_10_10_REV || + type == GL_UNSIGNED_INT_2_10_10_10_REV) { + assert(size == 4); + assert(!integer); + + if (format == GL_BGRA) { + if (type == GL_INT_2_10_10_10_REV) { + if (normalized) + return PIPE_FORMAT_B10G10R10A2_SNORM; + else + return PIPE_FORMAT_B10G10R10A2_SSCALED; + } else { + if (normalized) + return PIPE_FORMAT_B10G10R10A2_UNORM; + else + return PIPE_FORMAT_B10G10R10A2_USCALED; + } + } else { + if (type == GL_INT_2_10_10_10_REV) { + if (normalized) + return PIPE_FORMAT_R10G10B10A2_SNORM; + else + return PIPE_FORMAT_R10G10B10A2_SSCALED; + } else { + if (normalized) + return PIPE_FORMAT_R10G10B10A2_UNORM; + else + return PIPE_FORMAT_R10G10B10A2_USCALED; + } + } + } + + if (format == GL_BGRA) { + /* this is an odd-ball case */ + assert(type == GL_UNSIGNED_BYTE); + assert(normalized); + return PIPE_FORMAT_B8G8R8A8_UNORM; + } + + if (integer) { + switch (type) { + case GL_INT: return int_types_int[size-1]; + case GL_SHORT: return short_types_int[size-1]; + case GL_BYTE: return byte_types_int[size-1]; + case GL_UNSIGNED_INT: return uint_types_int[size-1]; + case GL_UNSIGNED_SHORT: return ushort_types_int[size-1]; + case GL_UNSIGNED_BYTE: return ubyte_types_int[size-1]; + default: assert(0); return 0; + } + } + else if (normalized) { + switch (type) { + case GL_DOUBLE: return double_types[size-1]; + case GL_FLOAT: return float_types[size-1]; + case GL_HALF_FLOAT: return half_float_types[size-1]; + case GL_INT: return int_types_norm[size-1]; + case GL_SHORT: return short_types_norm[size-1]; + case GL_BYTE: return byte_types_norm[size-1]; + case GL_UNSIGNED_INT: return uint_types_norm[size-1]; + case GL_UNSIGNED_SHORT: return ushort_types_norm[size-1]; + case GL_UNSIGNED_BYTE: return ubyte_types_norm[size-1]; + case GL_FIXED: return fixed_types[size-1]; + default: assert(0); return 0; + } + } + else { + switch (type) { + case GL_DOUBLE: return double_types[size-1]; + case GL_FLOAT: return float_types[size-1]; + case GL_HALF_FLOAT: return half_float_types[size-1]; + case GL_INT: return int_types_scale[size-1]; + case GL_SHORT: return short_types_scale[size-1]; + case GL_BYTE: return byte_types_scale[size-1]; + case GL_UNSIGNED_INT: return uint_types_scale[size-1]; + case GL_UNSIGNED_SHORT: return ushort_types_scale[size-1]; + case GL_UNSIGNED_BYTE: return ubyte_types_scale[size-1]; + case GL_FIXED: return fixed_types[size-1]; + default: assert(0); return 0; + } + } + return PIPE_FORMAT_NONE; /* silence compiler warning */ +} + +/** + * Examine the active arrays to determine if we have interleaved + * vertex arrays all living in one VBO, or all living in user space. + */ +static GLboolean +is_interleaved_arrays(const struct st_vertex_program *vp, + const struct st_vp_variant *vpv, + const struct gl_client_array **arrays) +{ + GLuint attr; + const struct gl_buffer_object *firstBufObj = NULL; + GLint firstStride = -1; + const GLubyte *firstPtr = NULL; + GLboolean userSpaceBuffer = GL_FALSE; + + for (attr = 0; attr < vpv->num_inputs; attr++) { + const GLuint mesaAttr = vp->index_to_input[attr]; + const struct gl_client_array *array = arrays[mesaAttr]; + const struct gl_buffer_object *bufObj = array->BufferObj; + const GLsizei stride = array->StrideB; /* in bytes */ + + if (attr == 0) { + /* save info about the first array */ + firstStride = stride; + firstPtr = array->Ptr; + firstBufObj = bufObj; + userSpaceBuffer = !bufObj || !bufObj->Name; + } + else { + /* check if other arrays interleave with the first, in same buffer */ + if (stride != firstStride) + return GL_FALSE; /* strides don't match */ + + if (bufObj != firstBufObj) + return GL_FALSE; /* arrays in different VBOs */ + + if (abs(array->Ptr - firstPtr) > firstStride) + return GL_FALSE; /* arrays start too far apart */ + + if ((!_mesa_is_bufferobj(bufObj)) != userSpaceBuffer) + return GL_FALSE; /* mix of VBO and user-space arrays */ + } + } + + return GL_TRUE; +} + +/** + * Set up for drawing interleaved arrays that all live in one VBO + * or all live in user space. + * \param vbuffer returns vertex buffer info + * \param velements returns vertex element info + */ +static boolean +setup_interleaved_attribs(const struct st_vertex_program *vp, + const struct st_vp_variant *vpv, + const struct gl_client_array **arrays, + struct pipe_vertex_buffer *vbuffer, + struct pipe_vertex_element velements[]) +{ + GLuint attr; + const GLubyte *low_addr = NULL; + GLboolean usingVBO; /* all arrays in a VBO? */ + struct gl_buffer_object *bufobj; + GLsizei stride; + + /* Find the lowest address of the arrays we're drawing, + * Init bufobj and stride. + */ + if (vpv->num_inputs) { + const GLuint mesaAttr0 = vp->index_to_input[0]; + const struct gl_client_array *array = arrays[mesaAttr0]; + + /* Since we're doing interleaved arrays, we know there'll be at most + * one buffer object and the stride will be the same for all arrays. + * Grab them now. + */ + bufobj = array->BufferObj; + stride = array->StrideB; + + low_addr = arrays[vp->index_to_input[0]]->Ptr; + + for (attr = 1; attr < vpv->num_inputs; attr++) { + const GLubyte *start = arrays[vp->index_to_input[attr]]->Ptr; + low_addr = MIN2(low_addr, start); + } + } + else { + /* not sure we'll ever have zero inputs, but play it safe */ + bufobj = NULL; + stride = 0; + low_addr = 0; + } + + /* are the arrays in user space? */ + usingVBO = _mesa_is_bufferobj(bufobj); + + for (attr = 0; attr < vpv->num_inputs; attr++) { + const GLuint mesaAttr = vp->index_to_input[attr]; + const struct gl_client_array *array = arrays[mesaAttr]; + unsigned src_offset = (unsigned) (array->Ptr - low_addr); + GLuint element_size = array->_ElementSize; + + assert(element_size == array->Size * _mesa_sizeof_type(array->Type)); + + velements[attr].src_offset = src_offset; + velements[attr].instance_divisor = array->InstanceDivisor; + velements[attr].vertex_buffer_index = 0; + velements[attr].src_format = st_pipe_vertex_format(array->Type, + array->Size, + array->Format, + array->Normalized, + array->Integer); + assert(velements[attr].src_format); + } + + /* + * Return the vbuffer info and setup user-space attrib info, if needed. + */ + if (vpv->num_inputs == 0) { + /* just defensive coding here */ + vbuffer->buffer = NULL; + vbuffer->user_buffer = NULL; + vbuffer->buffer_offset = 0; + vbuffer->stride = 0; + } + else if (usingVBO) { + /* all interleaved arrays in a VBO */ + struct st_buffer_object *stobj = st_buffer_object(bufobj); + + if (!stobj || !stobj->buffer) { + return FALSE; /* out-of-memory error probably */ + } + + vbuffer->buffer = stobj->buffer; + vbuffer->user_buffer = NULL; + vbuffer->buffer_offset = pointer_to_offset(low_addr); + vbuffer->stride = stride; + } + else { + /* all interleaved arrays in user memory */ + vbuffer->buffer = NULL; + vbuffer->user_buffer = low_addr; + vbuffer->buffer_offset = 0; + vbuffer->stride = stride; + } + return TRUE; +} + +/** + * Set up a separate pipe_vertex_buffer and pipe_vertex_element for each + * vertex attribute. + * \param vbuffer returns vertex buffer info + * \param velements returns vertex element info + */ +static boolean +setup_non_interleaved_attribs(struct st_context *st, + const struct st_vertex_program *vp, + const struct st_vp_variant *vpv, + const struct gl_client_array **arrays, + struct pipe_vertex_buffer vbuffer[], + struct pipe_vertex_element velements[]) +{ + struct gl_context *ctx = st->ctx; + GLuint attr; + + for (attr = 0; attr < vpv->num_inputs; attr++) { + const GLuint mesaAttr = vp->index_to_input[attr]; + const struct gl_client_array *array = arrays[mesaAttr]; + struct gl_buffer_object *bufobj = array->BufferObj; + GLsizei stride = array->StrideB; + + assert(array->_ElementSize == array->Size * _mesa_sizeof_type(array->Type)); + + if (_mesa_is_bufferobj(bufobj)) { + /* Attribute data is in a VBO. + * Recall that for VBOs, the gl_client_array->Ptr field is + * really an offset from the start of the VBO, not a pointer. + */ + struct st_buffer_object *stobj = st_buffer_object(bufobj); + + if (!stobj || !stobj->buffer) { + return FALSE; /* out-of-memory error probably */ + } + + vbuffer[attr].buffer = stobj->buffer; + vbuffer[attr].user_buffer = NULL; + vbuffer[attr].buffer_offset = pointer_to_offset(array->Ptr); + } + else { + /* wrap user data */ + void *ptr; + + if (array->Ptr) { + ptr = (void *) array->Ptr; + } + else { + /* no array, use ctx->Current.Attrib[] value */ + ptr = (void *) ctx->Current.Attrib[mesaAttr]; + stride = 0; + } + + assert(ptr); + + vbuffer[attr].buffer = NULL; + vbuffer[attr].user_buffer = ptr; + vbuffer[attr].buffer_offset = 0; + } + + /* common-case setup */ + vbuffer[attr].stride = stride; /* in bytes */ + + velements[attr].src_offset = 0; + velements[attr].instance_divisor = array->InstanceDivisor; + velements[attr].vertex_buffer_index = attr; + velements[attr].src_format = st_pipe_vertex_format(array->Type, + array->Size, + array->Format, + array->Normalized, + array->Integer); + assert(velements[attr].src_format); + } + return TRUE; +} + +static void update_array(struct st_context *st) +{ + struct gl_context *ctx = st->ctx; + const struct gl_client_array **arrays = ctx->Array._DrawArrays; + const struct st_vertex_program *vp; + const struct st_vp_variant *vpv; + struct pipe_vertex_buffer vbuffer[PIPE_MAX_SHADER_INPUTS]; + struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS]; + unsigned num_vbuffers, num_velements; + + st->vertex_array_out_of_memory = FALSE; + + /* No drawing has been done yet, so do nothing. */ + if (!arrays) + return; + + /* vertex program validation must be done before this */ + vp = st->vp; + vpv = st->vp_variant; + + memset(velements, 0, sizeof(struct pipe_vertex_element) * vpv->num_inputs); + + /* + * Setup the vbuffer[] and velements[] arrays. + */ + if (is_interleaved_arrays(vp, vpv, arrays)) { + if (!setup_interleaved_attribs(vp, vpv, arrays, vbuffer, velements)) { + st->vertex_array_out_of_memory = TRUE; + return; + } + + num_vbuffers = 1; + num_velements = vpv->num_inputs; + if (num_velements == 0) + num_vbuffers = 0; + } + else { + if (!setup_non_interleaved_attribs(st, vp, vpv, arrays, vbuffer, + velements)) { + st->vertex_array_out_of_memory = TRUE; + return; + } + + num_vbuffers = vpv->num_inputs; + num_velements = vpv->num_inputs; + } + + cso_set_vertex_buffers(st->cso_context, num_vbuffers, vbuffer); + cso_set_vertex_elements(st->cso_context, num_velements, velements); +} + + +const struct st_tracked_state st_update_array = { + "st_update_array", /* name */ + { /* dirty */ + (_NEW_PROGRAM | _NEW_BUFFER_OBJECT), /* mesa */ + ST_NEW_VERTEX_ARRAYS | ST_NEW_VERTEX_PROGRAM, /* st */ + }, + update_array /* update */ +}; diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c index 9a3f22465..d3f8d1368 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c @@ -217,7 +217,7 @@ st_make_drawpix_z_stencil_program(struct st_context *st, if (!p) return NULL; - p->NumInstructions = write_depth ? 2 : 1; + p->NumInstructions = write_depth ? 3 : 1; p->NumInstructions += write_stencil ? 1 : 0; p->Instructions = _mesa_alloc_instructions(p->NumInstructions); @@ -238,6 +238,13 @@ st_make_drawpix_z_stencil_program(struct st_context *st, p->Instructions[ic].TexSrcUnit = 0; p->Instructions[ic].TexSrcTarget = TEXTURE_2D_INDEX; ic++; + /* MOV result.color, fragment.color; */ + p->Instructions[ic].Opcode = OPCODE_MOV; + p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT; + p->Instructions[ic].DstReg.Index = FRAG_RESULT_COLOR; + p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT; + p->Instructions[ic].SrcReg[0].Index = FRAG_ATTRIB_COL0; + ic++; } if (write_stencil) { @@ -260,8 +267,10 @@ st_make_drawpix_z_stencil_program(struct st_context *st, p->InputsRead = FRAG_BIT_TEX0 | FRAG_BIT_COL0; p->OutputsWritten = 0; - if (write_depth) + if (write_depth) { p->OutputsWritten |= BITFIELD64_BIT(FRAG_RESULT_DEPTH); + p->OutputsWritten |= BITFIELD64_BIT(FRAG_RESULT_COLOR); + } if (write_stencil) p->OutputsWritten |= BITFIELD64_BIT(FRAG_RESULT_STENCIL); diff --git a/mesalib/src/mesa/state_tracker/st_context.h b/mesalib/src/mesa/state_tracker/st_context.h index 55ae65b3c..734b4d9c1 100644 --- a/mesalib/src/mesa/state_tracker/st_context.h +++ b/mesalib/src/mesa/state_tracker/st_context.h @@ -88,6 +88,8 @@ struct st_context */ boolean invalidate_on_gl_viewport; + boolean vertex_array_out_of_memory; + /* Some state is contained in constant objects. * Other state is just parameter values. */ diff --git a/mesalib/src/mesa/state_tracker/st_draw.c b/mesalib/src/mesa/state_tracker/st_draw.c index 0a06e9995..db8caa566 100644 --- a/mesalib/src/mesa/state_tracker/st_draw.c +++ b/mesalib/src/mesa/state_tracker/st_draw.c @@ -31,10 +31,6 @@ * this function whether the user called glBegin/End, glDrawArrays, * glDrawElements, glEvalMesh, or glCalList, etc. * - * We basically convert the VBO's vertex attribute/array information into - * Gallium vertex state, bind the vertex buffer objects and call - * pipe->draw_vbo(). - * * Authors: * Keith Whitwell <keith@tungstengraphics.com> */ @@ -68,261 +64,6 @@ #include "../glsl/ir_uniform.h" -static GLuint double_types[4] = { - PIPE_FORMAT_R64_FLOAT, - PIPE_FORMAT_R64G64_FLOAT, - PIPE_FORMAT_R64G64B64_FLOAT, - PIPE_FORMAT_R64G64B64A64_FLOAT -}; - -static GLuint float_types[4] = { - PIPE_FORMAT_R32_FLOAT, - PIPE_FORMAT_R32G32_FLOAT, - PIPE_FORMAT_R32G32B32_FLOAT, - PIPE_FORMAT_R32G32B32A32_FLOAT -}; - -static GLuint half_float_types[4] = { - PIPE_FORMAT_R16_FLOAT, - PIPE_FORMAT_R16G16_FLOAT, - PIPE_FORMAT_R16G16B16_FLOAT, - PIPE_FORMAT_R16G16B16A16_FLOAT -}; - -static GLuint uint_types_norm[4] = { - PIPE_FORMAT_R32_UNORM, - PIPE_FORMAT_R32G32_UNORM, - PIPE_FORMAT_R32G32B32_UNORM, - PIPE_FORMAT_R32G32B32A32_UNORM -}; - -static GLuint uint_types_scale[4] = { - PIPE_FORMAT_R32_USCALED, - PIPE_FORMAT_R32G32_USCALED, - PIPE_FORMAT_R32G32B32_USCALED, - PIPE_FORMAT_R32G32B32A32_USCALED -}; - -static GLuint uint_types_int[4] = { - PIPE_FORMAT_R32_UINT, - PIPE_FORMAT_R32G32_UINT, - PIPE_FORMAT_R32G32B32_UINT, - PIPE_FORMAT_R32G32B32A32_UINT -}; - -static GLuint int_types_norm[4] = { - PIPE_FORMAT_R32_SNORM, - PIPE_FORMAT_R32G32_SNORM, - PIPE_FORMAT_R32G32B32_SNORM, - PIPE_FORMAT_R32G32B32A32_SNORM -}; - -static GLuint int_types_scale[4] = { - PIPE_FORMAT_R32_SSCALED, - PIPE_FORMAT_R32G32_SSCALED, - PIPE_FORMAT_R32G32B32_SSCALED, - PIPE_FORMAT_R32G32B32A32_SSCALED -}; - -static GLuint int_types_int[4] = { - PIPE_FORMAT_R32_SINT, - PIPE_FORMAT_R32G32_SINT, - PIPE_FORMAT_R32G32B32_SINT, - PIPE_FORMAT_R32G32B32A32_SINT -}; - -static GLuint ushort_types_norm[4] = { - PIPE_FORMAT_R16_UNORM, - PIPE_FORMAT_R16G16_UNORM, - PIPE_FORMAT_R16G16B16_UNORM, - PIPE_FORMAT_R16G16B16A16_UNORM -}; - -static GLuint ushort_types_scale[4] = { - PIPE_FORMAT_R16_USCALED, - PIPE_FORMAT_R16G16_USCALED, - PIPE_FORMAT_R16G16B16_USCALED, - PIPE_FORMAT_R16G16B16A16_USCALED -}; - -static GLuint ushort_types_int[4] = { - PIPE_FORMAT_R16_UINT, - PIPE_FORMAT_R16G16_UINT, - PIPE_FORMAT_R16G16B16_UINT, - PIPE_FORMAT_R16G16B16A16_UINT -}; - -static GLuint short_types_norm[4] = { - PIPE_FORMAT_R16_SNORM, - PIPE_FORMAT_R16G16_SNORM, - PIPE_FORMAT_R16G16B16_SNORM, - PIPE_FORMAT_R16G16B16A16_SNORM -}; - -static GLuint short_types_scale[4] = { - PIPE_FORMAT_R16_SSCALED, - PIPE_FORMAT_R16G16_SSCALED, - PIPE_FORMAT_R16G16B16_SSCALED, - PIPE_FORMAT_R16G16B16A16_SSCALED -}; - -static GLuint short_types_int[4] = { - PIPE_FORMAT_R16_SINT, - PIPE_FORMAT_R16G16_SINT, - PIPE_FORMAT_R16G16B16_SINT, - PIPE_FORMAT_R16G16B16A16_SINT -}; - -static GLuint ubyte_types_norm[4] = { - PIPE_FORMAT_R8_UNORM, - PIPE_FORMAT_R8G8_UNORM, - PIPE_FORMAT_R8G8B8_UNORM, - PIPE_FORMAT_R8G8B8A8_UNORM -}; - -static GLuint ubyte_types_scale[4] = { - PIPE_FORMAT_R8_USCALED, - PIPE_FORMAT_R8G8_USCALED, - PIPE_FORMAT_R8G8B8_USCALED, - PIPE_FORMAT_R8G8B8A8_USCALED -}; - -static GLuint ubyte_types_int[4] = { - PIPE_FORMAT_R8_UINT, - PIPE_FORMAT_R8G8_UINT, - PIPE_FORMAT_R8G8B8_UINT, - PIPE_FORMAT_R8G8B8A8_UINT -}; - -static GLuint byte_types_norm[4] = { - PIPE_FORMAT_R8_SNORM, - PIPE_FORMAT_R8G8_SNORM, - PIPE_FORMAT_R8G8B8_SNORM, - PIPE_FORMAT_R8G8B8A8_SNORM -}; - -static GLuint byte_types_scale[4] = { - PIPE_FORMAT_R8_SSCALED, - PIPE_FORMAT_R8G8_SSCALED, - PIPE_FORMAT_R8G8B8_SSCALED, - PIPE_FORMAT_R8G8B8A8_SSCALED -}; - -static GLuint byte_types_int[4] = { - PIPE_FORMAT_R8_SINT, - PIPE_FORMAT_R8G8_SINT, - PIPE_FORMAT_R8G8B8_SINT, - PIPE_FORMAT_R8G8B8A8_SINT -}; - -static GLuint fixed_types[4] = { - PIPE_FORMAT_R32_FIXED, - PIPE_FORMAT_R32G32_FIXED, - PIPE_FORMAT_R32G32B32_FIXED, - PIPE_FORMAT_R32G32B32A32_FIXED -}; - - - -/** - * Return a PIPE_FORMAT_x for the given GL datatype and size. - */ -enum pipe_format -st_pipe_vertex_format(GLenum type, GLuint size, GLenum format, - GLboolean normalized, GLboolean integer) -{ - assert((type >= GL_BYTE && type <= GL_DOUBLE) || - type == GL_FIXED || type == GL_HALF_FLOAT || - type == GL_INT_2_10_10_10_REV || - type == GL_UNSIGNED_INT_2_10_10_10_REV); - assert(size >= 1); - assert(size <= 4); - assert(format == GL_RGBA || format == GL_BGRA); - - if (type == GL_INT_2_10_10_10_REV || - type == GL_UNSIGNED_INT_2_10_10_10_REV) { - assert(size == 4); - assert(!integer); - - if (format == GL_BGRA) { - if (type == GL_INT_2_10_10_10_REV) { - if (normalized) - return PIPE_FORMAT_B10G10R10A2_SNORM; - else - return PIPE_FORMAT_B10G10R10A2_SSCALED; - } else { - if (normalized) - return PIPE_FORMAT_B10G10R10A2_UNORM; - else - return PIPE_FORMAT_B10G10R10A2_USCALED; - } - } else { - if (type == GL_INT_2_10_10_10_REV) { - if (normalized) - return PIPE_FORMAT_R10G10B10A2_SNORM; - else - return PIPE_FORMAT_R10G10B10A2_SSCALED; - } else { - if (normalized) - return PIPE_FORMAT_R10G10B10A2_UNORM; - else - return PIPE_FORMAT_R10G10B10A2_USCALED; - } - } - } - - if (format == GL_BGRA) { - /* this is an odd-ball case */ - assert(type == GL_UNSIGNED_BYTE); - assert(normalized); - return PIPE_FORMAT_B8G8R8A8_UNORM; - } - - if (integer) { - switch (type) { - case GL_INT: return int_types_int[size-1]; - case GL_SHORT: return short_types_int[size-1]; - case GL_BYTE: return byte_types_int[size-1]; - case GL_UNSIGNED_INT: return uint_types_int[size-1]; - case GL_UNSIGNED_SHORT: return ushort_types_int[size-1]; - case GL_UNSIGNED_BYTE: return ubyte_types_int[size-1]; - default: assert(0); return 0; - } - } - else if (normalized) { - switch (type) { - case GL_DOUBLE: return double_types[size-1]; - case GL_FLOAT: return float_types[size-1]; - case GL_HALF_FLOAT: return half_float_types[size-1]; - case GL_INT: return int_types_norm[size-1]; - case GL_SHORT: return short_types_norm[size-1]; - case GL_BYTE: return byte_types_norm[size-1]; - case GL_UNSIGNED_INT: return uint_types_norm[size-1]; - case GL_UNSIGNED_SHORT: return ushort_types_norm[size-1]; - case GL_UNSIGNED_BYTE: return ubyte_types_norm[size-1]; - case GL_FIXED: return fixed_types[size-1]; - default: assert(0); return 0; - } - } - else { - switch (type) { - case GL_DOUBLE: return double_types[size-1]; - case GL_FLOAT: return float_types[size-1]; - case GL_HALF_FLOAT: return half_float_types[size-1]; - case GL_INT: return int_types_scale[size-1]; - case GL_SHORT: return short_types_scale[size-1]; - case GL_BYTE: return byte_types_scale[size-1]; - case GL_UNSIGNED_INT: return uint_types_scale[size-1]; - case GL_UNSIGNED_SHORT: return ushort_types_scale[size-1]; - case GL_UNSIGNED_BYTE: return ubyte_types_scale[size-1]; - case GL_FIXED: return fixed_types[size-1]; - default: assert(0); return 0; - } - } - return PIPE_FORMAT_NONE; /* silence compiler warning */ -} - - /** * This is very similar to vbo_all_varyings_in_vbos() but we are * only interested in per-vertex data. See bug 38626. @@ -342,240 +83,6 @@ all_varyings_in_vbos(const struct gl_client_array *arrays[]) } -/** - * Examine the active arrays to determine if we have interleaved - * vertex arrays all living in one VBO, or all living in user space. - */ -static GLboolean -is_interleaved_arrays(const struct st_vertex_program *vp, - const struct st_vp_variant *vpv, - const struct gl_client_array **arrays) -{ - GLuint attr; - const struct gl_buffer_object *firstBufObj = NULL; - GLint firstStride = -1; - const GLubyte *firstPtr = NULL; - GLboolean userSpaceBuffer = GL_FALSE; - - for (attr = 0; attr < vpv->num_inputs; attr++) { - const GLuint mesaAttr = vp->index_to_input[attr]; - const struct gl_client_array *array = arrays[mesaAttr]; - const struct gl_buffer_object *bufObj = array->BufferObj; - const GLsizei stride = array->StrideB; /* in bytes */ - - if (attr == 0) { - /* save info about the first array */ - firstStride = stride; - firstPtr = array->Ptr; - firstBufObj = bufObj; - userSpaceBuffer = !bufObj || !bufObj->Name; - } - else { - /* check if other arrays interleave with the first, in same buffer */ - if (stride != firstStride) - return GL_FALSE; /* strides don't match */ - - if (bufObj != firstBufObj) - return GL_FALSE; /* arrays in different VBOs */ - - if (abs(array->Ptr - firstPtr) > firstStride) - return GL_FALSE; /* arrays start too far apart */ - - if ((!_mesa_is_bufferobj(bufObj)) != userSpaceBuffer) - return GL_FALSE; /* mix of VBO and user-space arrays */ - } - } - - return GL_TRUE; -} - - -/** - * Set up for drawing interleaved arrays that all live in one VBO - * or all live in user space. - * \param vbuffer returns vertex buffer info - * \param velements returns vertex element info - * \return GL_TRUE for success, GL_FALSE otherwise (probably out of memory) - */ -static GLboolean -setup_interleaved_attribs(struct gl_context *ctx, - const struct st_vertex_program *vp, - const struct st_vp_variant *vpv, - const struct gl_client_array **arrays, - struct pipe_vertex_buffer *vbuffer, - struct pipe_vertex_element velements[]) -{ - GLuint attr; - const GLubyte *low_addr = NULL; - GLboolean usingVBO; /* all arrays in a VBO? */ - struct gl_buffer_object *bufobj; - GLsizei stride; - - /* Find the lowest address of the arrays we're drawing, - * Init bufobj and stride. - */ - if (vpv->num_inputs) { - const GLuint mesaAttr0 = vp->index_to_input[0]; - const struct gl_client_array *array = arrays[mesaAttr0]; - - /* Since we're doing interleaved arrays, we know there'll be at most - * one buffer object and the stride will be the same for all arrays. - * Grab them now. - */ - bufobj = array->BufferObj; - stride = array->StrideB; - - low_addr = arrays[vp->index_to_input[0]]->Ptr; - - for (attr = 1; attr < vpv->num_inputs; attr++) { - const GLubyte *start = arrays[vp->index_to_input[attr]]->Ptr; - low_addr = MIN2(low_addr, start); - } - } - else { - /* not sure we'll ever have zero inputs, but play it safe */ - bufobj = NULL; - stride = 0; - low_addr = 0; - } - - /* are the arrays in user space? */ - usingVBO = _mesa_is_bufferobj(bufobj); - - for (attr = 0; attr < vpv->num_inputs; attr++) { - const GLuint mesaAttr = vp->index_to_input[attr]; - const struct gl_client_array *array = arrays[mesaAttr]; - unsigned src_offset = (unsigned) (array->Ptr - low_addr); - GLuint element_size = array->_ElementSize; - - assert(element_size == array->Size * _mesa_sizeof_type(array->Type)); - - velements[attr].src_offset = src_offset; - velements[attr].instance_divisor = array->InstanceDivisor; - velements[attr].vertex_buffer_index = 0; - velements[attr].src_format = st_pipe_vertex_format(array->Type, - array->Size, - array->Format, - array->Normalized, - array->Integer); - assert(velements[attr].src_format); - } - - /* - * Return the vbuffer info and setup user-space attrib info, if needed. - */ - if (vpv->num_inputs == 0) { - /* just defensive coding here */ - vbuffer->buffer = NULL; - vbuffer->user_buffer = NULL; - vbuffer->buffer_offset = 0; - vbuffer->stride = 0; - } - else if (usingVBO) { - /* all interleaved arrays in a VBO */ - struct st_buffer_object *stobj = st_buffer_object(bufobj); - - if (!stobj || !stobj->buffer) { - /* probably out of memory (or zero-sized buffer) */ - return GL_FALSE; - } - - vbuffer->buffer = stobj->buffer; - vbuffer->user_buffer = NULL; - vbuffer->buffer_offset = pointer_to_offset(low_addr); - vbuffer->stride = stride; - } - else { - /* all interleaved arrays in user memory */ - vbuffer->buffer = NULL; - vbuffer->user_buffer = low_addr; - vbuffer->buffer_offset = 0; - vbuffer->stride = stride; - } - - return GL_TRUE; -} - - -/** - * Set up a separate pipe_vertex_buffer and pipe_vertex_element for each - * vertex attribute. - * \param vbuffer returns vertex buffer info - * \param velements returns vertex element info - * \return GL_TRUE for success, GL_FALSE otherwise (probably out of memory) - */ -static GLboolean -setup_non_interleaved_attribs(struct gl_context *ctx, - const struct st_vertex_program *vp, - const struct st_vp_variant *vpv, - const struct gl_client_array **arrays, - struct pipe_vertex_buffer vbuffer[], - struct pipe_vertex_element velements[]) -{ - GLuint attr; - - for (attr = 0; attr < vpv->num_inputs; attr++) { - const GLuint mesaAttr = vp->index_to_input[attr]; - const struct gl_client_array *array = arrays[mesaAttr]; - struct gl_buffer_object *bufobj = array->BufferObj; - GLsizei stride = array->StrideB; - - assert(array->_ElementSize == array->Size * _mesa_sizeof_type(array->Type)); - - if (_mesa_is_bufferobj(bufobj)) { - /* Attribute data is in a VBO. - * Recall that for VBOs, the gl_client_array->Ptr field is - * really an offset from the start of the VBO, not a pointer. - */ - struct st_buffer_object *stobj = st_buffer_object(bufobj); - - if (!stobj || !stobj->buffer) { - /* probably out of memory (or zero-sized buffer) */ - return GL_FALSE; - } - - vbuffer[attr].buffer = stobj->buffer; - vbuffer[attr].user_buffer = NULL; - vbuffer[attr].buffer_offset = pointer_to_offset(array->Ptr); - } - else { - /* wrap user data */ - void *ptr; - - if (array->Ptr) { - ptr = (void *) array->Ptr; - } - else { - /* no array, use ctx->Current.Attrib[] value */ - ptr = (void *) ctx->Current.Attrib[mesaAttr]; - stride = 0; - } - - assert(ptr); - - vbuffer[attr].buffer = NULL; - vbuffer[attr].user_buffer = ptr; - vbuffer[attr].buffer_offset = 0; - } - - /* common-case setup */ - vbuffer[attr].stride = stride; /* in bytes */ - - velements[attr].src_offset = 0; - velements[attr].instance_divisor = array->InstanceDivisor; - velements[attr].vertex_buffer_index = attr; - velements[attr].src_format = st_pipe_vertex_format(array->Type, - array->Size, - array->Format, - array->Normalized, - array->Integer); - assert(velements[attr].src_format); - } - - return GL_TRUE; -} - - static void setup_index_buffer(struct st_context *st, const struct _mesa_index_buffer *ib, @@ -665,58 +172,6 @@ translate_prim(const struct gl_context *ctx, unsigned prim) /** - * Setup vertex arrays and buffers prior to drawing. - * \return GL_TRUE for success, GL_FALSE otherwise (probably out of memory) - */ -static GLboolean -st_validate_varrays(struct gl_context *ctx, - const struct gl_client_array **arrays) -{ - struct st_context *st = st_context(ctx); - const struct st_vertex_program *vp; - const struct st_vp_variant *vpv; - struct pipe_vertex_buffer vbuffer[PIPE_MAX_SHADER_INPUTS]; - struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS]; - unsigned num_vbuffers, num_velements; - - /* must get these after state validation! */ - vp = st->vp; - vpv = st->vp_variant; - - memset(velements, 0, sizeof(struct pipe_vertex_element) * vpv->num_inputs); - - /* - * Setup the vbuffer[] and velements[] arrays. - */ - if (is_interleaved_arrays(vp, vpv, arrays)) { - if (!setup_interleaved_attribs(ctx, vp, vpv, arrays, vbuffer, - velements)) { - return GL_FALSE; - } - - num_vbuffers = 1; - num_velements = vpv->num_inputs; - if (num_velements == 0) - num_vbuffers = 0; - } - else { - if (!setup_non_interleaved_attribs(ctx, vp, vpv, arrays, - vbuffer, velements)) { - return GL_FALSE; - } - - num_vbuffers = vpv->num_inputs; - num_velements = vpv->num_inputs; - } - - cso_set_vertex_buffers(st->cso_context, num_vbuffers, vbuffer); - cso_set_vertex_elements(st->cso_context, num_velements, velements); - - return GL_TRUE; -} - - -/** * This function gets plugged into the VBO module and is called when * we have something to render. * Basically, translate the information into the format expected by gallium. @@ -736,38 +191,16 @@ st_draw_vbo(struct gl_context *ctx, struct pipe_draw_info info; const struct gl_client_array **arrays = ctx->Array._DrawArrays; unsigned i; - GLboolean new_array; /* Mesa core state should have been validated already */ assert(ctx->NewState == 0x0); - /* Get Mesa driver state. */ - st->dirty.st |= ctx->NewDriverState; - ctx->NewDriverState = 0; - - new_array = - (st->dirty.st & (ST_NEW_VERTEX_ARRAYS | ST_NEW_VERTEX_PROGRAM)) || - (st->dirty.mesa & (_NEW_PROGRAM | _NEW_BUFFER_OBJECT)) != 0; - /* Validate state. */ - if (st->dirty.st) { - GLboolean vertDataEdgeFlags; - - vertDataEdgeFlags = arrays[VERT_ATTRIB_EDGEFLAG]->BufferObj && - arrays[VERT_ATTRIB_EDGEFLAG]->BufferObj->Name; - if (vertDataEdgeFlags != st->vertdata_edgeflags) { - st->vertdata_edgeflags = vertDataEdgeFlags; - st->dirty.st |= ST_NEW_EDGEFLAGS_DATA; - } - + if (st->dirty.st || ctx->NewDriverState) { st_validate_state(st); - if (new_array) { - if (!st_validate_varrays(ctx, arrays)) { - /* probably out of memory, no-op the draw call */ - return; - } - } + if (st->vertex_array_out_of_memory) + return; #if 0 if (MESA_VERBOSE & VERBOSE_GLSL) { diff --git a/mesalib/src/mesa/state_tracker/st_draw.h b/mesalib/src/mesa/state_tracker/st_draw.h index c608051eb..3313fc8c7 100644 --- a/mesalib/src/mesa/state_tracker/st_draw.h +++ b/mesalib/src/mesa/state_tracker/st_draw.h @@ -67,13 +67,6 @@ st_feedback_draw_vbo(struct gl_context *ctx, 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, GLboolean integer); - - /** * When drawing with VBOs, the addresses specified with * glVertex/Color/TexCoordPointer() are really offsets into the VBO, not real |