Methods.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  1. using Ryujinx.Graphics.GAL;
  2. using Ryujinx.Graphics.GAL.Blend;
  3. using Ryujinx.Graphics.GAL.DepthStencil;
  4. using Ryujinx.Graphics.GAL.InputAssembler;
  5. using Ryujinx.Graphics.GAL.Texture;
  6. using Ryujinx.Graphics.Gpu.Image;
  7. using Ryujinx.Graphics.Gpu.Memory;
  8. using Ryujinx.Graphics.Gpu.State;
  9. using Ryujinx.Graphics.Shader;
  10. using System;
  11. using System.Runtime.InteropServices;
  12. namespace Ryujinx.Graphics.Gpu.Engine
  13. {
  14. partial class Methods
  15. {
  16. private GpuContext _context;
  17. private ShaderCache _shaderCache;
  18. private ShaderProgramInfo[] _currentProgramInfo;
  19. private BufferManager _bufferManager;
  20. private TextureManager _textureManager;
  21. public BufferManager BufferManager => _bufferManager;
  22. public TextureManager TextureManager => _textureManager;
  23. private bool _isAnyVbInstanced;
  24. private bool _vsUsesInstanceId;
  25. public Methods(GpuContext context)
  26. {
  27. _context = context;
  28. _shaderCache = new ShaderCache(_context);
  29. _currentProgramInfo = new ShaderProgramInfo[Constants.TotalShaderStages];
  30. _bufferManager = new BufferManager(context);
  31. _textureManager = new TextureManager(context);
  32. RegisterCallbacks();
  33. }
  34. private void RegisterCallbacks()
  35. {
  36. _context.State.RegisterCallback(MethodOffset.LaunchDma, LaunchDma);
  37. _context.State.RegisterCallback(MethodOffset.LoadInlineData, LoadInlineData);
  38. _context.State.RegisterCallback(MethodOffset.Dispatch, Dispatch);
  39. _context.State.RegisterCallback(MethodOffset.CopyBuffer, CopyBuffer);
  40. _context.State.RegisterCallback(MethodOffset.CopyTexture, CopyTexture);
  41. _context.State.RegisterCallback(MethodOffset.TextureBarrier, TextureBarrier);
  42. _context.State.RegisterCallback(MethodOffset.InvalidateTextures, InvalidateTextures);
  43. _context.State.RegisterCallback(MethodOffset.TextureBarrierTiled, TextureBarrierTiled);
  44. _context.State.RegisterCallback(MethodOffset.ResetCounter, ResetCounter);
  45. _context.State.RegisterCallback(MethodOffset.DrawEnd, DrawEnd);
  46. _context.State.RegisterCallback(MethodOffset.DrawBegin, DrawBegin);
  47. _context.State.RegisterCallback(MethodOffset.IndexBufferCount, SetIndexBufferCount);
  48. _context.State.RegisterCallback(MethodOffset.Clear, Clear);
  49. _context.State.RegisterCallback(MethodOffset.Report, Report);
  50. _context.State.RegisterCallback(MethodOffset.UniformBufferUpdateData, 16, UniformBufferUpdate);
  51. _context.State.RegisterCallback(MethodOffset.UniformBufferBindVertex, UniformBufferBindVertex);
  52. _context.State.RegisterCallback(MethodOffset.UniformBufferBindTessControl, UniformBufferBindTessControl);
  53. _context.State.RegisterCallback(MethodOffset.UniformBufferBindTessEvaluation, UniformBufferBindTessEvaluation);
  54. _context.State.RegisterCallback(MethodOffset.UniformBufferBindGeometry, UniformBufferBindGeometry);
  55. _context.State.RegisterCallback(MethodOffset.UniformBufferBindFragment, UniformBufferBindFragment);
  56. }
  57. public Image.Texture GetTexture(ulong address) => _textureManager.Find2(address);
  58. private void UpdateState()
  59. {
  60. // Shaders must be the first one to be updated if modified, because
  61. // some of the other state depends on information from the currently
  62. // bound shaders.
  63. if (_context.State.QueryModified(MethodOffset.ShaderBaseAddress, MethodOffset.ShaderState))
  64. {
  65. UpdateShaderState();
  66. }
  67. UpdateRenderTargetStateIfNeeded();
  68. if (_context.State.QueryModified(MethodOffset.DepthTestEnable,
  69. MethodOffset.DepthWriteEnable,
  70. MethodOffset.DepthTestFunc))
  71. {
  72. UpdateDepthTestState();
  73. }
  74. if (_context.State.QueryModified(MethodOffset.ViewportTransform, MethodOffset.ViewportExtents))
  75. {
  76. UpdateViewportTransform();
  77. }
  78. if (_context.State.QueryModified(MethodOffset.DepthBiasState,
  79. MethodOffset.DepthBiasFactor,
  80. MethodOffset.DepthBiasUnits,
  81. MethodOffset.DepthBiasClamp))
  82. {
  83. UpdateDepthBiasState();
  84. }
  85. if (_context.State.QueryModified(MethodOffset.StencilBackMasks,
  86. MethodOffset.StencilTestState,
  87. MethodOffset.StencilBackTestState))
  88. {
  89. UpdateStencilTestState();
  90. }
  91. // Pools.
  92. if (_context.State.QueryModified(MethodOffset.SamplerPoolState))
  93. {
  94. UpdateSamplerPoolState();
  95. }
  96. if (_context.State.QueryModified(MethodOffset.TexturePoolState))
  97. {
  98. UpdateTexturePoolState();
  99. }
  100. // Input assembler state.
  101. if (_context.State.QueryModified(MethodOffset.VertexAttribState))
  102. {
  103. UpdateVertexAttribState();
  104. }
  105. if (_context.State.QueryModified(MethodOffset.PrimitiveRestartState))
  106. {
  107. UpdatePrimitiveRestartState();
  108. }
  109. if (_context.State.QueryModified(MethodOffset.IndexBufferState))
  110. {
  111. UpdateIndexBufferState();
  112. }
  113. if (_context.State.QueryModified(MethodOffset.VertexBufferDrawState,
  114. MethodOffset.VertexBufferInstanced,
  115. MethodOffset.VertexBufferState,
  116. MethodOffset.VertexBufferEndAddress))
  117. {
  118. UpdateVertexBufferState();
  119. }
  120. if (_context.State.QueryModified(MethodOffset.FaceState))
  121. {
  122. UpdateFaceState();
  123. }
  124. if (_context.State.QueryModified(MethodOffset.RtColorMask))
  125. {
  126. UpdateRtColorMask();
  127. }
  128. if (_context.State.QueryModified(MethodOffset.BlendEnable, MethodOffset.BlendState))
  129. {
  130. UpdateBlendState();
  131. }
  132. CommitBindings();
  133. }
  134. private void CommitBindings()
  135. {
  136. UpdateStorageBuffers();
  137. _bufferManager.CommitBindings();
  138. _textureManager.CommitGraphicsBindings();
  139. }
  140. private void UpdateStorageBuffers()
  141. {
  142. for (int stage = 0; stage < _currentProgramInfo.Length; stage++)
  143. {
  144. ShaderProgramInfo info = _currentProgramInfo[stage];
  145. if (info == null)
  146. {
  147. continue;
  148. }
  149. for (int index = 0; index < info.SBuffers.Count; index++)
  150. {
  151. BufferDescriptor sb = info.SBuffers[index];
  152. ulong sbDescAddress = _bufferManager.GetGraphicsUniformBufferAddress(stage, 0);
  153. int sbDescOffset = 0x110 + stage * 0x100 + sb.Slot * 0x10;
  154. sbDescAddress += (ulong)sbDescOffset;
  155. Span<byte> sbDescriptorData = _context.PhysicalMemory.Read(sbDescAddress, 0x10);
  156. SbDescriptor sbDescriptor = MemoryMarshal.Cast<byte, SbDescriptor>(sbDescriptorData)[0];
  157. _bufferManager.SetGraphicsStorageBuffer(stage, sb.Slot, sbDescriptor.PackAddress(), (uint)sbDescriptor.Size);
  158. }
  159. }
  160. }
  161. private void UpdateRenderTargetStateIfNeeded()
  162. {
  163. if (_context.State.QueryModified(MethodOffset.RtColorState,
  164. MethodOffset.RtDepthStencilState,
  165. MethodOffset.RtDepthStencilSize,
  166. MethodOffset.RtDepthStencilEnable))
  167. {
  168. UpdateRenderTargetState();
  169. }
  170. }
  171. private void UpdateRenderTargetState()
  172. {
  173. var msaaMode = _context.State.Get<TextureMsaaMode>(MethodOffset.RtMsaaMode);
  174. int samplesInX = msaaMode.SamplesInX();
  175. int samplesInY = msaaMode.SamplesInY();
  176. for (int index = 0; index < Constants.TotalRenderTargets; index++)
  177. {
  178. var colorState = _context.State.Get<RtColorState>(MethodOffset.RtColorState, index);
  179. if (!IsRtEnabled(colorState))
  180. {
  181. _textureManager.SetRenderTargetColor(index, null);
  182. continue;
  183. }
  184. Image.Texture color = _textureManager.FindOrCreateTexture(
  185. colorState,
  186. samplesInX,
  187. samplesInY);
  188. _textureManager.SetRenderTargetColor(index, color);
  189. if (color != null)
  190. {
  191. color.Modified = true;
  192. }
  193. }
  194. bool dsEnable = _context.State.Get<Boolean32>(MethodOffset.RtDepthStencilEnable);
  195. Image.Texture depthStencil = null;
  196. if (dsEnable)
  197. {
  198. var dsState = _context.State.Get<RtDepthStencilState>(MethodOffset.RtDepthStencilState);
  199. var dsSize = _context.State.Get<Size3D> (MethodOffset.RtDepthStencilSize);
  200. depthStencil = _textureManager.FindOrCreateTexture(
  201. dsState,
  202. dsSize,
  203. samplesInX,
  204. samplesInY);
  205. }
  206. _textureManager.SetRenderTargetDepthStencil(depthStencil);
  207. if (depthStencil != null)
  208. {
  209. depthStencil.Modified = true;
  210. }
  211. }
  212. private static bool IsRtEnabled(RtColorState colorState)
  213. {
  214. // Colors are disabled by writing 0 to the format.
  215. return colorState.Format != 0 && colorState.WidthOrStride != 0;
  216. }
  217. private void UpdateDepthTestState()
  218. {
  219. _context.Renderer.Pipeline.SetDepthTest(new DepthTestDescriptor(
  220. _context.State.Get<Boolean32>(MethodOffset.DepthTestEnable),
  221. _context.State.Get<Boolean32>(MethodOffset.DepthWriteEnable),
  222. _context.State.Get<CompareOp>(MethodOffset.DepthTestFunc)));
  223. }
  224. private void UpdateViewportTransform()
  225. {
  226. Viewport[] viewports = new Viewport[Constants.TotalViewports];
  227. for (int index = 0; index < Constants.TotalViewports; index++)
  228. {
  229. var transform = _context.State.Get<ViewportTransform>(MethodOffset.ViewportTransform, index);
  230. var extents = _context.State.Get<ViewportExtents> (MethodOffset.ViewportExtents, index);
  231. float x = transform.TranslateX - MathF.Abs(transform.ScaleX);
  232. float y = transform.TranslateY - MathF.Abs(transform.ScaleY);
  233. float width = transform.ScaleX * 2;
  234. float height = transform.ScaleY * 2;
  235. RectangleF region = new RectangleF(x, y, width, height);
  236. viewports[index] = new Viewport(
  237. region,
  238. transform.UnpackSwizzleX(),
  239. transform.UnpackSwizzleY(),
  240. transform.UnpackSwizzleZ(),
  241. transform.UnpackSwizzleW(),
  242. extents.DepthNear,
  243. extents.DepthFar);
  244. }
  245. _context.Renderer.Pipeline.SetViewports(0, viewports);
  246. }
  247. private void UpdateDepthBiasState()
  248. {
  249. var depthBias = _context.State.Get<DepthBiasState>(MethodOffset.DepthBiasState);
  250. float factor = _context.State.Get<float>(MethodOffset.DepthBiasFactor);
  251. float units = _context.State.Get<float>(MethodOffset.DepthBiasUnits);
  252. float clamp = _context.State.Get<float>(MethodOffset.DepthBiasClamp);
  253. PolygonModeMask enables = 0;
  254. enables = (depthBias.PointEnable ? PolygonModeMask.Point : 0);
  255. enables |= (depthBias.LineEnable ? PolygonModeMask.Line : 0);
  256. enables |= (depthBias.FillEnable ? PolygonModeMask.Fill : 0);
  257. _context.Renderer.Pipeline.SetDepthBias(enables, factor, units, clamp);
  258. }
  259. private void UpdateStencilTestState()
  260. {
  261. var backMasks = _context.State.Get<StencilBackMasks> (MethodOffset.StencilBackMasks);
  262. var test = _context.State.Get<StencilTestState> (MethodOffset.StencilTestState);
  263. var backTest = _context.State.Get<StencilBackTestState>(MethodOffset.StencilBackTestState);
  264. CompareOp backFunc;
  265. StencilOp backSFail;
  266. StencilOp backDpPass;
  267. StencilOp backDpFail;
  268. int backFuncRef;
  269. int backFuncMask;
  270. int backMask;
  271. if (backTest.TwoSided)
  272. {
  273. backFunc = backTest.BackFunc;
  274. backSFail = backTest.BackSFail;
  275. backDpPass = backTest.BackDpPass;
  276. backDpFail = backTest.BackDpFail;
  277. backFuncRef = backMasks.FuncRef;
  278. backFuncMask = backMasks.FuncMask;
  279. backMask = backMasks.Mask;
  280. }
  281. else
  282. {
  283. backFunc = test.FrontFunc;
  284. backSFail = test.FrontSFail;
  285. backDpPass = test.FrontDpPass;
  286. backDpFail = test.FrontDpFail;
  287. backFuncRef = test.FrontFuncRef;
  288. backFuncMask = test.FrontFuncMask;
  289. backMask = test.FrontMask;
  290. }
  291. _context.Renderer.Pipeline.SetStencilTest(new StencilTestDescriptor(
  292. test.Enable,
  293. test.FrontFunc,
  294. test.FrontSFail,
  295. test.FrontDpPass,
  296. test.FrontDpFail,
  297. test.FrontFuncRef,
  298. test.FrontFuncMask,
  299. test.FrontMask,
  300. backFunc,
  301. backSFail,
  302. backDpPass,
  303. backDpFail,
  304. backFuncRef,
  305. backFuncMask,
  306. backMask));
  307. }
  308. private void UpdateSamplerPoolState()
  309. {
  310. var samplerPool = _context.State.Get<PoolState>(MethodOffset.SamplerPoolState);
  311. _textureManager.SetGraphicsSamplerPool(samplerPool.Address.Pack(), samplerPool.MaximumId);
  312. }
  313. private void UpdateTexturePoolState()
  314. {
  315. var texturePool = _context.State.Get<PoolState>(MethodOffset.TexturePoolState);
  316. _textureManager.SetGraphicsTexturePool(texturePool.Address.Pack(), texturePool.MaximumId);
  317. _textureManager.SetGraphicsTextureBufferIndex(_context.State.Get<int>(MethodOffset.TextureBufferIndex));
  318. }
  319. private void UpdateVertexAttribState()
  320. {
  321. VertexAttribDescriptor[] vertexAttribs = new VertexAttribDescriptor[16];
  322. for (int index = 0; index < 16; index++)
  323. {
  324. var vertexAttrib = _context.State.Get<VertexAttribState>(MethodOffset.VertexAttribState, index);
  325. if (!FormatTable.TryGetAttribFormat(vertexAttrib.UnpackFormat(), out Format format))
  326. {
  327. // TODO: warning.
  328. format = Format.R32G32B32A32Float;
  329. }
  330. vertexAttribs[index] = new VertexAttribDescriptor(
  331. vertexAttrib.UnpackBufferIndex(),
  332. vertexAttrib.UnpackOffset(),
  333. format);
  334. }
  335. _context.Renderer.Pipeline.BindVertexAttribs(vertexAttribs);
  336. }
  337. private void UpdatePrimitiveRestartState()
  338. {
  339. PrimitiveRestartState primitiveRestart = _context.State.Get<PrimitiveRestartState>(MethodOffset.PrimitiveRestartState);
  340. _context.Renderer.Pipeline.SetPrimitiveRestart(
  341. primitiveRestart.Enable,
  342. primitiveRestart.Index);
  343. }
  344. private void UpdateIndexBufferState()
  345. {
  346. var indexBuffer = _context.State.Get<IndexBufferState>(MethodOffset.IndexBufferState);
  347. _firstIndex = indexBuffer.First;
  348. _indexCount = indexBuffer.Count;
  349. if (_indexCount == 0)
  350. {
  351. return;
  352. }
  353. ulong gpuVa = indexBuffer.Address.Pack();
  354. // Do not use the end address to calculate the size, because
  355. // the result may be much larger than the real size of the index buffer.
  356. ulong size = (ulong)(_firstIndex + _indexCount);
  357. switch (indexBuffer.Type)
  358. {
  359. case IndexType.UShort: size *= 2; break;
  360. case IndexType.UInt: size *= 4; break;
  361. }
  362. _bufferManager.SetIndexBuffer(gpuVa, size, indexBuffer.Type);
  363. // The index buffer affects the vertex buffer size calculation, we
  364. // need to ensure that they are updated.
  365. UpdateVertexBufferState();
  366. }
  367. private void UpdateVertexBufferState()
  368. {
  369. _isAnyVbInstanced = false;
  370. for (int index = 0; index < 16; index++)
  371. {
  372. var vertexBuffer = _context.State.Get<VertexBufferState>(MethodOffset.VertexBufferState, index);
  373. if (!vertexBuffer.UnpackEnable())
  374. {
  375. _bufferManager.SetVertexBuffer(index, 0, 0, 0, 0);
  376. continue;
  377. }
  378. GpuVa endAddress = _context.State.Get<GpuVa>(MethodOffset.VertexBufferEndAddress, index);
  379. ulong address = vertexBuffer.Address.Pack();
  380. int stride = vertexBuffer.UnpackStride();
  381. bool instanced = _context.State.Get<Boolean32>(MethodOffset.VertexBufferInstanced + index);
  382. int divisor = instanced ? vertexBuffer.Divisor : 0;
  383. _isAnyVbInstanced |= divisor != 0;
  384. ulong size;
  385. if (_drawIndexed || stride == 0 || instanced)
  386. {
  387. // This size may be (much) larger than the real vertex buffer size.
  388. // Avoid calculating it this way, unless we don't have any other option.
  389. size = endAddress.Pack() - address + 1;
  390. }
  391. else
  392. {
  393. // For non-indexed draws, we can guess the size from the vertex count
  394. // and stride.
  395. int firstInstance = _context.State.Get<int>(MethodOffset.FirstInstance);
  396. var drawState = _context.State.Get<VertexBufferDrawState>(MethodOffset.VertexBufferDrawState);
  397. size = (ulong)((firstInstance + drawState.First + drawState.Count) * stride);
  398. }
  399. _bufferManager.SetVertexBuffer(index, address, size, stride, divisor);
  400. }
  401. }
  402. private void UpdateFaceState()
  403. {
  404. var face = _context.State.Get<FaceState>(MethodOffset.FaceState);
  405. _context.Renderer.Pipeline.SetFaceCulling(face.CullEnable, face.CullFace);
  406. _context.Renderer.Pipeline.SetFrontFace(face.FrontFace);
  407. }
  408. private void UpdateRtColorMask()
  409. {
  410. uint[] componentMasks = new uint[Constants.TotalRenderTargets];
  411. for (int index = 0; index < Constants.TotalRenderTargets; index++)
  412. {
  413. var colorMask = _context.State.Get<RtColorMask>(MethodOffset.RtColorMask, index);
  414. uint componentMask = 0;
  415. componentMask = (colorMask.UnpackRed() ? 1u : 0u);
  416. componentMask |= (colorMask.UnpackGreen() ? 2u : 0u);
  417. componentMask |= (colorMask.UnpackBlue() ? 4u : 0u);
  418. componentMask |= (colorMask.UnpackAlpha() ? 8u : 0u);
  419. componentMasks[index] = componentMask;
  420. }
  421. _context.Renderer.Pipeline.SetRenderTargetColorMasks(componentMasks);
  422. }
  423. private void UpdateBlendState()
  424. {
  425. BlendState[] blends = new BlendState[8];
  426. for (int index = 0; index < 8; index++)
  427. {
  428. bool enable = _context.State.Get<Boolean32>(MethodOffset.BlendEnable, index);
  429. var blend = _context.State.Get<BlendState>(MethodOffset.BlendState, index);
  430. BlendDescriptor descriptor = new BlendDescriptor(
  431. enable,
  432. blend.ColorOp,
  433. blend.ColorSrcFactor,
  434. blend.ColorDstFactor,
  435. blend.AlphaOp,
  436. blend.AlphaSrcFactor,
  437. blend.AlphaDstFactor);
  438. _context.Renderer.Pipeline.BindBlendState(index, descriptor);
  439. }
  440. }
  441. private struct SbDescriptor
  442. {
  443. public uint AddressLow;
  444. public uint AddressHigh;
  445. public int Size;
  446. public int Padding;
  447. public ulong PackAddress()
  448. {
  449. return AddressLow | ((ulong)AddressHigh << 32);
  450. }
  451. }
  452. private void UpdateShaderState()
  453. {
  454. ShaderAddresses addresses = new ShaderAddresses();
  455. Span<ShaderAddresses> addressesSpan = MemoryMarshal.CreateSpan(ref addresses, 1);
  456. Span<ulong> addressesArray = MemoryMarshal.Cast<ShaderAddresses, ulong>(addressesSpan);
  457. ulong baseAddress = _context.State.Get<GpuVa>(MethodOffset.ShaderBaseAddress).Pack();
  458. for (int index = 0; index < 6; index++)
  459. {
  460. var shader = _context.State.Get<ShaderState>(MethodOffset.ShaderState, index);
  461. if (!shader.UnpackEnable() && index != 1)
  462. {
  463. continue;
  464. }
  465. addressesArray[index] = baseAddress + shader.Offset;
  466. }
  467. GraphicsShader gs = _shaderCache.GetGraphicsShader(addresses);
  468. _vsUsesInstanceId = gs.Shader[0].Info.UsesInstanceId;
  469. for (int stage = 0; stage < Constants.TotalShaderStages; stage++)
  470. {
  471. ShaderProgramInfo info = gs.Shader[stage]?.Info;
  472. _currentProgramInfo[stage] = info;
  473. if (info == null)
  474. {
  475. continue;
  476. }
  477. var textureBindings = new TextureBindingInfo[info.Textures.Count];
  478. for (int index = 0; index < info.Textures.Count; index++)
  479. {
  480. var descriptor = info.Textures[index];
  481. Target target = GetTarget(descriptor.Type);
  482. textureBindings[index] = new TextureBindingInfo(target, descriptor.HandleIndex);
  483. }
  484. _textureManager.SetGraphicsTextures(stage, textureBindings);
  485. var imageBindings = new TextureBindingInfo[info.Images.Count];
  486. for (int index = 0; index < info.Images.Count; index++)
  487. {
  488. var descriptor = info.Images[index];
  489. Target target = GetTarget(descriptor.Type);
  490. imageBindings[index] = new TextureBindingInfo(target, descriptor.HandleIndex);
  491. }
  492. _textureManager.SetGraphicsImages(stage, imageBindings);
  493. uint sbEnableMask = 0;
  494. uint ubEnableMask = 0;
  495. for (int index = 0; index < info.SBuffers.Count; index++)
  496. {
  497. sbEnableMask |= 1u << info.SBuffers[index].Slot;
  498. }
  499. for (int index = 0; index < info.CBuffers.Count; index++)
  500. {
  501. ubEnableMask |= 1u << info.CBuffers[index].Slot;
  502. }
  503. _bufferManager.SetGraphicsStorageBufferEnableMask(stage, sbEnableMask);
  504. _bufferManager.SetGraphicsUniformBufferEnableMask(stage, ubEnableMask);
  505. }
  506. _context.Renderer.Pipeline.BindProgram(gs.Interface);
  507. }
  508. private static Target GetTarget(SamplerType type)
  509. {
  510. type &= ~SamplerType.Shadow;
  511. switch (type)
  512. {
  513. case SamplerType.Texture1D:
  514. return Target.Texture1D;
  515. case SamplerType.TextureBuffer:
  516. return Target.TextureBuffer;
  517. case SamplerType.Texture1D | SamplerType.Array:
  518. return Target.Texture1DArray;
  519. case SamplerType.Texture2D:
  520. return Target.Texture2D;
  521. case SamplerType.Texture2D | SamplerType.Array:
  522. return Target.Texture2DArray;
  523. case SamplerType.Texture2D | SamplerType.Multisample:
  524. return Target.Texture2DMultisample;
  525. case SamplerType.Texture2D | SamplerType.Multisample | SamplerType.Array:
  526. return Target.Texture2DMultisampleArray;
  527. case SamplerType.Texture3D:
  528. return Target.Texture3D;
  529. case SamplerType.TextureCube:
  530. return Target.Cubemap;
  531. case SamplerType.TextureCube | SamplerType.Array:
  532. return Target.CubemapArray;
  533. }
  534. // TODO: Warning.
  535. return Target.Texture2D;
  536. }
  537. private void TextureBarrier(int argument)
  538. {
  539. _context.Renderer.Pipeline.TextureBarrier();
  540. }
  541. private void InvalidateTextures(int argument)
  542. {
  543. _textureManager.Flush();
  544. }
  545. private void TextureBarrierTiled(int argument)
  546. {
  547. _context.Renderer.Pipeline.TextureBarrierTiled();
  548. }
  549. }
  550. }