GrMtlPipelineStateDataManager.mm 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. /*
  2. * Copyright 2018 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "src/gpu/mtl/GrMtlPipelineStateDataManager.h"
  8. #include "src/gpu/mtl/GrMtlBuffer.h"
  9. #include "src/gpu/mtl/GrMtlGpu.h"
  10. #if !__has_feature(objc_arc)
  11. #error This file must be compiled with Arc. Use -fobjc-arc flag
  12. #endif
  13. GrMtlPipelineStateDataManager::GrMtlPipelineStateDataManager(const UniformInfoArray& uniforms,
  14. uint32_t geometryUniformSize,
  15. uint32_t fragmentUniformSize)
  16. : fGeometryUniformSize(geometryUniformSize)
  17. , fFragmentUniformSize(fragmentUniformSize)
  18. , fGeometryUniformsDirty(false)
  19. , fFragmentUniformsDirty(false) {
  20. fGeometryUniformData.reset(geometryUniformSize);
  21. fFragmentUniformData.reset(fragmentUniformSize);
  22. int count = uniforms.count();
  23. fUniforms.push_back_n(count);
  24. // We must add uniforms in same order is the UniformInfoArray so that UniformHandles already
  25. // owned by other objects will still match up here.
  26. for (int i = 0; i < count; i++) {
  27. Uniform& uniform = fUniforms[i];
  28. const GrMtlUniformHandler::UniformInfo uniformInfo = uniforms[i];
  29. SkASSERT(GrShaderVar::kNonArray == uniformInfo.fVariable.getArrayCount() ||
  30. uniformInfo.fVariable.getArrayCount() > 0);
  31. SkDEBUGCODE(
  32. uniform.fArrayCount = uniformInfo.fVariable.getArrayCount();
  33. uniform.fType = uniformInfo.fVariable.getType();
  34. );
  35. if (!(kFragment_GrShaderFlag & uniformInfo.fVisibility)) {
  36. uniform.fBinding = GrMtlUniformHandler::kGeometryBinding;
  37. } else {
  38. SkASSERT(kFragment_GrShaderFlag == uniformInfo.fVisibility);
  39. uniform.fBinding = GrMtlUniformHandler::kFragBinding;
  40. }
  41. uniform.fOffset = uniformInfo.fUBOffset;
  42. }
  43. }
  44. void* GrMtlPipelineStateDataManager::getBufferPtrAndMarkDirty(const Uniform& uni) const {
  45. void* buffer;
  46. if (GrMtlUniformHandler::kGeometryBinding == uni.fBinding) {
  47. buffer = fGeometryUniformData.get();
  48. fGeometryUniformsDirty = true;
  49. } else {
  50. SkASSERT(GrMtlUniformHandler::kFragBinding == uni.fBinding);
  51. buffer = fFragmentUniformData.get();
  52. fFragmentUniformsDirty = true;
  53. }
  54. buffer = static_cast<char*>(buffer)+uni.fOffset;
  55. return buffer;
  56. }
  57. void GrMtlPipelineStateDataManager::set1i(UniformHandle u, int32_t i) const {
  58. const Uniform& uni = fUniforms[u.toIndex()];
  59. SkASSERT(uni.fType == kInt_GrSLType || uni.fType == kShort_GrSLType);
  60. SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
  61. void* buffer = this->getBufferPtrAndMarkDirty(uni);
  62. memcpy(buffer, &i, sizeof(int32_t));
  63. }
  64. void GrMtlPipelineStateDataManager::set1iv(UniformHandle u,
  65. int arrayCount,
  66. const int32_t v[]) const {
  67. const Uniform& uni = fUniforms[u.toIndex()];
  68. SkASSERT(uni.fType == kInt_GrSLType || uni.fType == kShort_GrSLType);
  69. SkASSERT(arrayCount > 0);
  70. SkASSERT(arrayCount <= uni.fArrayCount ||
  71. (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
  72. void* buffer = this->getBufferPtrAndMarkDirty(uni);
  73. SkASSERT(sizeof(int32_t) == 4);
  74. for (int i = 0; i < arrayCount; ++i) {
  75. const int32_t* curVec = &v[i];
  76. memcpy(buffer, curVec, sizeof(int32_t));
  77. buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
  78. }
  79. }
  80. void GrMtlPipelineStateDataManager::set1f(UniformHandle u, float v0) const {
  81. const Uniform& uni = fUniforms[u.toIndex()];
  82. SkASSERT(uni.fType == kFloat_GrSLType || uni.fType == kHalf_GrSLType);
  83. SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
  84. void* buffer = this->getBufferPtrAndMarkDirty(uni);
  85. SkASSERT(sizeof(float) == 4);
  86. memcpy(buffer, &v0, sizeof(float));
  87. }
  88. void GrMtlPipelineStateDataManager::set1fv(UniformHandle u,
  89. int arrayCount,
  90. const float v[]) const {
  91. const Uniform& uni = fUniforms[u.toIndex()];
  92. SkASSERT(uni.fType == kFloat_GrSLType || uni.fType == kHalf_GrSLType);
  93. SkASSERT(arrayCount > 0);
  94. SkASSERT(arrayCount <= uni.fArrayCount ||
  95. (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
  96. void* buffer = this->getBufferPtrAndMarkDirty(uni);
  97. SkASSERT(sizeof(float) == 4);
  98. memcpy(buffer, v, arrayCount * sizeof(float));
  99. }
  100. void GrMtlPipelineStateDataManager::set2i(UniformHandle u, int32_t i0, int32_t i1) const {
  101. const Uniform& uni = fUniforms[u.toIndex()];
  102. SkASSERT(uni.fType == kInt2_GrSLType || uni.fType == kShort2_GrSLType);
  103. SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
  104. void* buffer = this->getBufferPtrAndMarkDirty(uni);
  105. int32_t v[2] = { i0, i1 };
  106. memcpy(buffer, v, 2 * sizeof(int32_t));
  107. }
  108. void GrMtlPipelineStateDataManager::set2iv(UniformHandle u,
  109. int arrayCount,
  110. const int32_t v[]) const {
  111. const Uniform& uni = fUniforms[u.toIndex()];
  112. SkASSERT(uni.fType == kInt2_GrSLType || uni.fType == kShort2_GrSLType);
  113. SkASSERT(arrayCount > 0);
  114. SkASSERT(arrayCount <= uni.fArrayCount ||
  115. (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
  116. void* buffer = this->getBufferPtrAndMarkDirty(uni);
  117. SkASSERT(sizeof(int32_t) == 4);
  118. memcpy(buffer, v, arrayCount*sizeof(int32_t));
  119. }
  120. void GrMtlPipelineStateDataManager::set2f(UniformHandle u, float v0, float v1) const {
  121. const Uniform& uni = fUniforms[u.toIndex()];
  122. SkASSERT(uni.fType == kFloat2_GrSLType || uni.fType == kHalf2_GrSLType);
  123. SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
  124. void* buffer = this->getBufferPtrAndMarkDirty(uni);
  125. SkASSERT(sizeof(float) == 4);
  126. float v[2] = { v0, v1 };
  127. memcpy(buffer, v, 2 * sizeof(float));
  128. }
  129. void GrMtlPipelineStateDataManager::set2fv(UniformHandle u,
  130. int arrayCount,
  131. const float v[]) const {
  132. const Uniform& uni = fUniforms[u.toIndex()];
  133. SkASSERT(uni.fType == kFloat2_GrSLType || uni.fType == kHalf2_GrSLType);
  134. SkASSERT(arrayCount > 0);
  135. SkASSERT(arrayCount <= uni.fArrayCount ||
  136. (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
  137. void* buffer = this->getBufferPtrAndMarkDirty(uni);
  138. SkASSERT(sizeof(float) == 4);
  139. memcpy(buffer, v, arrayCount * 2 * sizeof(float));
  140. }
  141. void GrMtlPipelineStateDataManager::set3i(UniformHandle u,
  142. int32_t i0,
  143. int32_t i1,
  144. int32_t i2) const {
  145. const Uniform& uni = fUniforms[u.toIndex()];
  146. SkASSERT(uni.fType == kInt3_GrSLType || uni.fType == kShort3_GrSLType);
  147. SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
  148. void* buffer = this->getBufferPtrAndMarkDirty(uni);
  149. int32_t v[3] = { i0, i1, i2 };
  150. memcpy(buffer, v, 3 * sizeof(int32_t));
  151. }
  152. void GrMtlPipelineStateDataManager::set3iv(UniformHandle u,
  153. int arrayCount,
  154. const int32_t v[]) const {
  155. const Uniform& uni = fUniforms[u.toIndex()];
  156. SkASSERT(uni.fType == kInt3_GrSLType || uni.fType == kShort3_GrSLType);
  157. SkASSERT(arrayCount > 0);
  158. SkASSERT(arrayCount <= uni.fArrayCount ||
  159. (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
  160. void* buffer = this->getBufferPtrAndMarkDirty(uni);
  161. SkASSERT(sizeof(int32_t) == 4);
  162. for (int i = 0; i < arrayCount; ++i) {
  163. const int32_t* curVec = &v[3 * i];
  164. memcpy(buffer, curVec, 3 * sizeof(int32_t));
  165. buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
  166. }
  167. }
  168. void GrMtlPipelineStateDataManager::set3f(UniformHandle u, float v0, float v1, float v2) const {
  169. const Uniform& uni = fUniforms[u.toIndex()];
  170. SkASSERT(uni.fType == kFloat3_GrSLType || uni.fType == kHalf3_GrSLType);
  171. SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
  172. void* buffer = this->getBufferPtrAndMarkDirty(uni);
  173. SkASSERT(sizeof(float) == 4);
  174. float v[3] = { v0, v1, v2 };
  175. memcpy(buffer, v, 3 * sizeof(float));
  176. }
  177. void GrMtlPipelineStateDataManager::set3fv(UniformHandle u,
  178. int arrayCount,
  179. const float v[]) const {
  180. const Uniform& uni = fUniforms[u.toIndex()];
  181. SkASSERT(uni.fType == kFloat3_GrSLType || uni.fType == kHalf3_GrSLType);
  182. SkASSERT(arrayCount > 0);
  183. SkASSERT(arrayCount <= uni.fArrayCount ||
  184. (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
  185. void* buffer = this->getBufferPtrAndMarkDirty(uni);
  186. SkASSERT(sizeof(float) == 4);
  187. for (int i = 0; i < arrayCount; ++i) {
  188. const float* curVec = &v[3 * i];
  189. memcpy(buffer, curVec, 3 * sizeof(float));
  190. buffer = static_cast<char*>(buffer) + 4*sizeof(float);
  191. }
  192. }
  193. void GrMtlPipelineStateDataManager::set4i(UniformHandle u,
  194. int32_t i0,
  195. int32_t i1,
  196. int32_t i2,
  197. int32_t i3) const {
  198. const Uniform& uni = fUniforms[u.toIndex()];
  199. SkASSERT(uni.fType == kInt4_GrSLType || uni.fType == kShort4_GrSLType);
  200. SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
  201. void* buffer = this->getBufferPtrAndMarkDirty(uni);
  202. int32_t v[4] = { i0, i1, i2, i3 };
  203. memcpy(buffer, v, 4 * sizeof(int32_t));
  204. }
  205. void GrMtlPipelineStateDataManager::set4iv(UniformHandle u,
  206. int arrayCount,
  207. const int32_t v[]) const {
  208. const Uniform& uni = fUniforms[u.toIndex()];
  209. SkASSERT(uni.fType == kInt4_GrSLType || uni.fType == kShort4_GrSLType);
  210. SkASSERT(arrayCount > 0);
  211. SkASSERT(arrayCount <= uni.fArrayCount ||
  212. (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
  213. void* buffer = this->getBufferPtrAndMarkDirty(uni);
  214. SkASSERT(sizeof(int32_t) == 4);
  215. memcpy(buffer, v, arrayCount * 4 * sizeof(int32_t));
  216. }
  217. void GrMtlPipelineStateDataManager::set4f(UniformHandle u,
  218. float v0,
  219. float v1,
  220. float v2,
  221. float v3) const {
  222. const Uniform& uni = fUniforms[u.toIndex()];
  223. SkASSERT(uni.fType == kFloat4_GrSLType || uni.fType == kHalf4_GrSLType);
  224. SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
  225. void* buffer = this->getBufferPtrAndMarkDirty(uni);
  226. SkASSERT(sizeof(float) == 4);
  227. float v[4] = { v0, v1, v2, v3 };
  228. memcpy(buffer, v, 4 * sizeof(float));
  229. }
  230. void GrMtlPipelineStateDataManager::set4fv(UniformHandle u,
  231. int arrayCount,
  232. const float v[]) const {
  233. const Uniform& uni = fUniforms[u.toIndex()];
  234. SkASSERT(uni.fType == kFloat4_GrSLType || uni.fType == kHalf4_GrSLType);
  235. SkASSERT(arrayCount > 0);
  236. SkASSERT(arrayCount <= uni.fArrayCount ||
  237. (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
  238. void* buffer = this->getBufferPtrAndMarkDirty(uni);
  239. SkASSERT(sizeof(float) == 4);
  240. memcpy(buffer, v, arrayCount * 4 * sizeof(float));
  241. }
  242. void GrMtlPipelineStateDataManager::setMatrix2f(UniformHandle u, const float matrix[]) const {
  243. this->setMatrices<2>(u, 1, matrix);
  244. }
  245. void GrMtlPipelineStateDataManager::setMatrix2fv(UniformHandle u,
  246. int arrayCount,
  247. const float m[]) const {
  248. this->setMatrices<2>(u, arrayCount, m);
  249. }
  250. void GrMtlPipelineStateDataManager::setMatrix3f(UniformHandle u, const float matrix[]) const {
  251. this->setMatrices<3>(u, 1, matrix);
  252. }
  253. void GrMtlPipelineStateDataManager::setMatrix3fv(UniformHandle u,
  254. int arrayCount,
  255. const float m[]) const {
  256. this->setMatrices<3>(u, arrayCount, m);
  257. }
  258. void GrMtlPipelineStateDataManager::setMatrix4f(UniformHandle u, const float matrix[]) const {
  259. this->setMatrices<4>(u, 1, matrix);
  260. }
  261. void GrMtlPipelineStateDataManager::setMatrix4fv(UniformHandle u,
  262. int arrayCount,
  263. const float m[]) const {
  264. this->setMatrices<4>(u, arrayCount, m);
  265. }
  266. template<int N> struct set_uniform_matrix;
  267. template<int N> inline void GrMtlPipelineStateDataManager::setMatrices(
  268. UniformHandle u,
  269. int arrayCount,
  270. const float matrices[]) const {
  271. const Uniform& uni = fUniforms[u.toIndex()];
  272. SkASSERT(uni.fType == kFloat2x2_GrSLType + (N - 2) ||
  273. uni.fType == kHalf2x2_GrSLType + (N - 2));
  274. SkASSERT(arrayCount > 0);
  275. SkASSERT(arrayCount <= uni.fArrayCount ||
  276. (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
  277. void* buffer;
  278. if (GrMtlUniformHandler::kGeometryBinding == uni.fBinding) {
  279. buffer = fGeometryUniformData.get();
  280. fGeometryUniformsDirty = true;
  281. } else {
  282. SkASSERT(GrMtlUniformHandler::kFragBinding == uni.fBinding);
  283. buffer = fFragmentUniformData.get();
  284. fFragmentUniformsDirty = true;
  285. }
  286. set_uniform_matrix<N>::set(buffer, uni.fOffset, arrayCount, matrices);
  287. }
  288. template<> struct set_uniform_matrix<2> {
  289. inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
  290. GR_STATIC_ASSERT(sizeof(float) == 4);
  291. buffer = static_cast<char*>(buffer) + uniformOffset;
  292. memcpy(buffer, matrices, count * 4 * sizeof(float));
  293. }
  294. };
  295. template<> struct set_uniform_matrix<3> {
  296. inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
  297. GR_STATIC_ASSERT(sizeof(float) == 4);
  298. buffer = static_cast<char*>(buffer) + uniformOffset;
  299. for (int i = 0; i < count; ++i) {
  300. const float* matrix = &matrices[3 * 3 * i];
  301. for (int j = 0; j < 3; ++j) {
  302. memcpy(buffer, &matrix[j * 3], 3 * sizeof(float));
  303. buffer = static_cast<char*>(buffer) + 4 * sizeof(float);
  304. }
  305. }
  306. }
  307. };
  308. template<> struct set_uniform_matrix<4> {
  309. inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
  310. GR_STATIC_ASSERT(sizeof(float) == 4);
  311. buffer = static_cast<char*>(buffer) + uniformOffset;
  312. memcpy(buffer, matrices, count * 16 * sizeof(float));
  313. }
  314. };
  315. void GrMtlPipelineStateDataManager::uploadAndBindUniformBuffers(
  316. GrMtlGpu* gpu,
  317. id<MTLRenderCommandEncoder> renderCmdEncoder) const {
  318. if (fGeometryUniformSize && fGeometryUniformsDirty) {
  319. SkASSERT(fGeometryUniformSize < 4*1024);
  320. [renderCmdEncoder setVertexBytes: fGeometryUniformData.get()
  321. length: fGeometryUniformSize
  322. atIndex: GrMtlUniformHandler::kGeometryBinding];
  323. fGeometryUniformsDirty = false;
  324. }
  325. if (fFragmentUniformSize && fFragmentUniformsDirty) {
  326. SkASSERT(fFragmentUniformSize < 4*1024);
  327. [renderCmdEncoder setFragmentBytes: fFragmentUniformData.get()
  328. length: fFragmentUniformSize
  329. atIndex: GrMtlUniformHandler::kFragBinding];
  330. fFragmentUniformsDirty = false;
  331. }
  332. }
  333. void GrMtlPipelineStateDataManager::resetDirtyBits() {
  334. fGeometryUniformsDirty = true;
  335. fFragmentUniformsDirty = true;
  336. }