diff --git a/drivers/vulkan/rendering_device_driver_vulkan.cpp b/drivers/vulkan/rendering_device_driver_vulkan.cpp index 0b6c16e901c..2ef691b1f19 100644 --- a/drivers/vulkan/rendering_device_driver_vulkan.cpp +++ b/drivers/vulkan/rendering_device_driver_vulkan.cpp @@ -3925,7 +3925,14 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_container(const Re if (use_respv) { const bool inline_data = store_respv || !RESPV_ONLY_INLINE_SHADERS_WITH_SPEC_CONSTANTS; respv::Shader respv_shader(decoded_spirv.ptr(), decoded_spirv.size(), inline_data); - if (store_respv) { + if (respv_shader.empty()) { +#if RESPV_VERBOSE + print_line("re-spirv failed to parse the shader, skipping optimization."); +#endif + if (store_respv) { + shader_info.respv_stage_shaders.push_back(respv::Shader()); + } + } else if (store_respv) { shader_info.respv_stage_shaders.push_back(respv_shader); } else { std::vector respv_optimized_data; diff --git a/thirdparty/README.md b/thirdparty/README.md index 4a76e1c22e4..527d625df61 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -926,7 +926,7 @@ Files extracted from upstream source: ## re-spirv - Upstream: https://github.com/renderbag/re-spirv -- Version: git (00ed4d2c25be0c5ea78523c795119d7570d6209e, 2025) +- Version: git (5af3b606e6aaf11bae8dc7b5cd236c943e24865e, 2025) - License: MIT Files extracted from upstream source: diff --git a/thirdparty/re-spirv/re-spirv.cpp b/thirdparty/re-spirv/re-spirv.cpp index b9884b67dc1..64c31decd95 100644 --- a/thirdparty/re-spirv/re-spirv.cpp +++ b/thirdparty/re-spirv/re-spirv.cpp @@ -91,8 +91,13 @@ namespace respv { case SpvOpImageRead: case SpvOpImageWrite: case SpvOpImage: + case SpvOpImageQueryFormat: + case SpvOpImageQueryOrder: case SpvOpImageQuerySizeLod: + case SpvOpImageQuerySize: + case SpvOpImageQueryLod: case SpvOpImageQueryLevels: + case SpvOpImageQuerySamples: case SpvOpConvertFToU: case SpvOpConvertFToS: case SpvOpConvertSToF: @@ -326,7 +331,11 @@ namespace respv { case SpvOpCopyObject: case SpvOpTranspose: case SpvOpImage: + case SpvOpImageQueryFormat: + case SpvOpImageQueryOrder: + case SpvOpImageQuerySize: case SpvOpImageQueryLevels: + case SpvOpImageQuerySamples: case SpvOpConvertFToU: case SpvOpConvertFToS: case SpvOpConvertSToF: @@ -362,6 +371,7 @@ namespace respv { case SpvOpCompositeInsert: case SpvOpSampledImage: case SpvOpImageQuerySizeLod: + case SpvOpImageQueryLod: case SpvOpIAdd: case SpvOpFAdd: case SpvOpISub: @@ -759,6 +769,7 @@ namespace respv { phis.clear(); loopHeaders.clear(); listNodes.clear(); + defaultSwitchOpConstantInt = UINT32_MAX; } constexpr uint32_t SpvStartWordIndex = 5; @@ -997,7 +1008,7 @@ namespace respv { break; case SpvOpDecorate: { uint32_t resultId = dataWords[parseWordIndex + 1]; - if (resultId > dataIdBound) { + if (resultId >= dataIdBound) { fprintf(stderr, "Found decoration with invalid result %u.\n", resultId); return false; } @@ -1012,7 +1023,7 @@ namespace respv { if (currentFunction.resultId != UINT32_MAX) { // Identify the variable as a local function variable. uint32_t resultId = dataWords[parseWordIndex + 2]; - if (resultId > dataIdBound) { + if (resultId >= dataIdBound) { fprintf(stderr, "Found variable with invalid result %u.\n", resultId); return false; } @@ -1633,7 +1644,13 @@ namespace respv { // Ignore load operations with memory operands. if (wordCount == 4) { uint32_t pointerId = dataWords[callStack.back().wordIndex + 3]; - if ((functionResultMap[pointerId].wordIndex != UINT32_MAX) && (storeMap[pointerId] < dataIdBound)) { + if (pointerId >= dataIdBound) { + fprintf(stderr, "Found load operation with invalid pointer %u.\n", pointerId); + return false; + } + + uint32_t pointerWordIndex = functionResultMap[pointerId].wordIndex; + if ((pointerWordIndex != UINT32_MAX) && (SpvOp(dataWords[pointerWordIndex] & 0xFFFFU) == SpvOpVariable) && (storeMap[pointerId] < dataIdBound)) { uint32_t resultId = dataWords[callStack.back().wordIndex + 2]; if (loadMap[resultId] != storeMap[pointerId]) { loadMap[resultId] = storeMap[pointerId]; @@ -1649,7 +1666,17 @@ namespace respv { // Ignore store operations with memory operands. if (wordCount == 3) { uint32_t pointerId = dataWords[callStack.back().wordIndex + 1]; + if (pointerId >= dataIdBound) { + fprintf(stderr, "Found store operation with invalid pointer %u.\n", pointerId); + return false; + } + uint32_t resultId = dataWords[callStack.back().wordIndex + 2]; + if (resultId >= dataIdBound) { + fprintf(stderr, "Found store operation with invalid result %u.\n", resultId); + return false; + } + if (storeMap[pointerId] != resultId) { storeMap[pointerId] = resultId; storeMapChanges.emplace_back(pointerId); @@ -2194,20 +2221,24 @@ namespace respv { extSpirvWordCount = pSize / sizeof(uint32_t); if (pInlineFunctions && !inlineData(pData, pSize)) { + clear(); return false; } const void *data = pInlineFunctions ? inlinedSpirvWords.data() : pData; const size_t size = pInlineFunctions ? (inlinedSpirvWords.size() * sizeof(uint32_t)) : pSize; if (!parseData(data, size)) { + clear(); return false; } if (!process(data, size)) { + clear(); return false; } if (!sort(data, size)) { + clear(); return false; } @@ -2215,7 +2246,7 @@ namespace respv { } bool Shader::empty() const { - return false; + return inlinedSpirvWords.empty() && ((extSpirvWords == nullptr) || (extSpirvWordCount == 0)); } // Optimizer