mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +09:00
[Perf] (DirectGLES, ShaderTranspiler): fold the image-widening gate into the shared SPIR-V probe
This commit is contained in:
@@ -728,6 +728,8 @@ namespace MobileGL {
|
||||
LowerViewportIndexPass::DeclaresViewportIndexBuiltin(context.get());
|
||||
features.DeclaresMultisampledImage =
|
||||
ClampMultisampleFetchPass::DeclaresMultisampledImage(context.get());
|
||||
features.DeclaresWidenableImageFormat =
|
||||
WidenImageFormatsPass::DeclaresWidenableImageFormat(context.get());
|
||||
return features;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@ namespace MobileGL {
|
||||
struct SpirvGateFeatures {
|
||||
Bool WritesViewportIndexOutput = false;
|
||||
Bool DeclaresMultisampledImage = false;
|
||||
Bool DeclaresWidenableImageFormat = false;
|
||||
};
|
||||
static SpirvGateFeatures ProbeSpirvGateFeatures(const Vector<Uint32>& binary);
|
||||
// Replaces an ARRAY vertex input with one input per element at consecutive
|
||||
@@ -244,8 +245,10 @@ namespace MobileGL {
|
||||
Vector<uint32_t>& outputBinary,
|
||||
bool enableSpirvValidation = false);
|
||||
// Whether the module declares a storage image WidenImageFormatsForEssl would
|
||||
// widen. One module parse, so the ~every shader that declares none pays no
|
||||
// optimizer run.
|
||||
// widen, so the ~every shader that declares none pays no optimizer run. Costs its
|
||||
// own module parse: the transpile path asks the same question through
|
||||
// ProbeSpirvGateFeatures instead, because this gate is armed on every real driver
|
||||
// and would otherwise put a BuildModule on every stage of every program.
|
||||
static bool DeclaresWidenableImageFormat(const Vector<Uint32>& binary);
|
||||
// The core-ESSL GL internal format that carries `glInternalFormat` exactly, or 0
|
||||
// when it needs no widening or cannot be widened exactly. The single source of
|
||||
|
||||
@@ -231,11 +231,8 @@ namespace MobileGL {
|
||||
return ChannelsOfSpirvImageFormat(SpirvImageFormatOfGL(glInternalFormat));
|
||||
}
|
||||
|
||||
bool WidenImageFormatsPass::DeclaresWidenableImageFormat(const Vector<Uint32>& binary) {
|
||||
std::unique_ptr<IRContext> context = spvtools::BuildModule(
|
||||
SPV_ENV_VULKAN_1_1, [](spv_message_level_t, const char*, const spv_position_t&, const char*) {},
|
||||
binary.data(), binary.size());
|
||||
if (!context) {
|
||||
bool WidenImageFormatsPass::DeclaresWidenableImageFormat(IRContext* context) {
|
||||
if (context == nullptr) {
|
||||
return false;
|
||||
}
|
||||
for (const Instruction& type : context->module()->types_values()) {
|
||||
@@ -246,6 +243,13 @@ namespace MobileGL {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WidenImageFormatsPass::DeclaresWidenableImageFormat(const Vector<Uint32>& binary) {
|
||||
std::unique_ptr<IRContext> context = spvtools::BuildModule(
|
||||
SPV_ENV_VULKAN_1_1, [](spv_message_level_t, const char*, const spv_position_t&, const char*) {},
|
||||
binary.data(), binary.size());
|
||||
return DeclaresWidenableImageFormat(context.get());
|
||||
}
|
||||
|
||||
spvtools::opt::Pass::Status WidenImageFormatsPass::Process() {
|
||||
auto* irContext = context();
|
||||
auto* defUseMgr = irContext->get_def_use_mgr();
|
||||
@@ -519,8 +523,11 @@ namespace MobileGL {
|
||||
for (Instruction* type : imageTypes) {
|
||||
const auto widenedIt = widenedByTypeId.find(type->result_id());
|
||||
if (widenedIt == widenedByTypeId.end()) continue;
|
||||
// No def-use re-analysis: the Image Format operand is a LITERAL, so no use of
|
||||
// any id moves, and the masks above already left the manager describing a
|
||||
// module that has since grown instructions it was never told about. Every
|
||||
// analysis is dropped below instead.
|
||||
type->SetInOperand(kImageFormatOperand, {static_cast<uint32_t>(widenedIt->second.Carrier)});
|
||||
defUseMgr->AnalyzeInstUse(type);
|
||||
}
|
||||
|
||||
// StorageImageExtendedFormats is deliberately left declared even though every
|
||||
|
||||
@@ -82,6 +82,11 @@ namespace MobileGL {
|
||||
// the caller can skip the optimizer run entirely - which is every shader but a
|
||||
// handful.
|
||||
static bool DeclaresWidenableImageFormat(const Vector<Uint32>& binary);
|
||||
// The same question asked of a module the caller has ALREADY parsed, so a stage
|
||||
// that has to answer several gate questions pays one BuildModule rather than one
|
||||
// per gate - see ShaderCompiler::ProbeSpirvGateFeatures, and the ~10% it cost
|
||||
// compile-heavy CTS cases when two gates each parsed for themselves.
|
||||
static bool DeclaresWidenableImageFormat(spvtools::opt::IRContext* context);
|
||||
|
||||
// The core-ESSL GL internal format that carries `glInternalFormat` exactly, or 0
|
||||
// when the format needs no widening (it is core already) or cannot be widened
|
||||
|
||||
Reference in New Issue
Block a user