validate_derivatives.cpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. // Copyright (c) 2017 Google Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // Validates correctness of derivative SPIR-V instructions.
  15. #include "validate.h"
  16. #include "diagnostic.h"
  17. #include "opcode.h"
  18. #include "val/instruction.h"
  19. #include "val/validation_state.h"
  20. namespace libspirv {
  21. // Validates correctness of derivative instructions.
  22. spv_result_t DerivativesPass(ValidationState_t& _,
  23. const spv_parsed_instruction_t* inst) {
  24. const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
  25. const uint32_t result_type = inst->type_id;
  26. switch (opcode) {
  27. case SpvOpDPdx:
  28. case SpvOpDPdy:
  29. case SpvOpFwidth:
  30. case SpvOpDPdxFine:
  31. case SpvOpDPdyFine:
  32. case SpvOpFwidthFine:
  33. case SpvOpDPdxCoarse:
  34. case SpvOpDPdyCoarse:
  35. case SpvOpFwidthCoarse: {
  36. if (!_.IsFloatScalarOrVectorType(result_type)) {
  37. return _.diag(SPV_ERROR_INVALID_DATA)
  38. << "Expected Result Type to be float scalar or vector type: "
  39. << spvOpcodeString(opcode);
  40. }
  41. const uint32_t p_type = _.GetOperandTypeId(inst, 2);
  42. if (p_type != result_type) {
  43. return _.diag(SPV_ERROR_INVALID_DATA)
  44. << "Expected P type and Result Type to be the same: "
  45. << spvOpcodeString(opcode);
  46. }
  47. _.current_function().RegisterExecutionModelLimitation(
  48. SpvExecutionModelFragment, std::string(
  49. "Derivative instructions require Fragment execution model: ") +
  50. spvOpcodeString(opcode));
  51. break;
  52. }
  53. default:
  54. break;
  55. }
  56. return SPV_SUCCESS;
  57. }
  58. } // namespace libspirv