Image and ssbo bindings
This commit is contained in:
@@ -137,20 +137,28 @@ public class IrisVoxyRenderPipeline extends AbstractRenderPipeline {
|
|||||||
glColorMask(true, true, true, true);
|
glColorMask(true, true, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setupAndBindOpaque(Viewport<?> viewport) {
|
private void doBindings() {
|
||||||
this.fb.bind();
|
|
||||||
if (this.shaderUniforms != null) {
|
if (this.shaderUniforms != null) {
|
||||||
GL30.glBindBufferBase(GL_UNIFORM_BUFFER, 5, this.shaderUniforms.id);// todo: dont randomly select this to 5
|
GL30.glBindBufferBase(GL_UNIFORM_BUFFER, 5, this.shaderUniforms.id);// todo: dont randomly select this to 5
|
||||||
}
|
}
|
||||||
|
if (this.data.getSsboSet() != null) {
|
||||||
|
this.data.getSsboSet().bindingFunction().accept(10);
|
||||||
|
}
|
||||||
|
if (this.data.getImageSet() != null) {
|
||||||
|
this.data.getImageSet().bindingFunction().accept(6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void setupAndBindOpaque(Viewport<?> viewport) {
|
||||||
|
this.fb.bind();
|
||||||
|
this.doBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setupAndBindTranslucent(Viewport<?> viewport) {
|
public void setupAndBindTranslucent(Viewport<?> viewport) {
|
||||||
this.fbTranslucent.bind();
|
this.fbTranslucent.bind();
|
||||||
if (this.shaderUniforms != null) {
|
this.doBindings();
|
||||||
GL30.glBindBufferBase(GL_UNIFORM_BUFFER, 5, this.shaderUniforms.id);// todo: dont randomly select this to 5
|
|
||||||
}
|
|
||||||
if (this.data.getBlender() != null) {
|
if (this.data.getBlender() != null) {
|
||||||
this.data.getBlender().run();
|
this.data.getBlender().run();
|
||||||
}
|
}
|
||||||
@@ -162,17 +170,33 @@ public class IrisVoxyRenderPipeline extends AbstractRenderPipeline {
|
|||||||
super.addDebug(debug);
|
super.addDebug(debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private StringBuilder buildGenericShaderHeader(AbstractSectionRenderer<?, ?> renderer, String input) {
|
||||||
public String patchOpaqueShader(AbstractSectionRenderer<?, ?> renderer, String input) {
|
|
||||||
StringBuilder builder = new StringBuilder(input).append("\n\n\n");
|
StringBuilder builder = new StringBuilder(input).append("\n\n\n");
|
||||||
|
|
||||||
if (this.data.getUniforms() != null) {
|
if (this.data.getUniforms() != null) {
|
||||||
//TODO make ths binding point... not randomly 5
|
//TODO make ths binding point... not randomly 5
|
||||||
builder.append("layout(binding = 5, std140) uniform ShaderUniformBindings ")
|
builder.append("layout(binding = 5, std140) uniform ShaderUniformBindings ")
|
||||||
.append(this.data.getUniforms().layout())
|
.append(this.data.getUniforms().layout())
|
||||||
.append(";\n\n\n");
|
.append(";\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.data.getSsboSet() != null) {
|
||||||
|
builder.append("#define BUFFER_BINDING_INDEX_BASE 10\n");//TODO: DONT RANDOMLY MAKE THIS 10
|
||||||
|
builder.append(this.data.getSsboSet().layout()).append("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.data.getImageSet() != null) {
|
||||||
|
builder.append("#define BASE_SAMPLER_BINDING_INDEX 6\n");//TODO: DONT RANDOMLY MAKE THIS 6
|
||||||
|
builder.append(this.data.getImageSet().layout()).append("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.append("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String patchOpaqueShader(AbstractSectionRenderer<?, ?> renderer, String input) {
|
||||||
|
var builder = this.buildGenericShaderHeader(renderer, input);
|
||||||
|
|
||||||
builder.append(this.data.opaqueFragPatch());
|
builder.append(this.data.opaqueFragPatch());
|
||||||
|
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
@@ -182,17 +206,8 @@ public class IrisVoxyRenderPipeline extends AbstractRenderPipeline {
|
|||||||
public String patchTranslucentShader(AbstractSectionRenderer<?, ?> renderer, String input) {
|
public String patchTranslucentShader(AbstractSectionRenderer<?, ?> renderer, String input) {
|
||||||
if (this.data.translucentFragPatch() == null) return null;
|
if (this.data.translucentFragPatch() == null) return null;
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder(input).append("\n\n\n");
|
var builder = this.buildGenericShaderHeader(renderer, input);
|
||||||
|
|
||||||
if (this.data.getUniforms() != null) {
|
|
||||||
//TODO make ths binding point... not randomly 5
|
|
||||||
builder.append("layout(binding = 5, std140) uniform ShaderUniformBindings ")
|
|
||||||
.append(this.data.getUniforms().layout())
|
|
||||||
.append(";\n\n\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.append(this.data.translucentFragPatch());
|
builder.append(this.data.translucentFragPatch());
|
||||||
|
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package me.cortex.voxy.client.iris;
|
|||||||
|
|
||||||
import com.google.gson.*;
|
import com.google.gson.*;
|
||||||
import com.google.gson.annotations.JsonAdapter;
|
import com.google.gson.annotations.JsonAdapter;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import me.cortex.voxy.common.Logger;
|
import me.cortex.voxy.common.Logger;
|
||||||
@@ -137,7 +138,7 @@ public class IrisShaderPatch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Int2ObjectMap<String> getSSBOs() {
|
public Int2ObjectMap<String> getSSBOs() {
|
||||||
return this.ssbos;
|
return new Int2ObjectLinkedOpenHashMap<>(this.ssbos);
|
||||||
}
|
}
|
||||||
public String getPatchOpaqueSource() {
|
public String getPatchOpaqueSource() {
|
||||||
return String.join("\n", this.patchData.opaquePatchData);
|
return String.join("\n", this.patchData.opaquePatchData);
|
||||||
|
|||||||
@@ -26,10 +26,16 @@ import org.joml.*;
|
|||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.function.IntConsumer;
|
||||||
import java.util.function.IntSupplier;
|
import java.util.function.IntSupplier;
|
||||||
import java.util.function.LongConsumer;
|
import java.util.function.LongConsumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static org.lwjgl.opengl.ARBDirectStateAccess.glBindTextureUnit;
|
||||||
|
import static org.lwjgl.opengl.ARBUniformBufferObject.glBindBufferBase;
|
||||||
|
import static org.lwjgl.opengl.GL33C.glBindSampler;
|
||||||
|
import static org.lwjgl.opengl.GL43C.GL_SHADER_STORAGE_BUFFER;
|
||||||
|
|
||||||
public class IrisVoxyRenderPipelineData {
|
public class IrisVoxyRenderPipelineData {
|
||||||
public IrisVoxyRenderPipeline thePipeline;
|
public IrisVoxyRenderPipeline thePipeline;
|
||||||
public final int[] opaqueDrawTargets;
|
public final int[] opaqueDrawTargets;
|
||||||
@@ -38,13 +44,25 @@ public class IrisVoxyRenderPipelineData {
|
|||||||
private final String translucentPatch;
|
private final String translucentPatch;
|
||||||
private final StructLayout uniforms;
|
private final StructLayout uniforms;
|
||||||
private final Runnable blendingSetup;
|
private final Runnable blendingSetup;
|
||||||
private IrisVoxyRenderPipelineData(IrisShaderPatch patch, int[] opaqueDrawTargets, int[] translucentDrawTargets, StructLayout uniformSet, Runnable blendingSetup) {
|
private final ImageSet imageSet;
|
||||||
|
private final SSBOSet ssboSet;
|
||||||
|
private IrisVoxyRenderPipelineData(IrisShaderPatch patch, int[] opaqueDrawTargets, int[] translucentDrawTargets, StructLayout uniformSet, Runnable blendingSetup, ImageSet imageSet, SSBOSet ssboSet) {
|
||||||
this.opaqueDrawTargets = opaqueDrawTargets;
|
this.opaqueDrawTargets = opaqueDrawTargets;
|
||||||
this.translucentDrawTargets = translucentDrawTargets;
|
this.translucentDrawTargets = translucentDrawTargets;
|
||||||
this.opaquePatch = patch.getPatchOpaqueSource();
|
this.opaquePatch = patch.getPatchOpaqueSource();
|
||||||
this.translucentPatch = patch.getPatchTranslucentSource();
|
this.translucentPatch = patch.getPatchTranslucentSource();
|
||||||
this.uniforms = uniformSet;
|
this.uniforms = uniformSet;
|
||||||
this.blendingSetup = blendingSetup;
|
this.blendingSetup = blendingSetup;
|
||||||
|
this.imageSet = imageSet;
|
||||||
|
this.ssboSet = ssboSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SSBOSet getSsboSet() {
|
||||||
|
return this.ssboSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImageSet getImageSet() {
|
||||||
|
return this.imageSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StructLayout getUniforms() {
|
public StructLayout getUniforms() {
|
||||||
@@ -60,12 +78,13 @@ public class IrisVoxyRenderPipelineData {
|
|||||||
return this.translucentPatch;
|
return this.translucentPatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static IrisVoxyRenderPipelineData buildPipeline(IrisRenderingPipeline ipipe, IrisShaderPatch patch, CustomUniforms cu, ShaderStorageBufferHolder ssboHolder) {
|
public static IrisVoxyRenderPipelineData buildPipeline(IrisRenderingPipeline ipipe, IrisShaderPatch patch, CustomUniforms cu, ShaderStorageBufferHolder ssboHolder) {
|
||||||
var uniforms = createUniformLayoutStructAndUpdater(createUniformSet(cu, patch));
|
var uniforms = createUniformLayoutStructAndUpdater(createUniformSet(cu, patch));
|
||||||
|
|
||||||
createImageSet(ipipe, patch);
|
var imageSet = createImageSet(ipipe, patch);
|
||||||
|
|
||||||
createSSBOLayouts(patch.getSSBOs(), ssboHolder);
|
var ssboSet = createSSBOLayouts(patch.getSSBOs(), ssboHolder);
|
||||||
|
|
||||||
var opaqueDrawTargets = getDrawBuffers(patch.getOpqaueTargets(), ipipe.getFlippedAfterPrepare(), ((IrisRenderingPipelineAccessor)ipipe).getRenderTargets());
|
var opaqueDrawTargets = getDrawBuffers(patch.getOpqaueTargets(), ipipe.getFlippedAfterPrepare(), ((IrisRenderingPipelineAccessor)ipipe).getRenderTargets());
|
||||||
var translucentDrawTargets = getDrawBuffers(patch.getTranslucentTargets(), ipipe.getFlippedAfterPrepare(), ((IrisRenderingPipelineAccessor)ipipe).getRenderTargets());
|
var translucentDrawTargets = getDrawBuffers(patch.getTranslucentTargets(), ipipe.getFlippedAfterPrepare(), ((IrisRenderingPipelineAccessor)ipipe).getRenderTargets());
|
||||||
@@ -73,7 +92,7 @@ public class IrisVoxyRenderPipelineData {
|
|||||||
|
|
||||||
|
|
||||||
//TODO: need to transform the string patch with the uniform decleration aswell as sampler declerations
|
//TODO: need to transform the string patch with the uniform decleration aswell as sampler declerations
|
||||||
return new IrisVoxyRenderPipelineData(patch, opaqueDrawTargets, translucentDrawTargets, uniforms, patch.createBlendSetup());
|
return new IrisVoxyRenderPipelineData(patch, opaqueDrawTargets, translucentDrawTargets, uniforms, patch.createBlendSetup(), imageSet, ssboSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int[] getDrawBuffers(int[] targets, ImmutableSet<Integer> stageWritesToAlt, RenderTargets rt) {
|
private static int[] getDrawBuffers(int[] targets, ImmutableSet<Integer> stageWritesToAlt, RenderTargets rt) {
|
||||||
@@ -277,11 +296,13 @@ public class IrisVoxyRenderPipelineData {
|
|||||||
return uniforms;
|
return uniforms;
|
||||||
}
|
}
|
||||||
|
|
||||||
private record TextureWSampler(String name, IntSupplier texture, int sampler) {
|
private record TextureWSampler(String name, IntSupplier texture, int sampler) { }
|
||||||
|
public record ImageSet(String layout, IntConsumer bindingFunction) {
|
||||||
|
|
||||||
}
|
}
|
||||||
private static void createImageSet(IrisRenderingPipeline ipipe, IrisShaderPatch patch) {
|
private static ImageSet createImageSet(IrisRenderingPipeline ipipe, IrisShaderPatch patch) {
|
||||||
Set<String> samplerNameSet = new LinkedHashSet<>(List.of(patch.getSamplerList()));
|
Set<String> samplerNameSet = new LinkedHashSet<>(List.of(patch.getSamplerList()));
|
||||||
|
if (samplerNameSet.isEmpty()) return null;
|
||||||
Set<TextureWSampler> samplerSet = new LinkedHashSet<>();
|
Set<TextureWSampler> samplerSet = new LinkedHashSet<>();
|
||||||
SamplerHolder samplerBuilder = new SamplerHolder() {
|
SamplerHolder samplerBuilder = new SamplerHolder() {
|
||||||
@Override
|
@Override
|
||||||
@@ -350,10 +371,52 @@ public class IrisVoxyRenderPipelineData {
|
|||||||
|
|
||||||
//TODO: generate a layout (defines) for all the samplers with the correct types
|
//TODO: generate a layout (defines) for all the samplers with the correct types
|
||||||
|
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
TextureWSampler[] samplers = new TextureWSampler[samplerSet.size()];
|
||||||
|
int i = 0;
|
||||||
|
for (var entry : samplerSet) {
|
||||||
|
samplers[i]=entry;
|
||||||
|
builder.append("layout(binding=(BASE_SAMPLER_BINDING_INDEX+").append(i).append(")) uniform sampler2D ").append(entry.name).append(";\n");
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IntConsumer bindingFunction = base->{
|
||||||
|
for (int j = 0; j < samplers.length; j++) {
|
||||||
|
int unit = j+base;
|
||||||
|
var ts = samplers[j];
|
||||||
|
glBindTextureUnit(unit, ts.texture.getAsInt());
|
||||||
|
if (ts.sampler != -1) {
|
||||||
|
glBindSampler(unit, ts.sampler);
|
||||||
|
}//TODO: might need to bind sampler 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return new ImageSet(builder.toString(), bindingFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public record SSBOSet(String layout, IntConsumer bindingFunction){}
|
||||||
private static void createSSBOLayouts(Int2ObjectMap<String> ssbos, ShaderStorageBufferHolder ssboStore) {
|
private record SSBOBinding(int irisIndex, int bindingOffset) {}
|
||||||
|
private static SSBOSet createSSBOLayouts(Int2ObjectMap<String> ssbos, ShaderStorageBufferHolder ssboStore) {
|
||||||
|
if (ssbos.isEmpty()) return null;
|
||||||
|
String header = "";
|
||||||
|
if (ssbos.containsKey(-1)) header = ssbos.remove(-1);
|
||||||
|
StringBuilder builder = new StringBuilder(header);
|
||||||
|
builder.append("\n");
|
||||||
|
SSBOBinding[] bindings = new SSBOBinding[ssbos.size()];
|
||||||
|
int i = 0;
|
||||||
|
for (var entry : ssbos.int2ObjectEntrySet()) {
|
||||||
|
var val = entry.getValue();
|
||||||
|
bindings[i] = new SSBOBinding(entry.getIntKey(), i);
|
||||||
|
builder.append("layout(binding = (BUFFER_BINDING_INDEX_BASE+").append(i).append(")) restrict buffer IrisBufferBinding").append(i);
|
||||||
|
builder.append(" ").append(val).append(";\n");
|
||||||
|
i++;
|
||||||
|
}
|
||||||
//ssboStore.getBufferIndex()
|
//ssboStore.getBufferIndex()
|
||||||
|
IntConsumer bindingFunction = base->{
|
||||||
|
for (var binding : bindings) {
|
||||||
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, base+binding.bindingOffset, ssboStore.getBufferIndex(binding.irisIndex));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return new SSBOSet(builder.toString(), bindingFunction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user