Skip to content

Commit

Permalink
Merge pull request #12 from xirreal/master
Browse files Browse the repository at this point in the history
Custom textures, multiple descriptor sets
  • Loading branch information
MCRcortex authored Sep 21, 2023
2 parents 08737e2 + 7268687 commit 3995adc
Show file tree
Hide file tree
Showing 18 changed files with 485 additions and 88 deletions.
6 changes: 3 additions & 3 deletions src/main/java/me/cortex/vulkanite/client/Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,9 @@ public static void main(String[] args) throws IOException {
context.memory.createSharedBuffer(1000, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT).free();
context.memory.createSharedBuffer(1000, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT).free();
context.memory.createSharedBuffer(1000, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT).free();
context.memory.createSharedImage(128,128, 1, VK_FORMAT_R8G8B8A8_UNORM, GL_RGBA8, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT).free();
context.memory.createSharedImage(128,128, 1, VK_FORMAT_R8G8B8A8_UNORM, GL_RGBA8, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT).free();
context.memory.createSharedImage(128,128, 1, VK_FORMAT_R8G8B8A8_UNORM, GL_RGBA8, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT).free();
context.memory.createSharedImage(128,128, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, GL_RGBA8, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT).free();
context.memory.createSharedImage(128,128, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, GL_RGBA8, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT).free();
context.memory.createSharedImage(128,128, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, GL_RGBA8, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT).free();
context.memory.createAcceleration(100*256,256, 0, VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR).free();
var pool = context.cmd.createSingleUsePool();
pool.createCommandBuffer();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ static Vector4f getMoonPosition() {


static Vector4f getCelestialPosition(float y) {
final float sunPathRotation = 0.0f;
final float sunPathRotation = -45.0f;

Vector4f position = new Vector4f(0.0F, y, 0.0F, 0.0F);

Expand Down
125 changes: 95 additions & 30 deletions src/main/java/me/cortex/vulkanite/client/rendering/VulkanPipeline.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,16 @@ public class VulkanPipeline {
private final VCommandPool singleUsePool;

private VRaytracePipeline[] raytracePipelines;
private VDescriptorSetLayout layout;
private VDescriptorSetLayout commonLayout;
private VDescriptorSetLayout customtexLayout;
private VDescriptorSetLayout storageBufferLayout;
private VDescriptorPool descriptors;

private final VSampler sampler;
private final VSampler ctexSampler;

private final SharedImageViewTracker composite0mainView;
private final SharedImageViewTracker[] customTextureViews;
private final SharedImageViewTracker blockAtlasView;
private final SharedImageViewTracker blockAtlasNormalView;
private final SharedImageViewTracker blockAtlasSpecularView;
Expand All @@ -73,12 +77,18 @@ public class VulkanPipeline {

private int fidx;

public VulkanPipeline(VContext ctx, AccelerationManager accelerationManager, RaytracingShaderSet[] passes, int[] ssboIds) {
public VulkanPipeline(VContext ctx, AccelerationManager accelerationManager, RaytracingShaderSet[] passes, int[] ssboIds, VGImage[] customTextures) {
this.ctx = ctx;
this.accelerationManager = accelerationManager;
this.singleUsePool = ctx.cmd.createSingleUsePool();

{
this.customTextureViews = new SharedImageViewTracker[customTextures.length];
for(int i = 0; i < customTextures.length; i++) {
int index = i;
this.customTextureViews[i] = new SharedImageViewTracker(ctx, ()->customTextures[index]);
}

this.composite0mainView = new SharedImageViewTracker(ctx, null);
this.blockAtlasView = new SharedImageViewTracker(ctx, ()->{
AbstractTexture blockAtlas = MinecraftClient.getInstance().getTextureManager().getTexture(new Identifier("minecraft", "textures/atlas/blocks.png"));
Expand All @@ -94,9 +104,9 @@ public VulkanPipeline(VContext ctx, AccelerationManager accelerationManager, Ray
PBRTextureHolder holder = PBRTextureManager.INSTANCE.getOrLoadHolder(blockAtlas.getGlId());//((TextureAtlasExtension)blockAtlas).getPBRHolder()
return ((IVGImage)holder.getSpecularTexture()).getVGImage();
});
this.placeholderImage = ctx.memory.creatImage2D(1, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
this.placeholderImage = ctx.memory.createImage2D(1, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
this.placeholderImageView = new VImageView(ctx, placeholderImage);

try (var stack = stackPush()) {
var cmd = singleUsePool.createCommandBuffer();
cmd.begin(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
Expand All @@ -123,31 +133,58 @@ public VulkanPipeline(VContext ctx, AccelerationManager accelerationManager, Ray
.borderColor(VK_BORDER_COLOR_INT_OPAQUE_BLACK)
.maxAnisotropy(1.0f));

this.ctexSampler = new VSampler(ctx, a->a.magFilter(VK_FILTER_LINEAR)
.minFilter(VK_FILTER_LINEAR)
.mipmapMode(VK_SAMPLER_MIPMAP_MODE_NEAREST)
.addressModeU(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
.addressModeV(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
.addressModeW(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
.compareOp(VK_COMPARE_OP_NEVER)
.maxLod(1)
.borderColor(VK_BORDER_COLOR_INT_OPAQUE_BLACK)
.maxAnisotropy(1.0f));

try {
var layoutBuilder = new DescriptorSetLayoutBuilder()
.binding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_ALL)//camera data
.binding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_ALL)//funni acceleration buffer
.binding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL)//funni buffer buffer
.binding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_ALL)//output texture
commonLayout = new DescriptorSetLayoutBuilder()
.binding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_ALL)// camera data
.binding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_ALL)// funni acceleration buffer
.binding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL)// funni buffer buffer
.binding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_ALL)//block texture
.binding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_ALL)//block texture normal
.binding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_ALL);//block texture specular
.binding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_ALL)//block texture specular
// Reordered these so output texture is last... this means you can dynamically add more output textures without messing other ids
.binding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_ALL)// output texture
.build(ctx);

DescriptorSetLayoutBuilder ctexLayoutBuilder = new DescriptorSetLayoutBuilder();
for (int i = 0; i < customTextureViews.length; i++) {
ctexLayoutBuilder.binding(i, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_ALL);
}

customtexLayout = ctexLayoutBuilder.build(ctx);

DescriptorSetLayoutBuilder ssboLayoutBuilder = new DescriptorSetLayoutBuilder();
for (int id : ssboIds) {
//NOTE:FIXME: the + 7 is cause of all the other bindings
layoutBuilder.binding(id + 7, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
ssboLayoutBuilder.binding(id, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
}

storageBufferLayout = ssboLayoutBuilder.build(ctx);

layout = layoutBuilder.build(ctx);

// Using commonLayout.types is good enough because both VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER and VK_DESCRIPTOR_TYPE_STORAGE_BUFFER are used there already...
//TODO: use frameahead count instead of just... 10
descriptors = new VDescriptorPool(ctx, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 10, layout.types);
descriptors.allocateSets(layout);
descriptors = new VDescriptorPool(ctx, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 10, commonLayout.types);
descriptors.allocateSets(new VDescriptorSetLayout[]{
commonLayout,
customtexLayout,
storageBufferLayout
});

raytracePipelines = new VRaytracePipeline[passes.length];
for (int i = 0; i < passes.length; i++) {
var builder = new RaytracePipelineBuilder().addLayout(layout);
var builder = new RaytracePipelineBuilder()
.addLayout(commonLayout)
.addLayout(customtexLayout)
.addLayout(storageBufferLayout);
passes[i].apply(builder);
raytracePipelines[i] = builder.build(ctx, 1);
}
Expand All @@ -166,13 +203,13 @@ private static void applyImageBarrier(VkImageMemoryBarrier barrier, VImage image
.srcAccessMask(0)
.dstAccessMask(targetAccess)
.subresourceRange(e->e.levelCount(1).layerCount(1).aspectMask(VK_IMAGE_ASPECT_COLOR_BIT));

}


private VSemaphore previousSemaphore;

private int frameId;

public void renderPostShadows(VGImage outImg, Camera camera, ShaderStorageBuffer[] ssbos) {
this.singleUsePool.doReleases();
PBRTextureManager.notifyPBRTexturesChanged();
Expand Down Expand Up @@ -223,47 +260,67 @@ public void renderPostShadows(VGImage outImg, Camera camera, ShaderStorageBuffer

int flags = Uniforms.isEyeInWater()&3;
bb.putInt(Float.BYTES * 41, flags);
bb.rewind();
}
uboBuffer.unmap();
uboBuffer.flush();

long desc = descriptors.get(fidx);
long commonSet = descriptors.get(0);
long ctexSet = descriptors.get(1);
long ssboSet = descriptors.get(2);

var updater = new DescriptorUpdateBuilder(ctx, 7 + ssbos.length, placeholderImageView)
.set(desc)
var updater = new DescriptorUpdateBuilder(ctx, 7, placeholderImageView)
.set(commonSet)
.uniform(0, uboBuffer)
.acceleration(1, tlas)
.buffer(2, accelerationManager.getReferenceBuffer())
.imageStore(3, composite0mainView.getView(()->outImg))
.imageSampler(4, blockAtlasView.getView(), sampler)
.imageSampler(5, blockAtlasNormalView.getView(), sampler)
.imageSampler(6, blockAtlasSpecularView.getView(), sampler);
for (ShaderStorageBuffer ssbo : ssbos) {
updater.buffer(ssbo.getIndex() + 7, ((IVGBuffer) ssbo).getBuffer());
.imageSampler(3, blockAtlasView.getView(), sampler)
.imageSampler(4, blockAtlasNormalView.getView(), sampler)
.imageSampler(5, blockAtlasSpecularView.getView(), sampler)
.imageStore(6, composite0mainView.getView(()->outImg));
updater.apply();

updater = new DescriptorUpdateBuilder(ctx, customTextureViews.length, placeholderImageView)
.set(ctexSet);

for (int i = 0; i < customTextureViews.length; i++) {
updater.imageSampler(i, customTextureViews[i].getView(), ctexSampler);
}
updater.apply();

updater = new DescriptorUpdateBuilder(ctx, ssbos.length, placeholderImageView)
.set(ssboSet);

for (ShaderStorageBuffer ssbo : ssbos) {
updater.buffer(ssbo.getIndex(), ((IVGBuffer) ssbo).getBuffer());
}
updater.apply();

//TODO: dont use a single use pool for commands like this...
var cmd = singleUsePool.createCommandBuffer();
cmd.begin(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);

try (var stack = stackPush()) {
var barriers = VkImageMemoryBarrier.calloc(4, stack);
var barriers = VkImageMemoryBarrier.calloc(4 + customTextureViews.length, stack);
applyImageBarrier(barriers.get(), composite0mainView.getImage(), VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_SHADER_WRITE_BIT);
applyImageBarrier(barriers.get(), blockAtlasView.getImage(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_SHADER_READ_BIT);
var image = blockAtlasNormalView.getImage();
if (image != null) applyImageBarrier(barriers.get(), image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_SHADER_READ_BIT);
image = blockAtlasSpecularView.getImage();
if (image != null) applyImageBarrier(barriers.get(), image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_SHADER_READ_BIT);

for(SharedImageViewTracker customtexView : customTextureViews) {
applyImageBarrier(barriers.get(), customtexView.getImage(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_SHADER_READ_BIT);
}

barriers.limit(barriers.position());
barriers.rewind();
vkCmdPipelineBarrier(cmd.buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, 0, null, null, barriers);
}

for (var pipeline : raytracePipelines) {
pipeline.bind(cmd);
pipeline.bindDSet(cmd, desc);
pipeline.bindDSet(cmd, new long[]{commonSet, ctexSet, ssboSet});
pipeline.trace(cmd, outImg.width, outImg.height, 1);
}

Expand Down Expand Up @@ -299,21 +356,29 @@ public void destory() {
for (var pass : raytracePipelines) {
pass.free();
}
layout.free();
commonLayout.free();
customtexLayout.free();
storageBufferLayout.free();
descriptors.free();
ctx.sync.checkFences();
singleUsePool.doReleases();
singleUsePool.free();
if (previousSemaphore != null) {
previousSemaphore.free();
}

for (SharedImageViewTracker customTexView : customTextureViews) {
customTexView.free();
}

composite0mainView.free();
blockAtlasView.free();
blockAtlasNormalView.free();
blockAtlasSpecularView.free();
placeholderImageView.free();
placeholderImage.free();
sampler.free();
ctexSampler.free();
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,46 +17,50 @@ public class VDescriptorPool extends TrackedResourceObject {
private final long pool;

private final long[] sets;
private int usedSets = 0;

public VDescriptorPool(VContext ctx, int flags, int numSets, int... types) {
public VDescriptorPool(VContext ctx, int flags, int maxSets, int... types) {
this.ctx = ctx;
this.sets = new long[numSets];
this.sets = new long[maxSets];

try (var stack = stackPush()) {
var sizes = VkDescriptorPoolSize.calloc(types.length, stack);
for (int i = 0; i < types.length; i++) {
sizes.get(i).type(types[i]).descriptorCount(numSets);
sizes.get(i).type(types[i]).descriptorCount(maxSets);
}
LongBuffer pPool = stack.mallocLong(1);
_CHECK_(vkCreateDescriptorPool(ctx.device, VkDescriptorPoolCreateInfo.calloc(stack)
.sType$Default()
.flags(flags)
.maxSets(numSets)
.maxSets(maxSets)
.pPoolSizes(sizes), null, pPool));
pool = pPool.get(0);
}
}


public void allocateSets(VDescriptorSetLayout layout) {
public void allocateSets(VDescriptorSetLayout[] layouts) {
try (var stack = stackPush()) {
var layouts = stack.mallocLong(sets.length);
for (int i = 0; i < sets.length; i++) {
layouts.put(layout.layout);
usedSets = layouts.length;
var pLayouts = stack.mallocLong(usedSets);
for (int i = 0; i < usedSets; i++) {
pLayouts.put(layouts[i].layout);
}
layouts.rewind();
pLayouts.rewind();
LongBuffer pDescriptorSets = stack.mallocLong(sets.length);
_CHECK_(vkAllocateDescriptorSets(ctx.device, VkDescriptorSetAllocateInfo
.calloc(stack)
.sType$Default()
.descriptorPool(pool)
.pSetLayouts(layouts), pDescriptorSets),
.pSetLayouts(pLayouts), pDescriptorSets),
"Failed to allocate descriptor set");
pDescriptorSets.get(sets);
}
}

public long get(int idx) {
if(idx < 0 || idx >= usedSets) {
throw new IllegalArgumentException("Descriptor set out of range: " + idx);
}
return sets[idx];
}

Expand Down
Loading

0 comments on commit 3995adc

Please sign in to comment.