1818#include " llvm/ADT/SmallVector.h"
1919#include " llvm/ADT/StringRef.h"
2020#include " llvm/BinaryFormat/DXContainer.h"
21+ #include " llvm/Object/Error.h"
2122#include " llvm/Support/Error.h"
2223#include " llvm/Support/MemoryBufferRef.h"
2324#include " llvm/TargetParser/Triple.h"
@@ -122,7 +123,107 @@ struct RootParameter {
122123 union {
123124 dxbc::RootConstants Constants;
124125 };
126+
127+ RootParameter () = default ;
128+ };
129+
130+ struct ViewRootParameter {
131+ ViewArray<dxbc::RootParameterHeader> HeaderView;
132+ StringRef Data;
133+
134+ ViewRootParameter () = default ;
135+ ViewRootParameter (ViewArray<dxbc::RootParameterHeader> HV, StringRef D)
136+ : HeaderView(HV), Data(D) {}
137+
138+ using value_type = DirectX::RootParameter;
139+ struct iterator {
140+ const ViewArray<dxbc::RootParameterHeader> HeaderView;
141+ ViewArray<dxbc::RootParameterHeader>::iterator Current;
142+ StringRef Data;
143+
144+ iterator (const ViewRootParameter &VRP,
145+ ViewArray<dxbc::RootParameterHeader>::iterator C)
146+ : HeaderView(VRP.HeaderView), Current(C), Data(VRP.Data) {}
147+ iterator (const iterator &) = default ;
148+
149+ template <typename T>
150+ static Error readParameter (StringRef Buffer, const char *Src, T &Struct) {
151+ // Don't read before the beginning or past the end of the file
152+ if (Src < Buffer.begin () || Src + sizeof (T) > Buffer.end ())
153+ return make_error<GenericBinaryError>(
154+ " Reading structure out of file bounds" , object_error::parse_failed);
155+
156+ memcpy (&Struct, Src, sizeof (T));
157+ // DXContainer is always little endian
158+ if (sys::IsBigEndianHost)
159+ Struct.swapBytes ();
160+ return Error::success ();
161+ }
162+
163+ static Error validationFailed (const Twine &Msg) {
164+ return make_error<StringError>(Msg.str (), inconvertibleErrorCode ());
165+ }
166+
167+ llvm::Expected<value_type> operator *() {
168+ value_type Parameter;
169+ std::memset (&Parameter.Header , 0 , sizeof (dxbc::RootParameterHeader));
170+ memcpy (&Parameter.Header , Current.Current ,
171+ sizeof (dxbc::RootParameterHeader));
172+
173+ switch (Parameter.Header .ParameterType ) {
174+ case dxbc::RootParameterType::Constants32Bit:
175+ std::memset (&Parameter.Constants , 0 , sizeof (dxbc::RootConstants));
176+ if (Error Err = readParameter (
177+ Data, Data.begin () + Parameter.Header .ParameterOffset ,
178+ Parameter.Constants ))
179+ return Err;
180+ break ;
181+ case dxbc::RootParameterType::Empty:
182+ break ;
183+ }
184+
185+ return Parameter;
186+ }
187+
188+ iterator operator ++() {
189+ if (Current != HeaderView.end ())
190+ Current++;
191+ return *this ;
192+ }
193+
194+ iterator operator ++(int I) {
195+ iterator Tmp = *this ;
196+ for (; I > 0 ; I--)
197+ ++Tmp;
198+ return Tmp;
199+ }
200+
201+ iterator operator --() {
202+ if (Current != HeaderView.begin ())
203+ Current--;
204+ return *this ;
205+ }
206+
207+ iterator operator --(int I) {
208+ iterator Tmp = *this ;
209+ for (; I > 0 ; I--)
210+ --Tmp;
211+ return Tmp;
212+ }
213+
214+ bool operator ==(iterator I) { return I.Current == Current; }
215+ bool operator !=(const iterator I) { return !(*this == I); }
216+ };
217+
218+ iterator begin () const { return iterator (*this , this ->HeaderView .begin ()); }
219+
220+ iterator end () const { return iterator (*this , this ->HeaderView .end ()); }
221+
222+ size_t size () const { return HeaderView.size (); }
223+
224+ bool isEmpty () const { return HeaderView.isEmpty (); }
125225};
226+
126227class RootSignature {
127228private:
128229 uint32_t Version = 2 ;
@@ -132,9 +233,9 @@ class RootSignature {
132233 uint32_t StaticSamplersOffset = 0 ;
133234 uint32_t Flags = 0 ;
134235
135- SmallVector<DirectX::RootParameter> Parameters;
236+ ViewRootParameter Parameters;
136237
137- using param_iterator = SmallVector<DirectX::RootParameter> ::iterator;
238+ using param_iterator = ViewRootParameter ::iterator;
138239
139240public:
140241 RootSignature () {}
@@ -145,7 +246,7 @@ class RootSignature {
145246 uint32_t getRootParametersOffset () const { return RootParametersOffset; }
146247 uint32_t getNumStaticSamplers () const { return NumStaticSamplers; }
147248 uint32_t getStaticSamplersOffset () const { return StaticSamplersOffset; }
148- llvm::iterator_range<const RootParameter * > params () const {
249+ llvm::iterator_range<param_iterator > params () const {
149250 return llvm::make_range (Parameters.begin (), Parameters.end ());
150251 }
151252 param_iterator param_begin () { return Parameters.begin (); }
0 commit comments