add mirror-mode basic samplers

This commit is contained in:
jacob 2026-02-24 03:05:19 -06:00
parent 262d49fee8
commit cbf0961f4c
5 changed files with 54 additions and 21 deletions

View File

@ -23,10 +23,11 @@ void G_BootstrapCommon(void)
{ {
G_ResourceHandle blank_tex = G_PushTexture2D( G_ResourceHandle blank_tex = G_PushTexture2D(
gpu_perm, cl, gpu_perm, cl,
G_Format_R8G8B8A8_Uint, G_Format_R8G8B8A8_Unorm,
VEC2I32(8, 8), VEC2I32(8, 8),
G_Layout_Common, G_Layout_Common,
.flags = G_ResourceFlag_ZeroMemory .flags = G_ResourceFlag_ZeroMemory,
.name = Lit("Blank texture")
); );
G.blank_tex = G_PushTexture2DRef(gpu_perm, blank_tex); G.blank_tex = G_PushTexture2DRef(gpu_perm, blank_tex);
} }
@ -44,7 +45,8 @@ void G_BootstrapCommon(void)
gpu_perm, cl, gpu_perm, cl,
G_Format_R16_Uint, G_Format_R16_Uint,
noise_dims, noise_dims,
G_Layout_Common G_Layout_Common,
.name = Lit("Noise texture")
); );
G_CopyCpuToTexture( G_CopyCpuToTexture(
cl, cl,
@ -80,6 +82,13 @@ void G_BootstrapCommon(void)
G_ResourceHandle sampler_res = G_PushSampler(gpu_perm, cl, .filter = filter, .x = address_mode, .y = address_mode, .z = address_mode); G_ResourceHandle sampler_res = G_PushSampler(gpu_perm, cl, .filter = filter, .x = address_mode, .y = address_mode, .z = address_mode);
sampler = G_PushSamplerStateRef(gpu_perm, sampler_res); sampler = G_PushSamplerStateRef(gpu_perm, sampler_res);
} break; } break;
case G_BasicSamplerKind_PointMirror:
{
G_Filter filter = G_Filter_MinMagMipPoint;
G_AddressMode address_mode = G_AddressMode_Mirror;
G_ResourceHandle sampler_res = G_PushSampler(gpu_perm, cl, .filter = filter, .x = address_mode, .y = address_mode, .z = address_mode);
sampler = G_PushSamplerStateRef(gpu_perm, sampler_res);
} break;
case G_BasicSamplerKind_BilinearClamp: case G_BasicSamplerKind_BilinearClamp:
{ {
G_Filter filter = G_Filter_MinMagLinearMipPoint; G_Filter filter = G_Filter_MinMagLinearMipPoint;
@ -94,6 +103,13 @@ void G_BootstrapCommon(void)
G_ResourceHandle sampler_res = G_PushSampler(gpu_perm, cl, .filter = filter, .x = address_mode, .y = address_mode, .z = address_mode); G_ResourceHandle sampler_res = G_PushSampler(gpu_perm, cl, .filter = filter, .x = address_mode, .y = address_mode, .z = address_mode);
sampler = G_PushSamplerStateRef(gpu_perm, sampler_res); sampler = G_PushSamplerStateRef(gpu_perm, sampler_res);
} break; } break;
case G_BasicSamplerKind_BilinearMirror:
{
G_Filter filter = G_Filter_MinMagLinearMipPoint;
G_AddressMode address_mode = G_AddressMode_Mirror;
G_ResourceHandle sampler_res = G_PushSampler(gpu_perm, cl, .filter = filter, .x = address_mode, .y = address_mode, .z = address_mode);
sampler = G_PushSamplerStateRef(gpu_perm, sampler_res);
} break;
case G_BasicSamplerKind_TrilinearClamp: case G_BasicSamplerKind_TrilinearClamp:
{ {
G_Filter filter = G_Filter_MinMagMipLinear; G_Filter filter = G_Filter_MinMagMipLinear;
@ -108,14 +124,19 @@ void G_BootstrapCommon(void)
G_ResourceHandle sampler_res = G_PushSampler(gpu_perm, cl, .filter = filter, .x = address_mode, .y = address_mode, .z = address_mode); G_ResourceHandle sampler_res = G_PushSampler(gpu_perm, cl, .filter = filter, .x = address_mode, .y = address_mode, .z = address_mode);
sampler = G_PushSamplerStateRef(gpu_perm, sampler_res); sampler = G_PushSamplerStateRef(gpu_perm, sampler_res);
} break; } break;
case G_BasicSamplerKind_TrilinearMirror:
{
G_Filter filter = G_Filter_MinMagMipLinear;
G_AddressMode address_mode = G_AddressMode_Mirror;
G_ResourceHandle sampler_res = G_PushSampler(gpu_perm, cl, .filter = filter, .x = address_mode, .y = address_mode, .z = address_mode);
sampler = G_PushSamplerStateRef(gpu_perm, sampler_res);
} break;
} }
G.basic_samplers[sampler_kind] = sampler; G.basic_samplers[sampler_kind] = sampler;
} }
} }
G_CommitCommandList(cl); G_CommitCommandList(cl);
G_QueueSync(G_QueueMask_Direct, G_QueueMask_All);
// Barrier all queues until direct queue finishes initializing resources
G_Sync(G_QueueMask_Direct, G_QueueMask_All);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -284,7 +284,7 @@ Enum(G_Layout)
// Barrier will execute after stages specified by `stage_prev`, and before stages specified by `stage_next`. // Barrier will execute after stages specified by `stage_prev`, and before stages specified by `stage_next`.
// When barrier executes: // When barrier executes:
// - Necessary resource flushes will occur based on `access_prev` & `access_next` // - Necessary resource flushes will occur based on `access_prev` & `access_next`
// - Resource layout will transition based on `layout` (if specified) // - Texture layout will transition based on `layout` (if specified)
Struct(G_MemoryBarrierDesc) Struct(G_MemoryBarrierDesc)
{ {
G_ResourceHandle resource; G_ResourceHandle resource;
@ -794,23 +794,23 @@ void G_DiscardRenderTarget(G_CommandListHandle cl, G_ResourceHandle render_targe
void G_LogResource(G_CommandListHandle cl, G_ResourceHandle resource); void G_LogResource(G_CommandListHandle cl, G_ResourceHandle resource);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ @hookdecl Synchronization //~ @hookdecl Queue synchronization
i64 G_CompletionValueFromQueue(G_QueueKind queue_kind); i64 G_CompletionValueFromQueue(G_QueueKind queue_kind);
i64 G_CompletionTargetFromQueue(G_QueueKind queue_kind); i64 G_CompletionTargetFromQueue(G_QueueKind queue_kind);
G_QueueCompletions G_CompletionValuesFromQueues(G_QueueMask queue_mask); G_QueueCompletions G_CompletionValuesFromQueues(G_QueueMask queue_mask);
G_QueueCompletions G_CompletionTargetsFromQueues(G_QueueMask queue_mask); G_QueueCompletions G_CompletionTargetsFromQueues(G_QueueMask queue_mask);
void G_SyncEx(G_QueueBarrierDesc desc); void G_QueueSyncEx(G_QueueBarrierDesc desc);
#define G_Sync(completion_mask, ...) \ #define G_QueueSync(completion_mask, ...) \
G_SyncEx((G_QueueBarrierDesc) { \ G_QueueSyncEx((G_QueueBarrierDesc) { \
.completions = G_CompletionTargetsFromQueues(completion_mask), \ .completions = G_CompletionTargetsFromQueues(completion_mask), \
__VA_ARGS__ \ __VA_ARGS__ \
}) })
#define G_SyncGpu(completion_mask, wait_mask) G_Sync((completion_mask), .wait_queues = (wait_mask)) #define G_QueueSyncGpu(completion_mask, wait_mask) G_QueueSync((completion_mask), .wait_queues = (wait_mask))
#define G_SyncCpu(completion_mask) G_Sync((completion_mask), .wait_cpu = 1); #define G_QueueSyncCpu(completion_mask) G_QueueSync((completion_mask), .wait_cpu = 1);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ @hookdecl Statistics //~ @hookdecl Statistics

View File

@ -10,8 +10,8 @@ void G_Bootstrap(void)
Arena *perm = PermArena(); Arena *perm = PermArena();
// NOTE: Nsight seems to have trouble attaching when independent devices are enabled // NOTE: Nsight seems to have trouble attaching when independent devices are enabled
b32 independent_devices_enabled = !CommandlineArgFromName(Lit("no-independent-d3d12-device")).exists; G_D12.independent_devices_enabled = !CommandlineArgFromName(Lit("no-independent-d3d12-device")).exists;
LogInfoF("D3D12 independent devices enabled: %F", FmtSint(independent_devices_enabled)); LogInfoF("D3D12 independent devices enabled: %F", FmtSint(G_D12.independent_devices_enabled));
////////////////////////////// //////////////////////////////
//- Extract agility SDK //- Extract agility SDK
@ -131,7 +131,7 @@ void G_Bootstrap(void)
} }
if (skips <= 0) if (skips <= 0)
{ {
if (independent_devices_enabled) if (G_D12.independent_devices_enabled)
{ {
hr = ID3D12DeviceFactory_CreateDevice(G_D12.device_factory, (IUnknown *)adapter, D3D_FEATURE_LEVEL_12_0, &IID_ID3D12Device10, (void **)&device); hr = ID3D12DeviceFactory_CreateDevice(G_D12.device_factory, (IUnknown *)adapter, D3D_FEATURE_LEVEL_12_0, &IID_ID3D12Device10, (void **)&device);
} }
@ -276,6 +276,7 @@ void G_Bootstrap(void)
} }
// Log device configuration // Log device configuration
if (G_D12.independent_devices_enabled)
{ {
D3D12_DEVICE_CONFIGURATION_DESC desc = Zi; D3D12_DEVICE_CONFIGURATION_DESC desc = Zi;
ID3D12DeviceConfiguration_GetDesc(G_D12.device_config, &desc); ID3D12DeviceConfiguration_GetDesc(G_D12.device_config, &desc);
@ -424,8 +425,15 @@ void G_Bootstrap(void)
desc.Desc_1_1.NumStaticSamplers = 0; desc.Desc_1_1.NumStaticSamplers = 0;
desc.Desc_1_1.pStaticSamplers = 0; desc.Desc_1_1.pStaticSamplers = 0;
desc.Desc_1_1.Flags = D3D12_ROOT_SIGNATURE_FLAG_CBV_SRV_UAV_HEAP_DIRECTLY_INDEXED | D3D12_ROOT_SIGNATURE_FLAG_SAMPLER_HEAP_DIRECTLY_INDEXED; desc.Desc_1_1.Flags = D3D12_ROOT_SIGNATURE_FLAG_CBV_SRV_UAV_HEAP_DIRECTLY_INDEXED | D3D12_ROOT_SIGNATURE_FLAG_SAMPLER_HEAP_DIRECTLY_INDEXED;
if (G_D12.independent_devices_enabled)
{
hr = ID3D12DeviceConfiguration_SerializeVersionedRootSignature(G_D12.device_config, &desc, &blob, 0); hr = ID3D12DeviceConfiguration_SerializeVersionedRootSignature(G_D12.device_config, &desc, &blob, 0);
} }
else
{
hr = D3D12SerializeVersionedRootSignature(&desc, &blob, 0);
}
}
// Create root signature // Create root signature
ID3D12RootSignature *rootsig = 0; ID3D12RootSignature *rootsig = 0;
@ -3187,7 +3195,7 @@ void G_LogResource(G_CommandListHandle cl_handle, G_ResourceHandle resource_hand
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ @hookimpl Synchronization //~ @hookimpl Queue synchronization
i64 G_CompletionValueFromQueue(G_QueueKind queue_kind) i64 G_CompletionValueFromQueue(G_QueueKind queue_kind)
{ {
@ -3233,7 +3241,7 @@ G_QueueCompletions G_CompletionTargetsFromQueues(G_QueueMask queue_mask)
return completions; return completions;
} }
void G_SyncEx(G_QueueBarrierDesc desc) void G_QueueSyncEx(G_QueueBarrierDesc desc)
{ {
u64 fences_count = 0; u64 fences_count = 0;
ID3D12Fence *fences[G_QueueKind_COUNT] = Zi; ID3D12Fence *fences[G_QueueKind_COUNT] = Zi;
@ -3569,7 +3577,7 @@ void G_D12_CollectionWorkerEntryPoint(WaveLaneCtx *lane)
} }
// TODO: Collect asynchronously // TODO: Collect asynchronously
G_SyncCpu(G_QueueMask_Direct | G_QueueMask_AsyncCompute); G_QueueSyncCpu(G_QueueMask_Direct | G_QueueMask_AsyncCompute);
for (G_QueueKind queue_kind = 0; queue_kind < G_QueueKind_COUNT; ++queue_kind) for (G_QueueKind queue_kind = 0; queue_kind < G_QueueKind_COUNT; ++queue_kind)
{ {

View File

@ -442,6 +442,7 @@ Struct(G_D12_AsyncCtx)
Struct(G_D12_Ctx) Struct(G_D12_Ctx)
{ {
b32 independent_devices_enabled;
IsolatedAtomic64 resource_creation_gen; IsolatedAtomic64 resource_creation_gen;
// Stats // Stats

View File

@ -78,10 +78,13 @@ Enum(G_BasicSamplerKind)
{ {
G_BasicSamplerKind_PointClamp, G_BasicSamplerKind_PointClamp,
G_BasicSamplerKind_PointWrap, G_BasicSamplerKind_PointWrap,
G_BasicSamplerKind_PointMirror,
G_BasicSamplerKind_BilinearClamp, G_BasicSamplerKind_BilinearClamp,
G_BasicSamplerKind_BilinearWrap, G_BasicSamplerKind_BilinearWrap,
G_BasicSamplerKind_BilinearMirror,
G_BasicSamplerKind_TrilinearClamp, G_BasicSamplerKind_TrilinearClamp,
G_BasicSamplerKind_TrilinearWrap, G_BasicSamplerKind_TrilinearWrap,
G_BasicSamplerKind_TrilinearMirror,
G_BasicSamplerKind_COUNT G_BasicSamplerKind_COUNT
}; };