mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 06:08:30 +09:00
[Fix] (MG_Backend/DirectVulkan): a re-entrant cache lookup dangled the reference glShaderStorageBlockBinding then wrote through
This commit is contained in:
@@ -801,9 +801,18 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
// already recorded the new binding on the program - which is what reseeds this cache
|
// already recorded the new binding on the program - which is what reseeds this cache
|
||||||
// whenever it is rebuilt. Writing the entry here as well keeps an ALREADY-BUILT cache
|
// whenever it is rebuilt. Writing the entry here as well keeps an ALREADY-BUILT cache
|
||||||
// (the common case: the very next draw reads it) from having to be thrown away.
|
// (the common case: the very next draw reads it) from having to be thrown away.
|
||||||
auto& cache = GetProgramResourceCache(*programObject);
|
//
|
||||||
|
// Resolve the index BEFORE taking the reference, and bounds-check the way the
|
||||||
|
// sibling getter does. GetShaderStorageBlockIndex re-enters GetProgramResourceCache,
|
||||||
|
// which indexes g_programResourceCaches and can therefore insert - and that map is
|
||||||
|
// FastSTL's open-addressed unordered_map, whose rehash MOVES its buckets, so a
|
||||||
|
// reference taken before the call is left dangling. Binding a program's storage block
|
||||||
|
// while another program's entry was still absent from the cache was a reproducible
|
||||||
|
// segfault (ProgramPipelineScenario's two storage-block cases, in one process).
|
||||||
const GLuint blockIndex = GetShaderStorageBlockIndex(*programObject, storageBlockName);
|
const GLuint blockIndex = GetShaderStorageBlockIndex(*programObject, storageBlockName);
|
||||||
if (blockIndex == GL_INVALID_INDEX) return;
|
if (blockIndex == GL_INVALID_INDEX) return;
|
||||||
|
auto& cache = GetProgramResourceCache(*programObject);
|
||||||
|
if (blockIndex >= cache.storageBlocks.size()) return;
|
||||||
cache.storageBlocks[blockIndex].binding = storageBlockBinding;
|
cache.storageBlocks[blockIndex].binding = storageBlockBinding;
|
||||||
}
|
}
|
||||||
void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) {
|
void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) {
|
||||||
|
|||||||
Reference in New Issue
Block a user