Start building more accurate vertex as compute usage info
This commit is contained in:
parent
3214a4cf8e
commit
29cca80d9f
4 changed files with 143 additions and 13 deletions
|
@ -435,6 +435,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
geometryAsCompute = CreateHostVertexAsComputeProgram(program, currentStage, tfEnabled);
|
geometryAsCompute = CreateHostVertexAsComputeProgram(program, currentStage, tfEnabled);
|
||||||
program = null;
|
program = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
infoBuilder.AddStageInfoVac(currentStage.GetVertexAsComputeInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (program != null)
|
if (program != null)
|
||||||
|
@ -533,7 +535,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
private ShaderAsCompute CreateHostVertexAsComputeProgram(ShaderProgram program, TranslatorContext context, bool tfEnabled)
|
private ShaderAsCompute CreateHostVertexAsComputeProgram(ShaderProgram program, TranslatorContext context, bool tfEnabled)
|
||||||
{
|
{
|
||||||
ShaderSource source = new(program.Code, program.BinaryCode, ShaderStage.Compute, program.Language);
|
ShaderSource source = new(program.Code, program.BinaryCode, ShaderStage.Compute, program.Language);
|
||||||
ShaderInfo info = ShaderInfoBuilder.BuildForVertexAsCompute(_context, program.Info, tfEnabled);
|
ShaderInfo info = ShaderInfoBuilder.BuildForVertexAsCompute(_context, program.Info, context.GetVertexAsComputeInfo(), tfEnabled);
|
||||||
|
|
||||||
return new(_context.Renderer.CreateProgram(new[] { source }, info), program.Info, context.GetResourceReservations());
|
return new(_context.Renderer.CreateProgram(new[] { source }, info), program.Info, context.GetResourceReservations());
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
private void PopulateDescriptorAndUsages(ResourceStages stages, ResourceType type, int setIndex, int start, int count, bool write = false)
|
private void PopulateDescriptorAndUsages(ResourceStages stages, ResourceType type, int setIndex, int start, int count, bool write = false)
|
||||||
{
|
{
|
||||||
AddDescriptor(stages, type, setIndex, start, count);
|
AddDescriptor(stages, type, setIndex, start, count);
|
||||||
AddUsage(stages, type, setIndex, start, count, write);
|
// AddUsage(stages, type, setIndex, start, count, write);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -162,6 +162,25 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
AddUsage(info.Images, stages, isImage: true);
|
AddUsage(info.Images, stages, isImage: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddStageInfoVac(ShaderProgramInfo info)
|
||||||
|
{
|
||||||
|
ResourceStages stages = info.Stage switch
|
||||||
|
{
|
||||||
|
ShaderStage.Compute => ResourceStages.Compute,
|
||||||
|
ShaderStage.Vertex => ResourceStages.Vertex,
|
||||||
|
ShaderStage.TessellationControl => ResourceStages.TessellationControl,
|
||||||
|
ShaderStage.TessellationEvaluation => ResourceStages.TessellationEvaluation,
|
||||||
|
ShaderStage.Geometry => ResourceStages.Geometry,
|
||||||
|
ShaderStage.Fragment => ResourceStages.Fragment,
|
||||||
|
_ => ResourceStages.None,
|
||||||
|
};
|
||||||
|
|
||||||
|
AddUsage(info.CBuffers, stages, isStorage: false);
|
||||||
|
AddUsage(info.SBuffers, stages, isStorage: true);
|
||||||
|
AddUsage(info.Textures, stages, isImage: false);
|
||||||
|
AddUsage(info.Images, stages, isImage: true);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a resource descriptor to the list of descriptors.
|
/// Adds a resource descriptor to the list of descriptors.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -421,11 +440,12 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
/// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param>
|
/// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param>
|
||||||
/// <param name="fromCache">True if the compute shader comes from a disk cache, false otherwise</param>
|
/// <param name="fromCache">True if the compute shader comes from a disk cache, false otherwise</param>
|
||||||
/// <returns>Shader information</returns>
|
/// <returns>Shader information</returns>
|
||||||
public static ShaderInfo BuildForVertexAsCompute(GpuContext context, ShaderProgramInfo info, bool tfEnabled, bool fromCache = false)
|
public static ShaderInfo BuildForVertexAsCompute(GpuContext context, ShaderProgramInfo info, ShaderProgramInfo info2, bool tfEnabled, bool fromCache = false)
|
||||||
{
|
{
|
||||||
ShaderInfoBuilder builder = new(context, tfEnabled, vertexAsCompute: true, computeLocalSize: ComputeSize.VtgAsCompute);
|
ShaderInfoBuilder builder = new(context, tfEnabled, vertexAsCompute: true, computeLocalSize: ComputeSize.VtgAsCompute);
|
||||||
|
|
||||||
builder.AddStageInfo(info, vertexAsCompute: true);
|
builder.AddStageInfo(info, vertexAsCompute: true);
|
||||||
|
builder.AddStageInfoVac(info2);
|
||||||
|
|
||||||
return builder.Build(null, fromCache);
|
return builder.Build(null, fromCache);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
private readonly Dictionary<TextureInfo, TextureMeta> _usedTextures;
|
private readonly Dictionary<TextureInfo, TextureMeta> _usedTextures;
|
||||||
private readonly Dictionary<TextureInfo, TextureMeta> _usedImages;
|
private readonly Dictionary<TextureInfo, TextureMeta> _usedImages;
|
||||||
|
|
||||||
|
private readonly List<BufferDefinition> _vacConstantBuffers;
|
||||||
|
private readonly List<BufferDefinition> _vacStorageBuffers;
|
||||||
|
private readonly List<TextureDefinition> _vacTextures;
|
||||||
|
private readonly List<TextureDefinition> _vacImages;
|
||||||
|
|
||||||
public int LocalMemoryId { get; private set; }
|
public int LocalMemoryId { get; private set; }
|
||||||
public int SharedMemoryId { get; private set; }
|
public int SharedMemoryId { get; private set; }
|
||||||
|
|
||||||
|
@ -78,6 +83,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
_usedTextures = new();
|
_usedTextures = new();
|
||||||
_usedImages = new();
|
_usedImages = new();
|
||||||
|
|
||||||
|
_vacConstantBuffers = new();
|
||||||
|
_vacStorageBuffers = new();
|
||||||
|
_vacTextures = new();
|
||||||
|
_vacImages = new();
|
||||||
|
|
||||||
Properties.AddOrUpdateConstantBuffer(new(BufferLayout.Std140, 0, SupportBuffer.Binding, "support_buffer", SupportBuffer.GetStructureType()));
|
Properties.AddOrUpdateConstantBuffer(new(BufferLayout.Std140, 0, SupportBuffer.Binding, "support_buffer", SupportBuffer.GetStructureType()));
|
||||||
|
|
||||||
LocalMemoryId = -1;
|
LocalMemoryId = -1;
|
||||||
|
@ -563,6 +573,75 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
return descriptors.ToArray();
|
return descriptors.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ShaderProgramInfo GetVertexAsComputeInfo()
|
||||||
|
{
|
||||||
|
var cbDescriptors = new BufferDescriptor[_vacConstantBuffers.Count];
|
||||||
|
int cbDescriptorIndex = 0;
|
||||||
|
|
||||||
|
foreach (BufferDefinition definition in _vacConstantBuffers)
|
||||||
|
{
|
||||||
|
cbDescriptors[cbDescriptorIndex++] = new BufferDescriptor(definition.Set, definition.Binding, 0, 0, 0, BufferUsageFlags.None);
|
||||||
|
}
|
||||||
|
|
||||||
|
var sbDescriptors = new BufferDescriptor[_vacStorageBuffers.Count];
|
||||||
|
int sbDescriptorIndex = 0;
|
||||||
|
|
||||||
|
foreach (BufferDefinition definition in _vacStorageBuffers)
|
||||||
|
{
|
||||||
|
sbDescriptors[sbDescriptorIndex++] = new BufferDescriptor(definition.Set, definition.Binding, 0, 0, 0, BufferUsageFlags.Write);
|
||||||
|
}
|
||||||
|
|
||||||
|
var tDescriptors = new TextureDescriptor[_vacTextures.Count];
|
||||||
|
int tDescriptorIndex = 0;
|
||||||
|
|
||||||
|
foreach (TextureDefinition definition in _vacTextures)
|
||||||
|
{
|
||||||
|
tDescriptors[tDescriptorIndex++] = new TextureDescriptor(
|
||||||
|
definition.Set,
|
||||||
|
definition.Binding,
|
||||||
|
definition.Type,
|
||||||
|
definition.Format,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
definition.ArrayLength,
|
||||||
|
definition.Separate,
|
||||||
|
definition.Flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
var iDescriptors = new TextureDescriptor[_vacImages.Count];
|
||||||
|
int iDescriptorIndex = 0;
|
||||||
|
|
||||||
|
foreach (TextureDefinition definition in _vacImages)
|
||||||
|
{
|
||||||
|
iDescriptors[iDescriptorIndex++] = new TextureDescriptor(
|
||||||
|
definition.Set,
|
||||||
|
definition.Binding,
|
||||||
|
definition.Type,
|
||||||
|
definition.Format,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
definition.ArrayLength,
|
||||||
|
definition.Separate,
|
||||||
|
definition.Flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ShaderProgramInfo(
|
||||||
|
cbDescriptors,
|
||||||
|
sbDescriptors,
|
||||||
|
tDescriptors,
|
||||||
|
iDescriptors,
|
||||||
|
ShaderStage.Compute,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
public bool TryGetCbufSlotAndHandleForTexture(int binding, out int cbufSlot, out int handle)
|
public bool TryGetCbufSlotAndHandleForTexture(int binding, out int cbufSlot, out int handle)
|
||||||
{
|
{
|
||||||
foreach ((TextureInfo info, TextureMeta meta) in _usedTextures)
|
foreach ((TextureInfo info, TextureMeta meta) in _usedTextures)
|
||||||
|
@ -629,6 +708,30 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
Properties.AddOrUpdateStorageBuffer(new(BufferLayout.Std430, setIndex, binding, name, type));
|
Properties.AddOrUpdateStorageBuffer(new(BufferLayout.Std430, setIndex, binding, name, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddVertexAsComputeConstantBuffer(BufferDefinition definition)
|
||||||
|
{
|
||||||
|
_vacConstantBuffers.Add(definition);
|
||||||
|
Properties.AddOrUpdateConstantBuffer(definition);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddVertexAsComputeStorageBuffer(BufferDefinition definition)
|
||||||
|
{
|
||||||
|
_vacStorageBuffers.Add(definition);
|
||||||
|
Properties.AddOrUpdateStorageBuffer(definition);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddVertexAsComputeTexture(TextureDefinition definition)
|
||||||
|
{
|
||||||
|
_vacTextures.Add(definition);
|
||||||
|
Properties.AddOrUpdateTexture(definition);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddVertexAsComputeImage(TextureDefinition definition)
|
||||||
|
{
|
||||||
|
_vacImages.Add(definition);
|
||||||
|
Properties.AddOrUpdateImage(definition);
|
||||||
|
}
|
||||||
|
|
||||||
public static string GetShaderStagePrefix(ShaderStage stage)
|
public static string GetShaderStagePrefix(ShaderStage stage)
|
||||||
{
|
{
|
||||||
uint index = (uint)stage;
|
uint index = (uint)stage;
|
||||||
|
|
|
@ -394,7 +394,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
{
|
{
|
||||||
int binding = resourceManager.Reservations.GetTfeBufferStorageBufferBinding(i);
|
int binding = resourceManager.Reservations.GetTfeBufferStorageBufferBinding(i);
|
||||||
BufferDefinition tfeDataBuffer = new(BufferLayout.Std430, 1, binding, $"tfe_data{i}", tfeDataStruct);
|
BufferDefinition tfeDataBuffer = new(BufferLayout.Std430, 1, binding, $"tfe_data{i}", tfeDataStruct);
|
||||||
resourceManager.Properties.AddOrUpdateStorageBuffer(tfeDataBuffer);
|
resourceManager.AddVertexAsComputeStorageBuffer(tfeDataBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,7 +402,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
{
|
{
|
||||||
int vertexInfoCbBinding = resourceManager.Reservations.VertexInfoConstantBufferBinding;
|
int vertexInfoCbBinding = resourceManager.Reservations.VertexInfoConstantBufferBinding;
|
||||||
BufferDefinition vertexInfoBuffer = new(BufferLayout.Std140, 0, vertexInfoCbBinding, "vb_info", VertexInfoBuffer.GetStructureType());
|
BufferDefinition vertexInfoBuffer = new(BufferLayout.Std140, 0, vertexInfoCbBinding, "vb_info", VertexInfoBuffer.GetStructureType());
|
||||||
resourceManager.Properties.AddOrUpdateConstantBuffer(vertexInfoBuffer);
|
resourceManager.AddVertexAsComputeConstantBuffer(vertexInfoBuffer);
|
||||||
|
|
||||||
StructureType vertexOutputStruct = new(new StructureField[]
|
StructureType vertexOutputStruct = new(new StructureField[]
|
||||||
{
|
{
|
||||||
|
@ -411,13 +411,13 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
|
|
||||||
int vertexOutputSbBinding = resourceManager.Reservations.VertexOutputStorageBufferBinding;
|
int vertexOutputSbBinding = resourceManager.Reservations.VertexOutputStorageBufferBinding;
|
||||||
BufferDefinition vertexOutputBuffer = new(BufferLayout.Std430, 1, vertexOutputSbBinding, "vertex_output", vertexOutputStruct);
|
BufferDefinition vertexOutputBuffer = new(BufferLayout.Std430, 1, vertexOutputSbBinding, "vertex_output", vertexOutputStruct);
|
||||||
resourceManager.Properties.AddOrUpdateStorageBuffer(vertexOutputBuffer);
|
resourceManager.AddVertexAsComputeStorageBuffer(vertexOutputBuffer);
|
||||||
|
|
||||||
if (Stage == ShaderStage.Vertex)
|
if (Stage == ShaderStage.Vertex)
|
||||||
{
|
{
|
||||||
SetBindingPair ibSetAndBinding = resourceManager.Reservations.GetIndexBufferTextureSetAndBinding();
|
SetBindingPair ibSetAndBinding = resourceManager.Reservations.GetIndexBufferTextureSetAndBinding();
|
||||||
TextureDefinition indexBuffer = new(ibSetAndBinding.SetIndex, ibSetAndBinding.Binding, "ib_data", SamplerType.TextureBuffer);
|
TextureDefinition indexBuffer = new(ibSetAndBinding.SetIndex, ibSetAndBinding.Binding, "ib_data", SamplerType.TextureBuffer);
|
||||||
resourceManager.Properties.AddOrUpdateTexture(indexBuffer);
|
resourceManager.AddVertexAsComputeTexture(indexBuffer);
|
||||||
|
|
||||||
int inputMap = _program.AttributeUsage.UsedInputAttributes;
|
int inputMap = _program.AttributeUsage.UsedInputAttributes;
|
||||||
|
|
||||||
|
@ -426,7 +426,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
int location = BitOperations.TrailingZeroCount(inputMap);
|
int location = BitOperations.TrailingZeroCount(inputMap);
|
||||||
SetBindingPair setAndBinding = resourceManager.Reservations.GetVertexBufferTextureSetAndBinding(location);
|
SetBindingPair setAndBinding = resourceManager.Reservations.GetVertexBufferTextureSetAndBinding(location);
|
||||||
TextureDefinition vaBuffer = new(setAndBinding.SetIndex, setAndBinding.Binding, $"vb_data{location}", SamplerType.TextureBuffer);
|
TextureDefinition vaBuffer = new(setAndBinding.SetIndex, setAndBinding.Binding, $"vb_data{location}", SamplerType.TextureBuffer);
|
||||||
resourceManager.Properties.AddOrUpdateTexture(vaBuffer);
|
resourceManager.AddVertexAsComputeTexture(vaBuffer);
|
||||||
|
|
||||||
inputMap &= ~(1 << location);
|
inputMap &= ~(1 << location);
|
||||||
}
|
}
|
||||||
|
@ -435,11 +435,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
{
|
{
|
||||||
SetBindingPair trbSetAndBinding = resourceManager.Reservations.GetTopologyRemapBufferTextureSetAndBinding();
|
SetBindingPair trbSetAndBinding = resourceManager.Reservations.GetTopologyRemapBufferTextureSetAndBinding();
|
||||||
TextureDefinition remapBuffer = new(trbSetAndBinding.SetIndex, trbSetAndBinding.Binding, "trb_data", SamplerType.TextureBuffer);
|
TextureDefinition remapBuffer = new(trbSetAndBinding.SetIndex, trbSetAndBinding.Binding, "trb_data", SamplerType.TextureBuffer);
|
||||||
resourceManager.Properties.AddOrUpdateTexture(remapBuffer);
|
resourceManager.AddVertexAsComputeTexture(remapBuffer);
|
||||||
|
|
||||||
int geometryVbOutputSbBinding = resourceManager.Reservations.GeometryVertexOutputStorageBufferBinding;
|
int geometryVbOutputSbBinding = resourceManager.Reservations.GeometryVertexOutputStorageBufferBinding;
|
||||||
BufferDefinition geometryVbOutputBuffer = new(BufferLayout.Std430, 1, geometryVbOutputSbBinding, "geometry_vb_output", vertexOutputStruct);
|
BufferDefinition geometryVbOutputBuffer = new(BufferLayout.Std430, 1, geometryVbOutputSbBinding, "geometry_vb_output", vertexOutputStruct);
|
||||||
resourceManager.Properties.AddOrUpdateStorageBuffer(geometryVbOutputBuffer);
|
resourceManager.AddVertexAsComputeStorageBuffer(geometryVbOutputBuffer);
|
||||||
|
|
||||||
StructureType geometryIbOutputStruct = new(new StructureField[]
|
StructureType geometryIbOutputStruct = new(new StructureField[]
|
||||||
{
|
{
|
||||||
|
@ -448,7 +448,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
|
|
||||||
int geometryIbOutputSbBinding = resourceManager.Reservations.GeometryIndexOutputStorageBufferBinding;
|
int geometryIbOutputSbBinding = resourceManager.Reservations.GeometryIndexOutputStorageBufferBinding;
|
||||||
BufferDefinition geometryIbOutputBuffer = new(BufferLayout.Std430, 1, geometryIbOutputSbBinding, "geometry_ib_output", geometryIbOutputStruct);
|
BufferDefinition geometryIbOutputBuffer = new(BufferLayout.Std430, 1, geometryIbOutputSbBinding, "geometry_ib_output", geometryIbOutputStruct);
|
||||||
resourceManager.Properties.AddOrUpdateStorageBuffer(geometryIbOutputBuffer);
|
resourceManager.AddVertexAsComputeStorageBuffer(geometryIbOutputBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
resourceManager.SetVertexAsComputeLocalMemories(Definitions.Stage, Definitions.InputTopology);
|
resourceManager.SetVertexAsComputeLocalMemories(Definitions.Stage, Definitions.InputTopology);
|
||||||
|
@ -481,6 +481,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
return new ResourceReservations(GpuAccessor, IsTransformFeedbackEmulated, vertexAsCompute: true, _vertexOutput, ioUsage);
|
return new ResourceReservations(GpuAccessor, IsTransformFeedbackEmulated, vertexAsCompute: true, _vertexOutput, ioUsage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ShaderProgramInfo GetVertexAsComputeInfo()
|
||||||
|
{
|
||||||
|
return CreateResourceManager(true).GetVertexAsComputeInfo();
|
||||||
|
}
|
||||||
|
|
||||||
public void SetVertexOutputMapForGeometryAsCompute(TranslatorContext vertexContext)
|
public void SetVertexOutputMapForGeometryAsCompute(TranslatorContext vertexContext)
|
||||||
{
|
{
|
||||||
_vertexOutput = vertexContext._program.GetIoUsage();
|
_vertexOutput = vertexContext._program.GetIoUsage();
|
||||||
|
@ -498,7 +503,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
if (Stage == ShaderStage.Vertex)
|
if (Stage == ShaderStage.Vertex)
|
||||||
{
|
{
|
||||||
BufferDefinition vertexInfoBuffer = new(BufferLayout.Std140, 0, vertexInfoCbBinding, "vb_info", VertexInfoBuffer.GetStructureType());
|
BufferDefinition vertexInfoBuffer = new(BufferLayout.Std140, 0, vertexInfoCbBinding, "vb_info", VertexInfoBuffer.GetStructureType());
|
||||||
resourceManager.Properties.AddOrUpdateConstantBuffer(vertexInfoBuffer);
|
resourceManager.AddVertexAsComputeConstantBuffer(vertexInfoBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
StructureType vertexInputStruct = new(new StructureField[]
|
StructureType vertexInputStruct = new(new StructureField[]
|
||||||
|
@ -508,7 +513,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
||||||
|
|
||||||
int vertexDataSbBinding = reservations.VertexOutputStorageBufferBinding;
|
int vertexDataSbBinding = reservations.VertexOutputStorageBufferBinding;
|
||||||
BufferDefinition vertexOutputBuffer = new(BufferLayout.Std430, 1, vertexDataSbBinding, "vb_input", vertexInputStruct);
|
BufferDefinition vertexOutputBuffer = new(BufferLayout.Std430, 1, vertexDataSbBinding, "vb_input", vertexInputStruct);
|
||||||
resourceManager.Properties.AddOrUpdateStorageBuffer(vertexOutputBuffer);
|
resourceManager.AddVertexAsComputeStorageBuffer(vertexOutputBuffer);
|
||||||
|
|
||||||
var context = new EmitterContext();
|
var context = new EmitterContext();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue