screwing with legacy barriers

This commit is contained in:
jacob 2026-02-21 03:04:17 -06:00
parent 110407a063
commit 7014b1f02e
8 changed files with 198 additions and 578 deletions

View File

@ -316,7 +316,6 @@ void GC_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame)
gpu_perm, cl,
G_Format_R8G8B8A8_Unorm_Srgb,
atlas->dims,
G_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present,
.name = Lit("Glyph atlas")
);
atlas->tex = G_PushTexture2DRef(gpu_perm, atlas->tex_res);

View File

@ -25,7 +25,6 @@ void G_BootstrapCommon(void)
gpu_perm, cl,
G_Format_R8G8B8A8_Uint,
VEC2I32(8, 8),
G_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present,
.flags = G_ResourceFlag_ZeroMemory
);
G.blank_tex = G_PushTexture2DRef(gpu_perm, blank_tex);
@ -43,8 +42,7 @@ void G_BootstrapCommon(void)
noise_tex = G_PushTexture3D(
gpu_perm, cl,
G_Format_R16_Uint,
noise_dims,
G_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present
noise_dims
);
G_CopyCpuToTexture(
cl,

View File

@ -188,132 +188,6 @@ Enum(G_Format)
G_Format_COUNT = 192
};
////////////////////////////////////////////////////////////
//~ Memory sync types
Enum(G_Stage)
{
G_Stage_None = 0,
// Compute stages
G_Stage_ComputeShading = (1 << 1),
// Draw stages
G_Stage_IndexAssembly = (1 << 2),
G_Stage_VertexShading = (1 << 3),
G_Stage_PixelShading = (1 << 4),
G_Stage_DepthStencil = (1 << 5),
G_Stage_RenderTarget = (1 << 6),
// Copy stages
G_Stage_Copy = (1 << 7),
// Indirect stages
G_Stage_Indirect = (1 << 8),
// Aggregate stages
G_Stage_Drawing = G_Stage_IndexAssembly |
G_Stage_VertexShading |
G_Stage_PixelShading |
G_Stage_DepthStencil |
G_Stage_RenderTarget,
G_Stage_Shading = G_Stage_ComputeShading |
G_Stage_VertexShading |
G_Stage_PixelShading,
G_Stage_All = 0xFFFFFFFF
};
Enum(G_Access)
{
G_Access_None = 0,
G_Access_ShaderReadWrite = (1 << 1),
G_Access_ShaderRead = (1 << 2),
G_Access_CopyWrite = (1 << 3),
G_Access_CopyRead = (1 << 4),
G_Access_DepthStencilRead = (1 << 5),
G_Access_DepthStencilWrite = (1 << 6),
G_Access_RenderTargetWrite = (1 << 7),
G_Access_IndexBuffer = (1 << 8),
G_Access_IndirectArgument = (1 << 9),
G_Access_All = 0xFFFFFFFF // Represents all accesses relevant to the stage specified in the barrier
};
Enum(G_Layout)
{
G_Layout_NoChange,
// Simultaneous layout allows a resource to be used on any queue with any
// access type (except depth-stencil). Resources cannot transition to/from
// this layout, they must be created with it.
G_Layout_Simultaneous, // D3D12_BARRIER_LAYOUT_COMMON + D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS
G_Layout_Undefined, // D3D12_BARRIER_LAYOUT_UNDEFINED
//////////////////////////////
//- Queue-agnostic
G_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present, // D3D12_BARRIER_LAYOUT_COMMON
//////////////////////////////
//- Direct & Compute queue
G_Layout_DirectComputeQueue_ShaderRead_CopyRead, // D3D12_BARRIER_LAYOUT_GENERIC_READ
G_Layout_DirectComputeQueue_ShaderReadWrite, // D3D12_BARRIER_LAYOUT_UNORDERED_ACCESS
G_Layout_DirectComputeQueue_ShaderRead, // D3D12_BARRIER_LAYOUT_SHADER_RESOURCE
G_Layout_DirectComputeQueue_CopyRead, // D3D12_BARRIER_LAYOUT_COPY_SOURCE
G_Layout_DirectComputeQueue_CopyWrite, // D3D12_BARRIER_LAYOUT_COPY_DEST
//////////////////////////////
//- Direct queue
G_Layout_DirectQueue_ShaderRead_ShaderReadWrite_CopyRead_CopyWrite, // D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COMMON
G_Layout_DirectQueue_ShaderRead_CopyRead_DepthStencilRead, // D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_GENERIC_READ
G_Layout_DirectQueue_ShaderReadWrite, // D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_UNORDERED_ACCESS
G_Layout_DirectQueue_ShaderRead, // D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_SHADER_RESOURCE
G_Layout_DirectQueue_CopyRead, // D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_SOURCE
G_Layout_DirectQueue_CopyWrite, // D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_DEST
G_Layout_DirectQueue_DepthStencilRead_DepthStencilWrite, // D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE
G_Layout_DirectQueue_DepthStencilRead, // D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_READ
G_Layout_DirectQueue_RenderTargetWrite, // D3D12_BARRIER_LAYOUT_RENDER_TARGET
//////////////////////////////
//- Compute queue
G_Layout_ComputeQueue_ShaderRead_ShaderReadWrite_CopyRead_CopyWrite, // D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COMMON
G_Layout_ComputeQueue_ShaderRead_CopyRead, // D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_GENERIC_READ
G_Layout_ComputeQueue_ShaderReadWrite, // D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_UNORDERED_ACCESS
G_Layout_ComputeQueue_ShaderRead, // D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_SHADER_RESOURCE
G_Layout_ComputeQueue_CopyRead, // D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COPY_SOURCE
G_Layout_ComputeQueue_CopyWrite, // D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COPY_DEST
};
// Barrier will execute after previous stages specified by `stage_prev`, and before next stages specified by `stage_next`.
// When barrier executes:
// - Necessary resource flushes will occur based on `access_prev` & `access_next`
// - Texture layout will transition based on `layout` (if specified)
Struct(G_MemoryBarrierDesc)
{
G_ResourceHandle resource;
b32 is_global;
G_Stage stage_prev;
G_Stage stage_next;
G_Access access_prev;
G_Access access_next;
G_Layout layout;
RngI32 mips; // Inclusive range of texture mip indices to sync
};
////////////////////////////////////////////////////////////
//~ Filter types
@ -429,7 +303,6 @@ Struct(G_TextureDesc)
G_ResourceFlag flags;
G_Format format;
Vec3I32 dims;
G_Layout initial_layout;
Vec4 clear_color;
i32 max_mips; // Will be clamped to range [1, max mips]
String name;
@ -551,37 +424,34 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena, G_CommandListHandle cl, G_R
} \
)
#define G_PushTexture1D(arena, cl, _format, _size, _initial_layout, ...) G_PushResource((arena), (cl), \
#define G_PushTexture1D(arena, cl, _format, _size, ...) G_PushResource((arena), (cl), \
(G_ResourceDesc) { \
.kind = G_ResourceKind_Texture1D, \
.texture = { \
.format = (_format), \
.dims = VEC3I32((_size), 1, 1), \
.initial_layout = (_initial_layout), \
__VA_ARGS__ \
} \
} \
)
#define G_PushTexture2D(arena, cl, _format, _size, _initial_layout, ...) G_PushResource((arena), (cl), \
#define G_PushTexture2D(arena, cl, _format, _size, ...) G_PushResource((arena), (cl), \
(G_ResourceDesc) { \
.kind = G_ResourceKind_Texture2D, \
.texture = { \
.format = (_format), \
.dims = VEC3I32((_size).x, (_size).y, 1), \
.initial_layout = (_initial_layout), \
__VA_ARGS__ \
} \
} \
)
#define G_PushTexture3D(arena, cl, _format, _size, _initial_layout, ...) G_PushResource((arena), (cl), \
#define G_PushTexture3D(arena, cl, _format, _size, ...) G_PushResource((arena), (cl), \
(G_ResourceDesc) { \
.kind = G_ResourceKind_Texture3D, \
.texture = { \
.format = (_format), \
.dims = (_size), \
.initial_layout = (_initial_layout), \
__VA_ARGS__ \
} \
} \
@ -738,50 +608,7 @@ void G_SetConstantEx(G_CommandListHandle cl, i32 slot, void *src_32bit, u32 size
//- Memory sync
void G_MemorySyncEx(G_CommandListHandle cl, G_MemoryBarrierDesc desc);
#define G_MemorySync(_cl, _resource, _stage_prev, _access_prev, _stage_next, _access_next, ...) \
G_MemorySyncEx((_cl), (G_MemoryBarrierDesc) { \
.resource = (_resource), \
.stage_prev = _stage_prev, \
.access_prev = _access_prev, \
.stage_next = _stage_next, \
.access_next = _access_next, \
.mips.max = 64, \
__VA_ARGS__ \
})
#define G_MemoryLayoutSync(_cl, _resource, _stage_prev, _access_prev, _stage_next, _access_next, _layout, ...) \
G_MemorySyncEx((_cl), (G_MemoryBarrierDesc) { \
.resource = (_resource), \
.stage_prev = _stage_prev, \
.access_prev = _access_prev, \
.stage_next = _stage_next, \
.access_next = _access_next, \
.layout = _layout, \
.mips.max = 64, \
__VA_ARGS__ \
})
#define G_GlobalMemorySync(_cl, _stage_prev, _access_prev, _stage_next, _access_next, ...) \
G_MemorySyncEx((_cl), (G_MemoryBarrierDesc) { \
.is_global = 1, \
.stage_prev = _stage_prev, \
.access_prev = _access_prev, \
.stage_next = _stage_next, \
.access_next = _access_next, \
.mips.max = 64, \
__VA_ARGS__ \
})
#define G_DumbMemorySync(cl, resource, ...) \
G_MemorySync((cl), (resource), G_Stage_All, G_Access_All, G_Stage_All, G_Access_All, __VA_ARGS__)
#define G_DumbMemoryLayoutSync(cl, resource, layout, ...) \
G_MemoryLayoutSync((cl), (resource), G_Stage_All, G_Access_All, G_Stage_All, G_Access_All, (layout), __VA_ARGS__)
#define G_DumbGlobalMemorySync(cl, ...) \
G_GlobalMemorySync((cl), G_Stage_All, G_Access_All, G_Stage_All, G_Access_All, __VA_ARGS__)
void G_Barrier(G_CommandListHandle cl);
//- Compute

View File

@ -57,7 +57,7 @@ void G_Bootstrap(void)
// Create device
{
IDXGIAdapter3 *adapter = 0;
ID3D12Device10 *device = 0;
ID3D12Device1 *device = 0;
String error = Lit("Could not initialize GPU device.");
String first_gpu_name = Zi;
u32 adapter_index = 0;
@ -80,7 +80,7 @@ void G_Bootstrap(void)
// - ResourceBindingTier >= D3D12_RESOURCE_BINDING_TIER_3
// - EnhancedBarriersSupported == 1
// - AtomicInt64OnDescriptorHeapResourceSupported == 1
hr = D3D12CreateDevice((IUnknown *)adapter, D3D_FEATURE_LEVEL_12_0, &IID_ID3D12Device10, (void **)&device);
hr = D3D12CreateDevice((IUnknown *)adapter, D3D_FEATURE_LEVEL_12_0, &IID_ID3D12Device1, (void **)&device);
}
if (SUCCEEDED(hr) && skips <= 0)
{
@ -378,136 +378,6 @@ DXGI_FORMAT G_D12_DxgiFormatFromGpuFormat(G_Format format)
return (DXGI_FORMAT)format;
}
D3D12_BARRIER_SYNC G_D12_BarrierSyncFromStages(G_Stage stages)
{
D3D12_BARRIER_SYNC result = 0;
if (stages == G_Stage_All)
{
result = D3D12_BARRIER_SYNC_ALL;
}
else
{
result |= D3D12_BARRIER_SYNC_COMPUTE_SHADING * AnyBit(stages, G_Stage_ComputeShading);
result |= D3D12_BARRIER_SYNC_INDEX_INPUT * AnyBit(stages, G_Stage_IndexAssembly);
result |= D3D12_BARRIER_SYNC_VERTEX_SHADING * AnyBit(stages, G_Stage_VertexShading);
result |= D3D12_BARRIER_SYNC_PIXEL_SHADING * AnyBit(stages, G_Stage_PixelShading);
result |= D3D12_BARRIER_SYNC_DEPTH_STENCIL * AnyBit(stages, G_Stage_DepthStencil);
result |= D3D12_BARRIER_SYNC_RENDER_TARGET * AnyBit(stages, G_Stage_RenderTarget);
result |= D3D12_BARRIER_SYNC_COPY * AnyBit(stages, G_Stage_Copy);
result |= D3D12_BARRIER_SYNC_EXECUTE_INDIRECT * AnyBit(stages, G_Stage_Indirect);
}
return result;
}
D3D12_BARRIER_ACCESS G_D12_BarrierAccessFromAccesses(G_Access accesses)
{
D3D12_BARRIER_ACCESS result = 0;
if (accesses == 0)
{
result = D3D12_BARRIER_ACCESS_NO_ACCESS;
}
else if (accesses == G_Access_All)
{
result = D3D12_BARRIER_ACCESS_COMMON;
}
else
{
result |= D3D12_BARRIER_ACCESS_UNORDERED_ACCESS * AnyBit(accesses, G_Access_ShaderReadWrite);
result |= D3D12_BARRIER_ACCESS_SHADER_RESOURCE * AnyBit(accesses, G_Access_ShaderRead);
result |= D3D12_BARRIER_ACCESS_COPY_DEST * AnyBit(accesses, G_Access_CopyWrite);
result |= D3D12_BARRIER_ACCESS_COPY_SOURCE * AnyBit(accesses, G_Access_CopyRead);
result |= D3D12_BARRIER_ACCESS_INDEX_BUFFER * AnyBit(accesses, G_Access_IndexBuffer);
result |= D3D12_BARRIER_ACCESS_INDIRECT_ARGUMENT * AnyBit(accesses, G_Access_IndirectArgument);
result |= D3D12_BARRIER_ACCESS_DEPTH_STENCIL_READ * AnyBit(accesses, G_Access_DepthStencilRead);
result |= D3D12_BARRIER_ACCESS_DEPTH_STENCIL_WRITE * AnyBit(accesses, G_Access_DepthStencilWrite);
result |= D3D12_BARRIER_ACCESS_RENDER_TARGET * AnyBit(accesses, G_Access_RenderTargetWrite);
}
return result;
}
D3D12_BARRIER_LAYOUT G_D12_BarrierLayoutFromLayout(G_Layout layout)
{
PERSIST Readonly D3D12_BARRIER_LAYOUT translate[] = {
[G_Layout_Undefined] = D3D12_BARRIER_LAYOUT_UNDEFINED,
[G_Layout_Simultaneous] = D3D12_BARRIER_LAYOUT_COMMON,
[G_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present] = D3D12_BARRIER_LAYOUT_COMMON,
[G_Layout_DirectComputeQueue_ShaderReadWrite] = D3D12_BARRIER_LAYOUT_UNORDERED_ACCESS,
[G_Layout_DirectComputeQueue_ShaderRead_CopyRead] = D3D12_BARRIER_LAYOUT_GENERIC_READ,
[G_Layout_DirectComputeQueue_ShaderRead] = D3D12_BARRIER_LAYOUT_SHADER_RESOURCE,
[G_Layout_DirectComputeQueue_CopyRead] = D3D12_BARRIER_LAYOUT_COPY_SOURCE,
[G_Layout_DirectComputeQueue_CopyWrite] = D3D12_BARRIER_LAYOUT_COPY_DEST,
[G_Layout_DirectQueue_ShaderRead_ShaderReadWrite_CopyRead_CopyWrite] = D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COMMON,
[G_Layout_DirectQueue_ShaderReadWrite] = D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_UNORDERED_ACCESS,
[G_Layout_DirectQueue_ShaderRead_CopyRead_DepthStencilRead] = D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_GENERIC_READ,
[G_Layout_DirectQueue_ShaderRead] = D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_SHADER_RESOURCE,
[G_Layout_DirectQueue_CopyRead] = D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_SOURCE,
[G_Layout_DirectQueue_CopyWrite] = D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_DEST,
[G_Layout_DirectQueue_DepthStencilRead_DepthStencilWrite] = D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE,
[G_Layout_DirectQueue_DepthStencilRead] = D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_READ,
[G_Layout_DirectQueue_RenderTargetWrite] = D3D12_BARRIER_LAYOUT_RENDER_TARGET,
[G_Layout_ComputeQueue_ShaderRead_ShaderReadWrite_CopyRead_CopyWrite] = D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COMMON,
[G_Layout_ComputeQueue_ShaderReadWrite] = D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_UNORDERED_ACCESS,
[G_Layout_ComputeQueue_ShaderRead_CopyRead] = D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_GENERIC_READ,
[G_Layout_ComputeQueue_ShaderRead] = D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_SHADER_RESOURCE,
[G_Layout_ComputeQueue_CopyRead] = D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COPY_SOURCE,
[G_Layout_ComputeQueue_CopyWrite] = D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COPY_DEST,
};
D3D12_BARRIER_LAYOUT result = D3D12_BARRIER_LAYOUT_UNDEFINED;
if (layout >= 0 && layout < countof(translate))
{
result = translate[layout];
}
return result;
};
String G_D12_NameFromBarrierLayout(D3D12_BARRIER_LAYOUT layout)
{
PERSIST Readonly String names[] = {
[D3D12_BARRIER_LAYOUT_COMMON] = CompLit("D3D12_BARRIER_LAYOUT_COMMON"),
[D3D12_BARRIER_LAYOUT_PRESENT] = CompLit("D3D12_BARRIER_LAYOUT_PRESENT"),
[D3D12_BARRIER_LAYOUT_GENERIC_READ] = CompLit("D3D12_BARRIER_LAYOUT_GENERIC_READ"),
[D3D12_BARRIER_LAYOUT_RENDER_TARGET] = CompLit("D3D12_BARRIER_LAYOUT_RENDER_TARGET"),
[D3D12_BARRIER_LAYOUT_UNORDERED_ACCESS] = CompLit("D3D12_BARRIER_LAYOUT_UNORDERED_ACCESS"),
[D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE] = CompLit("D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE"),
[D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_READ] = CompLit("D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_READ"),
[D3D12_BARRIER_LAYOUT_SHADER_RESOURCE] = CompLit("D3D12_BARRIER_LAYOUT_SHADER_RESOURCE"),
[D3D12_BARRIER_LAYOUT_COPY_SOURCE] = CompLit("D3D12_BARRIER_LAYOUT_COPY_SOURCE"),
[D3D12_BARRIER_LAYOUT_COPY_DEST] = CompLit("D3D12_BARRIER_LAYOUT_COPY_DEST"),
[D3D12_BARRIER_LAYOUT_RESOLVE_SOURCE] = CompLit("D3D12_BARRIER_LAYOUT_RESOLVE_SOURCE"),
[D3D12_BARRIER_LAYOUT_RESOLVE_DEST] = CompLit("D3D12_BARRIER_LAYOUT_RESOLVE_DEST"),
[D3D12_BARRIER_LAYOUT_SHADING_RATE_SOURCE] = CompLit("D3D12_BARRIER_LAYOUT_SHADING_RATE_SOURCE"),
[D3D12_BARRIER_LAYOUT_VIDEO_DECODE_READ] = CompLit("D3D12_BARRIER_LAYOUT_VIDEO_DECODE_READ"),
[D3D12_BARRIER_LAYOUT_VIDEO_DECODE_WRITE] = CompLit("D3D12_BARRIER_LAYOUT_VIDEO_DECODE_WRITE"),
[D3D12_BARRIER_LAYOUT_VIDEO_PROCESS_READ] = CompLit("D3D12_BARRIER_LAYOUT_VIDEO_PROCESS_READ"),
[D3D12_BARRIER_LAYOUT_VIDEO_PROCESS_WRITE] = CompLit("D3D12_BARRIER_LAYOUT_VIDEO_PROCESS_WRITE"),
[D3D12_BARRIER_LAYOUT_VIDEO_ENCODE_READ] = CompLit("D3D12_BARRIER_LAYOUT_VIDEO_ENCODE_READ"),
[D3D12_BARRIER_LAYOUT_VIDEO_ENCODE_WRITE] = CompLit("D3D12_BARRIER_LAYOUT_VIDEO_ENCODE_WRITE"),
[D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COMMON] = CompLit("D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COMMON"),
[D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_GENERIC_READ] = CompLit("D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_GENERIC_READ"),
[D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_UNORDERED_ACCESS] = CompLit("D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_UNORDERED_ACCESS"),
[D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_SHADER_RESOURCE] = CompLit("D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_SHADER_RESOURCE"),
[D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_SOURCE] = CompLit("D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_SOURCE"),
[D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_DEST] = CompLit("D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_DEST"),
[D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COMMON] = CompLit("D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COMMON"),
[D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_GENERIC_READ] = CompLit("D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_GENERIC_READ"),
[D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_UNORDERED_ACCESS] = CompLit("D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_UNORDERED_ACCESS"),
[D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_SHADER_RESOURCE] = CompLit("D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_SHADER_RESOURCE"),
[D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COPY_SOURCE] = CompLit("D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COPY_SOURCE"),
[D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COPY_DEST] = CompLit("D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COPY_DEST"),
[D3D12_BARRIER_LAYOUT_VIDEO_QUEUE_COMMON] = CompLit("D3D12_BARRIER_LAYOUT_VIDEO_QUEUE_COMMON")
};
String result = Zi;
if (layout >= 0 && layout < countof(names))
{
result = names[layout];
}
else if (layout == D3D12_BARRIER_LAYOUT_UNDEFINED)
{
result = Lit("D3D12_BARRIER_LAYOUT_UNDEFINED");
}
return result;
}
void G_D12_InitRtv(G_D12_Resource *resource, D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle, i32 mip)
{
DXGI_FORMAT format = G_D12_DxgiFormatFromGpuFormat(resource->texture_format);
@ -871,7 +741,7 @@ G_D12_RawCommandList *G_D12_PrepareRawCommandList(G_QueueKind queue_kind)
if (SUCCEEDED(hr))
{
hr = ID3D12Device_CreateCommandList(G_D12.device, 0, queue->desc.type, cl->d3d_ca, 0, &IID_ID3D12GraphicsCommandList7, (void **)&cl->d3d_cl);
hr = ID3D12Device_CreateCommandList(G_D12.device, 0, queue->desc.type, cl->d3d_ca, 0, &IID_ID3D12GraphicsCommandList, (void **)&cl->d3d_cl);
}
if (SUCCEEDED(hr))
@ -1115,9 +985,9 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
//////////////////////////////
//- Initialize d3d resource desc
D3D12_BARRIER_LAYOUT d3d_initial_layout = D3D12_BARRIER_LAYOUT_UNDEFINED;
D3D12_RESOURCE_STATES d3d_initial_state = D3D12_RESOURCE_STATE_COMMON;
D3D12_CLEAR_VALUE clear_value = Zi;
D3D12_RESOURCE_DESC1 d3d_desc = Zi;
D3D12_RESOURCE_DESC d3d_desc = Zi;
if (is_buffer)
{
u64 min_buffer_size = 1024;
@ -1136,7 +1006,6 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
{
i32 largest_dim = MaxI32(MaxI32(desc.texture.dims.x, desc.texture.dims.y), desc.texture.dims.z);
i32 max_mips = MinI32(FloorF32(Log2F32(largest_dim)) + 1, G_MaxMips);
d3d_initial_layout = G_D12_BarrierLayoutFromLayout(desc.texture.initial_layout);
d3d_desc.Dimension = (
desc.kind == G_ResourceKind_Texture1D ? D3D12_RESOURCE_DIMENSION_TEXTURE1D :
desc.kind == G_ResourceKind_Texture2D ? D3D12_RESOURCE_DIMENSION_TEXTURE2D :
@ -1153,7 +1022,10 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS * AnyBit(flags, G_ResourceFlag_AllowShaderReadWrite);
d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET * AnyBit(flags, G_ResourceFlag_AllowRenderTarget);
d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL * AnyBit(flags, G_ResourceFlag_AllowDepthStencil);
d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS * (desc.texture.initial_layout == G_Layout_Simultaneous);
if (!AnyBit(d3d_desc.Flags, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL))
{
d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS;
}
clear_value.Color[0] = desc.texture.clear_color.x,
clear_value.Color[1] = desc.texture.clear_color.y,
clear_value.Color[2] = desc.texture.clear_color.z,
@ -1171,8 +1043,8 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
DllQueueRemove(gpu_arena->reset_resources.first, gpu_arena->reset_resources.last, resource);
--gpu_arena->reset_resources.count;
D3D12_RESOURCE_DESC1 reset_d3d_desc = Zi;
D3D12_RESOURCE_DESC1 compare_d3d_desc = Zi;
D3D12_RESOURCE_DESC reset_d3d_desc = Zi;
D3D12_RESOURCE_DESC compare_d3d_desc = Zi;
CopyStruct(&reset_d3d_desc, &resource->d3d_desc);
CopyStruct(&compare_d3d_desc, &reset_d3d_desc);
@ -1269,26 +1141,18 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
{
clear_value_arg = &clear_value;
}
HRESULT hr = ID3D12Device10_CreateCommittedResource3(
HRESULT hr = ID3D12Device_CreateCommittedResource(
G_D12.device,
&heap_props,
heap_flags,
&resource->d3d_desc,
d3d_initial_layout,
d3d_initial_state,
clear_value_arg,
0, // pProtectedSession
0, // NumCastableFormats
0, // pCastableFormats
&IID_ID3D12Resource,
(void **)&resource->d3d_resource
);
Atomic64FetchAdd(&G_D12.cumulative_nonreuse_count, 1);
for (i32 mip_idx = 0; mip_idx < resource->texture_mips; ++mip_idx)
{
resource->cmdlist_texture_layouts[mip_idx] = d3d_initial_layout;
}
if (!SUCCEEDED(hr))
{
// TODO: Don't panic
@ -1339,14 +1203,8 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
if (can_reuse)
{
if (is_buffer)
{
G_DumbMemorySync(cl_handle, G_D12_MakeHandle(G_ResourceHandle, resource));
}
else if (is_texture)
{
G_DumbMemoryLayoutSync(cl_handle, G_D12_MakeHandle(G_ResourceHandle, resource), desc.texture.initial_layout);
}
// FIXME: Remove this
G_Barrier(cl_handle);
}
return G_D12_MakeHandle(G_ResourceHandle, resource);
@ -1960,7 +1818,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
// Begin dx12 command list
G_D12_RawCommandList *rcl = G_D12_PrepareRawCommandList(queue_kind);
ID3D12GraphicsCommandList7 *d3d_cl = rcl->d3d_cl;
ID3D12GraphicsCommandList *d3d_cl = rcl->d3d_cl;
// Pipeline state
b32 graphics_rootsig_set = 0;
@ -2027,9 +1885,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
}
// Batch barrier cmds
i64 max_buffer_barriers = 0;
i64 max_texture_barriers = 0;
i64 max_global_barriers = 0;
i64 max_barriers = 0;
{
u64 cmd_idx = 0;
u64 batch_gen = 0;
@ -2060,31 +1916,12 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
if (prev_barrier_cmd->barrier.batch_gen != batch_gen)
{
// This barrier is part of new batch
prev_barrier_cmd->barrier.is_end_of_batch = 1;
prev_barrier_cmd->barrier.should_commit = 1;
}
}
cmd->barrier.batch_gen = batch_gen;
prev_barrier_cmd = cmd;
if (cmd->barrier.desc.is_global)
{
max_global_barriers += 1;
}
else
{
G_D12_Resource *resource = G_D12_ResourceFromHandle(cmd->barrier.desc.resource);
if (resource->is_texture)
{
RngI32 mips = cmd->barrier.desc.mips;
mips.min = ClampI32(mips.min, 0, resource->texture_mips - 1);
mips.max = ClampI32(mips.max, mips.min, resource->texture_mips - 1);
max_texture_barriers += mips.max - mips.min + 1;
}
else
{
max_buffer_barriers += 1;
}
}
max_barriers += 1;
cmd_idx += 1;
} break;
@ -2093,15 +1930,12 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
if (prev_barrier_cmd)
{
prev_barrier_cmd->barrier.is_end_of_batch = 1;
prev_barrier_cmd->barrier.should_commit = 1;
}
}
// Build d3d commands
{
u64 batch_barrier_idx_start = 0;
u64 batch_barrier_idx_opl = 0; // One past last
u64 cmd_idx = 0;
while (cmd_idx < cmds_count)
{
@ -2130,133 +1964,11 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
case G_D12_CmdKind_Barrier:
{
batch_barrier_idx_opl = cmd_idx + 1;
// Submit batched barriers
if (cmd->barrier.is_end_of_batch)
if (cmd->barrier.should_commit)
{
// Build barriers
u64 buffer_barriers_count = 0;
u64 texture_barriers_count = 0;
u64 global_barriers_count = 0;
D3D12_BUFFER_BARRIER *buffer_barriers = PushStructs(scratch.arena, D3D12_BUFFER_BARRIER, max_buffer_barriers);
D3D12_TEXTURE_BARRIER *texture_barriers = PushStructs(scratch.arena, D3D12_TEXTURE_BARRIER, max_texture_barriers);
D3D12_GLOBAL_BARRIER *global_barriers = PushStructs(scratch.arena, D3D12_GLOBAL_BARRIER, max_global_barriers);
for (u64 barrier_cmd_idx = batch_barrier_idx_start; barrier_cmd_idx < batch_barrier_idx_opl; ++barrier_cmd_idx)
{
G_D12_Cmd *barrier_cmd = &cmds[barrier_cmd_idx];
if (barrier_cmd->kind == G_D12_CmdKind_Barrier)
{
G_MemoryBarrierDesc desc = barrier_cmd->barrier.desc;
// Translate gpu barrier kind -> d3d barrier fields
D3D12_BARRIER_SYNC sync_before = G_D12_BarrierSyncFromStages(desc.stage_prev);
D3D12_BARRIER_SYNC sync_after = G_D12_BarrierSyncFromStages(desc.stage_next);
D3D12_BARRIER_ACCESS access_before = G_D12_BarrierAccessFromAccesses(desc.access_prev);
D3D12_BARRIER_ACCESS access_after = G_D12_BarrierAccessFromAccesses(desc.access_next);
D3D12_BARRIER_TYPE barrier_type = D3D12_BARRIER_TYPE_GLOBAL;
if (!desc.is_global)
{
G_D12_Resource *resource = G_D12_ResourceFromHandle(desc.resource);
barrier_type = resource->is_texture ? D3D12_BARRIER_TYPE_TEXTURE : D3D12_BARRIER_TYPE_BUFFER;
}
// Build barrier
switch (barrier_type)
{
case D3D12_BARRIER_TYPE_BUFFER:
{
G_D12_Resource *resource = G_D12_ResourceFromHandle(desc.resource);
D3D12_BUFFER_BARRIER *barrier = &buffer_barriers[buffer_barriers_count++];
barrier->SyncBefore = sync_before;
barrier->SyncAfter = sync_after;
barrier->AccessBefore = access_before;
barrier->AccessAfter = access_after;
barrier->pResource = resource->d3d_resource;
barrier->Offset = 0;
barrier->Size = U64Max;
} break;
case D3D12_BARRIER_TYPE_TEXTURE:
{
G_D12_Resource *resource = G_D12_ResourceFromHandle(desc.resource);
RngI32 mips = barrier_cmd->barrier.desc.mips;
{
mips.min = ClampI32(mips.min, 0, resource->texture_mips - 1);
mips.max = ClampI32(mips.max, mips.min, resource->texture_mips - 1);
}
// Create a barrier for each contiguous span of mips with matching layout
D3D12_TEXTURE_BARRIER *barrier = 0;
for (i32 mip_idx = mips.min; mip_idx <= mips.max; ++mip_idx)
{
D3D12_BARRIER_LAYOUT layout_before = resource->cmdlist_texture_layouts[mip_idx];
D3D12_BARRIER_LAYOUT layout_after = layout_before;
if (desc.layout != G_Layout_NoChange)
{
layout_after = G_D12_BarrierLayoutFromLayout(desc.layout);
}
if (barrier == 0 || barrier->LayoutBefore != layout_before)
{
barrier = &texture_barriers[texture_barriers_count++];
barrier->SyncBefore = sync_before;
barrier->SyncAfter = sync_after;
barrier->AccessBefore = access_before;
barrier->AccessAfter = access_after;
barrier->LayoutBefore = layout_before;
barrier->LayoutAfter = layout_after;
barrier->pResource = resource->d3d_resource;
barrier->Subresources.IndexOrFirstMipLevel = mip_idx;
barrier->Subresources.NumArraySlices = 1;
barrier->Subresources.NumPlanes = 1;
}
barrier->Subresources.NumMipLevels += 1;
resource->cmdlist_texture_layouts[mip_idx] = layout_after;
}
} break;
case D3D12_BARRIER_TYPE_GLOBAL:
{
D3D12_GLOBAL_BARRIER *barrier = &global_barriers[global_barriers_count++];
barrier->SyncBefore = sync_before;
barrier->SyncAfter = sync_after;
barrier->AccessBefore = access_before;
barrier->AccessAfter = access_after;
} break;
}
}
}
// Dispatch barriers
{
u32 barrier_groups_count = 0;
D3D12_BARRIER_GROUP barrier_groups[3] = Zi;
if (buffer_barriers_count > 0)
{
D3D12_BARRIER_GROUP *group = &barrier_groups[barrier_groups_count++];
group->Type = D3D12_BARRIER_TYPE_BUFFER;
group->NumBarriers = buffer_barriers_count;
group->pBufferBarriers = buffer_barriers;
}
if (texture_barriers_count > 0)
{
D3D12_BARRIER_GROUP *group = &barrier_groups[barrier_groups_count++];
group->Type = D3D12_BARRIER_TYPE_TEXTURE;
group->NumBarriers = texture_barriers_count;
group->pTextureBarriers = texture_barriers;
}
if (global_barriers_count > 0)
{
D3D12_BARRIER_GROUP *group = &barrier_groups[barrier_groups_count++];
group->Type = D3D12_BARRIER_TYPE_GLOBAL;
group->NumBarriers = global_barriers_count;
group->pGlobalBarriers = global_barriers;
}
if (barrier_groups_count > 0)
{
ID3D12GraphicsCommandList7_Barrier(d3d_cl, barrier_groups_count, barrier_groups);
}
}
batch_barrier_idx_start = cmd_idx + 1;
D3D12_RESOURCE_BARRIER barrier = Zi;
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
ID3D12GraphicsCommandList_ResourceBarrier(d3d_cl, 1, &barrier);
}
cmd_idx += 1;
@ -2277,6 +1989,32 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
copy_size
);
cmd_idx += 1;
// FIXME: Remove this (only apply during Barrier command on any implicit resource transitions that occured)
D3D12_RESOURCE_BARRIER barriers[2] = Zi;
{
D3D12_RESOURCE_BARRIER *barrier = &barriers[0];
barrier->Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barrier->Transition.pResource = cmd->copy_bytes.dst->d3d_resource;
barrier->Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
barrier->Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
barrier->Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON;
}
{
D3D12_RESOURCE_BARRIER *barrier = &barriers[1];
barrier->Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barrier->Transition.pResource = cmd->copy_bytes.src->d3d_resource;
barrier->Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
barrier->Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_SOURCE;
barrier->Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON;
}
ID3D12GraphicsCommandList_ResourceBarrier(d3d_cl, 2, barriers);
} break;
//- Copy texels
@ -2316,6 +2054,28 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
ID3D12GraphicsCommandList_CopyTextureRegion(d3d_cl, &dst_loc, dst_offset.x, dst_offset.y, dst_offset.z, &src_loc, src_box_ptr);
}
// FIXME: Remove this (only apply during Barrier command on any implicit resource transitions that occured)
D3D12_RESOURCE_BARRIER barriers[2] = Zi;
{
D3D12_RESOURCE_BARRIER *barrier = &barriers[0];
barrier->Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barrier->Transition.pResource = dst->d3d_resource;
barrier->Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
barrier->Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
barrier->Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON;
}
{
D3D12_RESOURCE_BARRIER *barrier = &barriers[1];
barrier->Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barrier->Transition.pResource = src->d3d_resource;
barrier->Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
barrier->Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_SOURCE;
barrier->Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON;
}
ID3D12GraphicsCommandList_ResourceBarrier(d3d_cl, 2, barriers);
cmd_idx += 1;
} break;
@ -2549,20 +2309,31 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
}
// Bind render targets
u32 barriers_count = 0;
D3D12_RESOURCE_BARRIER barriers[G_MaxRenderTargets] = Zi;
{
b32 om_dirty = 0;
u32 rtvs_count = 0;
for (u32 i = 0; i < countof(cmd->rasterize.render_target_descs); ++i)
b32 om_dirty = 0;
for (u32 rtv_idx = 0; rtv_idx < countof(cmd->rasterize.render_target_descs); ++rtv_idx)
{
G_RenderTargetDesc desc = cmd->rasterize.render_target_descs[i];
G_RenderTargetDesc desc = cmd->rasterize.render_target_descs[rtv_idx];
G_D12_Resource *rt = G_D12_ResourceFromHandle(desc.resource);
if (rt)
{
if (bound_render_target_uids[i] != rt->uid + desc.mip)
{
G_D12_Descriptor *rtv_descriptor = rcl->rtv_descriptors[i];
D3D12_RESOURCE_BARRIER *barrier = &barriers[barriers_count];
barrier->Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barrier->Transition.pResource = rt->d3d_resource;
barrier->Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
barrier->Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
barrier->Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON;
++barriers_count;
}
if (bound_render_target_uids[rtv_idx] != rt->uid + desc.mip)
{
G_D12_Descriptor *rtv_descriptor = rcl->rtv_descriptors[rtv_idx];
G_D12_InitRtv(rt, rtv_descriptor->handle, desc.mip);
bound_render_target_uids[i] = rt->uid + desc.mip;
bound_render_target_uids[rtv_idx] = rt->uid + desc.mip;
om_dirty = 1;
}
++rtvs_count;
@ -2575,9 +2346,9 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
if (om_dirty)
{
D3D12_CPU_DESCRIPTOR_HANDLE rtv_handles[G_MaxRenderTargets] = Zi;
for (u32 i = 0; i < rtvs_count; ++i)
for (u32 rtv_idx = 0; rtv_idx < rtvs_count; ++rtv_idx)
{
rtv_handles[i] = rcl->rtv_descriptors[i]->handle;
rtv_handles[rtv_idx] = rcl->rtv_descriptors[rtv_idx]->handle;
}
ID3D12GraphicsCommandList_OMSetRenderTargets(d3d_cl, rtvs_count, rtv_handles, 0, 0);
}
@ -2585,6 +2356,10 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
// Dispatch
ID3D12GraphicsCommandList_DrawIndexedInstanced(d3d_cl, indices_count, cmd->rasterize.instances_count, 0, 0, 0);
// FIXME: Remove this (only apply during Barrier command on any implicit resource transitions that occured)
// FIXME: Does the implicit promotion happen during Draw? Or during OMSetRenderTargets?
ID3D12GraphicsCommandList_ResourceBarrier(d3d_cl, barriers_count, barriers);
}
cmd_idx += 1;
@ -2610,6 +2385,17 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
}
ID3D12GraphicsCommandList_ClearRenderTargetView(d3d_cl, rtv_handle, clear_color, 0, 0);
cmd_idx += 1;
// FIXME: Remove this (only apply during Barrier command on any implicit resource transitions that occured)
D3D12_RESOURCE_BARRIER barrier = Zi;
{
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barrier.Transition.pResource = rt->d3d_resource;
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON;
}
ID3D12GraphicsCommandList_ResourceBarrier(d3d_cl, 1, &barrier);
} break;
//- Discard rtv
@ -2622,35 +2408,49 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
G_D12_Resource *resource = cmd->discard_rtv.render_target;
ID3D12GraphicsCommandList_DiscardResource(d3d_cl, resource->d3d_resource, 0);
cmd_idx += 1;
// FIXME: Remove this (only apply during Barrier command on any implicit resource transitions that occured)
D3D12_RESOURCE_BARRIER barrier = Zi;
{
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barrier.Transition.pResource = resource->d3d_resource;
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON;
}
ID3D12GraphicsCommandList_ResourceBarrier(d3d_cl, 1, &barrier);
} break;
//- Log
case G_D12_CmdKind_Log:
{
G_D12_Resource *resource = cmd->log.resource;
String resource_name = STRING(resource->name_len, resource->name_text);
// FIXME
String layouts_str = Zi;
{
StringList layout_names = Zi;
for (i32 mip_idx = 0; mip_idx < resource->texture_mips; ++mip_idx)
{
String layout_name = G_D12_NameFromBarrierLayout(resource->cmdlist_texture_layouts[mip_idx]);
String layout_str = StringF(scratch.arena, "[%F] %F", FmtSint(mip_idx), FmtString(layout_name));
PushStringToList(scratch.arena, &layout_names, layout_str);
}
layouts_str = StringFromList(scratch.arena, layout_names, Lit(", "));
}
// G_D12_Resource *resource = cmd->log.resource;
// String resource_name = STRING(resource->name_len, resource->name_text);
// String layouts_str = Zi;
// {
// StringList layout_names = Zi;
// for (i32 mip_idx = 0; mip_idx < resource->texture_mips; ++mip_idx)
// {
// String layout_name = G_D12_NameFromBarrierLayout(resource->cmdlist_texture_layouts[mip_idx]);
// String layout_str = StringF(scratch.arena, "[%F] %F", FmtSint(mip_idx), FmtString(layout_name));
// PushStringToList(scratch.arena, &layout_names, layout_str);
// }
// layouts_str = StringFromList(scratch.arena, layout_names, Lit(", "));
// }
// String msg = StringF(
// scratch.arena,
// "[Gpu command list resource log] uid: %F, name: \"%F\", layouts: { %F }",
// FmtUint(resource->uid),
// FmtString(resource_name),
// FmtString(layouts_str)
// );
// LogDebug(msg);
String msg = StringF(
scratch.arena,
"[Gpu command list resource log] uid: %F, name: \"%F\", layouts: { %F }",
FmtUint(resource->uid),
FmtString(resource_name),
FmtString(layouts_str)
);
LogDebug(msg);
cmd_idx += 1;
} break;
}
@ -2963,12 +2763,11 @@ void G_SetConstantEx(G_CommandListHandle cl_handle, i32 slot, void *src_32bit, u
//- Memory sync
void G_MemorySyncEx(G_CommandListHandle cl_handle, G_MemoryBarrierDesc desc)
void G_Barrier(G_CommandListHandle cl_handle)
{
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
G_D12_Cmd *cmd = G_D12_PushCmd(cl);
cmd->kind = G_D12_CmdKind_Barrier;
cmd->barrier.desc = desc;
}
//- Compute
@ -3325,14 +3124,13 @@ G_ResourceHandle G_PrepareBackbuffer(G_SwapchainHandle swapchain_handle, G_Forma
backbuffer->flags = G_ResourceFlag_AllowRenderTarget;
backbuffer->uid = Atomic64FetchAdd(&G_D12.resource_creation_gen.v, 1) + 1;
ID3D12Resource_GetDesc(d3d_resource, (D3D12_RESOURCE_DESC *)&backbuffer->d3d_desc);
ID3D12Resource_GetDesc(d3d_resource, &backbuffer->d3d_desc);
backbuffer->d3d_resource = d3d_resource;
backbuffer->is_texture = 1;
backbuffer->texture_format = format;
backbuffer->texture_dims = VEC3I32(size.x, size.y, 1);
backbuffer->texture_mips = 1;
backbuffer->cmdlist_texture_layouts[0] = D3D12_BARRIER_LAYOUT_PRESENT;
backbuffer->swapchain = swapchain;
}
}
@ -3358,6 +3156,21 @@ G_ResourceHandle G_PrepareBackbuffer(G_SwapchainHandle swapchain_handle, G_Forma
cur_backbuffer = &swapchain->backbuffers[backbuffer_idx];
}
// Transition backbuffer to render target
{
G_D12_RawCommandList *rcl = G_D12_PrepareRawCommandList(G_QueueKind_Direct);
{
D3D12_RESOURCE_BARRIER barrier = Zi;
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barrier.Transition.pResource = cur_backbuffer->d3d_resource;
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COMMON;
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
ID3D12GraphicsCommandList_ResourceBarrier(rcl->d3d_cl, 1, &barrier);
}
G_D12_CommitRawCommandList(rcl);
}
return G_D12_MakeHandle(G_ResourceHandle, cur_backbuffer);
}
@ -3367,6 +3180,21 @@ void G_CommitBackbuffer(G_ResourceHandle backbuffer_handle, i32 vsync)
G_D12_Swapchain *swapchain = backbuffer->swapchain;
G_D12_Queue *direct_queue = G_D12_QueueFromKind(G_QueueKind_Direct);
// Transition backbuffer to presentable
{
G_D12_RawCommandList *rcl = G_D12_PrepareRawCommandList(G_QueueKind_Direct);
{
D3D12_RESOURCE_BARRIER barrier = Zi;
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barrier.Transition.pResource = backbuffer->d3d_resource;
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
ID3D12GraphicsCommandList_ResourceBarrier(rcl->d3d_cl, 1, &barrier);
}
G_D12_CommitRawCommandList(rcl);
}
u32 present_flags = 0;
if (G_D12_TearingIsAllowed && vsync == 0)
{
@ -3417,12 +3245,8 @@ void G_D12_CollectionWorkerEntryPoint(WaveLaneCtx *lane)
{
// Copy print buffer to readback buffer
G_CopyBufferToBuffer(cl, queue->print_readback_buffer, 0, queue->print_buffer, RNGU64(0, queue->print_buffer_size));
G_Barrier(cl);
// Reset counters to 0
G_MemorySync(
cl, queue->print_buffer,
G_Stage_Copy, G_Access_CopyRead,
G_Stage_Copy, G_Access_CopyWrite
);
u8 zero[12] = Zi;
G_CopyCpuToBuffer(cl, queue->print_buffer, 0, zero, RNGU64(0, sizeof(zero)));
}

View File

@ -72,7 +72,7 @@ Struct(G_D12_Resource)
u64 uid;
// D3D12 resource
D3D12_RESOURCE_DESC1 d3d_desc;
D3D12_RESOURCE_DESC d3d_desc;
ID3D12Resource *d3d_resource;
D3D12_GPU_VIRTUAL_ADDRESS buffer_gpu_address;
void *mapped;
@ -86,7 +86,6 @@ Struct(G_D12_Resource)
G_Format texture_format;
Vec3I32 texture_dims;
i32 texture_mips;
D3D12_BARRIER_LAYOUT cmdlist_texture_layouts[G_D12_MaxMips];
// Sampler info
G_SamplerDesc sampler_desc;
@ -262,7 +261,7 @@ Struct(G_D12_RawCommandList)
u64 commit_fence_target;
ID3D12CommandAllocator *d3d_ca;
ID3D12GraphicsCommandList7 *d3d_cl;
ID3D12GraphicsCommandList *d3d_cl;
// Direct queue command lists keep a constant list of CPU-only descriptors
G_D12_Descriptor *rtv_descriptors[G_MaxRenderTargets];
@ -324,10 +323,8 @@ Struct(G_D12_Cmd)
struct
{
G_MemoryBarrierDesc desc;
// Post-batch data
b32 is_end_of_batch;
b32 should_commit;
u64 batch_gen;
} barrier;
@ -478,7 +475,7 @@ Struct(G_D12_Ctx)
// Device
IDXGIFactory6 *factory;
IDXGIAdapter3 *adapter;
ID3D12Device10 *device;
ID3D12Device1 *device;
// Release-queue
Mutex pending_releases_mutex;
@ -509,10 +506,6 @@ G_D12_Resource *G_D12_ResourceFromHandle(G_ResourceHandle handle);
G_D12_Swapchain *G_D12_SwapchainFromHandle(G_SwapchainHandle handle);
DXGI_FORMAT G_D12_DxgiFormatFromGpuFormat(G_Format format);
D3D12_BARRIER_SYNC G_D12_BarrierSyncFromStages(G_Stage stages);
D3D12_BARRIER_ACCESS G_D12_BarrierAccessFromAccesses(G_Access accesses);
D3D12_BARRIER_LAYOUT G_D12_BarrierLayoutFromLayout(G_Layout layout);
String G_D12_NameFromBarrierLayout(D3D12_BARRIER_LAYOUT layout);
void G_D12_InitRtv(G_D12_Resource *resource, D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle, i32 mip);

View File

@ -416,7 +416,6 @@ void V_TickForever(WaveLaneCtx *lane)
gpu_perm, cl,
G_Format_R8_Uint,
tiles_dims,
G_Layout_DirectQueue_ShaderRead_ShaderReadWrite_CopyRead_CopyWrite,
.flags = G_ResourceFlag_ZeroMemory,
.name = Lit("Tiles")
);
@ -441,7 +440,6 @@ void V_TickForever(WaveLaneCtx *lane)
gpu_perm, cl,
G_Format_R32_Uint,
cells_dims,
G_Layout_DirectQueue_ShaderRead_ShaderReadWrite_CopyRead_CopyWrite,
.flags = G_ResourceFlag_ZeroMemory | G_ResourceFlag_AllowShaderReadWrite,
.name = StringF(perm, "Particle cells - layer %F", FmtSint(layer))
);
@ -454,7 +452,6 @@ void V_TickForever(WaveLaneCtx *lane)
gpu_perm, cl,
G_Format_R32_Uint,
cells_dims,
G_Layout_DirectQueue_ShaderRead_ShaderReadWrite_CopyRead_CopyWrite,
.flags = G_ResourceFlag_ZeroMemory | G_ResourceFlag_AllowShaderReadWrite,
.name = StringF(perm, "Particle densities - layer %F", FmtSint(layer))
);
@ -469,7 +466,6 @@ void V_TickForever(WaveLaneCtx *lane)
gpu_perm, cl,
G_Format_R16G16B16A16_Float,
cells_dims,
G_Layout_DirectQueue_ShaderRead_ShaderReadWrite_CopyRead_CopyWrite,
.flags = G_ResourceFlag_ZeroMemory | G_ResourceFlag_AllowShaderReadWrite,
.name = Lit("Stains")
);
@ -481,7 +477,6 @@ void V_TickForever(WaveLaneCtx *lane)
gpu_perm, cl,
G_Format_R16G16B16A16_Float,
cells_dims,
G_Layout_DirectQueue_ShaderRead_ShaderReadWrite_CopyRead_CopyWrite,
.flags = G_ResourceFlag_ZeroMemory | G_ResourceFlag_AllowShaderReadWrite,
.name = Lit("Dry stains")
);
@ -493,7 +488,6 @@ void V_TickForever(WaveLaneCtx *lane)
gpu_perm, cl,
G_Format_R32_Float,
cells_dims,
G_Layout_DirectQueue_ShaderRead_ShaderReadWrite_CopyRead_CopyWrite,
.flags = G_ResourceFlag_ZeroMemory | G_ResourceFlag_AllowShaderReadWrite,
.name = Lit("Drynesses")
);
@ -505,7 +499,6 @@ void V_TickForever(WaveLaneCtx *lane)
gpu_perm, cl,
G_Format_R32_Uint,
cells_dims,
G_Layout_DirectQueue_ShaderRead_ShaderReadWrite_CopyRead_CopyWrite,
.flags = G_ResourceFlag_ZeroMemory | G_ResourceFlag_AllowShaderReadWrite,
.name = Lit("Occluders cells")
);
@ -2501,9 +2494,9 @@ void V_TickForever(WaveLaneCtx *lane)
//////////////////////////////
//- Push test emitter
// if (frame->held_buttons[Button_F])
if (frame->held_buttons[Button_F])
// if (frame->held_buttons[Button_F] && !prev_frame->held_buttons[Button_F])
if (0)
// if (0)
{
{
V_Emitter emitter = Zi;
@ -2563,9 +2556,9 @@ void V_TickForever(WaveLaneCtx *lane)
//////////////////////////////
//- Push test explosion
// if (frame->held_buttons[Button_G])
if (frame->held_buttons[Button_G])
// if (frame->held_buttons[Button_G] && !prev_frame->held_buttons[Button_G])
if (0)
// if (0)
{
// Fire
{
@ -4791,7 +4784,6 @@ void V_TickForever(WaveLaneCtx *lane)
frame->gpu_arena, frame->cl,
G_Format_R16G16B16A16_Float,
frame->screen_dims,
G_Layout_DirectQueue_ShaderRead_ShaderReadWrite_CopyRead_CopyWrite,
.flags = G_ResourceFlag_AllowShaderReadWrite | G_ResourceFlag_AllowRenderTarget,
.name = StringF(frame->arena, "Screen target [%F]", FmtSint(frame->tick))
);
@ -4805,7 +4797,6 @@ void V_TickForever(WaveLaneCtx *lane)
frame->gpu_arena, frame->cl,
G_Format_R16G16B16A16_Float,
G_DimsFromMip2D(G_Count2D(screen_target), 1),
G_Layout_DirectQueue_ShaderRead_ShaderReadWrite_CopyRead_CopyWrite,
.flags = G_ResourceFlag_AllowShaderReadWrite | G_ResourceFlag_AllowRenderTarget,
.name = StringF(frame->arena, "Bloom target [%F]", FmtSint(frame->tick)),
.max_mips = 64
@ -4821,7 +4812,6 @@ void V_TickForever(WaveLaneCtx *lane)
frame->gpu_arena, frame->cl,
G_Format_R16G16B16A16_Float,
frame->screen_dims,
G_Layout_DirectQueue_RenderTargetWrite,
.flags = G_ResourceFlag_AllowRenderTarget,
.name = StringF(frame->arena, "Albedo target [%F]", FmtSint(frame->tick))
);
@ -4832,7 +4822,6 @@ void V_TickForever(WaveLaneCtx *lane)
frame->gpu_arena, frame->cl,
G_Format_R16G16B16A16_Float,
frame->shade_dims,
G_Layout_DirectQueue_ShaderRead_ShaderReadWrite_CopyRead_CopyWrite,
.flags = G_ResourceFlag_AllowShaderReadWrite,
.name = StringF(frame->arena, "Shade target [%F]", FmtSint(frame->tick))
);
@ -4899,7 +4888,7 @@ void V_TickForever(WaveLaneCtx *lane)
G_SetConstant(frame->cl, V_GpuConst_NoiseTex, G_BasicNoiseTexture());
// Sync
G_DumbGlobalMemorySync(frame->cl);
G_Barrier(frame->cl);
//////////////////////////////
//- Initialization pass
@ -4923,7 +4912,7 @@ void V_TickForever(WaveLaneCtx *lane)
}
// Sync
G_DumbGlobalMemorySync(frame->cl);
G_Barrier(frame->cl);
//////////////////////////////
//- Quads & emitters pass
@ -4943,10 +4932,7 @@ void V_TickForever(WaveLaneCtx *lane)
G_Compute(frame->cl, V_EmitParticlesCS, V_ThreadGroupSizeFromBufferSize(frame->emitters_count));
// Sync particles & occluders
G_DumbGlobalMemorySync(frame->cl);
// Transition albedo
G_DumbMemoryLayoutSync(frame->cl, albedo_target, G_Layout_DirectQueue_ShaderRead_ShaderReadWrite_CopyRead_CopyWrite);
G_Barrier(frame->cl);
}
//////////////////////////////
@ -4957,7 +4943,7 @@ void V_TickForever(WaveLaneCtx *lane)
G_Compute(frame->cl, V_SimParticlesCS, V_ThreadGroupSizeFromBufferSize(V_ParticlesCap));
// Sync cells
G_DumbGlobalMemorySync(frame->cl);
G_Barrier(frame->cl);
}
//////////////////////////////
@ -4976,7 +4962,7 @@ void V_TickForever(WaveLaneCtx *lane)
G_Compute(frame->cl, V_CompositeCS, V_ThreadGroupSizeFromTexSize(frame->screen_dims));
// Sync screen tex
G_DumbGlobalMemorySync(frame->cl);
G_Barrier(frame->cl);
}
//////////////////////////////
@ -4998,7 +4984,7 @@ void V_TickForever(WaveLaneCtx *lane)
G_SetConstant(frame->cl, V_GpuConst_MipIdx, mip_idx);
G_Compute(frame->cl, V_BloomDownCS, V_ThreadGroupSizeFromTexSize(down_dims));
G_DumbGlobalMemorySync(frame->cl);
G_Barrier(frame->cl);
}
//- Upsample passes
@ -5009,7 +4995,7 @@ void V_TickForever(WaveLaneCtx *lane)
G_SetConstant(frame->cl, V_GpuConst_MipIdx, mip_idx);
G_Compute(frame->cl, V_BloomUpCS, V_ThreadGroupSizeFromTexSize(up_dims));
G_DumbGlobalMemorySync(frame->cl);
G_Barrier(frame->cl);
}
}
@ -5019,15 +5005,13 @@ void V_TickForever(WaveLaneCtx *lane)
{
G_Compute(frame->cl, V_FinalizeCS, V_ThreadGroupSizeFromTexSize(frame->screen_dims));
G_DumbGlobalMemorySync(frame->cl);
G_Barrier(frame->cl);
}
//////////////////////////////
//- Debug shapes pass
{
G_DumbMemoryLayoutSync(frame->cl, screen_target, G_Layout_DirectQueue_RenderTargetWrite);
G_Rasterize(
frame->cl,
V_DVertVS, V_DVertPS,
@ -5037,7 +5021,7 @@ void V_TickForever(WaveLaneCtx *lane)
G_RasterMode_TriangleList
);
G_DumbMemoryLayoutSync(frame->cl, screen_target, G_Layout_DirectQueue_ShaderRead_ShaderReadWrite_CopyRead_CopyWrite);
G_Barrier(frame->cl);
}
//////////////////////////////

