Clarify mapping of target env to SPIR-V version (#3150)

* Clarify mapping of target env to SPIR-V version

It depends on the API method.

* Update SPIR-V version comments on validator
diff --git a/include/spirv-tools/libspirv.h b/include/spirv-tools/libspirv.h
index f6af78f..d63f363 100644
--- a/include/spirv-tools/libspirv.h
+++ b/include/spirv-tools/libspirv.h
@@ -419,8 +419,17 @@
 SPIRV_TOOLS_EXPORT const char* spvSoftwareVersionDetailsString(void);
 
 // Certain target environments impose additional restrictions on SPIR-V, so it's
-// often necessary to specify which one applies.  SPV_ENV_UNIVERSAL means
+// often necessary to specify which one applies.  SPV_ENV_UNIVERSAL_* implies an
 // environment-agnostic SPIR-V.
+//
+// When an API method needs to derive a SPIR-V version from a target environment
+// (from the spv_context object), the method will choose the highest version of
+// SPIR-V supported by the target environment.  Examples:
+//    SPV_ENV_VULKAN_1_0           ->  SPIR-V 1.0
+//    SPV_ENV_VULKAN_1_1           ->  SPIR-V 1.3
+//    SPV_ENV_VULKAN_1_1_SPIRV_1_4 ->  SPIR-V 1.4
+//    SPV_ENV_VULKAN_1_2           ->  SPIR-V 1.5
+// Consult the description of API entry points for specific rules.
 typedef enum {
   SPV_ENV_UNIVERSAL_1_0,  // SPIR-V 1.0 latest revision, no other restrictions.
   SPV_ENV_VULKAN_1_0,     // Vulkan 1.0 latest revision.
@@ -448,7 +457,10 @@
   SPV_ENV_VULKAN_1_1,     // Vulkan 1.1 latest revision.
   SPV_ENV_WEBGPU_0,       // Work in progress WebGPU 1.0.
   SPV_ENV_UNIVERSAL_1_4,  // SPIR-V 1.4 latest revision, no other restrictions.
-  SPV_ENV_VULKAN_1_1_SPIRV_1_4,  // Vulkan 1.1 with SPIR-V 1.4 binary.
+
+  // Vulkan 1.1 with VK_KHR_spirv_1_4, i.e. SPIR-V 1.4 binary.
+  SPV_ENV_VULKAN_1_1_SPIRV_1_4,
+
   SPV_ENV_UNIVERSAL_1_5,  // SPIR-V 1.5 latest revision, no other restrictions.
   SPV_ENV_VULKAN_1_2,     // Vulkan 1.2 latest revision.
 } spv_target_env;
@@ -486,7 +498,11 @@
                                           uint32_t spirv_ver,
                                           spv_target_env* env);
 
-// Creates a context object.  Returns null if env is invalid.
+// Creates a context object for most of the SPIRV-Tools API.
+// Returns null if env is invalid.
+//
+// See specific API calls for how the target environment is interpeted
+// (particularly assembly and validation).
 SPIRV_TOOLS_EXPORT spv_context spvContextCreate(spv_target_env env);
 
 // Destroys the given context object.
@@ -667,6 +683,8 @@
 // be stored into *binary. Any error will be written into *diagnostic if
 // diagnostic is non-null, otherwise the context's message consumer will be
 // used. The generated binary is independent of the context and may outlive it.
