Welcome to mirror list, hosted at ThFree Co, Russian Federation.

convert_to_sampled_image_pass.h « opt « source - github.com/KhronosGroup/SPIRV-Tools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: a8b1501e6fe8f2e219ce0fcb69a797174430b177 (plain)
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
// Copyright (c) 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef SOURCE_OPT_CONVERT_TO_SAMPLED_IMAGE_PASS_H_
#define SOURCE_OPT_CONVERT_TO_SAMPLED_IMAGE_PASS_H_

#include <memory>
#include <unordered_set>
#include <utility>

#include "source/opt/pass.h"
#include "source/opt/types.h"

namespace spvtools {
namespace opt {

// A struct for a pair of descriptor set and binding.
struct DescriptorSetAndBinding {
  uint32_t descriptor_set;
  uint32_t binding;

  bool operator==(const DescriptorSetAndBinding& descriptor_set_binding) const {
    return descriptor_set_binding.descriptor_set == descriptor_set &&
           descriptor_set_binding.binding == binding;
  }
};

// See optimizer.hpp for documentation.
class ConvertToSampledImagePass : public Pass {
 public:
  // Hashing functor for the pair of descriptor set and binding.
  struct DescriptorSetAndBindingHash {
    size_t operator()(
        const DescriptorSetAndBinding& descriptor_set_binding) const {
      return std::hash<uint32_t>()(descriptor_set_binding.descriptor_set) ^
             std::hash<uint32_t>()(descriptor_set_binding.binding);
    }
  };

  using SetOfDescriptorSetAndBindingPairs =
      std::unordered_set<DescriptorSetAndBinding, DescriptorSetAndBindingHash>;
  using DescriptorSetBindingToInstruction =
      std::unordered_map<DescriptorSetAndBinding, Instruction*,
                         DescriptorSetAndBindingHash>;

  explicit ConvertToSampledImagePass(
      const std::vector<DescriptorSetAndBinding>& descriptor_set_binding_pairs)
      : descriptor_set_binding_pairs_(descriptor_set_binding_pairs.begin(),
                                      descriptor_set_binding_pairs.end()) {}

  const char* name() const override { return "convert-to-sampled-image"; }
  Status Process() override;

  // Parses the given null-terminated C string to get a vector of descriptor set
  // and binding pairs. Returns a unique pointer to the vector of descriptor set
  // and binding pairs built from the given |str| on success. Returns a nullptr
  // if the given string is not valid for building the vector of pairs.
  // A valid string for building the vector of pairs should follow the rule
  // below:
  //
  //  "<descriptor set>:<binding> <descriptor set>:<binding> ..."
  //  Example:
  //    "3:5 2:1 0:4"
  //
  //  Entries are separated with blank spaces (i.e.:' ', '\n', '\r', '\t',
  //  '\f', '\v'). Each entry corresponds to a descriptor set and binding pair.
  //  Multiple spaces between, before or after entries are allowed. However,
  //  spaces are not allowed within a descriptor set or binding.
  //
  //  In each entry, the descriptor set and binding are separated by ':'.
  //  Missing ':' in any entry is invalid. And it is invalid to have blank
  //  spaces in between the descriptor set and ':' or ':' and the binding.
  //
  //  <descriptor set>: the descriptor set.
  //    The text must represent a valid uint32_t number.
  //
  //  <binding>: the binding.
  //    The text must represent a valid uint32_t number.
  static std::unique_ptr<std::vector<DescriptorSetAndBinding>>
  ParseDescriptorSetBindingPairsString(const char* str);

 private:
  // Collects resources to convert to sampled image and saves them in
  // |descriptor_set_binding_pair_to_sampler| if the resource is a sampler and
  // saves them in |descriptor_set_binding_pair_to_image| if the resource is an
  // image. Returns false if two samplers or two images have the same descriptor
  // set and binding. Otherwise, returns true.
  bool CollectResourcesToConvert(
      DescriptorSetBindingToInstruction* descriptor_set_binding_pair_to_sampler,
      DescriptorSetBindingToInstruction* descriptor_set_binding_pair_to_image)
      const;

  // Finds an OpDecorate with DescriptorSet decorating |inst| and another
  // OpDecorate with Binding decorating |inst|. Stores the descriptor set and
  // binding in |descriptor_set_binding|. Returns whether it successfully finds
  // the descriptor set and binding or not.
  bool GetDescriptorSetBinding(
      const Instruction& inst,
      DescriptorSetAndBinding* descriptor_set_binding) const;

