265 lines
8.3 KiB
C
265 lines
8.3 KiB
C
G_Ctx G = Zi;
|
|
ThreadLocal G_ThreadLocalCtx G_tl = Zi;
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Bootstrap
|
|
|
|
void G_BootstrapCommon(void)
|
|
{
|
|
G_ArenaHandle gpu_perm = G_PermArena();
|
|
|
|
G_CommandListHandle cl = G_PrepareCommandList(G_QueueKind_Direct);
|
|
{
|
|
// Init quad index buffer
|
|
{
|
|
G_ResourceHandle quad_indices = Zi;
|
|
u16 quad_data[6] = { 0, 1, 2, 0, 2, 3 };
|
|
quad_indices = G_PushBuffer(gpu_perm, cl, u16, countof(quad_data));
|
|
G_CopyCpuToBuffer(cl, quad_indices, 0, quad_data, RNGU64(0, sizeof(quad_data)));
|
|
G.quad_indices = G_IdxBuff16(quad_indices);
|
|
}
|
|
|
|
// Init blank texture
|
|
{
|
|
G_ResourceHandle blank_tex = G_PushTexture2D(
|
|
gpu_perm, cl,
|
|
G_Format_R8G8B8A8_Unorm,
|
|
VEC2I32(8, 8),
|
|
G_Layout_Common,
|
|
.flags = G_ResourceFlag_ZeroMemory,
|
|
.name = Lit("Blank texture")
|
|
);
|
|
G.blank_tex = G_PushTexture2DRef(gpu_perm, blank_tex);
|
|
}
|
|
|
|
// Init noise texture
|
|
{
|
|
G_ResourceHandle noise_tex = Zi;
|
|
String noise_data = DataFromResource(ResourceKeyFromStore(&G_Resources, Lit("noise_128x128x64_16.dat")));
|
|
Vec3I32 noise_dims = VEC3I32(128, 128, 64);
|
|
if (noise_data.len != noise_dims.x * noise_dims.y * noise_dims.z * 2)
|
|
{
|
|
Panic(Lit("Unexpected noise texture size"));
|
|
}
|
|
noise_tex = G_PushTexture3D(
|
|
gpu_perm, cl,
|
|
G_Format_R16_Uint,
|
|
noise_dims,
|
|
G_Layout_Common,
|
|
.name = Lit("Noise texture")
|
|
);
|
|
G_CopyCpuToTexture(
|
|
cl,
|
|
noise_tex, VEC3I32(0, 0, 0),
|
|
noise_data.text, noise_dims,
|
|
RNG3I32(VEC3I32(0, 0, 0), noise_dims)
|
|
);
|
|
G.basic_noise = G_PushTexture3DRef(gpu_perm, noise_tex);
|
|
}
|
|
|
|
// Init basic samplers
|
|
for (G_BasicSamplerKind sampler_kind = 0; sampler_kind < countof(G.basic_samplers); ++sampler_kind)
|
|
{
|
|
G_SamplerStateRef sampler = Zi;
|
|
switch (sampler_kind)
|
|
{
|
|
default:
|
|
{
|
|
// Sampler unspecified
|
|
Assert(0);
|
|
} FALLTHROUGH;
|
|
case G_BasicSamplerKind_PointClamp:
|
|
{
|
|
G_Filter filter = G_Filter_MinMagMipPoint;
|
|
G_AddressMode address_mode = G_AddressMode_Clamp;
|
|
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_PointWrap:
|
|
{
|
|
G_Filter filter = G_Filter_MinMagMipPoint;
|
|
G_AddressMode address_mode = G_AddressMode_Wrap;
|
|
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_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:
|
|
{
|
|
G_Filter filter = G_Filter_MinMagLinearMipPoint;
|
|
G_AddressMode address_mode = G_AddressMode_Clamp;
|
|
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_BilinearWrap:
|
|
{
|
|
G_Filter filter = G_Filter_MinMagLinearMipPoint;
|
|
G_AddressMode address_mode = G_AddressMode_Wrap;
|
|
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_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:
|
|
{
|
|
G_Filter filter = G_Filter_MinMagMipLinear;
|
|
G_AddressMode address_mode = G_AddressMode_Clamp;
|
|
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_TrilinearWrap:
|
|
{
|
|
G_Filter filter = G_Filter_MinMagMipLinear;
|
|
G_AddressMode address_mode = G_AddressMode_Wrap;
|
|
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_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_CommitCommandList(cl);
|
|
G_QueueSync(G_QueueMask_Direct, G_QueueMask_All);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Utils
|
|
|
|
//- Arena
|
|
|
|
G_ArenaHandle G_PermArena(void)
|
|
{
|
|
if (G_IsArenaNil(G_tl.gpu_perm))
|
|
{
|
|
G_tl.gpu_perm = G_AcquireArena();
|
|
}
|
|
return G_tl.gpu_perm;
|
|
}
|
|
|
|
//- Push resource from cpu
|
|
|
|
G_ResourceHandle G_PushBufferFromCpuCopy_(G_ArenaHandle gpu_arena, G_CommandListHandle cl, String src, G_BufferDesc desc)
|
|
{
|
|
G_ResourceHandle buffer = G_PushResource(gpu_arena, cl, (G_ResourceDesc) { .kind = G_ResourceKind_Buffer, .buffer = desc });
|
|
G_CopyCpuToBuffer(cl, buffer, 0, src.text, RNGU64(0, src.len));
|
|
return buffer;
|
|
}
|
|
|
|
//- Mip
|
|
|
|
i32 G_DimsFromMip1D(i32 mip0_dims, i32 mip)
|
|
{
|
|
mip = ClampI32(mip, -31, 31);
|
|
i32 result = 0;
|
|
if (mip >= 0)
|
|
{
|
|
result = MaxI32(result >> mip, 1);
|
|
}
|
|
else
|
|
{
|
|
result = MaxI32(result << -mip, 1);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
Vec2I32 G_DimsFromMip2D(Vec2I32 mip0_dims, i32 mip)
|
|
{
|
|
mip = ClampI32(mip, -31, 31);
|
|
Vec2I32 result = Zi;
|
|
if (mip >= 0)
|
|
{
|
|
result.x = MaxI32(mip0_dims.x >> mip, 1);
|
|
result.y = MaxI32(mip0_dims.y >> mip, 1);
|
|
}
|
|
else
|
|
{
|
|
result.x = MaxI32(mip0_dims.x << -mip, 1);
|
|
result.y = MaxI32(mip0_dims.y << -mip, 1);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
Vec3I32 G_DimsFromMip3D(Vec3I32 mip0_dims, i32 mip)
|
|
{
|
|
mip = ClampI32(mip, -31, 31);
|
|
Vec3I32 result = Zi;
|
|
if (mip >= 0)
|
|
{
|
|
result.x = MaxI32(mip0_dims.x >> mip, 1);
|
|
result.y = MaxI32(mip0_dims.y >> mip, 1);
|
|
result.z = MaxI32(mip0_dims.z >> mip, 1);
|
|
}
|
|
else
|
|
{
|
|
result.x = MaxI32(mip0_dims.x << -mip, 1);
|
|
result.y = MaxI32(mip0_dims.y << -mip, 1);
|
|
result.z = MaxI32(mip0_dims.z << -mip, 1);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//- Thread count
|
|
|
|
Vec3I32 G_GroupCountFromThreadCount(ComputeShaderDesc cs, Vec3I32 threads)
|
|
{
|
|
return VEC3I32(
|
|
(threads.x + cs.x - 1) / cs.x,
|
|
(threads.y + cs.y - 1) / cs.y,
|
|
(threads.z + cs.z - 1) / cs.z
|
|
);
|
|
}
|
|
|
|
//- Viewport / scissor
|
|
|
|
Rng3 G_ViewportFromTexture(G_ResourceHandle texture)
|
|
{
|
|
Vec2I32 dims = G_Count2D(texture);
|
|
return RNG3(VEC3(0, 0, 0), VEC3(dims.x, dims.y, 1));
|
|
}
|
|
|
|
Rng2 G_ScissorFromTexture(G_ResourceHandle texture)
|
|
{
|
|
Vec2I32 dims = G_Count2D(texture);
|
|
return RNG2(VEC2(0, 0), VEC2(dims.x, dims.y));
|
|
}
|
|
|
|
//- Shared resources
|
|
|
|
|
|
G_SamplerStateRef G_BasicSamplerFromKind(G_BasicSamplerKind kind)
|
|
{
|
|
return G.basic_samplers[kind];
|
|
}
|
|
|
|
G_IndexBufferDesc G_QuadIndices(void)
|
|
{
|
|
return G.quad_indices;
|
|
}
|
|
|
|
G_Texture2DRef G_BlankTexture2D(void)
|
|
{
|
|
return G.blank_tex;
|
|
}
|
|
|
|
G_Texture3DRef G_BasicNoiseTexture(void)
|
|
{
|
|
return G.basic_noise;
|
|
}
|