Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 45faa08

Browse files
committed
VKPipeline: Log any errors produced by the SPIR-V optimizer
Some dEQP tests were not made for SPV_ENV_VULKAN_1_1, and error in the optimizer. This produces 0 words of SPIR-V, that then goes and explodes in SpirvShader. Add an assert to catch the 0-word case. Bug: b/127454276 Change-Id: I60576e6691a9cf74656dfcd9c53aeed7ab578de1 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/26188 Tested-by: Ben Clayton <bclayton@google.com> Reviewed-by: Nicolas Capens <nicolascapens@google.com>
1 parent 952d273 commit 45faa08

File tree

2 files changed

+53
-25
lines changed

2 files changed

+53
-25
lines changed

src/Pipeline/SpirvShader.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ namespace sw
2828
outputs{MAX_INTERFACE_COMPONENTS},
2929
serialID{serialCounter++}, modes{}
3030
{
31+
ASSERT(insns.size() > 0);
32+
3133
// Simplifying assumptions (to be satisfied by earlier transformations)
3234
// - There is exactly one entrypoint in the module, and it's the one we want
3335
// - The only input/output OpVariables present are those used by the entrypoint

src/Vulkan/VkPipeline.cpp

Lines changed: 51 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,57 @@ uint32_t getNumberOfChannels(VkFormat format)
187187
return 0;
188188
}
189189

190+
// preprocessSpirv applies and freezes specializations into constants, inlines
191+
// all functions and performs constant folding.
192+
std::vector<uint32_t> preprocessSpirv(
193+
std::vector<uint32_t> const &code,
194+
VkSpecializationInfo const *specializationInfo)
195+
{
196+
spvtools::Optimizer opt{SPV_ENV_VULKAN_1_1};
197+
198+
opt.SetMessageConsumer([](spv_message_level_t level, const char*, const spv_position_t& p, const char* m) {
199+
switch (level)
200+
{
201+
case SPV_MSG_FATAL:
202+
case SPV_MSG_INTERNAL_ERROR:
203+
case SPV_MSG_ERROR:
204+
ERR("%d:%d %s", p.line, p.column, m);
205+
break;
206+
case SPV_MSG_WARNING:
207+
case SPV_MSG_INFO:
208+
case SPV_MSG_DEBUG:
209+
TRACE("%d:%d %s", p.line, p.column, m);
210+
break;
211+
}
212+
});
213+
214+
opt.RegisterPass(spvtools::CreateInlineExhaustivePass());
215+
216+
// If the pipeline uses specialization, apply the specializations before freezing
217+
if (specializationInfo)
218+
{
219+
std::unordered_map<uint32_t, std::vector<uint32_t>> specializations;
220+
for (auto i = 0u; i < specializationInfo->mapEntryCount; ++i)
221+
{
222+
auto const &e = specializationInfo->pMapEntries[i];
223+
auto value_ptr =
224+
static_cast<uint32_t const *>(specializationInfo->pData) + e.offset / sizeof(uint32_t);
225+
specializations.emplace(e.constantID,
226+
std::vector<uint32_t>{value_ptr, value_ptr + e.size / sizeof(uint32_t)});
227+
}
228+
opt.RegisterPass(spvtools::CreateSetSpecConstantDefaultValuePass(specializations));
229+
}
230+
// Freeze specialization constants into normal constants, and propagate through
231+
opt.RegisterPass(spvtools::CreateFreezeSpecConstantValuePass());
232+
opt.RegisterPass(spvtools::CreateFoldSpecConstantOpAndCompositePass());
233+
234+
std::vector<uint32_t> optimized;
235+
opt.Run(code.data(), code.size(), &optimized);
236+
return optimized;
190237
}
191238

239+
} // anonymous namespace
240+
192241
namespace vk
193242
{
194243

@@ -418,33 +467,10 @@ void GraphicsPipeline::compileShaders(const VkAllocationCallbacks* pAllocator, c
418467
{
419468
auto module = Cast(pStage->module);
420469

421-
auto code = module->getCode();
422-
spvtools::Optimizer opt{SPV_ENV_VULKAN_1_1};
423-
opt.RegisterPass(spvtools::CreateInlineExhaustivePass());
424-
425-
// If the pipeline uses specialization, apply the specializations before freezing
426-
if (pStage->pSpecializationInfo)
427-
{
428-
std::unordered_map<uint32_t, std::vector<uint32_t>> specializations;
429-
for (auto i = 0u; i < pStage->pSpecializationInfo->mapEntryCount; ++i)
430-
{
431-
auto const &e = pStage->pSpecializationInfo->pMapEntries[i];
432-
auto value_ptr =
433-
static_cast<uint32_t const *>(pStage->pSpecializationInfo->pData) + e.offset / sizeof(uint32_t);
434-
specializations.emplace(e.constantID,
435-
std::vector<uint32_t>{value_ptr, value_ptr + e.size / sizeof(uint32_t)});
436-
}
437-
opt.RegisterPass(spvtools::CreateSetSpecConstantDefaultValuePass(specializations));
438-
}
439-
// Freeze specialization constants into normal constants, and propagate through
440-
opt.RegisterPass(spvtools::CreateFreezeSpecConstantValuePass());
441-
opt.RegisterPass(spvtools::CreateFoldSpecConstantOpAndCompositePass());
442-
443-
std::vector<uint32_t> postOptCode;
444-
opt.Run(code.data(), code.size(), &postOptCode);
470+
auto code = preprocessSpirv(module->getCode(), pStage->pSpecializationInfo);
445471

446472
// TODO: also pass in any pipeline state which will affect shader compilation
447-
auto spirvShader = new sw::SpirvShader{postOptCode};
473+
auto spirvShader = new sw::SpirvShader{code};
448474

449475
switch (pStage->stage)
450476
{

0 commit comments

Comments
 (0)