Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom textures, multiple descriptor sets #12

Merged
merged 9 commits into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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