Skip to content

Commit

Permalink
Support multiple render targets and pimp the copy functions
Browse files Browse the repository at this point in the history
  • Loading branch information
RobDangerous committed Sep 17, 2024
1 parent 5620fca commit 17b2ad7
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 71 deletions.
145 changes: 87 additions & 58 deletions Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,40 +12,49 @@
void kope_d3d12_command_list_begin_render_pass(kope_g5_command_list *list, const kope_g5_render_pass_parameters *parameters) {
list->d3d12.compute_pipeline_set = false;

kope_g5_texture *render_target = parameters->color_attachments[0].texture;
D3D12_CPU_DESCRIPTOR_HANDLE render_target_views[8];
D3D12_RECT scissors[8];
D3D12_VIEWPORT viewports[8];

if (render_target->d3d12.in_flight_frame_index > 0) {
list->d3d12.blocking_frame_index = render_target->d3d12.in_flight_frame_index;
}
for (size_t render_target_index = 0; render_target_index < parameters->color_attachments_count; ++render_target_index) {
kope_g5_texture *render_target = parameters->color_attachments[render_target_index].texture;

if (render_target->d3d12.resource_state != D3D12_RESOURCE_STATE_RENDER_TARGET) {
D3D12_RESOURCE_BARRIER barrier;
barrier.Transition.pResource = render_target->d3d12.resource;
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
barrier.Transition.StateBefore = (D3D12_RESOURCE_STATES)render_target->d3d12.resource_state;
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
if (render_target->d3d12.in_flight_frame_index > 0) {
list->d3d12.blocking_frame_index = render_target->d3d12.in_flight_frame_index;
}

list->d3d12.list->ResourceBarrier(1, &barrier);
if (render_target->d3d12.resource_state != D3D12_RESOURCE_STATE_RENDER_TARGET) {
D3D12_RESOURCE_BARRIER barrier;
barrier.Transition.pResource = render_target->d3d12.resource;
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
barrier.Transition.StateBefore = (D3D12_RESOURCE_STATES)render_target->d3d12.resource_state;
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;

render_target->d3d12.resource_state = D3D12_RESOURCE_STATE_RENDER_TARGET;
}
list->d3d12.list->ResourceBarrier(1, &barrier);

render_target->d3d12.resource_state = D3D12_RESOURCE_STATE_RENDER_TARGET;
}

D3D12_CPU_DESCRIPTOR_HANDLE rtv = list->d3d12.device->all_rtvs->GetCPUDescriptorHandleForHeapStart();
rtv.ptr += render_target->d3d12.rtv_index * list->d3d12.device->rtv_increment;
D3D12_CPU_DESCRIPTOR_HANDLE rtv = list->d3d12.device->all_rtvs->GetCPUDescriptorHandleForHeapStart();
rtv.ptr += render_target->d3d12.rtv_index * list->d3d12.device->rtv_increment;

D3D12_RECT scissor = {0, 0, 1024, 768};
render_target_views[render_target_index] = rtv;

D3D12_VIEWPORT viewport = {0.0f, 0.0f, 1024.0f, 768.0f, 0.0f, 1.0f};
scissors[render_target_index] = {0, 0, 1024, 768};
viewports[render_target_index] = {0.0f, 0.0f, 1024.0f, 768.0f, 0.0f, 1.0f};
}

list->d3d12.list->OMSetRenderTargets(1, &rtv, true, nullptr);
list->d3d12.list->RSSetViewports(1, &viewport);
list->d3d12.list->RSSetScissorRects(1, &scissor);
list->d3d12.list->OMSetRenderTargets((UINT)parameters->color_attachments_count, render_target_views, true, nullptr);
list->d3d12.list->RSSetViewports((UINT)parameters->color_attachments_count, viewports);
list->d3d12.list->RSSetScissorRects((UINT)parameters->color_attachments_count, scissors);

FLOAT color[4];
memcpy(color, &parameters->color_attachments[0].clear_value, sizeof(color));
list->d3d12.list->ClearRenderTargetView(rtv, color, 0, NULL);
for (size_t render_target_index = 0; render_target_index < parameters->color_attachments_count; ++render_target_index) {
FLOAT color[4];
memcpy(color, &parameters->color_attachments[render_target_index].clear_value, sizeof(color));
list->d3d12.list->ClearRenderTargetView(render_target_views[render_target_index], color, 0, NULL);
}
}

void kope_d3d12_command_list_end_render_pass(kope_g5_command_list *list) {}
Expand Down Expand Up @@ -115,93 +124,113 @@ void kope_d3d12_command_list_set_descriptor_table(kope_g5_command_list *list, ui
}
}

