DxilResourceProperties.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // DxilResourceProperites.cpp //
  4. // Copyright (C) Microsoft Corporation. All rights reserved. //
  5. // This file is distributed under the University of Illinois Open Source //
  6. // License. See LICENSE.TXT for details. //
  7. // //
  8. ///////////////////////////////////////////////////////////////////////////////
  9. #include "dxc/DXIL/DxilResourceProperties.h"
  10. #include "llvm/IR/Constant.h"
  11. #include "dxc/DXIL/DxilShaderModel.h"
  12. #include "llvm/IR/DerivedTypes.h"
  13. #include "llvm/IR/Constants.h"
  14. #include "dxc/DXIL/DxilResourceBase.h"
  15. #include "dxc/DXIL/DxilResource.h"
  16. #include "dxc/DXIL/DxilCBuffer.h"
  17. #include "dxc/DXIL/DxilSampler.h"
  18. #include "dxc/DXIL/DxilOperations.h"
  19. #include "dxc/DXIL/DxilInstructions.h"
  20. #include "dxc/DXIL/DxilUtil.h"
  21. using namespace llvm;
  22. namespace hlsl {
  23. bool DxilResourceProperties::operator==(const DxilResourceProperties &RP) {
  24. return Class == RP.Class && Kind == RP.Kind && RawDword0 == RP.RawDword0 &&
  25. RawDword1 == RP.RawDword1;
  26. }
  27. bool DxilResourceProperties::operator!=(const DxilResourceProperties &RP) {
  28. return !(*this == RP) ;
  29. }
  30. unsigned DxilResourceProperties::getSampleCount() {
  31. assert(DXIL::IsTyped(Kind));
  32. const unsigned SampleCountTable[] = {
  33. 1, // 0
  34. 2, // 1
  35. 4, // 2
  36. 8, // 3
  37. 16, // 4
  38. 32, // 5
  39. 0, // 6
  40. 0, // kSampleCountUndefined.
  41. };
  42. return SampleCountTable[Typed.SampleCountPow2];
  43. }
  44. namespace resource_helper {
  45. // Resource Class and Resource Kind is used as seperate parameter, other fileds
  46. // are saved in constant.
  47. // The constant is as struct with int32 fields.
  48. // ShaderModel 6.6 has 2 fileds.
  49. Constant *getAsConstant(const DxilResourceProperties &RP, Type *Ty,
  50. const ShaderModel &) {
  51. StructType *ST = cast<StructType>(Ty);
  52. switch (ST->getNumElements()) {
  53. case 2: {
  54. Constant *RawDwords[] = {
  55. ConstantInt::get(ST->getElementType(0), RP.RawDword0),
  56. ConstantInt::get(ST->getElementType(1), RP.RawDword1)};
  57. return ConstantStruct::get(ST, RawDwords);
  58. } break;
  59. default:
  60. return nullptr;
  61. break;
  62. }
  63. return nullptr;
  64. }
  65. DxilResourceProperties loadFromConstant(const Constant &C,
  66. DXIL::ResourceClass RC,
  67. DXIL::ResourceKind RK) {
  68. DxilResourceProperties RP;
  69. RP.Class = RC;
  70. RP.Kind = RK;
  71. // Ty Should match C.getType().
  72. Type *Ty = C.getType();
  73. StructType *ST = cast<StructType>(Ty);
  74. switch (ST->getNumElements()) {
  75. case 2: {
  76. if (isa<ConstantAggregateZero>(&C)) {
  77. RP.RawDword0 = 0;
  78. RP.RawDword1 = 0;
  79. } else {
  80. const ConstantStruct *CS = cast<ConstantStruct>(&C);
  81. const Constant *RawDword0 = CS->getOperand(0);
  82. const Constant *RawDword1 = CS->getOperand(1);
  83. RP.RawDword0 = cast<ConstantInt>(RawDword0)->getLimitedValue();
  84. RP.RawDword1 = cast<ConstantInt>(RawDword1)->getLimitedValue();
  85. }
  86. } break;
  87. default:
  88. RP.Class = DXIL::ResourceClass::Invalid;
  89. break;
  90. }
  91. return RP;
  92. }
  93. DxilResourceProperties
  94. loadFromAnnotateHandle(DxilInst_AnnotateHandle &annotateHandle, llvm::Type *Ty,
  95. const ShaderModel &SM) {
  96. Constant *ResProp = cast<Constant>(annotateHandle.get_props());
  97. return loadFromConstant(
  98. *ResProp, (DXIL::ResourceClass)annotateHandle.get_resourceClass_val(),
  99. (DXIL::ResourceKind)annotateHandle.get_resourceKind_val());
  100. }
  101. DxilResourceProperties loadFromResourceBase(DxilResourceBase *Res) {
  102. DxilResourceProperties RP;
  103. RP.Class = DXIL::ResourceClass::Invalid;
  104. if (!Res) {
  105. return RP;
  106. }
  107. RP.RawDword0 = 0;
  108. RP.RawDword1 = 0;
  109. auto SetResProperties = [&RP](DxilResource &Res) {
  110. switch (Res.GetKind()) {
  111. default:
  112. break;
  113. case DXIL::ResourceKind::FeedbackTexture2D:
  114. case DXIL::ResourceKind::FeedbackTexture2DArray:
  115. RP.SamplerFeedbackType = Res.GetSamplerFeedbackType();
  116. break;
  117. case DXIL::ResourceKind::RTAccelerationStructure:
  118. break;
  119. case DXIL::ResourceKind::StructuredBuffer:
  120. case DXIL::ResourceKind::StructuredBufferWithCounter:
  121. RP.ElementStride = Res.GetElementStride();
  122. break;
  123. case DXIL::ResourceKind::Texture2DMS:
  124. case DXIL::ResourceKind::Texture2DMSArray:
  125. switch (Res.GetSampleCount()) {
  126. default:
  127. RP.Typed.SampleCountPow2 =
  128. DxilResourceProperties::kSampleCountUndefined;
  129. break;
  130. case 1:
  131. RP.Typed.SampleCountPow2 = 0;
  132. break;
  133. case 2:
  134. RP.Typed.SampleCountPow2 = 1;
  135. break;
  136. case 4:
  137. RP.Typed.SampleCountPow2 = 2;
  138. break;
  139. case 8:
  140. RP.Typed.SampleCountPow2 = 3;
  141. break;
  142. case 16:
  143. RP.Typed.SampleCountPow2 = 4;
  144. break;
  145. case 32:
  146. RP.Typed.SampleCountPow2 = 5;
  147. break;
  148. }
  149. break;
  150. case DXIL::ResourceKind::TypedBuffer:
  151. case DXIL::ResourceKind::Texture1D:
  152. case DXIL::ResourceKind::Texture2D:
  153. case DXIL::ResourceKind::TextureCube:
  154. case DXIL::ResourceKind::Texture1DArray:
  155. case DXIL::ResourceKind::Texture2DArray:
  156. case DXIL::ResourceKind::TextureCubeArray:
  157. case DXIL::ResourceKind::Texture3D:
  158. Type *Ty = Res.GetRetType();
  159. RP.Typed.SingleComponent = dxilutil::IsResourceSingleComponent(Ty);
  160. RP.Typed.CompType = Res.GetCompType().GetKind();
  161. RP.Typed.SampleCountPow2 =
  162. DxilResourceProperties::kSampleCountUndefined;
  163. break;
  164. }
  165. };
  166. switch (Res->GetClass()) { case DXIL::ResourceClass::Invalid: return RP;
  167. case DXIL::ResourceClass::SRV: {
  168. DxilResource *SRV = (DxilResource*)(Res);
  169. RP.Kind = Res->GetKind();
  170. RP.Class = Res->GetClass();
  171. SetResProperties(*SRV);
  172. } break;
  173. case DXIL::ResourceClass::UAV: {
  174. DxilResource *UAV = (DxilResource *)(Res);
  175. RP.Kind = Res->GetKind();
  176. RP.Class = Res->GetClass();
  177. RP.UAV.bGloballyCoherent = UAV->IsGloballyCoherent();
  178. if (UAV->HasCounter()) {
  179. RP.Kind = DXIL::ResourceKind::StructuredBufferWithCounter;
  180. }
  181. RP.UAV.bROV = UAV->IsROV();
  182. SetResProperties(*UAV);
  183. } break;
  184. case DXIL::ResourceClass::Sampler: {
  185. RP.Class = DXIL::ResourceClass::Sampler;
  186. RP.Kind = Res->GetKind();
  187. DxilSampler *Sampler = (DxilSampler*)Res;
  188. if (Sampler->GetSamplerKind() == DXIL::SamplerKind::Comparison)
  189. RP.Kind = DXIL::ResourceKind::SamplerComparison;
  190. else if (Sampler->GetSamplerKind() == DXIL::SamplerKind::Invalid)
  191. RP.Kind = DXIL::ResourceKind::Invalid;
  192. } break;
  193. case DXIL::ResourceClass::CBuffer: {
  194. RP.Class = DXIL::ResourceClass::CBuffer;
  195. RP.Kind = Res->GetKind();
  196. DxilCBuffer *CB = (DxilCBuffer *)Res;
  197. RP.SizeInBytes = CB->GetSize();
  198. } break;
  199. }
  200. return RP;
  201. }
  202. } // namespace resource_helper
  203. } // namespace hlsl