diff --git a/src/reader/spirv/parser_impl.h b/src/reader/spirv/parser_impl.h index 253b202f40..1a18a0c833 100644 --- a/src/reader/spirv/parser_impl.h +++ b/src/reader/spirv/parser_impl.h @@ -549,7 +549,7 @@ class ParserImpl : Reader { return function_to_ep_info_[entry_point]; } - /// Returns the SPIR-V binary. + /// @returns the SPIR-V binary. const std::vector& spv_binary() { return spv_binary_; } private: diff --git a/src/reader/spirv/parser_impl_test_helper.h b/src/reader/spirv/parser_impl_test_helper.h index 0205cca3a1..1794f7fd96 100644 --- a/src/reader/spirv/parser_impl_test_helper.h +++ b/src/reader/spirv/parser_impl_test_helper.h @@ -36,96 +36,229 @@ namespace reader { namespace spirv { namespace test { -// A test class that wraps ParseImpl +/// A test class that wraps ParseImpl class ParserImplWrapperForTest { public: - // Constructor + /// Constructor + /// @param input the input data to parse explicit ParserImplWrapperForTest(const std::vector& input); - // Dumps SPIR-V if the conversion succeeded, then destroys the wrapper. + /// Dumps SPIR-V if the conversion succeeded, then destroys the wrapper. ~ParserImplWrapperForTest(); - // Sets global state to force dumping of the assembly text of succesfully - // SPIR-V. + /// Sets global state to force dumping of the assembly text of succesfully + /// SPIR-V. static void DumpSuccessfullyConvertedSpirv() { dump_successfully_converted_spirv_ = true; } + /// Marks the test has having deliberately invalid SPIR-V void DeliberatelyInvalidSpirv() { deliberately_invalid_spirv_ = true; } - // Returns a new function emitter for the given function ID. - // Assumes ParserImpl::BuildInternalRepresentation has been run and - // succeeded. + /// @returns a new function emitter for the given function ID. + /// Assumes ParserImpl::BuildInternalRepresentation has been run and + /// succeeded. + /// @param function_id the SPIR-V identifier of the function FunctionEmitter function_emitter(uint32_t function_id) { auto* spirv_function = impl_.ir_context()->GetFunction(function_id); return FunctionEmitter(&impl_, *spirv_function); } - // Forward methods used by tests to the real implementation. + /// Run the parser + /// @returns true if the parse was successful, false otherwise. bool Parse() { return impl_.Parse(); } + + /// @returns the program. The program builder in the parser will be reset + /// after this. Program program() { return impl_.program(); } + + /// @returns the namer object Namer& namer() { return impl_.namer(); } + + /// @returns a reference to the internal builder, without building the + /// program. To be used only for testing. ProgramBuilder& builder() { return impl_.builder(); } + + /// @returns the accumulated error string const std::string error() { return impl_.error(); } + + /// @return true if failure has not yet occurred bool success() { return impl_.success(); } + + /// Logs failure, ands return a failure stream to accumulate diagnostic + /// messages. By convention, a failure should only be logged along with + /// a non-empty string diagnostic. + /// @returns the failure stream FailStream& Fail() { return impl_.Fail(); } + + /// @returns a borrowed pointer to the internal representation of the module. + /// This is null until BuildInternalModule has been called. spvtools::opt::IRContext* ir_context() { return impl_.ir_context(); } + /// Builds the internal representation of the SPIR-V module. + /// Assumes the module is somewhat well-formed. Normally you + /// would want to validate the SPIR-V module before attempting + /// to build this internal representation. Also computes a topological + /// ordering of the functions. + /// This is a no-op if the parser has already failed. + /// @returns true if the parser is still successful. bool BuildInternalModule() { return impl_.BuildInternalModule(); } + + /// Builds an internal representation of the SPIR-V binary, + /// and parses the module, except functions, into a Tint AST module. + /// Diagnostics are emitted to the error stream. + /// @returns true if it was successful. bool BuildAndParseInternalModuleExceptFunctions() { return impl_.BuildAndParseInternalModuleExceptFunctions(); } + + /// Builds an internal representation of the SPIR-V binary, + /// and parses it into a Tint AST module. Diagnostics are emitted + /// to the error stream. + /// @returns true if it was successful. bool BuildAndParseInternalModule() { return impl_.BuildAndParseInternalModule(); } + + /// Registers user names for SPIR-V objects, from OpName, and OpMemberName. + /// Also synthesizes struct field names. Ensures uniqueness for names for + /// SPIR-V IDs, and uniqueness of names of fields within any single struct. + /// This is a no-op if the parser has already failed. + /// @returns true if parser is still successful. bool RegisterUserAndStructMemberNames() { return impl_.RegisterUserAndStructMemberNames(); } + + /// Register Tint AST types for SPIR-V types, including type aliases as + /// needed. This is a no-op if the parser has already failed. + /// @returns true if parser is still successful. bool RegisterTypes() { return impl_.RegisterTypes(); } + + /// Register sampler and texture usage for memory object declarations. + /// This must be called after we've registered line numbers for all + /// instructions. This is a no-op if the parser has already failed. + /// @returns true if parser is still successful. bool RegisterHandleUsage() { return impl_.RegisterHandleUsage(); } + + /// Emits module-scope variables. + /// This is a no-op if the parser has already failed. + /// @returns true if parser is still successful. bool EmitModuleScopeVariables() { return impl_.EmitModuleScopeVariables(); } + /// @returns the set of SPIR-V IDs for imports of the "GLSL.std.450" + /// extended instruction set. const std::unordered_set& glsl_std_450_imports() const { return impl_.glsl_std_450_imports(); } + /// Converts a SPIR-V type to a Tint type, and saves it for fast lookup. + /// If the type is only used for builtins, then register that specially, + /// and return null. If the type is a sampler, image, or sampled image, then + /// return the Void type, because those opaque types are handled in a + /// different way. + /// On failure, logs an error and returns null. This should only be called + /// after the internal representation of the module has been built. + /// @param id the SPIR-V ID of a type. + /// @returns a Tint type, or nullptr typ::Type ConvertType(uint32_t id) { return impl_.ConvertType(id); } + + /// Gets the list of decorations for a SPIR-V result ID. Returns an empty + /// vector if the ID is not a result ID, or if no decorations target that ID. + /// The internal representation must have already been built. + /// @param id SPIR-V ID + /// @returns the list of decorations on the given ID DecorationList GetDecorationsFor(uint32_t id) const { return impl_.GetDecorationsFor(id); } + + /// Gets the list of decorations for the member of a struct. Returns an empty + /// list if the `id` is not the ID of a struct, or if the member index is out + /// of range, or if the target member has no decorations. + /// The internal representation must have already been built. + /// @param id SPIR-V ID of a struct + /// @param member_index the member within the struct + /// @returns the list of decorations on the member DecorationList GetDecorationsForMember(uint32_t id, uint32_t member_index) const { return impl_.GetDecorationsForMember(id, member_index); } + + /// Converts a SPIR-V struct member decoration. If the decoration is + /// recognized but deliberately dropped, then returns nullptr without a + /// diagnostic. On failure, emits a diagnostic and returns nullptr. + /// @param struct_type_id the ID of the struct type + /// @param member_index the index of the member + /// @param decoration an encoded SPIR-V Decoration + /// @returns the corresponding ast::StructuMemberDecoration ast::Decoration* ConvertMemberDecoration(uint32_t struct_type_id, uint32_t member_index, const Decoration& decoration) { return impl_.ConvertMemberDecoration(struct_type_id, member_index, decoration); } + + /// For a SPIR-V ID that might define a sampler, image, or sampled image + /// value, return the SPIR-V instruction that represents the memory object + /// declaration for the object. If we encounter an OpSampledImage along the + /// way, follow the image operand when follow_image is true; otherwise follow + /// the sampler operand. Returns nullptr if we can't trace back to a memory + /// object declaration. Emits an error and returns nullptr when the scan + /// fails due to a malformed module. This method can be used any time after + /// BuildInternalModule has been invoked. + /// @param id the SPIR-V ID of the sampler, image, or sampled image + /// @param follow_image indicates whether to follow the image operand of + /// OpSampledImage + /// @returns the memory object declaration for the handle, or nullptr const spvtools::opt::Instruction* GetMemoryObjectDeclarationForHandle( uint32_t id, bool follow_image) { return impl_.GetMemoryObjectDeclarationForHandle(id, follow_image); } + + /// @param entry_point the SPIR-V ID of an entry point. + /// @returns the entry point info for the given ID const std::vector& GetEntryPointInfo(uint32_t entry_point) { return impl_.GetEntryPointInfo(entry_point); } + + /// Returns the handle usage for a memory object declaration. + /// @param id SPIR-V ID of a sampler or image OpVariable or + /// OpFunctionParameter + /// @returns the handle usage, or an empty usage object. Usage GetHandleUsage(uint32_t id) const { return impl_.GetHandleUsage(id); } + + /// Returns the SPIR-V instruction with the given ID, or nullptr. + /// @param id the SPIR-V result ID + /// @returns the instruction, or nullptr on error const spvtools::opt::Instruction* GetInstructionForTest(uint32_t id) const { return impl_.GetInstructionForTest(id); } + + /// @returns info about the gl_Position builtin variable. const ParserImpl::BuiltInPositionInfo& GetBuiltInPositionInfo() { return impl_.GetBuiltInPositionInfo(); } + + /// Returns the source record for the SPIR-V instruction with the given + /// result ID. + /// @param id the SPIR-V result id. + /// @return the Source record, or a default one Source GetSourceForResultIdForTest(uint32_t id) const { return impl_.GetSourceForResultIdForTest(id); } + + /// Changes pipeline IO to be HLSL-style: as entry point parameters and + /// return. + /// TODO(crbug.com/tint/508): Once all this support has landed, switch + /// over to that, and remove the old support. void SetHLSLStylePipelineIO() { impl_.SetHLSLStylePipelineIO(); } + + /// @returns true if HLSL-style IO should be used. bool UseHLSLStylePipelineIO() const { return impl_.UseHLSLStylePipelineIO(); } private: ParserImpl impl_; - // When true, indicates the input SPIR-V module is expected to fail - // validation, but the SPIR-V reader parser is permissive and lets it through. + /// When true, indicates the input SPIR-V module is expected to fail + /// validation, but the SPIR-V reader parser is permissive and lets it + /// through. bool deliberately_invalid_spirv_ = false; static bool dump_successfully_converted_spirv_; }; diff --git a/src/transform/external_texture_transform.h b/src/transform/external_texture_transform.h index 7c0001ea64..350122bf2b 100644 --- a/src/transform/external_texture_transform.h +++ b/src/transform/external_texture_transform.h @@ -22,11 +22,11 @@ namespace tint { namespace transform { -// Because an external texture is comprised of 1-3 texture views we can simply -// transform external textures into the appropriate number of sampled textures. -// This allows us to share SPIR-V/HLSL writer paths for sampled textures instead -// of adding dedicated writer paths for external textures. -// ExternalTextureTransform performs this transformation. +/// Because an external texture is comprised of 1-3 texture views we can simply +/// transform external textures into the appropriate number of sampled textures. +/// This allows us to share SPIR-V/HLSL writer paths for sampled textures +/// instead of adding dedicated writer paths for external textures. +/// ExternalTextureTransform performs this transformation. class ExternalTextureTransform : public Transform { public: /// Constructor