mip support

This commit is contained in:
jacob 2026-02-15 07:23:35 -06:00
parent 83a41fc289
commit e49bcfbe2c
6 changed files with 201 additions and 96 deletions

View File

@ -313,6 +313,7 @@ Struct(G_MemoryBarrierDesc)
G_Access access_prev; G_Access access_prev;
G_Access access_next; G_Access access_next;
G_Layout layout; G_Layout layout;
RngI32 mips; // Inclusive range of texture mip indices to sync
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -431,7 +432,7 @@ Struct(G_TextureDesc)
G_Format format; G_Format format;
Vec3I32 dims; Vec3I32 dims;
G_Layout initial_layout; G_Layout initial_layout;
i32 mip_levels; // Will be clamped to range [1, inf) i32 mips; // Will be clamped to range [1, max mips]
Vec4 clear_color; Vec4 clear_color;
String name; String name;
}; };
@ -468,6 +469,7 @@ Struct(G_RefDesc)
G_RefKind kind; G_RefKind kind;
u64 element_size; u64 element_size;
u64 element_offset; u64 element_offset;
RngI32 mips; // Inclusive range of texture mip indices to reference
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -505,6 +507,7 @@ Struct(G_RenderTargetDesc)
{ {
G_ResourceHandle resource; G_ResourceHandle resource;
G_BlendMode blend; G_BlendMode blend;
i32 mip;
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -616,6 +619,7 @@ Vec3I32 G_Count3D(G_ResourceHandle texture);
i32 G_CountWidth(G_ResourceHandle texture); i32 G_CountWidth(G_ResourceHandle texture);
i32 G_CountHeight(G_ResourceHandle texture); i32 G_CountHeight(G_ResourceHandle texture);
i32 G_CountDepth(G_ResourceHandle texture); i32 G_CountDepth(G_ResourceHandle texture);
i32 G_CountMips(G_ResourceHandle texture);
#define G_CountBuffer(buffer, type) G_CountBufferBytes(buffer) / sizeof(type) #define G_CountBuffer(buffer, type) G_CountBufferBytes(buffer) / sizeof(type)
@ -660,42 +664,42 @@ u32 G_PushRef(G_ArenaHandle arena, G_ResourceHandle resource, G_RefDesc desc);
#define G_PushTexture1DRef(arena, resource, ...) (G_Texture1DRef) { \ #define G_PushTexture1DRef(arena, resource, ...) (G_Texture1DRef) { \
.v = G_PushRef( \ .v = G_PushRef( \
(arena), (resource), \ (arena), (resource), \
(G_RefDesc) { .kind = G_RefKind_Texture1D, __VA_ARGS__ } \ (G_RefDesc) { .kind = G_RefKind_Texture1D, .mips.max = 64, __VA_ARGS__ } \
) \ ) \
} }
#define G_PushRWTexture1DRef(arena, resource, ...) (G_RWTexture1DRef) { \ #define G_PushRWTexture1DRef(arena, resource, ...) (G_RWTexture1DRef) { \
.v = G_PushRef( \ .v = G_PushRef( \
(arena), (resource), \ (arena), (resource), \
(G_RefDesc) { .kind = G_RefKind_RWTexture1D, __VA_ARGS__ } \ (G_RefDesc) { .kind = G_RefKind_RWTexture1D, .mips.max = 64, __VA_ARGS__ } \
) \ ) \
} }
#define G_PushTexture2DRef(arena, resource, ...) (G_Texture2DRef) { \ #define G_PushTexture2DRef(arena, resource, ...) (G_Texture2DRef) { \
.v = G_PushRef( \ .v = G_PushRef( \
(arena), (resource), \ (arena), (resource), \
(G_RefDesc) { .kind = G_RefKind_Texture2D, __VA_ARGS__ } \ (G_RefDesc) { .kind = G_RefKind_Texture2D, .mips.max = 64, __VA_ARGS__ } \
) \ ) \
} }
#define G_PushRWTexture2DRef(arena, resource, ...) (G_RWTexture2DRef) { \ #define G_PushRWTexture2DRef(arena, resource, ...) (G_RWTexture2DRef) { \
.v = G_PushRef( \ .v = G_PushRef( \
(arena), (resource), \ (arena), (resource), \
(G_RefDesc) { .kind = G_RefKind_RWTexture2D, __VA_ARGS__ } \ (G_RefDesc) { .kind = G_RefKind_RWTexture2D, .mips.max = 64, __VA_ARGS__ } \
) \ ) \
} }
#define G_PushTexture3DRef(arena, resource, ...) (G_Texture3DRef) { \ #define G_PushTexture3DRef(arena, resource, ...) (G_Texture3DRef) { \
.v = G_PushRef( \ .v = G_PushRef( \
(arena), (resource), \ (arena), (resource), \
(G_RefDesc) { .kind = G_RefKind_Texture3D, __VA_ARGS__ } \ (G_RefDesc) { .kind = G_RefKind_Texture3D, .mips.max = 64, __VA_ARGS__ } \
) \ ) \
} }
#define G_PushRWTexture3DRef(arena, resource, ...) (G_RWTexture3DRef) { \ #define G_PushRWTexture3DRef(arena, resource, ...) (G_RWTexture3DRef) { \
.v = G_PushRef( \ .v = G_PushRef( \
(arena), (resource), \ (arena), (resource), \
(G_RefDesc) { .kind = G_RefKind_RWTexture3D, __VA_ARGS__ } \ (G_RefDesc) { .kind = G_RefKind_RWTexture3D, .mips.max = 64, __VA_ARGS__ } \
) \ ) \
} }
@ -728,44 +732,50 @@ void G_CopyTextureToBuffer(G_CommandListHandle cl, G_ResourceHandle dst, Vec3I32
//- Constant //- Constant
void G_SetConstant_(G_CommandListHandle cl, i32 slot, void *src_32bit, u32 size); void G_SetConstantEx(G_CommandListHandle cl, i32 slot, void *src_32bit, u32 size);
#define G_SetConstant(cl, name, value) do { \ #define G_SetConstant(cl, name, value) do { \
name##__shaderconstanttype __src; \ name##__shaderconstanttype __src; \
__src.v = value; \ __src.v = value; \
G_SetConstant_((cl), (name), &__src, sizeof(__src)); \ G_SetConstantEx((cl), (name), &__src, sizeof(__src)); \
} while (0) } while (0)
//- Memory sync //- Memory sync
void G_MemorySyncEx(G_CommandListHandle cl, G_MemoryBarrierDesc desc); void G_MemorySyncEx(G_CommandListHandle cl, G_MemoryBarrierDesc desc);
#define G_MemorySync(_cl, _resource, _stage_prev, _access_prev, _stage_next, _access_next) \ #define G_MemorySync(_cl, _resource, _stage_prev, _access_prev, _stage_next, _access_next, ...) \
G_MemorySyncEx((_cl), (G_MemoryBarrierDesc) { \ G_MemorySyncEx((_cl), (G_MemoryBarrierDesc) { \
.resource = (_resource), \ .resource = (_resource), \
.stage_prev = _stage_prev, \ .stage_prev = _stage_prev, \
.access_prev = _access_prev, \ .access_prev = _access_prev, \
.stage_next = _stage_next, \ .stage_next = _stage_next, \
.access_next = _access_next, \ .access_next = _access_next, \
.mips.max = 64, \
__VA_ARGS__ \
}) })
#define G_MemoryLayoutSync(_cl, _resource, _stage_prev, _access_prev, _stage_next, _access_next, _layout) \ #define G_MemoryLayoutSync(_cl, _resource, _stage_prev, _access_prev, _stage_next, _access_next, _layout, ...) \
G_MemorySyncEx((_cl), (G_MemoryBarrierDesc) { \ G_MemorySyncEx((_cl), (G_MemoryBarrierDesc) { \
.resource = (_resource), \ .resource = (_resource), \
.stage_prev = _stage_prev, \ .stage_prev = _stage_prev, \
.access_prev = _access_prev, \ .access_prev = _access_prev, \
.stage_next = _stage_next, \ .stage_next = _stage_next, \
.access_next = _access_next, \ .access_next = _access_next, \
.layout = _layout, \ .layout = _layout, \
.mips.max = 64, \
__VA_ARGS__ \
}) })
#define G_GlobalMemorySync(_cl, _stage_prev, _access_prev, _stage_next, _access_next) \ #define G_GlobalMemorySync(_cl, _stage_prev, _access_prev, _stage_next, _access_next, ...) \
G_MemorySyncEx((_cl), (G_MemoryBarrierDesc) { \ G_MemorySyncEx((_cl), (G_MemoryBarrierDesc) { \
.is_global = 1, \ .is_global = 1, \
.stage_prev = _stage_prev, \ .stage_prev = _stage_prev, \
.access_prev = _access_prev, \ .access_prev = _access_prev, \
.stage_next = _stage_next, \ .stage_next = _stage_next, \
.access_next = _access_next, \ .access_next = _access_next, \
.mips.max = 64, \
__VA_ARGS__ \
}) })
#define G_DumbMemorySync(cl, resource) \ #define G_DumbMemorySync(cl, resource) \
@ -794,11 +804,11 @@ void G_Rasterize(
//- Clear //- Clear
void G_ClearRenderTarget(G_CommandListHandle cl, G_ResourceHandle render_target, Vec4 color); void G_ClearRenderTarget(G_CommandListHandle cl, G_ResourceHandle render_target, Vec4 color, i32 mip);
//- Discard //- Discard
void G_DiscardRenderTarget(G_CommandListHandle cl, G_ResourceHandle render_target); void G_DiscardRenderTarget(G_CommandListHandle cl, G_ResourceHandle render_target, i32 mip);
//- Log //- Log

View File

@ -502,6 +502,35 @@ String G_D12_NameFromBarrierLayout(D3D12_BARRIER_LAYOUT layout)
return result; 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);
D3D12_RESOURCE_DESC res_d3d_desc = Zi;
{
ID3D12Resource_GetDesc(resource->d3d_resource, &res_d3d_desc);
}
D3D12_RENDER_TARGET_VIEW_DESC rtv_desc = Zi;
{
rtv_desc.Format = res_d3d_desc.Format;
if (res_d3d_desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D)
{
rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE1D;
rtv_desc.Texture1D.MipSlice = mip;
}
else if (res_d3d_desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D)
{
rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
rtv_desc.Texture2D.MipSlice = mip;
}
else if (res_d3d_desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D)
{
rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE3D;
rtv_desc.Texture3D.MipSlice = mip;
}
}
ID3D12Device_CreateRenderTargetView(G_D12.device, resource->d3d_resource, &rtv_desc, rtv_handle);
}
void G_D12_SetObjectName(ID3D12Object *object, String name) void G_D12_SetObjectName(ID3D12Object *object, String name)
{ {
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
@ -1010,21 +1039,22 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
G_D12_Resource *resource = 0; G_D12_Resource *resource = 0;
b32 is_buffer = desc.kind == G_ResourceKind_Buffer; b32 is_buffer = desc.kind == G_ResourceKind_Buffer;
b32 is_texture= b32 is_texture = (
desc.kind == G_ResourceKind_Texture1D || desc.kind == G_ResourceKind_Texture1D ||
desc.kind == G_ResourceKind_Texture2D || desc.kind == G_ResourceKind_Texture2D ||
desc.kind == G_ResourceKind_Texture3D; desc.kind == G_ResourceKind_Texture3D
);
b32 is_sampler = desc.kind == G_ResourceKind_Sampler; b32 is_sampler = desc.kind == G_ResourceKind_Sampler;
G_ResourceFlag flags = (
G_ResourceFlag flags =
is_buffer ? desc.buffer.flags : is_buffer ? desc.buffer.flags :
is_texture ? desc.texture.flags : is_texture ? desc.texture.flags :
desc.sampler.flags; desc.sampler.flags
);
String new_name = String new_name = (
is_buffer ? desc.buffer.name : is_buffer ? desc.buffer.name :
is_texture ? desc.texture.name : is_texture ? desc.texture.name :
desc.sampler.name; desc.sampler.name
);
new_name.len = MinU64(new_name.len, countof(resource->name_text)); new_name.len = MinU64(new_name.len, countof(resource->name_text));
////////////////////////////// //////////////////////////////
@ -1098,17 +1128,20 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
} }
else if (is_texture) else if (is_texture)
{ {
i32 max_dim = MaxI32(MaxI32(desc.texture.dims.x, desc.texture.dims.y), desc.texture.dims.z);
i32 max_mips = FloorF32(Log2F32(max_dim)) + 1;
d3d_initial_layout = G_D12_BarrierLayoutFromLayout(desc.texture.initial_layout); d3d_initial_layout = G_D12_BarrierLayoutFromLayout(desc.texture.initial_layout);
d3d_desc.Dimension = d3d_desc.Dimension = (
desc.kind == G_ResourceKind_Texture1D ? D3D12_RESOURCE_DIMENSION_TEXTURE1D : desc.kind == G_ResourceKind_Texture1D ? D3D12_RESOURCE_DIMENSION_TEXTURE1D :
desc.kind == G_ResourceKind_Texture2D ? D3D12_RESOURCE_DIMENSION_TEXTURE2D : desc.kind == G_ResourceKind_Texture2D ? D3D12_RESOURCE_DIMENSION_TEXTURE2D :
D3D12_RESOURCE_DIMENSION_TEXTURE3D; D3D12_RESOURCE_DIMENSION_TEXTURE3D
);
d3d_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; d3d_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
d3d_desc.Format = G_D12_DxgiFormatFromGpuFormat(desc.texture.format); d3d_desc.Format = G_D12_DxgiFormatFromGpuFormat(desc.texture.format);
d3d_desc.Width = MaxI32(desc.texture.dims.x, 1); d3d_desc.Width = MaxI32(desc.texture.dims.x, 1);
d3d_desc.Height = MaxI32(desc.texture.dims.y, 1); d3d_desc.Height = MaxI32(desc.texture.dims.y, 1);
d3d_desc.DepthOrArraySize = MaxI32(desc.texture.dims.z, 1); d3d_desc.DepthOrArraySize = MaxI32(desc.texture.dims.z, 1);
d3d_desc.MipLevels = MaxI32(desc.texture.mip_levels, 1); d3d_desc.MipLevels = ClampF32(desc.texture.mips, 1, max_mips);
d3d_desc.SampleDesc.Count = 1; d3d_desc.SampleDesc.Count = 1;
d3d_desc.SampleDesc.Quality = 0; d3d_desc.SampleDesc.Quality = 0;
d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS * AnyBit(flags, G_ResourceFlag_AllowShaderReadWrite); d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS * AnyBit(flags, G_ResourceFlag_AllowShaderReadWrite);
@ -1196,20 +1229,20 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
//- Init resource //- Init resource
resource->flags = flags; resource->flags = flags;
resource->uid = Atomic64FetchAdd(&G_D12.resource_creation_gen.v, 1) + 1; resource->uid = Atomic64FetchAdd(&G_D12.resource_creation_gen.v, d3d_desc.MipLevels) + 1;
if (is_buffer) if (is_buffer)
{ {
resource->buffer_size = desc.buffer.size; resource->buffer_size = desc.buffer.size;
resource->buffer_size_actual = d3d_desc.Width; resource->buffer_size_actual = d3d_desc.Width;
} }
if (is_texture) if (is_texture)
{ {
resource->is_texture = is_texture; resource->is_texture = is_texture;
resource->texture_format = desc.texture.format; resource->texture_format = desc.texture.format;
resource->texture_dims = desc.texture.dims; resource->texture_dims = desc.texture.dims;
resource->texture_mip_levels = d3d_desc.MipLevels; resource->texture_mips = d3d_desc.MipLevels;
} }
if (is_sampler) if (is_sampler)
@ -1399,24 +1432,25 @@ u32 G_PushRef(G_ArenaHandle arena_handle, G_ResourceHandle resource_handle, G_Re
u32 result = 0; u32 result = 0;
G_RefKind kind = ref_desc.kind; G_RefKind kind = ref_desc.kind;
b32 is_buffer = (
b32 is_buffer = kind == G_RefKind_StructuredBuffer || kind == G_RefKind_StructuredBuffer ||
kind == G_RefKind_RWStructuredBuffer || kind == G_RefKind_RWStructuredBuffer ||
kind == G_RefKind_ByteAddressBuffer || kind == G_RefKind_ByteAddressBuffer ||
kind == G_RefKind_RWByteAddressBuffer; kind == G_RefKind_RWByteAddressBuffer
);
b32 is_sampler = kind == G_RefKind_SamplerState; b32 is_sampler = kind == G_RefKind_SamplerState;
b32 is_texture = !is_buffer && !is_sampler; b32 is_texture = !is_buffer && !is_sampler;
b32 is_raw = (
b32 is_raw = kind == G_RefKind_ByteAddressBuffer || kind == G_RefKind_ByteAddressBuffer ||
kind == G_RefKind_RWByteAddressBuffer; kind == G_RefKind_RWByteAddressBuffer
);
b32 is_uav = kind == G_RefKind_RWStructuredBuffer || b32 is_uav = (
kind == G_RefKind_RWStructuredBuffer ||
kind == G_RefKind_RWByteAddressBuffer || kind == G_RefKind_RWByteAddressBuffer ||
kind == G_RefKind_RWTexture1D || kind == G_RefKind_RWTexture1D ||
kind == G_RefKind_RWTexture2D || kind == G_RefKind_RWTexture2D ||
kind == G_RefKind_RWTexture3D; kind == G_RefKind_RWTexture3D
);
if (is_uav) if (is_uav)
{ {
@ -1484,13 +1518,60 @@ u32 G_PushRef(G_ArenaHandle arena_handle, G_ResourceHandle resource_handle, G_Re
else if (is_texture) else if (is_texture)
{ {
descriptor = G_D12_PushDescriptor(gpu_arena, G_D12_DescriptorHeapKind_CbvSrvUav); descriptor = G_D12_PushDescriptor(gpu_arena, G_D12_DescriptorHeapKind_CbvSrvUav);
DXGI_FORMAT format = G_D12_DxgiFormatFromGpuFormat(resource->texture_format);
RngI32 mips = ref_desc.mips;
mips.min = ClampI32(mips.min, 0, resource->texture_mips - 1);
mips.max = ClampI32(mips.max, mips.min, resource->texture_mips - 1);
if (is_uav) if (is_uav)
{ {
ID3D12Device_CreateUnorderedAccessView(G_D12.device, resource->d3d_resource, 0, 0, descriptor->handle); D3D12_UNORDERED_ACCESS_VIEW_DESC desc = Zi;
{
desc.Format = DXGI_FORMAT_UNKNOWN;
if (ref_desc.kind == G_RefKind_RWTexture1D)
{
desc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE1D;
desc.Texture1D.MipSlice = mips.min;
}
else if (ref_desc.kind == G_RefKind_RWTexture2D)
{
desc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
desc.Texture2D.MipSlice = mips.min;
}
else if (ref_desc.kind == G_RefKind_RWTexture3D)
{
desc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE3D;
desc.Texture3D.MipSlice = mips.min;
desc.Texture3D.WSize = U32Max;
}
}
ID3D12Device_CreateUnorderedAccessView(G_D12.device, resource->d3d_resource, 0, &desc, descriptor->handle);
} }
else else
{ {
ID3D12Device_CreateShaderResourceView(G_D12.device, resource->d3d_resource, 0, descriptor->handle); D3D12_SHADER_RESOURCE_VIEW_DESC desc = Zi;
{
desc.Format = DXGI_FORMAT_UNKNOWN;
desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
if (ref_desc.kind == G_RefKind_Texture1D)
{
desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D;
desc.Texture1D.MostDetailedMip = mips.min;
desc.Texture1D.MipLevels = mips.max - mips.min + 1;
}
else if (ref_desc.kind == G_RefKind_Texture2D)
{
desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
desc.Texture2D.MostDetailedMip = mips.min;
desc.Texture2D.MipLevels = mips.max - mips.min + 1;
}
else if (ref_desc.kind == G_RefKind_Texture3D)
{
desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D;
desc.Texture3D.MostDetailedMip = mips.min;
desc.Texture3D.MipLevels = mips.max - mips.min + 1;
}
}
ID3D12Device_CreateShaderResourceView(G_D12.device, resource->d3d_resource, &desc, descriptor->handle);
} }
} }
else if (is_sampler) else if (is_sampler)
@ -1570,6 +1651,12 @@ i32 G_CountDepth(G_ResourceHandle texture)
return resource->texture_dims.z; return resource->texture_dims.z;
} }
i32 G_CountMips(G_ResourceHandle texture)
{
G_D12_Resource *resource = G_D12_ResourceFromHandle(texture);
return resource->texture_mips;
}
//- Map //- Map
void *G_HostPointerFromResource(G_ResourceHandle resource_handle) void *G_HostPointerFromResource(G_ResourceHandle resource_handle)
@ -2071,6 +2158,9 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
case D3D12_BARRIER_TYPE_TEXTURE: case D3D12_BARRIER_TYPE_TEXTURE:
{ {
G_D12_Resource *resource = G_D12_ResourceFromHandle(desc.resource); 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);
D3D12_TEXTURE_BARRIER *barrier = &texture_barriers[texture_barriers_count++]; D3D12_TEXTURE_BARRIER *barrier = &texture_barriers[texture_barriers_count++];
barrier->SyncBefore = sync_before; barrier->SyncBefore = sync_before;
barrier->SyncAfter = sync_after; barrier->SyncAfter = sync_after;
@ -2079,7 +2169,10 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
barrier->LayoutBefore = layout_before; barrier->LayoutBefore = layout_before;
barrier->LayoutAfter = layout_after; barrier->LayoutAfter = layout_after;
barrier->pResource = resource->d3d_resource; barrier->pResource = resource->d3d_resource;
barrier->Subresources.IndexOrFirstMipLevel = 0xffffffff; barrier->Subresources.IndexOrFirstMipLevel = mips.min;
barrier->Subresources.NumMipLevels = mips.max - mips.min + 1;
barrier->Subresources.NumArraySlices = 1;
barrier->Subresources.NumPlanes = 1;
} break; } break;
case D3D12_BARRIER_TYPE_GLOBAL: case D3D12_BARRIER_TYPE_GLOBAL:
@ -2427,11 +2520,11 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
G_D12_Resource *rt = G_D12_ResourceFromHandle(desc.resource); G_D12_Resource *rt = G_D12_ResourceFromHandle(desc.resource);
if (rt) if (rt)
{ {
if (bound_render_target_uids[i] != rt->uid) if (bound_render_target_uids[i] != rt->uid + desc.mip)
{ {
G_D12_Descriptor *rtv_descriptor = rcl->rtv_descriptors[i]; G_D12_Descriptor *rtv_descriptor = rcl->rtv_descriptors[i];
ID3D12Device_CreateRenderTargetView(G_D12.device, rt->d3d_resource, 0, rtv_descriptor->handle); G_D12_InitRtv(rt, rtv_descriptor->handle, desc.mip);
bound_render_target_uids[i] = rt->uid; bound_render_target_uids[i] = rt->uid + desc.mip;
om_dirty = 1; om_dirty = 1;
} }
++rtvs_count; ++rtvs_count;
@ -2472,10 +2565,10 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
clear_color[3] = cmd->clear_rtv.color.w; clear_color[3] = cmd->clear_rtv.color.w;
} }
D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle = rcl->rtv_clear_descriptor->handle; D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle = rcl->rtv_clear_descriptor->handle;
if (bound_render_clear_target_uid != rt->uid) if (bound_render_clear_target_uid != rt->uid + cmd->clear_rtv.mip)
{ {
ID3D12Device_CreateRenderTargetView(G_D12.device, rt->d3d_resource, 0, rtv_handle); G_D12_InitRtv(rt, rtv_handle, cmd->clear_rtv.mip);
bound_render_clear_target_uid = rt->uid; bound_render_clear_target_uid = rt->uid + cmd->clear_rtv.mip;
} }
ID3D12GraphicsCommandList_ClearRenderTargetView(d3d_cl, rtv_handle, clear_color, 0, 0); ID3D12GraphicsCommandList_ClearRenderTargetView(d3d_cl, rtv_handle, clear_color, 0, 0);
cmd_idx += 1; cmd_idx += 1;
@ -2485,6 +2578,9 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
case G_D12_CmdKind_DiscardRtv: case G_D12_CmdKind_DiscardRtv:
{ {
D3D12_DISCARD_REGION region = Zi;
region.FirstSubresource = cmd->discard_rtv.mip;
region.NumSubresources = 1;
G_D12_Resource *resource = cmd->discard_rtv.render_target; G_D12_Resource *resource = cmd->discard_rtv.render_target;
ID3D12GraphicsCommandList_DiscardResource(d3d_cl, resource->d3d_resource, 0); ID3D12GraphicsCommandList_DiscardResource(d3d_cl, resource->d3d_resource, 0);
cmd_idx += 1; cmd_idx += 1;
@ -2806,7 +2902,7 @@ void G_CopyTextureToBuffer(G_CommandListHandle cl_handle, G_ResourceHandle dst_h
//- Constant //- Constant
void G_SetConstant_(G_CommandListHandle cl_handle, i32 slot, void *src_32bit, u32 size) void G_SetConstantEx(G_CommandListHandle cl_handle, i32 slot, void *src_32bit, u32 size)
{ {
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle); G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
G_D12_Cmd *cmd = G_D12_PushCmd(cl); G_D12_Cmd *cmd = G_D12_PushCmd(cl);
@ -2871,23 +2967,25 @@ void G_Rasterize(
//- Clear //- Clear
void G_ClearRenderTarget(G_CommandListHandle cl_handle, G_ResourceHandle resource_handle, Vec4 color) void G_ClearRenderTarget(G_CommandListHandle cl_handle, G_ResourceHandle resource_handle, Vec4 color, i32 mip)
{ {
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle); G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
G_D12_Cmd *cmd = G_D12_PushCmd(cl); G_D12_Cmd *cmd = G_D12_PushCmd(cl);
cmd->kind = G_D12_CmdKind_ClearRtv; cmd->kind = G_D12_CmdKind_ClearRtv;
cmd->clear_rtv.render_target = G_D12_ResourceFromHandle(resource_handle); cmd->clear_rtv.render_target = G_D12_ResourceFromHandle(resource_handle);
cmd->clear_rtv.color = color; cmd->clear_rtv.color = color;
cmd->clear_rtv.mip = mip;
} }
//- Discard //- Discard
void G_DiscardRenderTarget(G_CommandListHandle cl_handle, G_ResourceHandle resource_handle) void G_DiscardRenderTarget(G_CommandListHandle cl_handle, G_ResourceHandle resource_handle, i32 mip)
{ {
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle); G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
G_D12_Cmd *cmd = G_D12_PushCmd(cl); G_D12_Cmd *cmd = G_D12_PushCmd(cl);
cmd->kind = G_D12_CmdKind_DiscardRtv; cmd->kind = G_D12_CmdKind_DiscardRtv;
cmd->discard_rtv.render_target = G_D12_ResourceFromHandle(resource_handle); cmd->discard_rtv.render_target = G_D12_ResourceFromHandle(resource_handle);
cmd->discard_rtv.mip = mip;
} }
//- Log //- Log
@ -3183,7 +3281,7 @@ G_ResourceHandle G_PrepareBackbuffer(G_SwapchainHandle swapchain_handle, G_Forma
backbuffer->is_texture = 1; backbuffer->is_texture = 1;
backbuffer->texture_format = format; backbuffer->texture_format = format;
backbuffer->texture_dims = VEC3I32(size.x, size.y, 1); backbuffer->texture_dims = VEC3I32(size.x, size.y, 1);
backbuffer->texture_mip_levels = 1; backbuffer->texture_mips = 1;
backbuffer->cmdlist_texture_layout = D3D12_BARRIER_LAYOUT_PRESENT; backbuffer->cmdlist_texture_layout = D3D12_BARRIER_LAYOUT_PRESENT;
backbuffer->swapchain = swapchain; backbuffer->swapchain = swapchain;
} }

View File

@ -84,7 +84,7 @@ Struct(G_D12_Resource)
b32 is_texture; b32 is_texture;
G_Format texture_format; G_Format texture_format;
Vec3I32 texture_dims; Vec3I32 texture_dims;
i32 texture_mip_levels; i32 texture_mips;
D3D12_BARRIER_LAYOUT cmdlist_texture_layout; D3D12_BARRIER_LAYOUT cmdlist_texture_layout;
// Sampler info // Sampler info
@ -369,11 +369,13 @@ Struct(G_D12_Cmd)
{ {
G_D12_Resource *render_target; G_D12_Resource *render_target;
Vec4 color; Vec4 color;
i32 mip;
} clear_rtv; } clear_rtv;
struct struct
{ {
G_D12_Resource *render_target; G_D12_Resource *render_target;
i32 mip;
} discard_rtv; } discard_rtv;
struct struct
@ -510,6 +512,8 @@ D3D12_BARRIER_ACCESS G_D12_BarrierAccessFromAccesses(G_Access accesses);
D3D12_BARRIER_LAYOUT G_D12_BarrierLayoutFromLayout(G_Layout layout); D3D12_BARRIER_LAYOUT G_D12_BarrierLayoutFromLayout(G_Layout layout);
String G_D12_NameFromBarrierLayout(D3D12_BARRIER_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);
void G_D12_SetObjectName(ID3D12Object *object, String name); void G_D12_SetObjectName(ID3D12Object *object, String name);
String G_D12_NameFromObject(Arena *arena, ID3D12Object *object); String G_D12_NameFromObject(Arena *arena, ID3D12Object *object);

View File

@ -4943,8 +4943,6 @@ void V_TickForever(WaveLaneCtx *lane)
////////////////////////////// //////////////////////////////
//- Initialization pass //- Initialization pass
b32 disable_vis_draw = TweakBool("Disable vis draw", 0);
{ {
// Prepare shade // Prepare shade
G_Compute(frame->cl, V_PrepareShadeCS, V_ThreadGroupSizeFromTexSize(frame->shade_dims)); G_Compute(frame->cl, V_PrepareShadeCS, V_ThreadGroupSizeFromTexSize(frame->shade_dims));
@ -4959,18 +4957,8 @@ void V_TickForever(WaveLaneCtx *lane)
V.particle_seq = 0; V.particle_seq = 0;
} }
// Prepare screen RT
if (disable_vis_draw)
{
G_ClearRenderTarget(frame->cl, screen_target, VEC4(0, 0, 0, 0));
}
else
{
G_DiscardRenderTarget(frame->cl, screen_target);
}
// Prepare albedo RT // Prepare albedo RT
G_ClearRenderTarget(frame->cl, albedo_target, VEC4(0, 0, 0, 0)); G_ClearRenderTarget(frame->cl, albedo_target, VEC4(0, 0, 0, 0), 0);
} }
// Sync // Sync
@ -5028,16 +5016,21 @@ void V_TickForever(WaveLaneCtx *lane)
////////////////////////////// //////////////////////////////
//- Composite pass //- Composite pass
if (!disable_vis_draw)
{ {
G_Compute(frame->cl, V_CompositeCS, V_ThreadGroupSizeFromTexSize(frame->screen_dims)); G_Compute(frame->cl, V_CompositeCS, V_ThreadGroupSizeFromTexSize(frame->screen_dims));
}
G_DumbMemoryLayoutSync(frame->cl, screen_target, G_Layout_DirectQueue_RenderTargetWrite); //////////////////////////////
//- Bloom pass
{
} }
////////////////////////////// //////////////////////////////
//- Debug shapes pass //- Debug shapes pass
G_DumbMemoryLayoutSync(frame->cl, screen_target, G_Layout_DirectQueue_RenderTargetWrite);
{ {
G_Rasterize( G_Rasterize(
frame->cl, frame->cl,
@ -5119,7 +5112,6 @@ void V_TickForever(WaveLaneCtx *lane)
BB_ResetWriter(&packer_bbw); BB_ResetWriter(&packer_bbw);
String packed = P_PackMessages(&packer_bbw, P_tl.out_msgs); String packed = P_PackMessages(&packer_bbw, P_tl.out_msgs);
NET_Send(net_pipe, frame->sim_key, packed, NET_SendFlag_None); NET_Send(net_pipe, frame->sim_key, packed, NET_SendFlag_None);
} }
} }

View File

@ -887,6 +887,7 @@ ComputeShader2D(V_CompositeCS, 8, 8)
//- Crosshair //- Crosshair
// TODO: Remove this // TODO: Remove this
// TODO: Move to final step after post-processing pass
Vec4 crosshair_color = 0; Vec4 crosshair_color = 0;
if (!frame.is_editing) if (!frame.is_editing)

View File

@ -1747,7 +1747,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
//- Clear pass //- Clear pass
{ {
G_ClearRenderTarget(frame->cl, draw_target, VEC4(0, 0, 0, 0)); G_ClearRenderTarget(frame->cl, draw_target, VEC4(0, 0, 0, 0), 0);
} }
//- Rect pass //- Rect pass