power_play/src/gpu/gpu_common.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;
}