diff --git a/src/gpu/gpu.h b/src/gpu/gpu.h index ec50f137..d2f82f68 100644 --- a/src/gpu/gpu.h +++ b/src/gpu/gpu.h @@ -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); diff --git a/src/gpu/gpu_dx12/gpu_dx12.c b/src/gpu/gpu_dx12/gpu_dx12.c index 9dfba581..73c05803 100644 --- a/src/gpu/gpu_dx12/gpu_dx12.c +++ b/src/gpu/gpu_dx12/gpu_dx12.c @@ -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) diff --git a/src/gpu/gpu_dx12/gpu_dx12.h b/src/gpu/gpu_dx12/gpu_dx12.h index 1a8fe58f..af1ca705 100644 --- a/src/gpu/gpu_dx12/gpu_dx12.h +++ b/src/gpu/gpu_dx12/gpu_dx12.h @@ -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 diff --git a/src/pp/pp.c b/src/pp/pp.c index 73fba8bf..7ec4a2ce 100644 --- a/src/pp/pp.c +++ b/src/pp/pp.c @@ -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); diff --git a/src/pp/pp_draw.gpu b/src/pp/pp_draw.gpu index 734d7813..f2d8900d 100644 --- a/src/pp/pp_draw.gpu +++ b/src/pp/pp_draw.gpu @@ -198,10 +198,10 @@ f32 RandAngle(Vec2U32 pos, u32 ray_index) ConstantBuffer sig = shade_sig; Texture3D 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;