void kope_d3d12_command_list_copy_buffer_to_texture(kope_g5_command_list *list, kope_g5_buffer *source, kope_g5_texture *destination, kope_uint3 size) {
if (source->d3d12.resource_state != D3D12_RESOURCE_STATE_COPY_SOURCE) {
void kope_d3d12_command_list_copy_buffer_to_texture(kope_g5_command_list *list, const kope_g5_image_copy_buffer *source,
const kope_g5_image_copy_texture *destination, uint32_t width, uint32_t height,
uint32_t depth_or_array_layers) {
if (source->buffer->d3d12.resource_state != D3D12_RESOURCE_STATE_COPY_SOURCE) {
D3D12_RESOURCE_BARRIER barrier;
barrier.Transition.pResource = source->d3d12.resource;
barrier.Transition.pResource = source->buffer->d3d12.resource;
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
barrier.Transition.StateBefore = (D3D12_RESOURCE_STATES)source->d3d12.resource_state;
barrier.Transition.StateBefore = (D3D12_RESOURCE_STATES)source->buffer->d3d12.resource_state;
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE;
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;

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

source->d3d12.resource_state = D3D12_RESOURCE_STATE_COPY_SOURCE;
source->buffer->d3d12.resource_state = D3D12_RESOURCE_STATE_COPY_SOURCE;
}

if (destination->d3d12.resource_state != D3D12_RESOURCE_STATE_COPY_DEST) {
if (destination->texture->d3d12.resource_state != D3D12_RESOURCE_STATE_COPY_DEST) {
D3D12_RESOURCE_BARRIER barrier;
barrier.Transition.pResource = destination->d3d12.resource;
barrier.Transition.pResource = destination->texture->d3d12.resource;
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
barrier.Transition.StateBefore = (D3D12_RESOURCE_STATES)destination->d3d12.resource_state;
barrier.Transition.StateBefore = (D3D12_RESOURCE_STATES)destination->texture->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->d3d12.resource_state = D3D12_RESOURCE_STATE_COPY_DEST;
destination->texture->d3d12.resource_state = D3D12_RESOURCE_STATE_COPY_DEST;
}

D3D12_TEXTURE_COPY_LOCATION dst;
dst.pResource = destination->d3d12.resource;
dst.pResource = destination->texture->d3d12.resource;
dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
dst.SubresourceIndex = 0;

D3D12_TEXTURE_COPY_LOCATION src;
src.pResource = source->d3d12.resource;
src.pResource = source->buffer->d3d12.resource;
src.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
src.PlacedFootprint.Offset = 0;
src.PlacedFootprint.Offset = source->offset;
src.PlacedFootprint.Footprint.Depth = 1;
src.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
src.PlacedFootprint.Footprint.Height = 512;
src.PlacedFootprint.Footprint.RowPitch = 512 * 4;
src.PlacedFootprint.Footprint.Width = 512;

list->d3d12.list->CopyTextureRegion(&dst, 0, 0, 0, &src, NULL);
src.PlacedFootprint.Footprint.Height = width;
src.PlacedFootprint.Footprint.Width = height;
src.PlacedFootprint.Footprint.RowPitch = source->bytes_per_row;

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 = 1;

list->d3d12.list->CopyTextureRegion(&dst, destination->origin_x, destination->origin_y, destination->origin_z, &src, &source_box);
}

void kope_d3d12_command_list_copy_texture_to_texture(kope_g5_command_list *list, kope_g5_texture *source, kope_g5_texture *destination, kope_uint3 size) {
if (source->d3d12.resource_state != D3D12_RESOURCE_STATE_COPY_SOURCE) {
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) {
if (source->texture->d3d12.resource_state != D3D12_RESOURCE_STATE_COPY_SOURCE) {
D3D12_RESOURCE_BARRIER barrier;
barrier.Transition.pResource = source->d3d12.resource;
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->d3d12.resource_state;
barrier.Transition.StateBefore = (D3D12_RESOURCE_STATES)source->texture->d3d12.resource_state;
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE;
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;

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

source->d3d12.resource_state = D3D12_RESOURCE_STATE_COPY_SOURCE;
source->texture->d3d12.resource_state = D3D12_RESOURCE_STATE_COPY_SOURCE;
}

if (destination->d3d12.resource_state != D3D12_RESOURCE_STATE_COPY_DEST) {
if (destination->texture->d3d12.resource_state != D3D12_RESOURCE_STATE_COPY_DEST) {
D3D12_RESOURCE_BARRIER barrier;
barrier.Transition.pResource = destination->d3d12.resource;
barrier.Transition.pResource = destination->texture->d3d12.resource;
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
barrier.Transition.StateBefore = (D3D12_RESOURCE_STATES)destination->d3d12.resource_state;
barrier.Transition.StateBefore = (D3D12_RESOURCE_STATES)destination->texture->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->d3d12.resource_state = D3D12_RESOURCE_STATE_COPY_DEST;
destination->texture->d3d12.resource_state = D3D12_RESOURCE_STATE_COPY_DEST;
}

D3D12_TEXTURE_COPY_LOCATION dst;
dst.pResource = destination->d3d12.resource;
dst.pResource = destination->texture->d3d12.resource;
dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
dst.SubresourceIndex = 0;

D3D12_TEXTURE_COPY_LOCATION src;
src.pResource = source->d3d12.resource;
src.pResource = source->texture->d3d12.resource;
src.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
src.SubresourceIndex = 0;

list->d3d12.list->CopyTextureRegion(&dst, 0, 0, 0, &src, NULL);
D3D12_BOX source_box = {0};
source_box.left = source->origin_x;
source_box.right = source_box.left + width;
source_box.top = source->origin_y;
source_box.bottom = source_box.top + height;
source_box.front = 0;
source_box.back = 1;

list->d3d12.list->CopyTextureRegion(&dst, destination->origin_x, destination->origin_y, destination->origin_z, &src, &source_box);
}

void kope_d3d12_command_list_set_compute_pipeline(kope_g5_command_list *list, kope_d3d12_compute_pipeline *pipeline) {
Expand Down Expand Up @@ -326,7 +355,7 @@ void kope_d3d12_command_list_set_ray_pipeline(kope_g5_command_list *list, kope_d
list->d3d12.compute_pipeline_set = true;
}

void kope_d3d12_command_list_trace_rays(kope_g5_command_list *list) {
void kope_d3d12_command_list_trace_rays(kope_g5_command_list *list, uint32_t width, uint32_t height, uint32_t depth) {
D3D12_DISPATCH_RAYS_DESC desc = {};
desc.RayGenerationShaderRecord.StartAddress = list->d3d12.ray_pipe->shader_ids.d3d12.resource->GetGPUVirtualAddress();
desc.RayGenerationShaderRecord.SizeInBytes = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES;
Expand All @@ -336,9 +365,9 @@ void kope_d3d12_command_list_trace_rays(kope_g5_command_list *list) {
list->d3d12.ray_pipe->shader_ids.d3d12.resource->GetGPUVirtualAddress() + 2 * D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT;
desc.HitGroupTable.SizeInBytes = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES;

desc.Width = 1024;
desc.Height = 768;
desc.Depth = 1;
desc.Width = width;
desc.Height = height;
desc.Depth = depth;

list->d3d12.list->DispatchRays(&desc);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@
extern "C" {
#endif

void kope_d3d12_command_list_copy_buffer_to_texture(kope_g5_command_list *list, kope_g5_buffer *source, kope_g5_texture *destination, kope_uint3 size);
void kope_d3d12_command_list_copy_buffer_to_texture(kope_g5_command_list *list, const kope_g5_image_copy_buffer *source,
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_texture(kope_g5_command_list *list, kope_g5_texture *source, kope_g5_texture *destination, kope_uint3 size);
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);

void kope_d3d12_command_list_begin_render_pass(kope_g5_command_list *list, const kope_g5_render_pass_parameters *parameters);

Expand Down Expand Up @@ -46,7 +50,7 @@ void kope_d3d12_command_list_update_raytracing_hierarchy(kope_g5_command_list *l

void kope_d3d12_command_list_set_ray_pipeline(kope_g5_command_list *list, kope_d3d12_ray_pipeline *pipeline);

void kope_d3d12_command_list_trace_rays(kope_g5_command_list *list);
void kope_d3d12_command_list_trace_rays(kope_g5_command_list *list, uint32_t width, uint32_t height, uint32_t depth);

#ifdef __cplusplus
}
Expand Down
16 changes: 10 additions & 6 deletions Sources/kope/graphics5/commandlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@
#include <kope/vulkan/commandlist_functions.h>
#endif

void kope_g5_command_list_copy_buffer_to_texture(kope_g5_command_list *list, kope_g5_buffer *source, kope_g5_texture *destination, kope_uint3 size) {
KOPE_G5_CALL4(command_list_copy_buffer_to_texture, list, source, destination, size);
void kope_g5_command_list_copy_buffer_to_texture(kope_g5_command_list *list, const kope_g5_image_copy_buffer *source,
const kope_g5_image_copy_texture *destination, uint32_t width, uint32_t height,
uint32_t depth_or_array_layers) {
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_texture(kope_g5_command_list *list, kope_g5_texture *source, kope_g5_texture *destination, kope_uint3 size) {
KOPE_G5_CALL4(command_list_copy_texture_to_texture, list, source, destination, size);
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) {
KOPE_G5_CALL6(command_list_copy_texture_to_texture, list, source, destination, width, height, depth_or_array_layers);
}

void kope_g5_command_list_begin_render_pass(kope_g5_command_list *list, const kope_g5_render_pass_parameters *parameters) {
Expand Down Expand Up @@ -54,6 +58,6 @@ void kope_g5_command_list_update_raytracing_hierarchy(kope_g5_command_list *list
KOPE_G5_CALL4(command_list_update_raytracing_hierarchy, list, volume_transforms, volumes_count, hierarchy);
}

void kope_g5_command_list_trace_rays(kope_g5_command_list *list) {
KOPE_G5_CALL1(command_list_trace_rays, list);
void kope_g5_command_list_trace_rays(kope_g5_command_list *list, uint32_t width, uint32_t height, uint32_t depth) {
KOPE_G5_CALL4(command_list_trace_rays, list, width, height, depth);
}
38 changes: 34 additions & 4 deletions Sources/kope/graphics5/commandlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,21 +73,51 @@ typedef struct kope_g5_render_pass_depth_stencil_attachment {

typedef struct kope_g5_render_pass_parameters {
kope_g5_render_pass_color_attachment color_attachments[8];
size_t color_attachments_count;
kope_g5_render_pass_depth_stencil_attachment depth_stencil_attachments[8];
size_t depth_stencil_attachments_count;
// GPUQuerySet occlusionQuerySet;
// GPURenderPassTimestampWrites timestampWrites;
} kope_g5_render_pass_parameters;

KOPE_FUNC void kope_g5_command_list_begin_render_pass(kope_g5_command_list *list, const kope_g5_render_pass_parameters *parameters);

typedef enum kope_g5_image_copy_aspect {
KOPE_G5_IMAGE_COPY_ASPECT_ALL,
KOPE_G5_IMAGE_COPY_ASPECT_DEPTH_ONLY,
KOPE_G5_IMAGE_COPY_ASPECT_STENCIL_ONLY
} kope_g5_image_copy_aspect;

typedef struct kope_g5_image_copy_texture {
kope_g5_image_copy_aspect aspect;
uint32_t mip_level;
uint32_t origin_x;
uint32_t origin_y;
uint32_t origin_z;
kope_g5_texture *texture;
} kope_g5_image_copy_texture;

typedef struct kope_g5_image_copy_buffer {
kope_g5_buffer *buffer;
uint64_t offset;
uint32_t bytes_per_row;
uint32_t rows_per_image;
} kope_g5_image_copy_buffer;

KOPE_FUNC void kope_g5_command_list_copy_buffer_to_buffer(kope_g5_command_list *list, kope_g5_buffer *source, uint64_t source_offset,
kope_g5_buffer *destination, uint64_t destination_offset, uint64_t size);

KOPE_FUNC void kope_g5_command_list_copy_buffer_to_texture(kope_g5_command_list *list, kope_g5_buffer *source, kope_g5_texture *destination, kope_uint3 size);
KOPE_FUNC void kope_g5_command_list_copy_buffer_to_texture(kope_g5_command_list *list, const kope_g5_image_copy_buffer *source,
const kope_g5_image_copy_texture *destination, uint32_t width, uint32_t height,
uint32_t depth_or_array_layers);

KOPE_FUNC void kope_g5_command_list_copy_texture_to_buffer(kope_g5_command_list *list, kope_g5_texture *source, kope_g5_buffer *destination, kope_uint3 size);
KOPE_FUNC 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_FUNC void kope_g5_command_list_copy_texture_to_texture(kope_g5_command_list *list, kope_g5_texture *source, kope_g5_texture *destination, kope_uint3 size);
KOPE_FUNC 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);

KOPE_FUNC void kope_g5_command_list_clear_buffer(kope_g5_command_list *list, kope_g5_buffer *buffer, size_t offset, uint64_t size);

Expand Down Expand Up @@ -138,7 +168,7 @@ KOPE_FUNC void kope_g5_command_list_prepare_raytracing_hierarchy(kope_g5_command
KOPE_FUNC void kope_g5_command_list_update_raytracing_hierarchy(kope_g5_command_list *list, kinc_matrix4x4_t *volume_transforms, uint32_t volumes_count,
struct kope_g5_raytracing_hierarchy *hierarchy);

KOPE_FUNC void kope_g5_command_list_trace_rays(kope_g5_command_list *list);
KOPE_FUNC void kope_g5_command_list_trace_rays(kope_g5_command_list *list, uint32_t width, uint32_t height, uint32_t depth);

KOPE_FUNC void kope_g5_command_list_present(kope_g5_command_list *list);

Expand Down

0 comments on commit 17b2ad7

Please sign in to comment.