Methods.cs 27 KB

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