  // Returns whether |descriptor_set_binding| is a pair of a descriptor set
  // and a binding that we have to convert resources with it to a sampled image
  // or not.
  bool ShouldResourceBeConverted(
      const DescriptorSetAndBinding& descriptor_set_binding) const;

  // Returns the pointee type of the type of variable |variable|. If |variable|
  // is not an OpVariable instruction, just returns nullptr.
  const analysis::Type* GetVariableType(const Instruction& variable) const;

  // Returns the storage class of |variable|.
  spv::StorageClass GetStorageClass(const Instruction& variable) const;

  // Finds |inst|'s users whose opcode is |user_opcode| or users of OpCopyObject
  // instructions of |inst| whose opcode is |user_opcode| and puts them in
  // |uses|.
  void FindUses(const Instruction* inst, std::vector<Instruction*>* uses,
                spv::Op user_opcode) const;

  // Finds OpImage* instructions using |image| or OpCopyObject instructions that
  // copy |image| and puts them in |uses|.
  void FindUsesOfImage(const Instruction* image,
                       std::vector<Instruction*>* uses) const;

  // Creates an OpImage instruction that extracts the image from the sampled
  // image |sampled_image|.
  Instruction* CreateImageExtraction(Instruction* sampled_image);

  // Converts |image_variable| whose type is an image pointer to sampled image
  // type. Updates users of |image_variable| accordingly. If some instructions
  // e.g., OpImageRead use |image_variable| as an Image operand, creates an
  // image extracted from the sampled image using OpImage and replace the Image
  // operands of the users with the extracted image. If some OpSampledImage
  // instructions use |image_variable| and sampler whose descriptor set and
  // binding are the same with |image_variable|, just combines |image_variable|
  // and the sampler to a sampled image.
  Pass::Status UpdateImageVariableToSampledImage(
      Instruction* image_variable,
      const DescriptorSetAndBinding& descriptor_set_binding);

  // Returns the id of type sampled image type whose image type is the one of
  // |image_variable|.
  uint32_t GetSampledImageTypeForImage(Instruction* image_variable);

  // Moves |inst| next to the OpType* instruction with |type_id|.
  void MoveInstructionNextToType(Instruction* inst, uint32_t type_id);

  // Converts |image_variable| whose type is an image pointer to sampled image
  // with the type id |sampled_image_type_id|. Returns whether it successfully
  // converts the type of |image_variable| or not.
  bool ConvertImageVariableToSampledImage(Instruction* image_variable,
                                          uint32_t sampled_image_type_id);

  // Replaces |sampled_image_load| instruction used by OpImage* with the image
  // extracted from |sampled_image_load|. Returns the extracted image or nullptr
  // if it does not have uses.
  Instruction* UpdateImageUses(Instruction* sampled_image_load);

  // Returns true if the sampler of |sampled_image_inst| is decorated by a
  // descriptor set and a binding |descriptor_set_binding|.
  bool IsSamplerOfSampledImageDecoratedByDescriptorSetBinding(
      Instruction* sampled_image_inst,
      const DescriptorSetAndBinding& descriptor_set_binding);

  // Replaces OpSampledImage instructions using |image_load| with |image_load|
  // if the sampler of the OpSampledImage instruction has descriptor set and
  // binding |image_descriptor_set_binding|. Otherwise, replaces |image_load|
  // with |image_extraction|.
  void UpdateSampledImageUses(
      Instruction* image_load, Instruction* image_extraction,
      const DescriptorSetAndBinding& image_descriptor_set_binding);

  // Checks the uses of |sampler_variable|. When a sampler is used by
  // OpSampledImage instruction, the corresponding image must be
  // |image_to_be_combined_with| that should be already converted to a sampled
  // image by UpdateImageVariableToSampledImage() method.
  Pass::Status CheckUsesOfSamplerVariable(
      const Instruction* sampler_variable,
      Instruction* image_to_be_combined_with);

  // Returns true if Image operand of |sampled_image_inst| is the image of
  // |image_variable|.
  bool DoesSampledImageReferenceImage(Instruction* sampled_image_inst,
                                      Instruction* image_variable);

  // A set of pairs of descriptor set and binding. If an image and/or a sampler
  // have a pair of descriptor set and binding that is an element of
  // |descriptor_set_binding_pairs_|, they/it will be converted to a sampled
  // image by this pass.
  const SetOfDescriptorSetAndBindingPairs descriptor_set_binding_pairs_;
};

}  // namespace opt
}  // namespace spvtools

#endif  // SOURCE_OPT_CONVERT_TO_SAMPLED_IMAGE_PASS_H_