From c5ccd6232d330bebe98413b612409f1c111ecae5 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 31 Jan 2023 15:30:52 +0100 Subject: [PATCH 1/7] glgsg: Prevent exceeding max supported vertex attrib stride See also Moguri/panda3d-gltf#117 --- panda/src/gles2gsg/gles2gsg.h | 1 + panda/src/glstuff/glGeomMunger_src.cxx | 58 ++++++++++++++----- .../src/glstuff/glGraphicsStateGuardian_src.I | 13 +++++ .../glstuff/glGraphicsStateGuardian_src.cxx | 35 +++++++++++ .../src/glstuff/glGraphicsStateGuardian_src.h | 3 + 5 files changed, 94 insertions(+), 16 deletions(-) diff --git a/panda/src/gles2gsg/gles2gsg.h b/panda/src/gles2gsg/gles2gsg.h index 044ac72991..7cfa72ee76 100644 --- a/panda/src/gles2gsg/gles2gsg.h +++ b/panda/src/gles2gsg/gles2gsg.h @@ -171,6 +171,7 @@ typedef char GLchar; #define GL_RG32I 0x823B #define GL_RG32UI 0x823C #define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 #define GL_PROGRAM_BINARY_LENGTH 0x8741 #define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE #define GL_PROGRAM_BINARY_FORMATS 0x87FF diff --git a/panda/src/glstuff/glGeomMunger_src.cxx b/panda/src/glstuff/glGeomMunger_src.cxx index 5d1bbad9b5..f6bf36da4a 100644 --- a/panda/src/glstuff/glGeomMunger_src.cxx +++ b/panda/src/glstuff/glGeomMunger_src.cxx @@ -220,6 +220,7 @@ munge_format_impl(const GeomVertexFormat *orig, // Combine the primary data columns into a single array. new_format = new GeomVertexFormat(*format); PT(GeomVertexArrayFormat) new_array_format = new GeomVertexArrayFormat; + size_t insert_at = 0; const GeomVertexColumn *column = format->get_vertex_column(); if (column != nullptr) { @@ -263,22 +264,34 @@ munge_format_impl(const GeomVertexFormat *orig, // This is the first time we've encountered this texcoord name. const GeomVertexColumn *texcoord_type = format->get_column(name); + // Note that we have to add something as a placeholder, even if the + // texture coordinates aren't defined. + int num_values = 2; + int column_alignment = 0; + int start = new_array_format->get_total_bytes(); + start = (start + sizeof(PN_stdfloat) - 1) & ~(sizeof(PN_stdfloat) - 1); if (texcoord_type != nullptr) { - new_array_format->add_column - (name, texcoord_type->get_num_values(), NT_stdfloat, C_texcoord, - -1, texcoord_type->get_column_alignment()); - } else { - // We have to add something as a placeholder, even if the - // texture coordinates aren't defined. - new_array_format->add_column(name, 2, NT_stdfloat, C_texcoord); + column_alignment = texcoord_type->get_column_alignment(); + num_values = texcoord_type->get_num_values(); } + if (start + num_values * sizeof(PN_stdfloat) > glgsg->get_max_vertex_attrib_stride()) { + // We are exceeding the limit for stride reported by the driver. + // Start a new array. + new_format->insert_array(insert_at++, new_array_format); + new_array_format = new GeomVertexArrayFormat; + start = 0; + } + new_array_format->add_column(name, num_values, NT_stdfloat, + C_texcoord, start, column_alignment); new_format->remove_column(name); } } } } - new_format->insert_array(0, new_array_format); + if (new_array_format->get_num_columns() > 0) { + new_format->insert_array(insert_at, new_array_format); + } format = GeomVertexFormat::register_format(new_format); } @@ -377,6 +390,7 @@ premunge_format_impl(const GeomVertexFormat *orig) { // of doing this step at load time than you might be at run time. new_format = new GeomVertexFormat(*format); PT(GeomVertexArrayFormat) new_array_format = new GeomVertexArrayFormat; + size_t insert_at = 0; const GeomVertexColumn *column = format->get_vertex_column(); if (column != nullptr) { @@ -421,15 +435,25 @@ premunge_format_impl(const GeomVertexFormat *orig) { // This is the first time we've encountered this texcoord name. const GeomVertexColumn *texcoord_type = format->get_column(name); + // Note that we have to add something as a placeholder, even if the + // texture coordinates aren't defined. + int num_values = 2; + int column_alignment = 0; + int start = new_array_format->get_total_bytes(); + start = (start + sizeof(PN_stdfloat) - 1) & ~(sizeof(PN_stdfloat) - 1); if (texcoord_type != nullptr) { - new_array_format->add_column - (name, texcoord_type->get_num_values(), NT_stdfloat, C_texcoord, - -1, texcoord_type->get_column_alignment()); - } else { - // We have to add something as a placeholder, even if the - // texture coordinates aren't defined. - new_array_format->add_column(name, 2, NT_stdfloat, C_texcoord); + column_alignment = texcoord_type->get_column_alignment(); + num_values = texcoord_type->get_num_values(); } + if (start + num_values * sizeof(PN_stdfloat) > 2048) { + // We are exceeding the limit for stride (and the one that is + // guaranteed to be supported). Start a new array. + new_format->insert_array(insert_at++, new_array_format); + new_array_format = new GeomVertexArrayFormat; + start = 0; + } + new_array_format->add_column(name, num_values, NT_stdfloat, + C_texcoord, start, column_alignment); new_format->remove_column(name); } } @@ -453,7 +477,9 @@ premunge_format_impl(const GeomVertexFormat *orig) { } // Finally, insert the interleaved array first in the format. - new_format->insert_array(0, new_array_format); + if (new_array_format->get_num_columns() > 0) { + new_format->insert_array(insert_at, new_array_format); + } format = GeomVertexFormat::register_format(new_format); } diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.I b/panda/src/glstuff/glGraphicsStateGuardian_src.I index 5cb8d8db10..216c16f259 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.I +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.I @@ -181,6 +181,19 @@ has_fixed_function_pipeline() const { #endif } +/** + * + */ +INLINE int CLP(GraphicsStateGuardian):: +get_max_vertex_attrib_stride() const { +#ifdef OPENGLES_1 + // Best guess. + return 2048; +#else + return _max_vertex_attrib_stride; +#endif +} + /** * Calls glFinish() if the config variable gl-finish is set True. */ diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 0bb976eb25..6e1d734bc4 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -3434,6 +3434,31 @@ reset() { } #endif +#ifndef OPENGLES_1 +#ifdef OPENGLES + if (is_at_least_gles_version(3, 1)) +#else + if (is_at_least_gl_version(4, 4)) +#endif + { + _max_vertex_attrib_stride = -1; + glGetIntegerv(GL_MAX_VERTEX_ATTRIB_STRIDE, &_max_vertex_attrib_stride); + + if (_max_vertex_attrib_stride < 0) { + GLCAT.warning() + << "Failed to query GL_MAX_VERTEX_ATTRIB_STRIDE.\n"; + _max_vertex_attrib_stride = INT_MAX; + } + else if (GLCAT.is_debug()) { + GLCAT.debug() + << "max vertex attrib stride = " << _max_vertex_attrib_stride << "\n"; + } + } + else { + _max_vertex_attrib_stride = INT_MAX; + } +#endif // !OPENGLES_1 + _current_vbuffer_index = 0; _current_ibuffer_index = 0; _current_vao_index = 0; @@ -6483,6 +6508,16 @@ setup_array_data(const unsigned char *&client_pointer, return (client_pointer != nullptr); } +#ifndef OPENGLES_1 + int stride = array_reader->get_array_format()->get_stride(); + if (stride > _max_vertex_attrib_stride) { + GLCAT.error() + << "Vertex array stride " << stride << " exceeds supported maximum " + << _max_vertex_attrib_stride << "!\n"; + return false; + } +#endif + // Prepare the buffer object and bind it. CLP(VertexBufferContext) *gvbc = DCAST(CLP(VertexBufferContext), array_reader->prepare_now(get_prepared_objects(), this)); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index d9c8ab3265..ab9f58ce90 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -428,6 +428,8 @@ public: INLINE int get_gl_version_minor() const; INLINE bool has_fixed_function_pipeline() const; + INLINE int get_max_vertex_attrib_stride() const; + virtual void set_state_and_transform(const RenderState *state, const TransformState *transform); @@ -727,6 +729,7 @@ protected: bool _use_vertex_attrib_binding; CPT(GeomVertexFormat) _current_vertex_format; const GeomVertexColumn *_vertex_attrib_columns[32]; + int _max_vertex_attrib_stride = INT_MAX; GLuint _current_sbuffer_index; pvector _current_sbuffer_base; From 614502d183bd4b5891a8ce46f0fc525de6dbc014 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 31 Jan 2023 15:36:43 +0100 Subject: [PATCH 2/7] gobj: Add note to API doc about maximum stride value --- panda/src/gobj/geomVertexArrayFormat.I | 3 +++ 1 file changed, 3 insertions(+) diff --git a/panda/src/gobj/geomVertexArrayFormat.I b/panda/src/gobj/geomVertexArrayFormat.I index 10fb6b8329..ec76a6dca7 100644 --- a/panda/src/gobj/geomVertexArrayFormat.I +++ b/panda/src/gobj/geomVertexArrayFormat.I @@ -48,6 +48,9 @@ get_stride() const { * Changes the total number of bytes reserved in the array for each vertex. * You may not reduce this below get_total_bytes(), but you may increase it * arbitrarily. + * + * You should avoid arrays with stride higher than 2048, which is the typical + * limit supported by graphics hardware. */ INLINE void GeomVertexArrayFormat:: set_stride(int stride) { From 51d0a55264bac908c5f2a916fb3cd9b6739e9476 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 31 Jan 2023 15:37:22 +0100 Subject: [PATCH 3/7] general: Fix silly new clang warning about unprefixed `std::move()` --- panda/src/downloader/downloadDb.cxx | 11 +++++------ panda/src/gobj/geomVertexArrayFormat.cxx | 23 +++++++++++------------ panda/src/gobj/shader.cxx | 9 ++++----- panda/src/pgraph/nodePath.cxx | 9 ++++----- panda/src/pgraph/nodePath_ext.cxx | 10 ++++------ panda/src/text/textAssembler.cxx | 11 +++++------ 6 files changed, 33 insertions(+), 40 deletions(-) diff --git a/panda/src/downloader/downloadDb.cxx b/panda/src/downloader/downloadDb.cxx index 0679614c8b..bacf9dc04d 100644 --- a/panda/src/downloader/downloadDb.cxx +++ b/panda/src/downloader/downloadDb.cxx @@ -23,7 +23,6 @@ using std::endl; using std::istream; using std::istringstream; -using std::move; using std::ostream; using std::string; @@ -713,7 +712,7 @@ read(StreamReader &sr, bool want_server_info) { } // Parse the header - int num_multifiles = parse_header(Datagram(move(header))); + int num_multifiles = parse_header(Datagram(std::move(header))); if (num_multifiles < 0) { downloader_cat.error() << "invalid db header" << endl; return false; @@ -733,7 +732,7 @@ read(StreamReader &sr, bool want_server_info) { } // Parse the header - int mfr_length = parse_record_header(Datagram(move(mfr_header))); + int mfr_length = parse_record_header(Datagram(std::move(mfr_header))); // Ok, now that we know the size of the mfr, read it in Make a buffer to // read the multifile record into do not count the header length twice @@ -745,7 +744,7 @@ read(StreamReader &sr, bool want_server_info) { } // Parse the mfr - PT(DownloadDb::MultifileRecord) mfr = parse_mfr(Datagram(move(mfr_record))); + PT(DownloadDb::MultifileRecord) mfr = parse_mfr(Datagram(std::move(mfr_record))); // Only read in the individual file info if you are the server if (want_server_info) { @@ -764,7 +763,7 @@ read(StreamReader &sr, bool want_server_info) { } // Parse the header - int fr_length = parse_record_header(Datagram(move(fr_header))); + int fr_length = parse_record_header(Datagram(std::move(fr_header))); // Ok, now that we know the size of the mfr, read it in do not count // the header length twice @@ -777,7 +776,7 @@ read(StreamReader &sr, bool want_server_info) { } // Parse the file record - PT(DownloadDb::FileRecord) fr = parse_fr(Datagram(move(fr_record))); + PT(DownloadDb::FileRecord) fr = parse_fr(Datagram(std::move(fr_record))); // Add this file record to the current multifilerecord mfr->add_file_record(fr); diff --git a/panda/src/gobj/geomVertexArrayFormat.cxx b/panda/src/gobj/geomVertexArrayFormat.cxx index 578e99d805..9cb5c41e91 100644 --- a/panda/src/gobj/geomVertexArrayFormat.cxx +++ b/panda/src/gobj/geomVertexArrayFormat.cxx @@ -23,7 +23,6 @@ using std::max; using std::min; -using std::move; GeomVertexArrayFormat::Registry *GeomVertexArrayFormat::_registry = nullptr; TypeHandle GeomVertexArrayFormat::_type_handle; @@ -56,7 +55,7 @@ GeomVertexArrayFormat(CPT_InternalName name0, int num_components0, _divisor(0), _columns_unsorted(false) { - add_column(move(name0), num_components0, numeric_type0, contents0); + add_column(std::move(name0), num_components0, numeric_type0, contents0); } /** @@ -76,8 +75,8 @@ GeomVertexArrayFormat(CPT_InternalName name0, int num_components0, _divisor(0), _columns_unsorted(false) { - add_column(move(name0), num_components0, numeric_type0, contents0); - add_column(move(name1), num_components1, numeric_type1, contents1); + add_column(std::move(name0), num_components0, numeric_type0, contents0); + add_column(std::move(name1), num_components1, numeric_type1, contents1); } /** @@ -100,9 +99,9 @@ GeomVertexArrayFormat(CPT_InternalName name0, int num_components0, _divisor(0), _columns_unsorted(false) { - add_column(move(name0), num_components0, numeric_type0, contents0); - add_column(move(name1), num_components1, numeric_type1, contents1); - add_column(move(name2), num_components2, numeric_type2, contents2); + add_column(std::move(name0), num_components0, numeric_type0, contents0); + add_column(std::move(name1), num_components1, numeric_type1, contents1); + add_column(std::move(name2), num_components2, numeric_type2, contents2); } /** @@ -128,10 +127,10 @@ GeomVertexArrayFormat(CPT_InternalName name0, int num_components0, _divisor(0), _columns_unsorted(false) { - add_column(move(name0), num_components0, numeric_type0, contents0); - add_column(move(name1), num_components1, numeric_type1, contents1); - add_column(move(name2), num_components2, numeric_type2, contents2); - add_column(move(name3), num_components3, numeric_type3, contents3); + add_column(std::move(name0), num_components0, numeric_type0, contents0); + add_column(std::move(name1), num_components1, numeric_type1, contents1); + add_column(std::move(name2), num_components2, numeric_type2, contents2); + add_column(std::move(name3), num_components3, numeric_type3, contents3); } /** @@ -223,7 +222,7 @@ add_column(CPT_InternalName name, int num_components, start = _total_bytes; } - return add_column(GeomVertexColumn(move(name), num_components, numeric_type, contents, + return add_column(GeomVertexColumn(std::move(name), num_components, numeric_type, contents, start, column_alignment)); } diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index 6e911dfd5e..c43ff22e5e 100644 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -28,7 +28,6 @@ #endif using std::istream; -using std::move; using std::ostream; using std::ostringstream; using std::string; @@ -3475,7 +3474,7 @@ make(string body, ShaderLanguage lang) { } #endif - ShaderFile sbody(move(body)); + ShaderFile sbody(std::move(body)); if (cache_generated_shaders) { ShaderTable::const_iterator i = _make_table.find(sbody); @@ -3535,8 +3534,8 @@ make(ShaderLanguage lang, string vertex, string fragment, string geometry, return nullptr; } - ShaderFile sbody(move(vertex), move(fragment), move(geometry), - move(tess_control), move(tess_evaluation)); + ShaderFile sbody(std::move(vertex), std::move(fragment), std::move(geometry), + std::move(tess_control), std::move(tess_evaluation)); if (cache_generated_shaders) { ShaderTable::const_iterator i = _make_table.find(sbody); @@ -3580,7 +3579,7 @@ make_compute(ShaderLanguage lang, string body) { ShaderFile sbody; sbody._separate = true; - sbody._compute = move(body); + sbody._compute = std::move(body); if (cache_generated_shaders) { ShaderTable::const_iterator i = _make_table.find(sbody); diff --git a/panda/src/pgraph/nodePath.cxx b/panda/src/pgraph/nodePath.cxx index 8e0f986436..7d3eeb9bf6 100644 --- a/panda/src/pgraph/nodePath.cxx +++ b/panda/src/pgraph/nodePath.cxx @@ -74,7 +74,6 @@ #include "weakNodePath.h" using std::max; -using std::move; using std::ostream; using std::ostringstream; using std::string; @@ -3383,11 +3382,11 @@ set_shader_input(ShaderInput &&inp) { pnode->get_attrib(ShaderAttrib::get_class_slot()); if (attrib != nullptr) { const ShaderAttrib *sa = (const ShaderAttrib *)attrib; - pnode->set_attrib(sa->set_shader_input(move(inp))); + pnode->set_attrib(sa->set_shader_input(std::move(inp))); } else { // Create a new ShaderAttrib for this node. CPT(ShaderAttrib) sa = DCAST(ShaderAttrib, ShaderAttrib::make()); - pnode->set_attrib(sa->set_shader_input(move(inp))); + pnode->set_attrib(sa->set_shader_input(std::move(inp))); } } @@ -5526,7 +5525,7 @@ calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point, bool found_any = false; node()->calc_tight_bounds(min_point, max_point, found_any, - move(transform), current_thread); + std::move(transform), current_thread); return found_any; } @@ -5826,7 +5825,7 @@ NodePath NodePath:: decode_from_bam_stream(vector_uchar data, BamReader *reader) { NodePath result; - DatagramBuffer buffer(move(data)); + DatagramBuffer buffer(std::move(data)); BamReader local_reader; if (reader == nullptr) { diff --git a/panda/src/pgraph/nodePath_ext.cxx b/panda/src/pgraph/nodePath_ext.cxx index 4be58f3201..c4f7925f24 100644 --- a/panda/src/pgraph/nodePath_ext.cxx +++ b/panda/src/pgraph/nodePath_ext.cxx @@ -16,8 +16,6 @@ #include "shaderInput_ext.h" #include "shaderAttrib.h" -using std::move; - #ifdef HAVE_PYTHON #ifndef CPPPARSER @@ -215,7 +213,7 @@ find_net_python_tag(PyObject *key) const { */ NodePath py_decode_NodePath_from_bam_stream(vector_uchar data) { - return py_decode_NodePath_from_bam_stream_persist(nullptr, move(data)); + return py_decode_NodePath_from_bam_stream_persist(nullptr, std::move(data)); } /** @@ -235,7 +233,7 @@ py_decode_NodePath_from_bam_stream_persist(PyObject *unpickler, vector_uchar dat } } - return NodePath::decode_from_bam_stream(move(data), reader); + return NodePath::decode_from_bam_stream(std::move(data), reader); } /** @@ -253,7 +251,7 @@ set_shader_input(CPT_InternalName name, PyObject *value, int priority) { } ShaderInput &input = attrib->_inputs[name]; - invoke_extension(&input).__init__(move(name), value, priority); + invoke_extension(&input).__init__(std::move(name), value, priority); if (!_PyErr_OCCURRED()) { node->set_attrib(ShaderAttrib::return_new(attrib)); @@ -298,7 +296,7 @@ set_shader_inputs(PyObject *args, PyObject *kwargs) { CPT_InternalName name(std::string(buffer, length)); ShaderInput &input = attrib->_inputs[name]; - invoke_extension(&input).__init__(move(name), value); + invoke_extension(&input).__init__(std::move(name), value); } if (!_PyErr_OCCURRED()) { diff --git a/panda/src/text/textAssembler.cxx b/panda/src/text/textAssembler.cxx index 1453103fc2..081f86f8ca 100644 --- a/panda/src/text/textAssembler.cxx +++ b/panda/src/text/textAssembler.cxx @@ -42,7 +42,6 @@ using std::max; using std::min; -using std::move; using std::wstring; // This is the factor by which CT_small scales the character down. @@ -1197,7 +1196,7 @@ generate_quads(GeomNode *geom_node, const QuadMap &quad_map) { tex_ptr[1] = quad._uvs[1]; tex_ptr += stride; - glyphs.push_back(move(quad._glyph)); + glyphs.push_back(std::move(quad._glyph)); } } else { // 64-bit vertex case. @@ -1245,7 +1244,7 @@ generate_quads(GeomNode *geom_node, const QuadMap &quad_map) { tex_ptr[1] = quad._uvs[1]; tex_ptr += stride; - glyphs.push_back(move(quad._glyph)); + glyphs.push_back(std::move(quad._glyph)); } } } @@ -1751,7 +1750,7 @@ shape_buffer(hb_buffer_t *buf, PlacedGlyphs &placed_glyphs, PN_stdfloat &xpos, // it may involve multiple Geoms if we need to add cheesy accents or // ligatures. GlyphPlacement placement; - placement._glyph = move(glyph); + placement._glyph = std::move(glyph); placement._scale = glyph_scale; placement._xpos = xpos + x_offset; placement._ypos = properties.get_glyph_shift() + y_offset; @@ -1801,7 +1800,7 @@ draw_underscore(TextAssembler::PlacedGlyphs &placed_glyphs, // LVecBase4(0), RenderState::make_empty()); GlyphPlacement placement; - placement._glyph = move(glyph); + placement._glyph = std::move(glyph); placement._xpos = 0; placement._ypos = 0; placement._scale = 1; @@ -2458,7 +2457,7 @@ assign_quad_to(QuadMap &quad_map, const RenderState *state, quad._dimensions += LVecBase4(offset[0], -offset[1], offset[0], -offset[1]); quad._glyph = _glyph; - quad_map[state->compose(_glyph->get_state())].push_back(move(quad)); + quad_map[state->compose(_glyph->get_state())].push_back(std::move(quad)); } } From 52c7d6bddb9b8c24797bb61afd73305a14663b01 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 31 Jan 2023 17:37:18 +0100 Subject: [PATCH 4/7] shader: Add missing handling for 1D array textures in Cg shaders --- panda/src/gobj/shader.cxx | 32 ++++++++++++++++++++++---------- panda/src/gobj/shader.h | 1 + 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index c43ff22e5e..b7fee41221 100644 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -91,10 +91,11 @@ cp_report_error(ShaderArgInfo &p, const string &msg) { case SAT_sampler1d: tstr = "sampler1D "; break; case SAT_sampler2d: tstr = "sampler2D "; break; case SAT_sampler3d: tstr = "sampler3D "; break; - case SAT_sampler2d_array: tstr = "sampler2DArray "; break; + case SAT_sampler2d_array: tstr = "sampler2DARRAY "; break; case SAT_sampler_cube: tstr = "samplerCUBE "; break; case SAT_sampler_buffer: tstr = "samplerBUF "; break; case SAT_sampler_cube_array:tstr = "samplerCUBEARRAY "; break; + case SAT_sampler1d_array: tstr = "sampler1DARRAY "; break; default: tstr = "unknown "; break; } @@ -227,15 +228,15 @@ cp_errchk_parameter_ptr(ShaderArgInfo &p) { * message and return false. */ bool Shader:: -cp_errchk_parameter_sampler(ShaderArgInfo &p) -{ - if ((p._type!=SAT_sampler1d)&& - (p._type!=SAT_sampler2d)&& - (p._type!=SAT_sampler3d)&& - (p._type!=SAT_sampler2d_array)&& - (p._type!=SAT_sampler_cube)&& - (p._type!=SAT_sampler_buffer)&& - (p._type!=SAT_sampler_cube_array)) { +cp_errchk_parameter_sampler(ShaderArgInfo &p) { + if (p._type != SAT_sampler1d && + p._type != SAT_sampler2d && + p._type != SAT_sampler3d && + p._type != SAT_sampler2d_array && + p._type != SAT_sampler_cube && + p._type != SAT_sampler_buffer && + p._type != SAT_sampler_cube_array && + p._type != SAT_sampler1d_array) { cp_report_error(p, "parameter should have a 'sampler' type"); return false; } @@ -1372,6 +1373,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { case SAT_sampler_cube: bind._desired_type = Texture::TT_cube_map; break; case SAT_sampler_buffer: bind._desired_type = Texture::TT_buffer_texture; break; case SAT_sampler_cube_array:bind._desired_type = Texture::TT_cube_map_array; break; + case SAT_sampler1d_array:bind._desired_type = Texture::TT_1d_texture_array; break; default: cp_report_error(p, "Invalid type for a tex-parameter"); return false; @@ -1577,6 +1579,15 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { _tex_spec.push_back(bind); return true; } + case SAT_sampler1d_array: { + ShaderTexSpec bind; + bind._id = p._id; + bind._name = kinputname; + bind._part = STO_named_input; + bind._desired_type = Texture::TT_1d_texture_array; + _tex_spec.push_back(bind); + return true; + } default: cp_report_error(p, "invalid type for non-prefix parameter"); return false; @@ -1698,6 +1709,7 @@ cg_parameter_type(CGparameter p) { case CG_SAMPLERCUBE: return Shader::SAT_sampler_cube; case CG_SAMPLERBUF: return Shader::SAT_sampler_buffer; case CG_SAMPLERCUBEARRAY:return Shader::SAT_sampler_cube_array; + case CG_SAMPLER1DARRAY: return Shader::SAT_sampler1d_array; // CG_SAMPLER1DSHADOW and CG_SAMPLER2DSHADOW case 1313: return Shader::SAT_sampler1d; case 1314: return Shader::SAT_sampler2d; diff --git a/panda/src/gobj/shader.h b/panda/src/gobj/shader.h index ef7d6ceef4..ef3a24d559 100644 --- a/panda/src/gobj/shader.h +++ b/panda/src/gobj/shader.h @@ -280,6 +280,7 @@ public: SAT_sampler_cube, SAT_sampler_buffer, SAT_sampler_cube_array, + SAT_sampler1d_array, SAT_unknown }; From d69d393e4cae35190bef9e7278c144f83c944360 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 31 Jan 2023 17:38:02 +0100 Subject: [PATCH 5/7] glgsg: Set ultimate Cg profiles to gp5vp/gp5fp/gp5gp These support the most features, including cube map arrays (which aren't even supported in glslv/glslf) This improves the quality of error messages, eg. using cube map arrays will no longer display a cryptic error about no overload of texCUBEARRAY() being available --- panda/src/glstuff/glGraphicsStateGuardian_src.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 6e1d734bc4..fa6db72522 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -1820,9 +1820,9 @@ reset() { _shader_caps._active_gprofile = (int)CG_PROFILE_GLSLG; } } - _shader_caps._ultimate_vprofile = (int)CG_PROFILE_VP40; - _shader_caps._ultimate_fprofile = (int)CG_PROFILE_FP40; - _shader_caps._ultimate_gprofile = (int)CG_PROFILE_GPU_GP; + _shader_caps._ultimate_vprofile = (int)CG_PROFILE_GP5VP; + _shader_caps._ultimate_fprofile = (int)CG_PROFILE_GP5FP; + _shader_caps._ultimate_gprofile = (int)CG_PROFILE_GP5GP; // Bug workaround for radeons. if (_shader_caps._active_fprofile == CG_PROFILE_ARBFP1) { From a20996d2aa1ae9a3070bc7e85f8bddbddaecde06 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 31 Jan 2023 17:40:25 +0100 Subject: [PATCH 6/7] pgraphnodes: Support missing texture types in shader generator: - Cube arrays - 1D texture arrays - Buffer textures Not to say that they are displayed meaningfully, but better than a cryptic error message. --- panda/src/pgraphnodes/shaderGenerator.cxx | 55 +++++++++++++++-------- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/panda/src/pgraphnodes/shaderGenerator.cxx b/panda/src/pgraphnodes/shaderGenerator.cxx index ed13b05a34..4189367eee 100644 --- a/panda/src/pgraphnodes/shaderGenerator.cxx +++ b/panda/src/pgraphnodes/shaderGenerator.cxx @@ -1293,15 +1293,20 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { text << "\t float4 tex" << i << " = tex" << texture_type_as_string(tex._type); text << "(tex_" << i << ", texcoord" << i << "."; switch (tex._type) { + case Texture::TT_cube_map_array: + text << "xyzw"; + break; case Texture::TT_cube_map: case Texture::TT_3d_texture: case Texture::TT_2d_texture_array: text << "xyz"; break; case Texture::TT_2d_texture: + case Texture::TT_1d_texture_array: text << "xy"; break; case Texture::TT_1d_texture: + case Texture::TT_buffer_texture: text << "x"; break; default: @@ -1342,15 +1347,20 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { text << "\t float4 tex" << i << " = tex" << texture_type_as_string(tex._type); text << "(tex_" << i << ", texcoord" << i << "."; switch (tex._type) { + case Texture::TT_cube_map_array: + text << "xyzw"; + break; case Texture::TT_cube_map: case Texture::TT_3d_texture: case Texture::TT_2d_texture_array: text << "xyz"; break; case Texture::TT_2d_texture: + case Texture::TT_1d_texture_array: text << "xy"; break; case Texture::TT_1d_texture: + case Texture::TT_buffer_texture: text << "x"; break; default: @@ -1970,24 +1980,33 @@ combine_source_as_string(const ShaderKey::TextureInfo &info, short num, bool alp const char *ShaderGenerator:: texture_type_as_string(Texture::TextureType ttype) { switch (ttype) { - case Texture::TT_1d_texture: - return "1D"; - break; - case Texture::TT_2d_texture: - return "2D"; - break; - case Texture::TT_3d_texture: - return "3D"; - break; - case Texture::TT_cube_map: - return "CUBE"; - break; - case Texture::TT_2d_texture_array: - return "2DARRAY"; - break; - default: - pgraphnodes_cat.error() << "Unsupported texture type!\n"; - return "2D"; + case Texture::TT_1d_texture: + return "1D"; + + case Texture::TT_2d_texture: + return "2D"; + + case Texture::TT_3d_texture: + return "3D"; + + case Texture::TT_2d_texture_array: + return "2DARRAY"; + + case Texture::TT_cube_map: + return "CUBE"; + + case Texture::TT_buffer_texture: + return "BUF"; + + case Texture::TT_cube_map_array: + return "CUBEARRAY"; + + case Texture::TT_1d_texture_array: + return "1DARRAY"; + + default: + pgraphnodes_cat.error() << "Unsupported texture type!\n"; + return "2D"; } } From 718bac1c697c1657ca0100fd8c39aef4423009e5 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 3 Feb 2023 14:44:14 +0100 Subject: [PATCH 7/7] audiotraits: Fix crash when encountering corruption in OpenAL stream Partial backport of #1452 --- panda/src/audiotraits/openalAudioManager.cxx | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/panda/src/audiotraits/openalAudioManager.cxx b/panda/src/audiotraits/openalAudioManager.cxx index c3c64b1c57..59ce773cb1 100644 --- a/panda/src/audiotraits/openalAudioManager.cxx +++ b/panda/src/audiotraits/openalAudioManager.cxx @@ -968,23 +968,22 @@ update() { SoundsPlaying sounds_finished; double rtc = TrueClock::get_global_ptr()->get_short_time(); - SoundsPlaying::iterator i=_sounds_playing.begin(); - for (; i!=_sounds_playing.end(); ++i) { - OpenALAudioSound *sound = (*i); + SoundsPlaying::iterator it = _sounds_playing.begin(); + while (it != _sounds_playing.end()) { + PT(OpenALAudioSound) sound = *(it++); sound->pull_used_buffers(); sound->push_fresh_buffers(); sound->restart_stalled_audio(); sound->cache_time(rtc); - if ((sound->_source == 0)|| - ((sound->_stream_queued.size() == 0)&& + if (sound->_source == 0 || + (sound->_stream_queued.empty() && (sound->_loops_completed >= sound->_playing_loops))) { - sounds_finished.insert(*i); + sounds_finished.insert(std::move(sound)); } } - i=sounds_finished.begin(); - for (; i!=sounds_finished.end(); ++i) { - (**i).finished(); + for (OpenALAudioSound *sound : sounds_finished) { + sound->finished(); } }