texture2DMS-to-texture2D.azsl 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. // Used for validation of compiler flag --no-ms
  2. // This file contains most common use cases of Texture2DMS & Texture2DMSArray and related APIs and system semantics.
  3. // This file is used to validate automatic conversion of the Texture2DMS
  4. // variables into Texture2D variables, and Texture2DMSArray to Texture2DArray, along with changes in API usage
  5. // of the methods Load(), GetSamplePosition() and GetDimensions().
  6. // Also system semantics like SV_SampleIndex and SV_Coverage are also mutated.
  7. ShaderResourceGroupSemantic SRG_PerPass
  8. {
  9. FrequencyId = 0;
  10. }
  11. ShaderResourceGroup PassSrg : SRG_PerPass
  12. {
  13. Texture2DMS<float4> m_texture0ms;
  14. // We use regular Texture2D to validate that --no-ms
  15. // does not affect Texture2D
  16. Texture2D<float4> m_texture1;
  17. Texture2DMS<float4> m_texture2ms;
  18. Texture2DMSArray<float4> m_textureArray0ms;
  19. // We use regular Texture2DArray to validate that --no-ms
  20. // does not affect Texture2DArray
  21. Texture2DArray<float4> m_textureArray1;
  22. // Let's declare some functions with identical name
  23. // as Load() to prove that the code only modifies Load()
  24. // when called as instance method of Texture2DMS
  25. float4 Load(int2 texelLoc, int2 texelLocDelta, int element, int sampleIndex)
  26. {
  27. float4 color = float4(0,0,0,0);
  28. color += m_texture0ms.Load(texelLoc, sampleIndex);
  29. color -= m_texture0ms.Load(texelLoc + texelLocDelta, sampleIndex + sampleIndex);
  30. color += m_texture0ms.Load(texelLoc + texelLocDelta, sampleIndex + sampleIndex, int2(0, 2));
  31. color -= m_texture1.Load(int3(texelLoc, 0)); // mip 0
  32. color += m_texture1.Load(int3(texelLoc, 1)); // mip 1
  33. color -= m_texture2ms.Load(texelLoc - 2.0*texelLocDelta, sampleIndex + 1, int2(1,1));
  34. color += m_textureArray0ms.Load(int3(texelLoc, element), sampleIndex/2) - m_textureArray1.Load(int4(texelLoc, element, 3));
  35. return color;
  36. }
  37. float2 GetSamplePosition(int sampleIndex)
  38. {
  39. return m_texture0ms.GetSamplePosition(2 * sampleIndex) +
  40. m_texture2ms.GetSamplePosition(sampleIndex) +
  41. m_textureArray0ms.GetSamplePosition((sampleIndex + 7)/3);
  42. }
  43. void GetDimensions(out uint width, out uint height, out uint elements, out uint numSamples)
  44. {
  45. uint tmpWidth;
  46. uint tmpHeight;
  47. uint tmpElements;
  48. uint tmpNumSamples;
  49. width = 0;
  50. height = 0;
  51. elements = 0;
  52. numSamples = 0;
  53. m_texture0ms.GetDimensions(tmpWidth, tmpHeight, tmpNumSamples);
  54. width += tmpWidth; height += tmpHeight; numSamples += tmpNumSamples;
  55. m_texture1.GetDimensions(tmpWidth, tmpHeight);
  56. width += tmpWidth; height += tmpHeight;
  57. m_texture2ms.GetDimensions(tmpWidth, tmpHeight, tmpNumSamples);
  58. width += tmpWidth; height += tmpHeight; numSamples += tmpNumSamples;
  59. m_textureArray0ms.GetDimensions(tmpWidth, tmpHeight, tmpElements, tmpNumSamples);
  60. width += tmpWidth; height += tmpHeight; elements += tmpElements; numSamples += tmpNumSamples;
  61. m_textureArray1.GetDimensions(tmpWidth, tmpHeight, tmpElements);
  62. width += tmpWidth; height += tmpHeight; elements += tmpElements;
  63. width /= 5;
  64. height /= 5;
  65. elements /= 2;
  66. numSamples /= 3;
  67. }
  68. }
  69. // A simple global function called Load to make sure its signature is not messed up.
  70. float4 Load(int2 texelLoc, int2 texelLocDelta, int element, int sampleIndex,
  71. Texture2DMS<float4> tex0ms, Texture2D<float4> tex1, Texture2DMS<float4> tex2ms,
  72. Texture2DMSArray<float4> texArray0ms, Texture2DArray<float4> texArray1)
  73. {
  74. float4 color = float4(0,0,0,0);
  75. color += tex0ms.Load(texelLoc, sampleIndex);
  76. color -= tex0ms.Load(texelLoc + texelLocDelta, sampleIndex + sampleIndex);
  77. color += tex0ms.Load(texelLoc + texelLocDelta, sampleIndex + sampleIndex, int2(0, 2));
  78. color -= tex1.Load(int3(texelLoc, 0)); // mip 0
  79. color += tex1.Load(int3(texelLoc, 1)); // mip 1
  80. color -= tex2ms.Load(texelLoc - 2.0*texelLocDelta, sampleIndex + 1, int2(1,1));
  81. color += texArray0ms.Load(int3(texelLoc, element), sampleIndex/2) - texArray1.Load(int4(texelLoc, element, 3));
  82. return color;
  83. }
  84. struct VSOutput
  85. {
  86. float4 m_position : SV_Position;
  87. float2 m_texCoord : TEXCOORD0;
  88. };
  89. struct PSOutput
  90. {
  91. float4 m_color : SV_Target0;
  92. };
  93. PSOutput PSMain(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
  94. {
  95. PSOutput OUT;
  96. int2 texelCoord = int2(IN.m_position.xy);
  97. float4 color1 = PassSrg::Load(texelCoord, int2(0, 0), 1, sampleIndex);
  98. float4 color2 = Load(texelCoord, int2(0, 0), 1, sampleIndex,
  99. PassSrg::m_texture0ms, PassSrg::m_texture1, PassSrg::m_texture2ms,
  100. PassSrg::m_textureArray0ms, PassSrg::m_textureArray1);
  101. float2 samplePos = PassSrg::GetSamplePosition(sampleIndex);
  102. uint width; uint height; uint elements; uint numSamples;
  103. PassSrg::GetDimensions(width, height, elements, numSamples);
  104. if ((samplePos.x == samplePos.y) && (width == height) && (elements != numSamples))
  105. {
  106. OUT.m_color = color1;
  107. }
  108. else
  109. {
  110. OUT.m_color = color2;
  111. }
  112. return OUT;
  113. }
  114. PSOutput PSMainCoverage(VSOutput IN, inout uint coverage : SV_Coverage)
  115. {
  116. PSOutput OUT;
  117. int2 texelCoord = int2(IN.m_position.xy);
  118. // Let's get the number of samples
  119. uint width; uint height; uint elements; uint numSamples;
  120. PassSrg::GetDimensions(width, height, elements, numSamples);
  121. for (uint sampleIndex = 0; sampleIndex < numSamples; ++sampleIndex)
  122. {
  123. if ( !(coverage & (1 << sampleIndex)) )
  124. {
  125. continue;
  126. }
  127. float4 color1 = PassSrg::Load(texelCoord, int2(0, 0), 1, sampleIndex);
  128. float4 color2 = Load(texelCoord, int2(0, 0), 1, sampleIndex,
  129. PassSrg::m_texture0ms, PassSrg::m_texture1, PassSrg::m_texture2ms,
  130. PassSrg::m_textureArray0ms, PassSrg::m_textureArray1);
  131. float2 samplePos = PassSrg::GetSamplePosition(sampleIndex);
  132. if ((samplePos.x == samplePos.y) && (width == height) && (elements != numSamples))
  133. {
  134. OUT.m_color += color1;
  135. coverage &= ~(1 << sampleIndex);
  136. }
  137. else
  138. {
  139. OUT.m_color -= color2;
  140. }
  141. }
  142. return OUT;
  143. }
  144. // In this case, SV_SampleIndex is embedded on the input struct, instead
  145. // of the function arguments.
  146. struct VSOutputWithSampleIndex
  147. {
  148. float4 m_position : SV_Position;
  149. float2 m_texCoord : TEXCOORD0;
  150. uint m_sampleIndex : SV_SampleIndex;
  151. };
  152. PSOutput PSMain2(VSOutputWithSampleIndex IN)
  153. {
  154. PSOutput OUT;
  155. int2 texelCoord = int2(IN.m_position.xy);
  156. float4 color1 = PassSrg::Load(texelCoord, int2(0, 0), 1, IN.m_sampleIndex);
  157. float4 color2 = Load(texelCoord, int2(0, 0), 1, IN.m_sampleIndex,
  158. PassSrg::m_texture0ms, PassSrg::m_texture1, PassSrg::m_texture2ms,
  159. PassSrg::m_textureArray0ms, PassSrg::m_textureArray1);
  160. float2 samplePos = PassSrg::GetSamplePosition(IN.m_sampleIndex);
  161. uint width; uint height; uint elements; uint numSamples;
  162. PassSrg::GetDimensions(width, height, elements, numSamples);
  163. if ((samplePos.x == samplePos.y) && (width == height) && (elements != numSamples))
  164. {
  165. OUT.m_color = color1;
  166. }
  167. else
  168. {
  169. OUT.m_color = color2;
  170. }
  171. return OUT;
  172. }