Hash :
8e9dc1a6
Author :
Date :
2024-11-19T11:08:31
Validate anonymous struct names with namespace
Consider GLSL:
struct { vec4 e; } g;
struct sbbf { vec4 f; };
The struct name validation would fail if user chosen struct name would
clash with a symbol name that ANGLE internally gave to an anonymous
struct.
Fix by importing Name abstraction from MSL backend. A symbol name is
a pair (namespace, string).
Move operator<<(std::ostream &os, const ImmutableString &str)
to sh namespace because that is more natural for operator overloading
name resolution. MSVC works with this.
Bug: angleproject:379758201
Change-Id: Icc9b02aa8cb532e1d925e2fba4c45468f01b9144
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/6035029
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Auto-Submit: Kimmo Kinnunen <kkinnunen@apple.com>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Commit-Queue: Kimmo Kinnunen <kkinnunen@apple.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#ifndef COMPILER_TRANSLATOR_MSL_PIPELINE_H_
#define COMPILER_TRANSLATOR_MSL_PIPELINE_H_
#include "compiler/translator/Name.h"
#include "compiler/translator/Symbol.h"
#include "compiler/translator/msl/ModifyStruct.h"
#include "compiler/translator/msl/SymbolEnv.h"
namespace sh
{
// Data that is scoped as `external` and `internal` for a given pipeline.
template <typename T>
struct PipelineScoped
{
// Data that is configured to talk externally to the program.
// May coincide with `internal`, but may also diverge from `internal`.
const T *external = nullptr;
// Extra data that is configured to talk externally to the program.
// Used for framebuffer fetch and for adjusting Metal's InstanceId.
const T *externalExtra = nullptr;
// Data that is configured to talk internally within the program.
// May coincide with `external`, but may also diverge from `external`.
const T *internal = nullptr;
// Returns true iff the input coincides with either `external` or `internal` data.
bool matches(const T &object) const { return external == &object || internal == &object; }
// Both `external` and `internal` representations are non-null.
bool isTotallyFull() const { return external && internal; }
// Both `external` and `internal` representations are null.
bool isTotallyEmpty() const { return !external && !internal; }
// Both `external` and `internal` representations are the same.
bool isUniform() const { return external == internal; }
};
// Represents a high-level program pipeline.
class Pipeline
{
public:
enum class Type
{
VertexIn,
VertexOut,
FragmentIn,
FragmentOut,
UserUniforms,
AngleUniforms,
NonConstantGlobals,
InvocationVertexGlobals,
InvocationFragmentGlobals,
UniformBuffer,
Texture,
Image,
InstanceId,
};
enum class Variant
{
// For all internal pipeline uses.
// For external pipeline uses if pipeline does not require splitting or saturation.
Original,
// Only for external pipeline uses if the pipeline was split or saturated.
Modified,
};
public:
// The type of the pipeline.
Type type;
// Non-null if a global instance of the pipeline struct already exists.
// If non-null struct splitting should not be needed.
const TVariable *globalInstanceVar;
public:
// Returns true iff the variable belongs to the pipeline.
bool uses(const TVariable &var) const;
// Returns the name for the struct type that stores variables of this pipeline.
Name getStructTypeName(Variant variant) const;
// Returns the name for the struct instance that stores variables of this pipeline.
Name getStructInstanceName(Variant variant) const;
ModifyStructConfig externalStructModifyConfig() const;
// Returns true if the pipeline always requires a non-parameter local instance declaration of
// the pipeline structures.
bool alwaysRequiresLocalVariableDeclarationInMain() const;
// Returns true iff the pipeline is an output pipeline. The external pipeline structure should
// be returned from `main`.
bool isPipelineOut() const;
AddressSpace externalAddressSpace() const;
};
// A collection of various pipeline structures.
struct PipelineStructs : angle::NonCopyable
{
PipelineScoped<TStructure> fragmentIn;
PipelineScoped<TStructure> fragmentOut;
PipelineScoped<TStructure> vertexIn;
PipelineScoped<TStructure> vertexOut;
PipelineScoped<TStructure> userUniforms;
PipelineScoped<TStructure> angleUniforms;
PipelineScoped<TStructure> nonConstantGlobals;
PipelineScoped<TStructure> invocationVertexGlobals;
PipelineScoped<TStructure> invocationFragmentGlobals;
PipelineScoped<TStructure> uniformBuffers;
PipelineScoped<TStructure> texture;
PipelineScoped<TStructure> image;
PipelineScoped<TStructure> instanceId;
bool matches(const TStructure &s, bool internal, bool external) const;
};
} // namespace sh
#endif // COMPILER_TRANSLATOR_MSL_PIPELINE_H_