allow present to target backbuffer coordinates

This commit is contained in:
jacob 2025-09-23 18:30:58 -05:00
parent 38d9b90bf1
commit d4aa3de928
5 changed files with 101 additions and 20 deletions

View File

@ -270,7 +270,7 @@ Enum(GPU_ReleaseFlag)
{
GPU_ReleaseFlag_None = 0,
/* Hints to the GPU layer that more resources using the same desc will
/* Hints to the GPU layer that more resources using a similar desc will
* be allocated soon, so the resource's memory should be kept around for
* re-use. */
GPU_ReleaseFlag_Reuse = (1 << 0)
@ -468,8 +468,8 @@ void GPU_ReleaseSwapchain(GPU_Swapchain *swapchain);
* This should be called before rendering for minimum latency. */
void GPU_YieldOnSwapchain(GPU_Swapchain *swapchain);
/* 1. Ensures the backbuffer matches the size of `texture`
* 2. Blits `texture` to the backbuffer
/* 1. Ensures the backbuffer size matches `backbuffer_size`
* 2. Blits `texture` into position `dst` in the backbuffer
* 3. Presents the backbuffer
* 4. Returns the value that the Direct queue fence will reach once GPU completes blitting (`texture` shouldn't be released while blit is in flight) */
i64 GPU_PresentSwapchain(GPU_Swapchain *swapchain, GPU_Resource *texture, i32 vsync);
i64 GPU_PresentSwapchain(GPU_Swapchain *swapchain, GPU_Resource *texture, Vec2I32 backbuffer_size, Vec2I32 dst, i32 vsync);

View File

@ -773,14 +773,36 @@ GPU_D12_SwapchainBuffer *GPU_D12_UpdateSwapchain(GPU_D12_Swapchain *swapchain, V
return &swapchain->buffers[backbuffer_index];
}
i64 GPU_D12_BlitToSwapchain(GPU_D12_SwapchainBuffer *dst, GPU_D12_Resource *texture)
i64 GPU_D12_BlitToSwapchain(GPU_D12_SwapchainBuffer *dst, GPU_D12_Resource *texture, Vec2I32 dst_pos)
{
GPU_D12_SharedState *g = &GPU_D12_shared_state;
GPU_D12_Swapchain *swapchain = dst->swapchain;
GPU_D12_RawCommandList *dx12_cl = GPU_D12_BeginRawCommandList(GPU_QueueKind_Direct);
ID3D12GraphicsCommandList *rcl = dx12_cl->cl;
D3D12_RESOURCE_STATES old_texture_state = texture->state;
{
u32 barriers_count = 0;
D3D12_RESOURCE_BARRIER rbs[2] = ZI;
/* Transition backbuffer to RENDER_TARGET */
{
D3D12_RESOURCE_BARRIER *rb = &rbs[barriers_count++];
rb->Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
rb->Transition.pResource = dst->d3d_resource;
rb->Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
rb->Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
rb->Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
}
ID3D12GraphicsCommandList_ResourceBarrier(rcl, barriers_count, rbs);
}
/* Clear */
{
f32 clear_color[4] = ZI;
ID3D12GraphicsCommandList_ClearRenderTargetView(rcl, dst->rtv_descriptor->handle, clear_color, 0, 0);
}
{
u32 barriers_count = 0;
D3D12_RESOURCE_BARRIER rbs[2] = ZI;
@ -790,7 +812,7 @@ i64 GPU_D12_BlitToSwapchain(GPU_D12_SwapchainBuffer *dst, GPU_D12_Resource *text
rb->Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
rb->Transition.pResource = dst->d3d_resource;
rb->Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
rb->Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
rb->Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
rb->Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST;
}
/* Transition texture to COPY_SRC */
@ -808,7 +830,59 @@ i64 GPU_D12_BlitToSwapchain(GPU_D12_SwapchainBuffer *dst, GPU_D12_Resource *text
}
/* Copy */
ID3D12GraphicsCommandList_CopyResource(rcl, dst->d3d_resource, texture->d3d_resource);
{
D3D12_TEXTURE_COPY_LOCATION dst_loc = ZI;
dst_loc.pResource = dst->d3d_resource;
dst_loc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
dst_loc.SubresourceIndex = 0;
D3D12_TEXTURE_COPY_LOCATION src_loc = ZI;
src_loc.pResource = texture->d3d_resource;
src_loc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
src_loc.SubresourceIndex = 0;
Vec2I32 dst_size = swapchain->resolution;
Vec2I32 src_size = VEC2I32(texture->desc.texture.size.x, texture->desc.texture.size.y);
i32 dst_left = dst_pos.x;
i32 dst_top = dst_pos.y;
i32 src_left = 0;
i32 src_top = 0;
i32 src_right = src_size.x;
i32 src_bottom = src_size.y;
/* Clamp copy src & dst */
if (dst_left < 0)
{
src_left -= dst_left;
dst_left = 0;
}
if (dst_top < 0)
{
src_top -= dst_top;
dst_top = 0;
}
if (dst_left + (src_left + src_right) > dst_size.x)
{
src_right -= (dst_left + (src_left + src_right)) - dst_size.x;
}
if (dst_top + (src_top + src_bottom) > dst_size.y)
{
src_bottom -= (dst_top + (src_top + src_bottom)) - dst_size.y;
}
if (src_left < src_right && src_bottom > src_top)
{
D3D12_BOX src_box = ZI;
src_box.left = src_left;
src_box.top = src_top;
src_box.right = src_right;
src_box.bottom = src_bottom;
src_box.back = 1;
ID3D12GraphicsCommandList_CopyTextureRegion(rcl, &dst_loc, dst_left, dst_top, 0, &src_loc, &src_box);
}
}
{
u32 barriers_count = 0;
@ -1541,6 +1615,11 @@ i64 GPU_EndCommandList(GPU_CommandList *gpu_cl)
/* TODO */
Assert(0);
}
else if (dst_desc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER && src_desc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER)
{ /* Copy texture -> texture */
/* TODO */
Assert(0);
}
cmd = cmd->next;
} break;
@ -1994,6 +2073,7 @@ GPU_Swapchain *GPU_AcquireSwapchain(P_Window *window, GPU_Format format, Vec2I32
PushAlign(perm, CachelineSize);
}
ZeroStruct(swapchain);
swapchain->format = format;
/* Create swapchain1 */
IDXGISwapChain1 *swapchain1 = 0;
@ -2052,11 +2132,11 @@ void GPU_YieldOnSwapchain(GPU_Swapchain *swapchain)
/* TODO */
}
i64 GPU_PresentSwapchain(GPU_Swapchain *gpu_swapchain, GPU_Resource *gpu_texture, i32 vsync)
i64 GPU_PresentSwapchain(GPU_Swapchain *gpu_swapchain, GPU_Resource *gpu_texture, Vec2I32 backbuffer_size, Vec2I32 dst, i32 vsync)
{
GPU_D12_Swapchain *swapchain = (GPU_D12_Swapchain *)gpu_swapchain;
GPU_D12_Resource *texture = (GPU_D12_Resource *)gpu_texture;
GPU_D12_SwapchainBuffer *swapchain_buffer = GPU_D12_UpdateSwapchain(swapchain, VEC2I32(texture->desc.texture.size.x, texture->desc.texture.size.y));
GPU_D12_SwapchainBuffer *swapchain_buffer = GPU_D12_UpdateSwapchain(swapchain, backbuffer_size);
D3D12_RESOURCE_DESC src_desc = ZI;
D3D12_RESOURCE_DESC dst_desc = ZI;
@ -2065,17 +2145,14 @@ i64 GPU_PresentSwapchain(GPU_Swapchain *gpu_swapchain, GPU_Resource *gpu_texture
b32 is_blitable = src_desc.Dimension == dst_desc.Dimension
&& src_desc.SampleDesc.Count == dst_desc.SampleDesc.Count
&& src_desc.SampleDesc.Quality == dst_desc.SampleDesc.Quality
&& src_desc.Width == dst_desc.Width
&& src_desc.Height == dst_desc.Height
&& src_desc.DepthOrArraySize == dst_desc.DepthOrArraySize;
&& src_desc.SampleDesc.Quality == dst_desc.SampleDesc.Quality;
Assert(is_blitable == 1); /* Texture resource must be similar enough to backbuffer resource to blit */
i64 fence_target = 0;
if (is_blitable)
{
/* Blit */
fence_target = GPU_D12_BlitToSwapchain(swapchain_buffer, texture);
fence_target = GPU_D12_BlitToSwapchain(swapchain_buffer, texture, dst);
u32 present_flags = 0;
if (GPU_D12_TearingIsAllowed && vsync == 0)

View File

@ -258,6 +258,7 @@ Struct(GPU_D12_SwapchainBuffer)
Struct(GPU_D12_Swapchain)
{
GPU_D12_Swapchain *next;
GPU_Format format;
IDXGISwapChain3 *swapchain;
HWND window_hwnd;
@ -369,7 +370,7 @@ u64 GPU_D12_EndRawCommandList(GPU_D12_RawCommandList *cl);
void GPU_D12_InitSwapchainResources(GPU_D12_Swapchain *swapchain);
GPU_D12_SwapchainBuffer *GPU_D12_UpdateSwapchain(GPU_D12_Swapchain *swapchain, Vec2I32 resolution);
i64 GPU_D12_BlitToSwapchain(GPU_D12_SwapchainBuffer *swapchain_buffer, GPU_D12_Resource *texture);
i64 GPU_D12_BlitToSwapchain(GPU_D12_SwapchainBuffer *swapchain_buffer, GPU_D12_Resource *texture, Vec2I32 dst_pos);
////////////////////////////////
//~ Sync job

View File

@ -2538,7 +2538,10 @@ void UpdateUser(P_Window *window)
ResetArena(g->ui_shape_indices_arena);
ResetArena(g->grids_arena);
}
g->gpu_render_fence_target = GPU_PresentSwapchain(g->swapchain, g->ui_target, 0);
Vec2 backbuffer_dst_f = MulXformV2(g->ui_to_screen_xf, VEC2(0, 0));
Vec2I32 backbuffer_dst = VEC2I32(RoundF32ToI32(backbuffer_dst_f.x), RoundF32ToI32(backbuffer_dst_f.y));
g->gpu_render_fence_target = GPU_PresentSwapchain(g->swapchain, g->ui_target, g->screen_size, backbuffer_dst, 0);
}
EndScratch(scratch);

View File

@ -198,10 +198,10 @@ f32 RandAngle(Vec2U32 pos, u32 ray_index)
ConstantBuffer<ShadeSig> sig = shade_sig;
Texture3D<u32> noise_tex = GpuResourceFromUrid(sig.noise_tex_urid);
Vec3U32 noise_coord = Vec3U32(1, 1, 1);
Vec3I32 noise_coord = Vec3U32(1, 1, 1);
noise_coord += Vec3I32(pos.xy, ray_index);
noise_coord.xyz += sig.frame_seed.xyz;
// noise_coord.xy -= sig.camera_offset;
// noise_coord.xyz += sig.frame_seed.xyz;
noise_coord.xy -= sig.camera_offset;
u32 noise = noise_tex[noise_coord % Vec3U32(sig.noise_tex_width, sig.noise_tex_height, sig.noise_tex_depth)];
return ((f32)noise / (f32)0xFFFF) * Tau;