View File

@ -439,7 +439,6 @@ void SPR_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame)
gpu_perm, cl,
G_Format_R8G8B8A8_Unorm_Srgb,
atlas->dims,
G_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present,
.name = Lit("Sprite atlas")
);
atlas->tex = G_PushTexture2DRef(gpu_perm, atlas->tex_res);

View File

@ -1703,7 +1703,6 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
frame->gpu_arena, frame->cl,
G_Format_R16G16B16A16_Float,
monitor_size,
G_Layout_DirectQueue_RenderTargetWrite,
.flags = G_ResourceFlag_AllowRenderTarget,
.name = Lit("UI draw target")
);
@ -1739,7 +1738,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
G_SetConstant(frame->cl, UI_GpuConst_Params, params_ro);
// Sync
G_DumbGlobalMemorySync(frame->cl);
G_Barrier(frame->cl);
//////////////////////////////
//- Dispatch shaders
@ -1781,8 +1780,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
//- Backbuffer blit pass
G_DumbMemoryLayoutSync(frame->cl, draw_target, G_Layout_DirectQueue_ShaderRead);
G_DumbMemoryLayoutSync(frame->cl, backbuffer, G_Layout_DirectQueue_RenderTargetWrite);
G_Barrier(frame->cl);
{
G_Rasterize(
@ -1794,8 +1792,6 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
G_RasterMode_TriangleList
);
}
G_DumbMemoryLayoutSync(frame->cl, backbuffer, G_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present);
}
//////////////////////////////