Skip to content

Commit

Permalink
Implement kope_g5_command_list_copy_texture_to_buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
RobDangerous committed Sep 23, 2024
1 parent d98750c commit 728e3fc
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,65 @@ void kope_d3d12_command_list_copy_buffer_to_texture(kope_g5_command_list *list,
&source_box); // Set DstZ to zero because it has already been selected via dst.SubresourceIndex
}

void kope_d3d12_command_list_copy_texture_to_buffer(kope_g5_command_list *list, const kope_g5_image_copy_texture *source,
const kope_g5_image_copy_buffer *destination, uint32_t width, uint32_t height,
uint32_t depth_or_array_layers) {
if (source->texture->d3d12.resource_states[source->mip_level] != D3D12_RESOURCE_STATE_COPY_SOURCE) {
D3D12_RESOURCE_BARRIER barrier;
barrier.Transition.pResource = source->texture->d3d12.resource;
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
barrier.Transition.StateBefore = (D3D12_RESOURCE_STATES)source->texture->d3d12.resource_states[source->mip_level];
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE;
barrier.Transition.Subresource =
D3D12CalcSubresource(source->mip_level, source->origin_z, 0, source->texture->d3d12.mip_level_count, source->texture->d3d12.depth_or_array_layers);

list->d3d12.list->ResourceBarrier(1, &barrier);

source->texture->d3d12.resource_states[source->mip_level] = D3D12_RESOURCE_STATE_COPY_SOURCE;
}

if (destination->buffer->d3d12.resource_state != D3D12_RESOURCE_STATE_COPY_DEST) {
D3D12_RESOURCE_BARRIER barrier;
barrier.Transition.pResource = destination->buffer->d3d12.resource;
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
barrier.Transition.StateBefore = (D3D12_RESOURCE_STATES)destination->buffer->d3d12.resource_state;
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST;
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;

list->d3d12.list->ResourceBarrier(1, &barrier);

destination->buffer->d3d12.resource_state = D3D12_RESOURCE_STATE_COPY_DEST;
}

D3D12_TEXTURE_COPY_LOCATION src;
src.pResource = source->texture->d3d12.resource;
src.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
src.SubresourceIndex =
D3D12CalcSubresource(source->mip_level, source->origin_z, 0, source->texture->d3d12.mip_level_count, source->texture->d3d12.depth_or_array_layers);

D3D12_BOX source_box = {0};
source_box.left = 0;
source_box.right = source_box.left + width;
source_box.top = 0;
source_box.bottom = source_box.top + height;
source_box.front = 0;
source_box.back = source_box.front + depth_or_array_layers;

D3D12_TEXTURE_COPY_LOCATION dst;
dst.pResource = destination->buffer->d3d12.resource;
dst.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
dst.PlacedFootprint.Offset = destination->offset;
dst.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
dst.PlacedFootprint.Footprint.RowPitch = destination->bytes_per_row;
dst.PlacedFootprint.Footprint.Width = width;
dst.PlacedFootprint.Footprint.Height = height;
dst.PlacedFootprint.Footprint.Depth = depth_or_array_layers;

list->d3d12.list->CopyTextureRegion(&dst, 0, 0, 0, &src, &source_box);
}

void kope_d3d12_command_list_copy_texture_to_texture(kope_g5_command_list *list, const kope_g5_image_copy_texture *source,
const kope_g5_image_copy_texture *destination, uint32_t width, uint32_t height,
uint32_t depth_or_array_layers) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ void kope_d3d12_command_list_copy_buffer_to_texture(kope_g5_command_list *list,
const kope_g5_image_copy_texture *destination, uint32_t width, uint32_t height,
uint32_t depth_or_array_layers);

void kope_d3d12_command_list_copy_texture_to_buffer(kope_g5_command_list *list, const kope_g5_image_copy_texture *source,
const kope_g5_image_copy_buffer *destination, uint32_t width, uint32_t height,
uint32_t depth_or_array_layers);

