Skip to content

Commit

Permalink
Merge pull request #278 from NoiseStudio/feature/277/add-indexer-in-v…
Browse files Browse the repository at this point in the history
…alue-constructor

Add indexer in value constructor
  • Loading branch information
Vixenka authored May 27, 2023
2 parents b4658ab + fee6076 commit 035bfe4
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 25 deletions.
12 changes: 8 additions & 4 deletions NoiseEngine.Tests/Nesl/CompilerTools/Execute/Methods/Indexer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ public Indexer(ApplicationFixture fixture) : base(fixture) {
}

[Fact]
public void SetConst() {
NeslAssembly assembly = NeslCompiler.Compile(nameof(SetConst), "", new NeslFile[] { new NeslFile("H", @"
public void LoadAndSet() {
NeslAssembly assembly = NeslCompiler.Compile(nameof(LoadAndSet), "", new NeslFile[] { new NeslFile("H", @"
using System;
uniform RwBuffer<f32> buffer;
[Kernel(1, 1, 1)]
void Main() {
buffer[0] = 26.05;
buffer[0] = buffer[2];
}
")});

Expand All @@ -33,11 +33,15 @@ void Main() {
NeslMethod? method = type.GetMethod("Main");
Assert.NotNull(method);

Span<float> data = stackalloc float[1];
Span<float> data = stackalloc float[] {
-1, 0, 26.05f
};

foreach (GraphicsDevice graphicsDevice in GraphicsDevices) {
GraphicsHostBuffer<float> buffer = new GraphicsHostBuffer<float>(
graphicsDevice, GraphicsBufferUsage.TransferAll, (ulong)data.Length
);
buffer.SetData(data);

ComputeMaterial material = new ComputeMaterial(new ComputeShader(graphicsDevice, type));
material.GetProperty(field!)!.SetBuffer(buffer);
Expand Down
21 changes: 15 additions & 6 deletions NoiseEngine.Tests/Nesl/CompilerTools/Parsing/Methods/Indexer.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
using NoiseEngine.Mathematics;
using NoiseEngine.Nesl;
using NoiseEngine.Rendering;
using NoiseEngine.Rendering.Buffers;
using NoiseEngine.Tests.Environments;
using System.Linq;
using NoiseEngine.Tests.Environments;

namespace NoiseEngine.Tests.Nesl.CompilerTools.Parsing.Methods;

Expand All @@ -23,4 +18,18 @@ void Main() {
");
}

[Fact]
public void LoadAndSet() {
CompileSingle(@"
using System;
uniform RwBuffer<f32> buffer;
[Kernel(1, 1, 1)]
void Main() {
buffer[7] = buffer[3];
}
");
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using NoiseEngine.Nesl.CompilerTools.Architectures.SpirV.Types;
using System;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace NoiseEngine.Nesl.CompilerTools.Architectures.SpirV.IlCompilation;

Expand All @@ -8,13 +9,6 @@ internal class BranchOperations : IlCompilerOperation {
public BranchOperations(IlCompiler ilCompiler) : base(ilCompiler) {
}

public static void ReturnValueStore(SpirVGenerator generator, SpirVFunction function, SpirVVariable result) {
LoadOperations.SpirVStore(
generator, function.OutputVariable!, LoadOperations.SpirVLoad(generator, result)
);
generator.Emit(SpirVOpCode.OpReturn);
}

public void Call(Instruction instruction) {
SpirVVariable? result = instruction.ReadSpirVVariable(IlCompiler, NeslMethod);
NeslMethod method = Assembly.GetMethod(instruction.ReadUInt64());
Expand Down Expand Up @@ -77,7 +71,10 @@ public void ReturnValue(Instruction instruction) {
}

private void ReturnValueStore(SpirVVariable result) {
ReturnValueStore(Generator, IlCompiler.Function, result);
IlCompiler.LoadOperations.SpirVStore(
IlCompiler.Function.OutputVariable!, IlCompiler.LoadOperations.SpirVLoad(result)
);
Generator.Emit(SpirVOpCode.OpReturn);
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using NoiseEngine.Nesl.CompilerTools.Architectures.SpirV.IlCompilation;
using NoiseEngine.Nesl.CompilerTools.Architectures.SpirV.Types;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;

namespace NoiseEngine.Nesl.CompilerTools.Architectures.SpirV.Intrinsics;

Expand Down Expand Up @@ -41,18 +43,20 @@ private void IndexerSet() {
}

private void IndexerGet() {
SpirVVariable result = Function.OutputVariable!;
SpirVVariable buffer = Parameters[0];
SpirVVariable index = Parameters[1];

SpirVType elementType = Compiler.GetSpirVType(result.NeslType);
SpirVVariable result = new SpirVVariable(
Compiler, NeslMethod.ReturnType!, StorageClass.Function, Generator
);

SpirVType elementType = Compiler.GetSpirVType(NeslMethod.ReturnType);
SpirVId accessChain = GetAccessChainFromIndex(elementType, buffer, index);

SpirVId load = Compiler.GetNextId();
Generator.Emit(SpirVOpCode.OpLoad, elementType.Id, load, accessChain);

LoadOperations.SpirVStore(Generator, result, load);
Generator.Emit(SpirVOpCode.OpReturn);
Generator.Emit(SpirVOpCode.OpReturnValue, load);
}

private SpirVId GetAccessChainFromIndex(SpirVType elementType, SpirVVariable buffer, SpirVVariable index) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,13 @@ public static ValueData Construct(ValueToken value, Parser parser) {
throw new UnreachableException();

foreach (ExpressionValueContent expression in container.Expressions) {
if (expression.IsNew)
return ConstructNew(parser, expression);
return ConstructValue(parser, expression);
ValueData data = expression.IsNew ?
ConstructNew(parser, expression) : ConstructValue(parser, expression);

if (expression.Indexer is not null)
CallIndexer(ref data, parser, expression.Indexer, NeslOperators.IndexerGet);

return data;
}
}

Expand Down Expand Up @@ -169,6 +173,28 @@ private static ValueData CallMethod(Parser parser, ExpressionValueContent expres
return new ValueData(method.ReturnType, variableId);
}

private static void CallIndexer(ref ValueData data, Parser parser, ValueToken indexer, string name) {
ValueData indexerData = Construct(indexer, parser);

NeslMethod? method = data.Type.GetMethod(name);
if (method is null) {
parser.Throw(new CompilationError(indexer.Pointer, CompilationErrorType.IndexerNotFound, name));
return;
}

indexerData = indexerData.LoadConst(parser, method.ParameterTypes[0]);
if (method.ReturnType is null)
throw new UnreachableException();

IlGenerator il = parser.CurrentMethod.IlGenerator;
il.Emit(OpCode.DefVariable, method.ReturnType);
uint variableId = il.GetNextVariableId();
il.Emit(OpCode.Call, variableId, method, stackalloc uint[] {
data.Id, indexerData.Id
});
data = new ValueData(method.ReturnType, variableId);
}

private static List<ValueData>? GetParameters(Parser parser, TokenBuffer buffer) {
List<ValueData> list = new List<ValueData>();
if (!buffer.HasNextTokens)
Expand Down

0 comments on commit 035bfe4

Please sign in to comment.