fix descriptor transfers

This commit is contained in:
Matthew 2026-03-07 16:39:41 +11:00
parent 64673b1bf4
commit 6f4b0ab6d5

View File

@ -4,7 +4,7 @@ import vulkan_util;
import std.stdio; import std.stdio;
import std.algorithm.comparison; import std.algorithm.comparison;
import std.algorithm.searching : canFind; import std.algorithm.searching : canFind;
import std.traits : isPointer; import std.traits : isPointer, isArray;
import core.stdc.string : strcmp, memcpy; import core.stdc.string : strcmp, memcpy;
import core.stdc.stdio : Printf = printf; import core.stdc.stdio : Printf = printf;
import std.format : sformat; import std.format : sformat;
@ -1115,7 +1115,7 @@ CreateDescriptor(T = u8[])(Descriptor* desc, DescInfo info, T data = null) if(is
if(data) if(data)
{ {
Transfer(desc, data); Transfer!(false)(desc, data);
} }
} }
else if(canFind(buffer_types, info.type)) else if(canFind(buffer_types, info.type))
@ -1124,7 +1124,7 @@ CreateDescriptor(T = u8[])(Descriptor* desc, DescInfo info, T data = null) if(is
if(data) if(data)
{ {
Transfer(desc, data); Transfer!(false)(desc, data);
} }
} }
else if(info.type == DT.Sampler) else if(info.type == DT.Sampler)
@ -1146,14 +1146,14 @@ CreateImageView(Descriptor* desc, u8[] data)
} }
else else
{ {
Descriptor buf; Descriptor buffer;
CreateDescriptor(&buf, DescInfo( CreateDescriptor(&buffer, DescInfo(
type: DT.Storage, type: DT.Storage,
buffer_type: BT.Storage, buffer_type: BT.Storage,
size: desc.image.w * desc.image.h * desc.image.ch, size: desc.image.w * desc.image.h * desc.image.ch,
binding: 1, binding: 1,
)); ));
bool result = Transfer(&buf.buffer, data); bool result = Transfer!(false)(&buffer, data);
assert(result, "CreateImageView failure: Buffer Transfer error"); assert(result, "CreateImageView failure: Buffer Transfer error");
Descriptor conv_view; Descriptor conv_view;
@ -1165,7 +1165,7 @@ CreateImageView(Descriptor* desc, u8[] data)
usage: IU.Convert, usage: IU.Convert,
)); ));
Write(g_vk.conv_desc_set, [conv_view, buf]); Write(g_vk.conv_desc_set, [conv_view, buffer]);
BeginComputePass(); BeginComputePass();
@ -1203,7 +1203,7 @@ CreateImageView(Descriptor* desc, u8[] data)
vkQueueWaitIdle(g_vk.tfer_queue); vkQueueWaitIdle(g_vk.tfer_queue);
Destroy(&buf); Destroy(&buffer);
Destroy(&conv_view); Destroy(&conv_view);
} }
} }
@ -1373,52 +1373,6 @@ ImageBarrier()
vkCmdPipelineBarrier2(g_vk.cmd, &dependency); vkCmdPipelineBarrier2(g_vk.cmd, &dependency);
} }
bool
Transfer(T, U)(T* dst, U[] data)
{
static if(is(T: Descriptor))
{
Buffer* buffer = &dst.buffer;
}
else static if(is(T: Buffer))
{
Buffer* buffer = dst;
}
else static assert(false, "Invalid type for transfer target");
u8[] u8_data = (cast(u8*)(data.ptr))[0 .. T.sizeof * data.length];
return Transfer(buffer, u8_data);
}
bool
Transfer(T)(Buffer* buf, T* ptr)
{
assert(T.sizeof < g_vk.transfer_buf.data.length, "Transfer failure: structure size is too large");
bool success = TransferReady();
if(success)
{
memcpy(g_vk.transfer_buf.data.ptr, ptr, T.sizeof);
auto fn = function(Buffer* buf, VkBufferCopy copy)
{
vkCmdCopyBuffer(g_vk.imm_cmd, g_vk.transfer_buf.buffer, buf.buffer, 1, &copy);
};
VkBufferCopy copy = {
srcOffset: 0,
dstOffset: 0,
size: T.sizeof,
};
success = ImmSubmit(buf, copy, fn);
}
WaitForTransfers();
return success;
}
// Needs to be done before writing to the transfer buffer as otherwise it'll overwrite it while previous transfers are occurring // Needs to be done before writing to the transfer buffer as otherwise it'll overwrite it while previous transfers are occurring
bool bool
TransferReady() TransferReady()
@ -1428,15 +1382,25 @@ TransferReady()
} }
bool bool
Transfer(bool image)(Descriptor* desc, u8[] data) Transfer(bool image, T)(Descriptor* desc, T data) if(isArray!(T) || isPointer!(T))
{ {
bool success = true; bool success = true;
u64 transfer_length = cast(u64)g_vk.transfer_buf.data.length;
static if(isArray!(T))
{
u64 data_length = cast(u64)(data.length * T[0].sizeof);
}
else static if(isPointer!(T))
{
u64 data_length = cast(u64)(*T).sizeof;
}
u64 copied = 0; u64 copied = 0;
while(copied != data.length) while(copied != data.length)
{ {
u64 transfer_length = cast(u64)g_vk.transfer_buf.data.length; data_length -= copied;
u64 data_length = cast(u64)data.length - copied;
u64 copy_length = transfer_length > data_length ? data_length : transfer_length; u64 copy_length = transfer_length > data_length ? data_length : transfer_length;
g_vk.transfer_buf.data[0 .. copy_length] = data[copied .. copy_length]; g_vk.transfer_buf.data[0 .. copy_length] = data[copied .. copy_length];