void kope_d3d12_command_list_copy_texture_to_texture(kope_g5_command_list *list, const kope_g5_image_copy_texture *source,
const kope_g5_image_copy_texture *destination, uint32_t width, uint32_t height,
uint32_t depth_or_array_layers);
Expand Down
61 changes: 35 additions & 26 deletions Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,54 +173,59 @@ void kope_d3d12_device_create_buffer(kope_g5_device *device, const kope_g5_buffe
// static_assert(sizeof(D3D12IindexBufferView) == sizeof(D3D12_INDEX_BUFFER_VIEW), "Something is wrong with D3D12IindexBufferView");
// int uploadBufferSize = format == KINC_G5_INDEX_BUFFER_FORMAT_16BIT ? sizeof(uint16_t) * count : sizeof(uint32_t) * count;

D3D12_HEAP_PROPERTIES heapProperties;
heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
heapProperties.CreationNodeMask = 1;
heapProperties.VisibleNodeMask = 1;
if ((parameters->usage_flags & KOPE_G5_BUFFER_USAGE_CPU_READ) || (parameters->usage_flags & KOPE_G5_BUFFER_USAGE_CPU_WRITE)) {
heapProperties.Type = D3D12_HEAP_TYPE_UPLOAD;
D3D12_HEAP_PROPERTIES props;
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
props.CreationNodeMask = 1;
props.VisibleNodeMask = 1;
if ((parameters->usage_flags & KOPE_G5_BUFFER_USAGE_CPU_WRITE) != 0) {
props.Type = D3D12_HEAP_TYPE_UPLOAD;
}
else if ((parameters->usage_flags & KOPE_G5_BUFFER_USAGE_CPU_READ) != 0) {
props.Type = D3D12_HEAP_TYPE_READBACK;
}
else {
heapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
props.Type = D3D12_HEAP_TYPE_DEFAULT;
}

D3D12_RESOURCE_DESC resourceDesc = {};
resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
resourceDesc.Alignment = 0;
D3D12_RESOURCE_DESC desc = {};
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
desc.Alignment = 0;
if ((parameters->usage_flags & KOPE_G5_BUFFER_USAGE_RAYTRACING_VOLUME) != 0 || (parameters->usage_flags & KOPE_G5_BUFFER_USAGE_READ_WRITE) != 0) {
resourceDesc.Width = parameters->size;
desc.Width = parameters->size;
}
else {
resourceDesc.Width = align_pow2((int)parameters->size, 256); // 256 required for CBVs
desc.Width = align_pow2((int)parameters->size, 256); // 256 required for CBVs
}
resourceDesc.Height = 1;
resourceDesc.DepthOrArraySize = 1;
resourceDesc.MipLevels = 1;
resourceDesc.Format = DXGI_FORMAT_UNKNOWN;
resourceDesc.SampleDesc.Count = 1;
resourceDesc.SampleDesc.Quality = 0;
resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
resourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
desc.Height = 1;
desc.DepthOrArraySize = 1;
desc.MipLevels = 1;
desc.Format = DXGI_FORMAT_UNKNOWN;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
desc.Flags = D3D12_RESOURCE_FLAG_NONE;

buffer->d3d12.size = parameters->size;

if ((parameters->usage_flags & KOPE_G5_BUFFER_USAGE_READ_WRITE) != 0) {
buffer->d3d12.resource_state = D3D12_RESOURCE_STATE_COMMON;
resourceDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
}
else if ((parameters->usage_flags & KOPE_G5_BUFFER_USAGE_CPU_READ) != 0) {
buffer->d3d12.resource_state = D3D12_RESOURCE_STATE_COMMON;
}
else {
buffer->d3d12.resource_state = D3D12_RESOURCE_STATE_GENERIC_READ;
}

if ((parameters->usage_flags & KOPE_G5_BUFFER_USAGE_RAYTRACING_VOLUME) != 0) {
buffer->d3d12.resource_state = D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE;
resourceDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
}

kinc_microsoft_affirm(device->d3d12.device->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, &resourceDesc,
(D3D12_RESOURCE_STATES)buffer->d3d12.resource_state, NULL,
IID_GRAPHICS_PPV_ARGS(&buffer->d3d12.resource)));
kinc_microsoft_affirm(device->d3d12.device->CreateCommittedResource(
&props, D3D12_HEAP_FLAG_NONE, &desc, (D3D12_RESOURCE_STATES)buffer->d3d12.resource_state, NULL, IID_GRAPHICS_PPV_ARGS(&buffer->d3d12.resource)));
}

