diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp index a998292c4..304a1be04 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp @@ -226,24 +226,24 @@ void kope_d3d12_command_list_copy_buffer_to_texture(kope_g5_command_list *list, source->buffer->d3d12.resource_state = D3D12_RESOURCE_STATE_COPY_SOURCE; } - if (destination->texture->d3d12.resource_states[0] != D3D12_RESOURCE_STATE_COPY_DEST) { + if (destination->texture->d3d12.resource_states[destination->mip_level] != D3D12_RESOURCE_STATE_COPY_DEST) { D3D12_RESOURCE_BARRIER barrier; 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->texture->d3d12.resource_states[0]; + barrier.Transition.StateBefore = (D3D12_RESOURCE_STATES)destination->texture->d3d12.resource_states[destination->mip_level]; barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST; - barrier.Transition.Subresource = 0; + barrier.Transition.Subresource = D3D12CalcSubresource(destination->mip_level, 0, 0, 0, 0); list->d3d12.list->ResourceBarrier(1, &barrier); - destination->texture->d3d12.resource_states[0] = D3D12_RESOURCE_STATE_COPY_DEST; + destination->texture->d3d12.resource_states[destination->mip_level] = D3D12_RESOURCE_STATE_COPY_DEST; } D3D12_TEXTURE_COPY_LOCATION dst; dst.pResource = destination->texture->d3d12.resource; dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - dst.SubresourceIndex = 0; + dst.SubresourceIndex = D3D12CalcSubresource(destination->mip_level, 0, 0, 0, 0); D3D12_TEXTURE_COPY_LOCATION src; src.pResource = source->buffer->d3d12.resource; @@ -269,43 +269,43 @@ void kope_d3d12_command_list_copy_buffer_to_texture(kope_g5_command_list *list, 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_states[0] != D3D12_RESOURCE_STATE_COPY_SOURCE) { + 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[0]; + 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 = 0; + barrier.Transition.Subresource = D3D12CalcSubresource(source->mip_level, 0, 0, 0, 0); list->d3d12.list->ResourceBarrier(1, &barrier); - source->texture->d3d12.resource_states[0] = D3D12_RESOURCE_STATE_COPY_SOURCE; + source->texture->d3d12.resource_states[source->mip_level] = D3D12_RESOURCE_STATE_COPY_SOURCE; } - if (destination->texture->d3d12.resource_states[0] != D3D12_RESOURCE_STATE_COPY_DEST) { + if (destination->texture->d3d12.resource_states[destination->mip_level] != D3D12_RESOURCE_STATE_COPY_DEST) { D3D12_RESOURCE_BARRIER barrier; 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->texture->d3d12.resource_states[0]; + barrier.Transition.StateBefore = (D3D12_RESOURCE_STATES)destination->texture->d3d12.resource_states[destination->mip_level]; barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST; - barrier.Transition.Subresource = 0; + barrier.Transition.Subresource = D3D12CalcSubresource(destination->mip_level, 0, 0, 0, 0); list->d3d12.list->ResourceBarrier(1, &barrier); - destination->texture->d3d12.resource_states[0] = D3D12_RESOURCE_STATE_COPY_DEST; + destination->texture->d3d12.resource_states[destination->mip_level] = D3D12_RESOURCE_STATE_COPY_DEST; } D3D12_TEXTURE_COPY_LOCATION dst; dst.pResource = destination->texture->d3d12.resource; dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - dst.SubresourceIndex = 0; + dst.SubresourceIndex = D3D12CalcSubresource(destination->mip_level, 0, 0, 0, 0); D3D12_TEXTURE_COPY_LOCATION src; src.pResource = source->texture->d3d12.resource; src.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - src.SubresourceIndex = 0; + src.SubresourceIndex = D3D12CalcSubresource(source->mip_level, 0, 0, 0, 0); D3D12_BOX source_box = {0}; source_box.left = source->origin_x; diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/d3d12unit.h b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/d3d12unit.h index ef17a416e..de13c8893 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/d3d12unit.h +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/d3d12unit.h @@ -54,4 +54,9 @@ #define IID_GRAPHICS_PPV_ARGS(x) IID_PPV_ARGS(x) #endif +// https://learn.microsoft.com/en-us/windows/win32/direct3d12/subresources +static inline UINT D3D12CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSlice, UINT MipLevels, UINT ArraySize) { + return MipSlice + (ArraySlice * MipLevels) + (PlaneSlice * MipLevels * ArraySize); +} + #endif diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/descriptorset.cpp b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/descriptorset.cpp index e7cfeca9b..90444b6d2 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/descriptorset.cpp +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/descriptorset.cpp @@ -40,8 +40,8 @@ void kope_d3d12_descriptor_set_set_bvh_view_srv(kope_g5_device *device, kope_d3d device->d3d12.device->CreateShaderResourceView(nullptr, &desc, descriptor_handle); } -void kope_d3d12_descriptor_set_set_texture_view_srv(kope_g5_device *device, kope_d3d12_descriptor_set *set, kope_g5_texture *texture, uint32_t mip_level, - uint32_t index) { +void kope_d3d12_descriptor_set_set_texture_view_srv(kope_g5_device *device, kope_d3d12_descriptor_set *set, kope_g5_texture *texture, + uint32_t highest_mip_level, uint32_t mip_count, uint32_t index) { D3D12_SHADER_RESOURCE_VIEW_DESC desc = {}; desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; @@ -59,8 +59,8 @@ void kope_d3d12_descriptor_set_set_texture_view_srv(kope_g5_device *device, kope break; } - desc.Texture2D.MipLevels = 1; - desc.Texture2D.MostDetailedMip = mip_level; + desc.Texture2D.MipLevels = mip_count; + desc.Texture2D.MostDetailedMip = highest_mip_level; desc.Texture2D.ResourceMinLODClamp = 0.0f; D3D12_CPU_DESCRIPTOR_HANDLE descriptor_handle = device->d3d12.descriptor_heap->GetCPUDescriptorHandleForHeapStart(); @@ -131,24 +131,21 @@ void kope_d3d12_descriptor_set_prepare_cbv_buffer(kope_g5_command_list *list, ko } } -// https://learn.microsoft.com/en-us/windows/win32/direct3d12/subresources -inline UINT D3D12CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSlice, UINT MipLevels, UINT ArraySize) { - return MipSlice + (ArraySlice * MipLevels) + (PlaneSlice * MipLevels * ArraySize); -} - -void kope_d3d12_descriptor_set_prepare_srv_texture(kope_g5_command_list *list, kope_g5_texture *texture, uint32_t mip_level) { - if (texture->d3d12.resource_states[mip_level] != (D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE)) { - D3D12_RESOURCE_BARRIER barrier; - barrier.Transition.pResource = texture->d3d12.resource; - barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - barrier.Transition.StateBefore = (D3D12_RESOURCE_STATES)texture->d3d12.resource_states[mip_level]; - barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; - barrier.Transition.Subresource = D3D12CalcSubresource(mip_level, 0, 0, 0, 0); - - list->d3d12.list->ResourceBarrier(1, &barrier); - - texture->d3d12.resource_states[mip_level] = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; +void kope_d3d12_descriptor_set_prepare_srv_texture(kope_g5_command_list *list, kope_g5_texture *texture, uint32_t highest_mip_level, uint32_t mip_count) { + for (uint32_t mip_level = highest_mip_level; mip_level < highest_mip_level + mip_count; ++mip_level) { + if (texture->d3d12.resource_states[mip_level] != (D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE)) { + D3D12_RESOURCE_BARRIER barrier; + barrier.Transition.pResource = texture->d3d12.resource; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier.Transition.StateBefore = (D3D12_RESOURCE_STATES)texture->d3d12.resource_states[mip_level]; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; + barrier.Transition.Subresource = D3D12CalcSubresource(mip_level, 0, 0, 0, 0); + + list->d3d12.list->ResourceBarrier(1, &barrier); + + texture->d3d12.resource_states[mip_level] = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; + } } } diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/descriptorset_functions.h b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/descriptorset_functions.h index ed2d10ec3..7f4e56fd3 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/descriptorset_functions.h +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/descriptorset_functions.h @@ -14,15 +14,15 @@ extern "C" { void kope_d3d12_descriptor_set_set_buffer_view_cbv(kope_g5_device *device, kope_d3d12_descriptor_set *set, kope_g5_buffer *buffer, uint32_t index); void kope_d3d12_descriptor_set_set_buffer_view_srv(kope_g5_device *device, kope_d3d12_descriptor_set *set, kope_g5_buffer *buffer, uint32_t index); void kope_d3d12_descriptor_set_set_bvh_view_srv(kope_g5_device *device, kope_d3d12_descriptor_set *set, kope_g5_raytracing_hierarchy *bvh, uint32_t index); -void kope_d3d12_descriptor_set_set_texture_view_srv(kope_g5_device *device, kope_d3d12_descriptor_set *set, kope_g5_texture *texture, uint32_t mip_level, - uint32_t index); +void kope_d3d12_descriptor_set_set_texture_view_srv(kope_g5_device *device, kope_d3d12_descriptor_set *set, kope_g5_texture *texture, + uint32_t highest_mip_level, uint32_t mip_count, uint32_t index); void kope_d3d12_descriptor_set_set_texture_cube_view_srv(kope_g5_device *device, kope_d3d12_descriptor_set *set, kope_g5_texture *texture, uint32_t index); void kope_d3d12_descriptor_set_set_texture_view_uav(kope_g5_device *device, kope_d3d12_descriptor_set *set, kope_g5_texture *texture, uint32_t mip_level, uint32_t index); void kope_d3d12_descriptor_set_set_sampler(kope_g5_device *device, kope_d3d12_descriptor_set *set, kope_g5_sampler *sampler, uint32_t index); void kope_d3d12_descriptor_set_prepare_cbv_buffer(kope_g5_command_list *list, kope_g5_buffer *buffer); -void kope_d3d12_descriptor_set_prepare_srv_texture(kope_g5_command_list *list, kope_g5_texture *texture, uint32_t mip_level); +void kope_d3d12_descriptor_set_prepare_srv_texture(kope_g5_command_list *list, kope_g5_texture *texture, uint32_t highest_mip_level, uint32_t mip_count); void kope_d3d12_descriptor_set_prepare_uav_texture(kope_g5_command_list *list, kope_g5_texture *texture, uint32_t mip_level); #ifdef __cplusplus