+// The SPIR-V binary version is set to the highest version of SPIR-V supported
+// by the context's target environment.
 SPIRV_TOOLS_EXPORT spv_result_t spvTextToBinary(const spv_const_context context,
                                                 const char* text,
                                                 const size_t length,
@@ -704,6 +722,12 @@
 // Validates a SPIR-V binary for correctness. Any errors will be written into
 // *diagnostic if diagnostic is non-null, otherwise the context's message
 // consumer will be used.
+//
+// Validate for SPIR-V spec rules for the SPIR-V version named in the
+// binary's header (at word offset 1).  Additionally, if the context target
+// environment is a client API (such as Vulkan 1.1), then validate for that
+// client API version, to the extent that it is verifiable from data in the
+// binary itself.
 SPIRV_TOOLS_EXPORT spv_result_t spvValidate(const spv_const_context context,
                                             const spv_const_binary binary,
                                             spv_diagnostic* diagnostic);
@@ -711,6 +735,12 @@
 // Validates a SPIR-V binary for correctness. Uses the provided Validator
 // options. Any errors will be written into *diagnostic if diagnostic is
 // non-null, otherwise the context's message consumer will be used.
+//
+// Validate for SPIR-V spec rules for the SPIR-V version named in the
+// binary's header (at word offset 1).  Additionally, if the context target
+// environment is a client API (such as Vulkan 1.1), then validate for that
+// client API version, to the extent that it is verifiable from data in the
+// binary itself, or in the validator options.
 SPIRV_TOOLS_EXPORT spv_result_t spvValidateWithOptions(
     const spv_const_context context, const spv_const_validator_options options,
     const spv_const_binary binary, spv_diagnostic* diagnostic);
diff --git a/include/spirv-tools/libspirv.hpp b/include/spirv-tools/libspirv.hpp
index ceadef8..5e1819e 100644
--- a/include/spirv-tools/libspirv.hpp
+++ b/include/spirv-tools/libspirv.hpp
@@ -36,6 +36,9 @@
  public:
   // Constructs a context targeting the given environment |env|.
   //
+  // See specific API calls for how the target environment is interpeted
+  // (particularly assembly and validation).
+  //
   // The constructed instance will have an empty message consumer, which just
   // ignores all messages from the library. Use SetMessageConsumer() to supply
   // one if messages are of concern.
@@ -279,16 +282,20 @@
   // Assembles the given assembly |text| and writes the result to |binary|.
   // Returns true on successful assembling. |binary| will be kept untouched if
   // assembling is unsuccessful.
+  // The SPIR-V binary version is set to the highest version of SPIR-V supported
+  // by the target environment with which this SpirvTools object was created.
   bool Assemble(const std::string& text, std::vector<uint32_t>* binary,
                 uint32_t options = kDefaultAssembleOption) const;
   // |text_size| specifies the number of bytes in |text|. A terminating null
   // character is not required to present in |text| as long as |text| is valid.
+  // The SPIR-V binary version is set to the highest version of SPIR-V supported
+  // by the target environment with which this SpirvTools object was created.
   bool Assemble(const char* text, size_t text_size,
                 std::vector<uint32_t>* binary,
                 uint32_t options = kDefaultAssembleOption) const;
 
   // Disassembles the given SPIR-V |binary| with the given |options| and writes
-  // the assembly to |text|. Returns ture on successful disassembling. |text|
+  // the assembly to |text|. Returns true on successful disassembling. |text|
   // will be kept untouched if diassembling is unsuccessful.
   bool Disassemble(const std::vector<uint32_t>& binary, std::string* text,
                    uint32_t options = kDefaultDisassembleOption) const;
@@ -300,10 +307,26 @@
   // Validates the given SPIR-V |binary|. Returns true if no issues are found.
   // Otherwise, returns false and communicates issues via the message consumer
   // registered.
+  // Validates for SPIR-V spec rules for the SPIR-V version named in the
+  // binary's header (at word offset 1).  Additionally, if the target
+  // environment is a client API (such as Vulkan 1.1), then validate for that
+  // client API version, to the extent that it is verifiable from data in the
+  // binary itself.
   bool Validate(const std::vector<uint32_t>& binary) const;
+  // Like the previous overload, but provides the binary as a pointer and size:
   // |binary_size| specifies the number of words in |binary|.
+  // Validates for SPIR-V spec rules for the SPIR-V version named in the
+  // binary's header (at word offset 1).  Additionally, if the target
+  // environment is a client API (such as Vulkan 1.1), then validate for that
+  // client API version, to the extent that it is verifiable from data in the
+  // binary itself.
   bool Validate(const uint32_t* binary, size_t binary_size) const;
   // Like the previous overload, but takes an options object.
+  // Validates for SPIR-V spec rules for the SPIR-V version named in the
+  // binary's header (at word offset 1).  Additionally, if the target
+  // environment is a client API (such as Vulkan 1.1), then validate for that
+  // client API version, to the extent that it is verifiable from data in the
+  // binary itself, or in the validator options.
   bool Validate(const uint32_t* binary, size_t binary_size,
                 spv_validator_options options) const;
 
diff --git a/include/spirv-tools/optimizer.hpp b/include/spirv-tools/optimizer.hpp
index ba8cbaf..c31ccef 100644
--- a/include/spirv-tools/optimizer.hpp
+++ b/include/spirv-tools/optimizer.hpp
@@ -65,9 +65,9 @@
   // Constructs an instance with the given target |env|, which is used to decode
   // the binaries to be optimized later.
   //
-  // The constructed instance will have an empty message consumer, which just
-  // ignores all messages from the library. Use SetMessageConsumer() to supply
-  // one if messages are of concern.
+  // The instance will have an empty message consumer, which ignores all
+  // messages from the library. Use SetMessageConsumer() to supply a consumer
+  // if messages are of concern.
   //
   // For collections of passes that are meant to transform the input into
   // another execution environment, then the source environment should be
@@ -164,17 +164,26 @@
   bool FlagHasValidForm(const std::string& flag) const;
 
   // Allows changing, after creation time, the target environment to be
-  // optimized for.  Should be called before calling Run().
+  // optimized for and validated.  Should be called before calling Run().
   void SetTargetEnv(const spv_target_env env);
 
   // Optimizes the given SPIR-V module |original_binary| and writes the
-  // optimized binary into |optimized_binary|.
+  // optimized binary into |optimized_binary|. The optimized binary uses
+  // the same SPIR-V version as the original binary.
+  //
   // Returns true on successful optimization, whether or not the module is
   // modified. Returns false if |original_binary| fails to validate or if errors
   // occur when processing |original_binary| using any of the registered passes.
   // In that case, no further passes are executed and the contents in
   // |optimized_binary| may be invalid.
   //
+  // By default, the binary is validated before any transforms are performed,
+  // and optionally after each transform.  Validation uses SPIR-V spec rules
+  // for the SPIR-V version named in the binary's header (at word offset 1).
+  // Additionally, if the target environment is a client API (such as
+  // Vulkan 1.1), then validate for that client API version, to the extent
+  // that it is verifiable from data in the binary itself.
+  //
   // It's allowed to alias |original_binary| to the start of |optimized_binary|.
   bool Run(const uint32_t* original_binary, size_t original_binary_size,
            std::vector<uint32_t>* optimized_binary) const;
@@ -190,6 +199,14 @@
 
   // Same as above, except it takes an options object.  See the documentation
   // for |OptimizerOptions| to see which options can be set.
+  //
+  // By default, the binary is validated before any transforms are performed,
+  // and optionally after each transform.  Validation uses SPIR-V spec rules
+  // for the SPIR-V version named in the binary's header (at word offset 1).
+  // Additionally, if the target environment is a client API (such as
+  // Vulkan 1.1), then validate for that client API version, to the extent
+  // that it is verifiable from data in the binary itself, or from the
+  // validator options set on the optimizer options.
   bool Run(const uint32_t* original_binary, const size_t original_binary_size,
            std::vector<uint32_t>* optimized_binary,
            const spv_optimizer_options opt_options) const;