static uint32_t current_command_list_allocator_index(kope_g5_command_list *list) {
Expand Down Expand Up @@ -522,6 +527,10 @@ void kope_d3d12_device_execute_command_list(kope_g5_device *device, kope_g5_comm
}
}

void kope_d3d12_device_wait_until_idle(kope_g5_device *device) {
// wait_for_fence(device, list->d3d12.fence, list->d3d12.event, list->d3d12.execution_index - (KOPE_D3D12_COMMAND_LIST_ALLOCATOR_COUNT - 1));
}

void kope_d3d12_device_create_descriptor_set(kope_g5_device *device, uint32_t descriptor_count, uint32_t sampler_count, kope_d3d12_descriptor_set *set) {
if (descriptor_count > 0) {
oa_allocate(&device->d3d12.descriptor_heap_allocator, descriptor_count, &set->descriptor_allocation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ kope_g5_texture *kope_d3d12_device_get_framebuffer(kope_g5_device *device);

void kope_d3d12_device_execute_command_list(kope_g5_device *device, kope_g5_command_list *list);

void kope_d3d12_device_wait_until_idle(kope_g5_device *device);

void kope_d3d12_device_create_raytracing_volume(kope_g5_device *device, kope_g5_buffer *vertex_buffer, uint64_t vertex_count, kope_g5_buffer *index_buffer,
uint32_t index_count, kope_g5_raytracing_volume *volume);

Expand Down
6 changes: 6 additions & 0 deletions Sources/kope/graphics5/commandlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ void kope_g5_command_list_copy_buffer_to_texture(kope_g5_command_list *list, con
KOPE_G5_CALL6(command_list_copy_buffer_to_texture, list, source, destination, width, height, depth_or_array_layers);
}

void kope_g5_command_list_copy_texture_to_buffer(kope_g5_command_list *list, const kope_g5_image_copy_texture *source,
const kope_g5_image_copy_buffer *destination, uint32_t width, uint32_t height,
uint32_t depth_or_array_layers) {
KOPE_G5_CALL6(command_list_copy_texture_to_buffer, list, source, destination, width, height, depth_or_array_layers);
}

void kope_g5_command_list_copy_texture_to_texture(kope_g5_command_list *list, const kope_g5_image_copy_texture *source,
const kope_g5_image_copy_texture *destination, uint32_t width, uint32_t height,
uint32_t depth_or_array_layers) {
Expand Down
4 changes: 4 additions & 0 deletions Sources/kope/graphics5/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,7 @@ void kope_g5_device_create_raytracing_hierarchy(kope_g5_device *device, kope_g5_
uint32_t volumes_count, kope_g5_raytracing_hierarchy *hierarchy) {
KOPE_G5_CALL5(device_create_raytracing_hierarchy, device, volumes, volume_transforms, volumes_count, hierarchy);
}

void kope_g5_device_wait_until_idle(kope_g5_device *device) {
KOPE_G5_CALL1(device_wait_until_idle, device);
}
2 changes: 2 additions & 0 deletions Sources/kope/graphics5/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ KOPE_FUNC void kope_g5_device_create_query_set(void *descriptor);

KOPE_FUNC void kope_g5_device_execute_command_list(kope_g5_device *device, kope_g5_command_list *list);

KOPE_FUNC void kope_g5_device_wait_until_idle(kope_g5_device *device);

typedef struct kope_g5_raytracing_volume {
KOPE_G5_IMPL(raytracing_volume);
} kope_g5_raytracing_volume;
Expand Down

0 comments on commit 728e3fc

Please sign in to comment.