fix oob resource access during composition pass
This commit is contained in:
parent
e3ae1a789f
commit
201d0c2bf0
@ -81,7 +81,6 @@ void AsyncWorkerEntryPoint(WaveLaneCtx *lane)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WaveSync(lane);
|
WaveSync(lane);
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
|
|||||||
@ -439,7 +439,6 @@ CR_Item *CR_ItemFromString(Arena *arena, String str)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EndScratch(scratch);
|
EndScratch(scratch);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,7 +29,6 @@ u64 ClampU64(u64 v, u64 min, u64 max) { return v < min ? min : v > max ? max : v
|
|||||||
i64 ClampI64(i64 v, i64 min, i64 max) { return v < min ? min : v > max ? max : v; }
|
i64 ClampI64(i64 v, i64 min, i64 max) { return v < min ? min : v > max ? max : v; }
|
||||||
f64 ClampF64(f64 v, f64 min, f64 max) { return v < min ? min : v > max ? max : v; }
|
f64 ClampF64(f64 v, f64 min, f64 max) { return v < min ? min : v > max ? max : v; }
|
||||||
|
|
||||||
|
|
||||||
//- Saturate
|
//- Saturate
|
||||||
u32 SaturateU32(u32 v) { return v < 0 ? 0 : v > 1 ? 1 : v; }
|
u32 SaturateU32(u32 v) { return v < 0 ? 0 : v > 1 ? 1 : v; }
|
||||||
i32 SaturateI32(i32 v) { return v < 0 ? 0 : v > 1 ? 1 : v; }
|
i32 SaturateI32(i32 v) { return v < 0 ? 0 : v > 1 ? 1 : v; }
|
||||||
|
|||||||
@ -39,7 +39,6 @@ void BootstrapResources(u64 archive_strings_count, String *archive_strings)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Resource ops
|
//~ Resource ops
|
||||||
|
|
||||||
|
|||||||
@ -49,66 +49,65 @@ u32 countof(T arr[N])
|
|||||||
//~ C -> HLSL interoperability stubs
|
//~ C -> HLSL interoperability stubs
|
||||||
|
|
||||||
//- Min
|
//- Min
|
||||||
#define MinU8 min
|
#define MinU8 (u8)min
|
||||||
#define MinI8 min
|
#define MinI8 (i8)min
|
||||||
#define MinU32 min
|
#define MinU32 (u32)min
|
||||||
#define MinI32 min
|
#define MinI32 (i32)min
|
||||||
#define MinF32 min
|
#define MinF32 (f32)min
|
||||||
#define MinU64 min
|
#define MinU64 (u64)min
|
||||||
#define MinI64 min
|
#define MinI64 (i64)min
|
||||||
#define MinF64 min
|
#define MinF64 (f64)min
|
||||||
|
|
||||||
//- Max
|
//- Max
|
||||||
#define MaxU8 max
|
#define MaxU8 (u8)max
|
||||||
#define MaxI8 max
|
#define MaxI8 (i8)max
|
||||||
#define MaxU32 max
|
#define MaxU32 (u32)max
|
||||||
#define MaxI32 max
|
#define MaxI32 (i32)max
|
||||||
#define MaxF32 max
|
#define MaxF32 (f32)max
|
||||||
#define MaxU64 max
|
#define MaxU64 (u64)max
|
||||||
#define MaxI64 max
|
#define MaxI64 (i64)max
|
||||||
#define MaxF64 max
|
#define MaxF64 (f64)max
|
||||||
|
|
||||||
//- Clamp
|
//- Clamp
|
||||||
#define ClampU32 clamp
|
#define ClampU32 (u32)clamp
|
||||||
#define ClampI32 clamp
|
#define ClampI32 (i32)clamp
|
||||||
#define ClampF32 clamp
|
#define ClampF32 (f32)clamp
|
||||||
#define ClampU64 clamp
|
#define ClampU64 (u64)clamp
|
||||||
#define ClampI64 clamp
|
#define ClampI64 (i64)clamp
|
||||||
#define ClampF64 clamp
|
#define ClampF64 (f64)clamp
|
||||||
|
|
||||||
//- Round
|
//- Round
|
||||||
#define RoundF32 round
|
#define RoundF32 (f32)round
|
||||||
#define RoundF64 round
|
#define RoundF64 (f64)round
|
||||||
|
|
||||||
//- Floor
|
//- Floor
|
||||||
#define FloorF32 floor
|
#define FloorF32 (f32)floor
|
||||||
#define FloorF64 floor
|
#define FloorF64 (f64)floor
|
||||||
|
|
||||||
//- Ceil
|
//- Ceil
|
||||||
#define CeilF32 ceil
|
#define CeilF32 (f32)ceil
|
||||||
#define CeilF64 ceil
|
#define CeilF64 (f64)ceil
|
||||||
|
|
||||||
//- Trunc
|
//- Trunc
|
||||||
#define TruncF32 trunc
|
#define TruncF32 (f32)trunc
|
||||||
#define TruncF64 trunc
|
#define TruncF64 (f64)trunc
|
||||||
|
|
||||||
//- Mod
|
//- Mod
|
||||||
#define ModF32 fmod
|
#define ModF32 (f32)fmod
|
||||||
#define ModF64 fmod
|
#define ModF64 (f64)fmod
|
||||||
|
|
||||||
//- Abs
|
//- Abs
|
||||||
#define AbsF32 abs
|
#define AbsF32 (f32)abs
|
||||||
#define AbsF64 abs
|
#define AbsF64 (f64)abs
|
||||||
|
|
||||||
//- Sign
|
//- Sign
|
||||||
#define SignF32 sign
|
#define SignF32 (f32)sign
|
||||||
#define SignF64 sign
|
#define SignF64 (f64)sign
|
||||||
|
|
||||||
//- Smoothstep
|
//- Smoothstep
|
||||||
#define SmoothstepF32 smoothstep
|
#define SmoothstepF32 (f32)smoothstep
|
||||||
#define SmoothstepF64 smoothstep
|
#define SmoothstepF64 (f64)smoothstep
|
||||||
|
|
||||||
//- Matchfloor
|
|
||||||
#define MatchFloor(a, b) all(floor(a) == floor(b))
|
#define MatchFloor(a, b) all(floor(a) == floor(b))
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -166,12 +165,12 @@ Inline Vec4 LinearFromSrgb(Vec4 srgb)
|
|||||||
Inline f32 LuminanceFromColor(Vec4 v)
|
Inline f32 LuminanceFromColor(Vec4 v)
|
||||||
{
|
{
|
||||||
return 0.2126 * v.r + 0.7152 * v.g + 0.0722 * v.b;
|
return 0.2126 * v.r + 0.7152 * v.g + 0.0722 * v.b;
|
||||||
};
|
}
|
||||||
|
|
||||||
Inline Vec4 InvertColor(Vec4 v)
|
Inline Vec4 InvertColor(Vec4 v)
|
||||||
{
|
{
|
||||||
return Vec4(Vec3(1, 1, 1) - v.rgb, v.a);
|
return Vec4(Vec3(1, 1, 1) - v.rgb, v.a);
|
||||||
};
|
}
|
||||||
|
|
||||||
Inline Vec4 Premul(Vec4 v)
|
Inline Vec4 Premul(Vec4 v)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -132,7 +132,6 @@ String StringFromList(Arena *arena, StringList l, String separator);
|
|||||||
#define FmtChar(v, ...) FMTARG(FmtArgKind_Char, .value.c = (v), __VA_ARGS__)
|
#define FmtChar(v, ...) FMTARG(FmtArgKind_Char, .value.c = (v), __VA_ARGS__)
|
||||||
#define FmtString(v, ...) FMTARG(FmtArgKind_String, .value.string = (v), __VA_ARGS__)
|
#define FmtString(v, ...) FMTARG(FmtArgKind_String, .value.string = (v), __VA_ARGS__)
|
||||||
|
|
||||||
|
|
||||||
#define FmtUint(v, ...) FMTARG(FmtArgKind_Uint, .value.uints = VEC4U64((v), 0, 0, 0), __VA_ARGS__)
|
#define FmtUint(v, ...) FMTARG(FmtArgKind_Uint, .value.uints = VEC4U64((v), 0, 0, 0), __VA_ARGS__)
|
||||||
#define FmtUint2(v, ...) FMTARG(FmtArgKind_Uint2, .value.uints = VEC4U64((v).x, (v).y, 0, 0), __VA_ARGS__)
|
#define FmtUint2(v, ...) FMTARG(FmtArgKind_Uint2, .value.uints = VEC4U64((v).x, (v).y, 0, 0), __VA_ARGS__)
|
||||||
#define FmtUint3(v, ...) FMTARG(FmtArgKind_Uint3, .value.uints = VEC4U64((v).x, (v).y, (v).z, 0), __VA_ARGS__)
|
#define FmtUint3(v, ...) FMTARG(FmtArgKind_Uint3, .value.uints = VEC4U64((v).x, (v).y, (v).z, 0), __VA_ARGS__)
|
||||||
|
|||||||
@ -317,6 +317,7 @@ void GC_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame)
|
|||||||
G_Format_R8G8B8A8_Unorm_Srgb,
|
G_Format_R8G8B8A8_Unorm_Srgb,
|
||||||
atlas->dims,
|
atlas->dims,
|
||||||
G_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present,
|
G_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present,
|
||||||
|
.debug = Lit("Glyph atlas")
|
||||||
);
|
);
|
||||||
atlas->tex_ref = G_PushTexture2DRef(gpu_perm, atlas->tex);
|
atlas->tex_ref = G_PushTexture2DRef(gpu_perm, atlas->tex);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -415,12 +415,14 @@ Enum(G_ResourceFlag)
|
|||||||
G_ResourceFlag_ZeroMemory = (1 << 3),
|
G_ResourceFlag_ZeroMemory = (1 << 3),
|
||||||
G_ResourceFlag_HostMemory = (1 << 4), // Resource will be mapped into the cpu's address space
|
G_ResourceFlag_HostMemory = (1 << 4), // Resource will be mapped into the cpu's address space
|
||||||
G_ResourceFlag_Uncached = (1 << 5), // Cpu writes will be combined & reads will be uncached
|
G_ResourceFlag_Uncached = (1 << 5), // Cpu writes will be combined & reads will be uncached
|
||||||
|
G_ResourceFlag_ForceNoReuse = (1 << 6),
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(G_BufferDesc)
|
Struct(G_BufferDesc)
|
||||||
{
|
{
|
||||||
G_ResourceFlag flags;
|
G_ResourceFlag flags;
|
||||||
u64 size;
|
u64 size;
|
||||||
|
String debug;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(G_TextureDesc)
|
Struct(G_TextureDesc)
|
||||||
@ -431,6 +433,7 @@ Struct(G_TextureDesc)
|
|||||||
G_Layout initial_layout;
|
G_Layout initial_layout;
|
||||||
i32 mip_levels; // Will be clamped to range [1, inf)
|
i32 mip_levels; // Will be clamped to range [1, inf)
|
||||||
Vec4 clear_color;
|
Vec4 clear_color;
|
||||||
|
String debug;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(G_SamplerDesc)
|
Struct(G_SamplerDesc)
|
||||||
@ -446,6 +449,7 @@ Struct(G_SamplerDesc)
|
|||||||
Vec4 border_color;
|
Vec4 border_color;
|
||||||
f32 min_lod;
|
f32 min_lod;
|
||||||
f32 max_lod;
|
f32 max_lod;
|
||||||
|
String debug;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(G_ResourceDesc)
|
Struct(G_ResourceDesc)
|
||||||
|
|||||||
@ -450,6 +450,34 @@ D3D12_BARRIER_LAYOUT G_D12_BarrierLayoutFromLayout(G_Layout layout)
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void G_D12_SetObjectName(ID3D12Object *object, String name)
|
||||||
|
{
|
||||||
|
TempArena scratch = BeginScratchNoConflict();
|
||||||
|
{
|
||||||
|
wchar_t *name_wstr = WstrFromString(scratch.arena, name);
|
||||||
|
ID3D12Resource_SetName(object, name_wstr);
|
||||||
|
}
|
||||||
|
EndScratch(scratch);
|
||||||
|
}
|
||||||
|
|
||||||
|
String G_D12_NameFromObject(Arena *arena, ID3D12Object *object)
|
||||||
|
{
|
||||||
|
String result = Zi;
|
||||||
|
{
|
||||||
|
wchar_t dbg_text[G_D12_MaxDebugTextLen] = Zi;
|
||||||
|
u32 dbg_text_sz = sizeof(dbg_text);
|
||||||
|
ID3D12Object_GetPrivateData(object, &WKPDID_D3DDebugObjectNameW, &dbg_text_sz, dbg_text);
|
||||||
|
if (dbg_text_sz > 2)
|
||||||
|
{
|
||||||
|
String16 str16 = Zi;
|
||||||
|
str16.len = (dbg_text_sz / 2) - 1;
|
||||||
|
str16.text = dbg_text;
|
||||||
|
result = StringFromString16(arena, str16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Pipeline
|
//~ Pipeline
|
||||||
|
|
||||||
@ -497,13 +525,39 @@ G_D12_Pipeline *G_D12_PipelineFromDesc(G_D12_PipelineDesc desc)
|
|||||||
// Create pipeline
|
// Create pipeline
|
||||||
if (is_pipeline_new)
|
if (is_pipeline_new)
|
||||||
{
|
{
|
||||||
|
TempArena scratch = BeginScratchNoConflict();
|
||||||
HRESULT hr = 0;
|
HRESULT hr = 0;
|
||||||
b32 ok = 1;
|
b32 ok = 1;
|
||||||
String error_str = Zi;
|
String error_str = Zi;
|
||||||
|
b32 is_compute = IsResourceNil(desc.vs.resource) || IsResourceNil(desc.ps.resource);
|
||||||
|
|
||||||
|
String pipeline_name = Zi;
|
||||||
|
if (is_compute)
|
||||||
|
{
|
||||||
|
pipeline_name = StringF(
|
||||||
|
scratch.arena,
|
||||||
|
"%F%F",
|
||||||
|
FmtHandle(desc.cs.resource.v),
|
||||||
|
FmtString(NameFromResource(desc.cs.resource))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pipeline_name = StringF(
|
||||||
|
scratch.arena,
|
||||||
|
"%F%F-%F%F",
|
||||||
|
FmtHandle(desc.vs.resource.v),
|
||||||
|
FmtString(NameFromResource(desc.vs.resource)),
|
||||||
|
FmtHandle(desc.ps.resource.v),
|
||||||
|
FmtString(NameFromResource(desc.ps.resource))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Create PSO
|
// Create PSO
|
||||||
ID3D12PipelineState *pso = 0;
|
ID3D12PipelineState *pso = 0;
|
||||||
if (ok && (!IsResourceNil(desc.vs.resource) || !IsResourceNil(desc.ps.resource)))
|
if (ok)
|
||||||
|
{
|
||||||
|
if (!is_compute)
|
||||||
{
|
{
|
||||||
i32 rts_count = 0;
|
i32 rts_count = 0;
|
||||||
b32 has_multiple_blend_modes = 0;
|
b32 has_multiple_blend_modes = 0;
|
||||||
@ -632,11 +686,11 @@ G_D12_Pipeline *G_D12_PipelineFromDesc(G_D12_PipelineDesc desc)
|
|||||||
hr = ID3D12Device_CreateGraphicsPipelineState(G_D12.device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso);
|
hr = ID3D12Device_CreateGraphicsPipelineState(G_D12.device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
error_str = Lit("Failed to create graphics pipeline");
|
error_str = StringF(scratch.arena, "Failed to create graphics pipeline \"%F\"", FmtString(pipeline_name));
|
||||||
ok = 0;
|
ok = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ok)
|
else
|
||||||
{
|
{
|
||||||
String cs = DataFromResource(desc.cs.resource);
|
String cs = DataFromResource(desc.cs.resource);
|
||||||
D3D12_COMPUTE_PIPELINE_STATE_DESC pso_desc = Zi;
|
D3D12_COMPUTE_PIPELINE_STATE_DESC pso_desc = Zi;
|
||||||
@ -648,12 +702,20 @@ G_D12_Pipeline *G_D12_PipelineFromDesc(G_D12_PipelineDesc desc)
|
|||||||
hr = ID3D12Device_CreateComputePipelineState(G_D12.device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso);
|
hr = ID3D12Device_CreateComputePipelineState(G_D12.device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
error_str = Lit("Failed to create compute pipeline");
|
error_str = StringF(scratch.arena, "Failed to create compute pipeline \"%F\"", FmtString(pipeline_name));
|
||||||
ok = 0;
|
ok = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!ok)
|
if (ok)
|
||||||
|
{
|
||||||
|
if (GPU_DEBUG)
|
||||||
|
{
|
||||||
|
G_D12_SetObjectName((ID3D12Object *)pso, pipeline_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// TOOD: Don't panic
|
// TOOD: Don't panic
|
||||||
Panic(error_str);
|
Panic(error_str);
|
||||||
@ -662,6 +724,7 @@ G_D12_Pipeline *G_D12_PipelineFromDesc(G_D12_PipelineDesc desc)
|
|||||||
pipeline->pso = pso;
|
pipeline->pso = pso;
|
||||||
pipeline->error = error_str;
|
pipeline->error = error_str;
|
||||||
pipeline->ok = ok;
|
pipeline->ok = ok;
|
||||||
|
EndScratch(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pipeline;
|
return pipeline;
|
||||||
@ -900,15 +963,22 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
|
|||||||
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_debug_text =
|
||||||
|
is_buffer ? desc.buffer.debug :
|
||||||
|
is_texture ? desc.texture.debug :
|
||||||
|
desc.sampler.debug;
|
||||||
|
new_debug_text.len = MinU64(new_debug_text.len, countof(resource->debug_text));
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Initialize heap info
|
//- Initialize heap info
|
||||||
|
|
||||||
b32 can_reuse = 1;
|
b32 can_reuse = !AnyBit(flags, G_ResourceFlag_ForceNoReuse);
|
||||||
|
|
||||||
D3D12_HEAP_FLAGS heap_flags = 0;
|
D3D12_HEAP_FLAGS heap_flags = 0;
|
||||||
D3D12_HEAP_PROPERTIES heap_props = Zi;
|
D3D12_HEAP_PROPERTIES heap_props = Zi;
|
||||||
@ -1047,8 +1117,14 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
|
|||||||
Unlock(&lock);
|
Unlock(&lock);
|
||||||
}
|
}
|
||||||
ZeroStruct(release);
|
ZeroStruct(release);
|
||||||
release->d3d_resource = resource->d3d_resource;
|
|
||||||
SllQueuePush(cl->releases.first, cl->releases.last, release);
|
SllQueuePush(cl->releases.first, cl->releases.last, release);
|
||||||
|
release->d3d_resource = resource->d3d_resource;
|
||||||
|
if (GPU_DEBUG)
|
||||||
|
{
|
||||||
|
StaticAssert(countof(release->debug_text) == countof(resource->debug_text));
|
||||||
|
release->debug_text_len = resource->debug_text_len;
|
||||||
|
CopyBytes(release->debug_text, resource->debug_text, resource->debug_text_len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ZeroStruct(resource);
|
ZeroStruct(resource);
|
||||||
}
|
}
|
||||||
@ -1146,6 +1222,20 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
//- Set debug information
|
||||||
|
|
||||||
|
if (GPU_DEBUG)
|
||||||
|
{
|
||||||
|
String old_debug_text = STRING(resource->debug_text_len, resource->debug_text);
|
||||||
|
if (!MatchString(old_debug_text, new_debug_text))
|
||||||
|
{
|
||||||
|
resource->debug_text_len = new_debug_text.len;
|
||||||
|
CopyBytes(resource->debug_text, new_debug_text.text, new_debug_text.len);
|
||||||
|
G_D12_SetObjectName((ID3D12Object *)resource->d3d_resource, new_debug_text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Barrier if reusing
|
//- Barrier if reusing
|
||||||
|
|
||||||
@ -1221,7 +1311,7 @@ G_D12_Descriptor *G_D12_PushDescriptor(G_D12_Arena *gpu_arena, G_D12_DescriptorH
|
|||||||
{
|
{
|
||||||
Panic(Lit("Max descriptors reached in heap"));
|
Panic(Lit("Max descriptors reached in heap"));
|
||||||
}
|
}
|
||||||
descriptor = PushStruct(heap->descriptors_arena, G_D12_Descriptor);
|
descriptor = PushStructNoZero(heap->descriptors_arena, G_D12_Descriptor);
|
||||||
index = descriptors_count;
|
index = descriptors_count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
#pragma comment(lib, "dxgi")
|
#pragma comment(lib, "dxgi")
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Tweakable defines
|
//~ Tweakable definitions
|
||||||
|
|
||||||
#define G_D12_TearingIsAllowed 1
|
#define G_D12_TearingIsAllowed 1
|
||||||
#define G_D12_FrameLatency 1
|
#define G_D12_FrameLatency 1
|
||||||
@ -25,6 +25,8 @@
|
|||||||
#define G_D12_MaxSamplerDescriptors (1024 * 1)
|
#define G_D12_MaxSamplerDescriptors (1024 * 1)
|
||||||
#define G_D12_MaxRtvDescriptors (1024 * 64)
|
#define G_D12_MaxRtvDescriptors (1024 * 64)
|
||||||
|
|
||||||
|
#define G_D12_MaxDebugTextLen 64
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Pipeline types
|
//~ Pipeline types
|
||||||
|
|
||||||
@ -90,6 +92,9 @@ Struct(G_D12_Resource)
|
|||||||
|
|
||||||
// Backbuffer info
|
// Backbuffer info
|
||||||
struct G_D12_Swapchain *swapchain;
|
struct G_D12_Swapchain *swapchain;
|
||||||
|
|
||||||
|
u64 debug_text_len;
|
||||||
|
u8 debug_text[G_D12_MaxDebugTextLen];
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(G_D12_ResourceList)
|
Struct(G_D12_ResourceList)
|
||||||
@ -273,6 +278,9 @@ Struct(G_D12_Releasable)
|
|||||||
i64 completion_queue_target;
|
i64 completion_queue_target;
|
||||||
|
|
||||||
ID3D12Resource *d3d_resource;
|
ID3D12Resource *d3d_resource;
|
||||||
|
|
||||||
|
u64 debug_text_len;
|
||||||
|
u8 debug_text[G_D12_MaxDebugTextLen];
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(G_D12_ReleasableList)
|
Struct(G_D12_ReleasableList)
|
||||||
@ -495,6 +503,9 @@ D3D12_BARRIER_SYNC G_D12_BarrierSyncFromStages(G_Stage stages);
|
|||||||
D3D12_BARRIER_ACCESS G_D12_BarrierAccessFromAccesses(G_Access accesses);
|
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);
|
||||||
|
|
||||||
|
void G_D12_SetObjectName(ID3D12Object *object, String name);
|
||||||
|
String G_D12_NameFromObject(Arena *arena, ID3D12Object *object);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Pipeline
|
//~ Pipeline
|
||||||
|
|
||||||
|
|||||||
@ -426,11 +426,13 @@ void BuildEntryPoint(WaveLaneCtx *lane)
|
|||||||
//- Dxc
|
//- Dxc
|
||||||
{
|
{
|
||||||
PushStringToList(perm, &cp.flags_dxc, Lit("-O3"));
|
PushStringToList(perm, &cp.flags_dxc, Lit("-O3"));
|
||||||
|
// PushStringToList(perm, &cp.flags_dxc, Lit("-Od"));
|
||||||
PushStringToList(perm, &cp.flags_dxc, Lit("-Zi -Qembed_debug"));
|
PushStringToList(perm, &cp.flags_dxc, Lit("-Zi -Qembed_debug"));
|
||||||
|
|
||||||
// Enable warnings
|
// Enable warnings
|
||||||
PushStringToList(perm, &cp.warnings_dxc, Lit("-Wall"));
|
PushStringToList(perm, &cp.warnings_dxc, Lit("-Wall"));
|
||||||
PushStringToList(perm, &cp.warnings_dxc, Lit("-WX"));
|
PushStringToList(perm, &cp.warnings_dxc, Lit("-WX"));
|
||||||
|
PushStringToList(perm, &cp.warnings_dxc, Lit("-Wshadow"));
|
||||||
|
|
||||||
// Disable warnings
|
// Disable warnings
|
||||||
PushStringToList(perm, &cp.warnings_dxc, Lit("-Wno-unused-variable"));
|
PushStringToList(perm, &cp.warnings_dxc, Lit("-Wno-unused-variable"));
|
||||||
|
|||||||
@ -815,7 +815,6 @@ void NET_W32_TickForever(WaveLaneCtx *lane)
|
|||||||
// Post initial recv
|
// Post initial recv
|
||||||
CreateIoCompletionPort((HANDLE)sock, NET_W32.iocp, 0, 0);
|
CreateIoCompletionPort((HANDLE)sock, NET_W32.iocp, 0, 0);
|
||||||
|
|
||||||
|
|
||||||
NET_W32_PostRecv(pipe);
|
NET_W32_PostRecv(pipe);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@ -392,7 +392,6 @@ PLT_FileMap PLT_OpenFileMap(PLT_File file)
|
|||||||
map.mapped_memory = STRING(size, base_ptr);
|
map.mapped_memory = STRING(size, base_ptr);
|
||||||
map.valid = map_handle != INVALID_HANDLE_VALUE && base_ptr != 0;
|
map.valid = map_handle != INVALID_HANDLE_VALUE && base_ptr != 0;
|
||||||
|
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -411,7 +411,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
gpu_perm, cl,
|
gpu_perm, cl,
|
||||||
V_GpuState,
|
V_GpuState,
|
||||||
1,
|
1,
|
||||||
.flags = G_ResourceFlag_ZeroMemory | G_ResourceFlag_AllowShaderReadWrite
|
.flags = G_ResourceFlag_ZeroMemory | G_ResourceFlag_AllowShaderReadWrite,
|
||||||
|
.debug = Lit("Gpu state")
|
||||||
);
|
);
|
||||||
gpu_state_ref = G_PushRWStructuredBufferRef(gpu_perm, gpu_state, V_GpuState);
|
gpu_state_ref = G_PushRWStructuredBufferRef(gpu_perm, gpu_state, V_GpuState);
|
||||||
}
|
}
|
||||||
@ -422,7 +423,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
G_Format_R8_Uint,
|
G_Format_R8_Uint,
|
||||||
tiles_dims,
|
tiles_dims,
|
||||||
G_Layout_DirectQueue_ShaderRead,
|
G_Layout_DirectQueue_ShaderRead,
|
||||||
.flags = G_ResourceFlag_ZeroMemory
|
.flags = G_ResourceFlag_ZeroMemory,
|
||||||
|
.debug = Lit("Tiles")
|
||||||
);
|
);
|
||||||
gpu_tiles_ref = G_PushTexture2DRef(gpu_perm, gpu_tiles);
|
gpu_tiles_ref = G_PushTexture2DRef(gpu_perm, gpu_tiles);
|
||||||
}
|
}
|
||||||
@ -432,7 +434,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
gpu_perm, cl,
|
gpu_perm, cl,
|
||||||
V_Particle,
|
V_Particle,
|
||||||
V_ParticlesCap,
|
V_ParticlesCap,
|
||||||
.flags = G_ResourceFlag_ZeroMemory | G_ResourceFlag_AllowShaderReadWrite
|
.flags = G_ResourceFlag_ZeroMemory | G_ResourceFlag_AllowShaderReadWrite,
|
||||||
|
.debug = Lit("Particles")
|
||||||
);
|
);
|
||||||
gpu_particles_ref = G_PushRWStructuredBufferRef(gpu_perm, gpu_particles, V_Particle);
|
gpu_particles_ref = G_PushRWStructuredBufferRef(gpu_perm, gpu_particles, V_Particle);
|
||||||
}
|
}
|
||||||
@ -446,7 +449,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
G_Format_R16G16B16A16_Float,
|
G_Format_R16G16B16A16_Float,
|
||||||
cells_dims,
|
cells_dims,
|
||||||
G_Layout_DirectQueue_ShaderReadWrite,
|
G_Layout_DirectQueue_ShaderReadWrite,
|
||||||
.flags = G_ResourceFlag_ZeroMemory | G_ResourceFlag_AllowShaderReadWrite
|
.flags = G_ResourceFlag_ZeroMemory | G_ResourceFlag_AllowShaderReadWrite,
|
||||||
|
.debug = Lit("Cells")
|
||||||
);
|
);
|
||||||
gpu_cells_ref = G_PushRWTexture2DRef(gpu_perm, gpu_cells);
|
gpu_cells_ref = G_PushRWTexture2DRef(gpu_perm, gpu_cells);
|
||||||
}
|
}
|
||||||
@ -460,7 +464,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
G_Format_R16G16B16A16_Float,
|
G_Format_R16G16B16A16_Float,
|
||||||
cells_dims,
|
cells_dims,
|
||||||
G_Layout_DirectQueue_ShaderReadWrite,
|
G_Layout_DirectQueue_ShaderReadWrite,
|
||||||
.flags = G_ResourceFlag_ZeroMemory | G_ResourceFlag_AllowShaderReadWrite
|
.flags = G_ResourceFlag_ZeroMemory | G_ResourceFlag_AllowShaderReadWrite,
|
||||||
|
.debug = Lit("Stains")
|
||||||
);
|
);
|
||||||
gpu_stains_ref = G_PushRWTexture2DRef(gpu_perm, gpu_stains);
|
gpu_stains_ref = G_PushRWTexture2DRef(gpu_perm, gpu_stains);
|
||||||
}
|
}
|
||||||
@ -475,7 +480,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
G_Format_R32_Float,
|
G_Format_R32_Float,
|
||||||
cells_dims,
|
cells_dims,
|
||||||
G_Layout_DirectQueue_ShaderReadWrite,
|
G_Layout_DirectQueue_ShaderReadWrite,
|
||||||
.flags = G_ResourceFlag_ZeroMemory | G_ResourceFlag_AllowShaderReadWrite
|
.flags = G_ResourceFlag_ZeroMemory | G_ResourceFlag_AllowShaderReadWrite,
|
||||||
|
.debug = Lit("Drynesses")
|
||||||
);
|
);
|
||||||
gpu_drynesses_ref = G_PushRWTexture2DRef(gpu_perm, gpu_drynesses);
|
gpu_drynesses_ref = G_PushRWTexture2DRef(gpu_perm, gpu_drynesses);
|
||||||
}
|
}
|
||||||
@ -853,9 +859,10 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
f32 fire_presses = fire_held && !prev_frame->held_buttons[Button_M1];
|
f32 fire_presses = fire_held && !prev_frame->held_buttons[Button_M1];
|
||||||
{
|
{
|
||||||
// TODO: Adjustable sensitivity
|
// TODO: Adjustable sensitivity
|
||||||
|
f32 mouse_sensitivity = TweakFloat("Mouse sensitivity", 1.0, 0.1, 5.0);
|
||||||
f32 mouse_scale_factor = 0.005;
|
f32 mouse_scale_factor = 0.005;
|
||||||
look = frame->look;
|
look = frame->look;
|
||||||
look = AddVec2(look, MulVec2(mouse_delta, mouse_scale_factor));
|
look = AddVec2(look, MulVec2(mouse_delta, mouse_sensitivity * mouse_scale_factor));
|
||||||
look = ClampVec2Len(look, look_radius);
|
look = ClampVec2Len(look, look_radius);
|
||||||
}
|
}
|
||||||
if (frame->is_editing)
|
if (frame->is_editing)
|
||||||
@ -4445,7 +4452,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
G_Format_R16G16B16A16_Float,
|
G_Format_R16G16B16A16_Float,
|
||||||
frame->screen_dims,
|
frame->screen_dims,
|
||||||
G_Layout_DirectQueue_RenderTargetWrite,
|
G_Layout_DirectQueue_RenderTargetWrite,
|
||||||
.flags = G_ResourceFlag_AllowRenderTarget
|
.flags = G_ResourceFlag_AllowRenderTarget,
|
||||||
|
.debug = StringF(frame->arena, "Screen target [%F]", FmtSint(frame->tick))
|
||||||
);
|
);
|
||||||
G_Texture2DRef screen_target_ro = G_PushTexture2DRef(frame->gpu_arena, screen_target);
|
G_Texture2DRef screen_target_ro = G_PushTexture2DRef(frame->gpu_arena, screen_target);
|
||||||
Rng3 screen_viewport = RNG3(VEC3(0, 0, 0), VEC3(frame->screen_dims.x, frame->screen_dims.y, 1));
|
Rng3 screen_viewport = RNG3(VEC3(0, 0, 0), VEC3(frame->screen_dims.x, frame->screen_dims.y, 1));
|
||||||
@ -4457,7 +4465,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
G_Format_R16G16B16A16_Float,
|
G_Format_R16G16B16A16_Float,
|
||||||
frame->screen_dims,
|
frame->screen_dims,
|
||||||
G_Layout_DirectQueue_RenderTargetWrite,
|
G_Layout_DirectQueue_RenderTargetWrite,
|
||||||
.flags = G_ResourceFlag_AllowRenderTarget
|
.flags = G_ResourceFlag_AllowRenderTarget,
|
||||||
|
.debug = StringF(frame->arena, "Albedo target [%F]", FmtSint(frame->tick))
|
||||||
);
|
);
|
||||||
G_Texture2DRef albedo_target_ro = G_PushTexture2DRef(frame->gpu_arena, albedo_target);
|
G_Texture2DRef albedo_target_ro = G_PushTexture2DRef(frame->gpu_arena, albedo_target);
|
||||||
|
|
||||||
@ -4467,7 +4476,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
G_Format_R16G16B16A16_Float,
|
G_Format_R16G16B16A16_Float,
|
||||||
frame->shade_dims,
|
frame->shade_dims,
|
||||||
G_Layout_DirectQueue_ShaderReadWrite,
|
G_Layout_DirectQueue_ShaderReadWrite,
|
||||||
.flags = G_ResourceFlag_AllowShaderReadWrite
|
.flags = G_ResourceFlag_AllowShaderReadWrite,
|
||||||
|
.debug = StringF(frame->arena, "Shade target [%F]", FmtSint(frame->tick))
|
||||||
);
|
);
|
||||||
G_Texture2DRef shade_target_ro = G_PushTexture2DRef(frame->gpu_arena, shade_target);
|
G_Texture2DRef shade_target_ro = G_PushTexture2DRef(frame->gpu_arena, shade_target);
|
||||||
G_RWTexture2DRef shade_target_rw = G_PushRWTexture2DRef(frame->gpu_arena, shade_target);
|
G_RWTexture2DRef shade_target_rw = G_PushRWTexture2DRef(frame->gpu_arena, shade_target);
|
||||||
@ -4475,12 +4485,24 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
Rng2 shade_scissor = RNG2(VEC2(shade_viewport.p0.x, shade_viewport.p0.y), VEC2(shade_viewport.p1.x, shade_viewport.p1.y));
|
Rng2 shade_scissor = RNG2(VEC2(shade_viewport.p0.x, shade_viewport.p0.y), VEC2(shade_viewport.p1.x, shade_viewport.p1.y));
|
||||||
|
|
||||||
// Quad buffers
|
// Quad buffers
|
||||||
G_ResourceHandle quads_buff = G_PushBufferFromCpuCopy(frame->gpu_arena, frame->cl, StringFromArena(frame->quads_arena));
|
G_ResourceHandle quads_buff = G_PushBufferFromCpuCopy(
|
||||||
|
frame->gpu_arena, frame->cl,
|
||||||
|
StringFromArena(frame->quads_arena),
|
||||||
|
.debug = StringF(frame->arena, "quads [%F]", FmtSint(frame->tick))
|
||||||
|
);
|
||||||
G_StructuredBufferRef quads_ref = G_PushStructuredBufferRef(frame->gpu_arena, quads_buff, V_Quad);
|
G_StructuredBufferRef quads_ref = G_PushStructuredBufferRef(frame->gpu_arena, quads_buff, V_Quad);
|
||||||
|
|
||||||
// Debug shape buffers
|
// Debug shape buffers
|
||||||
G_ResourceHandle dverts_buff = G_PushBufferFromCpuCopy(frame->gpu_arena, frame->cl, StringFromArena(frame->dverts_arena));
|
G_ResourceHandle dverts_buff = G_PushBufferFromCpuCopy(
|
||||||
G_ResourceHandle dvert_idxs_buff = G_PushBufferFromCpuCopy(frame->gpu_arena, frame->cl, StringFromArena(frame->dvert_idxs_arena));
|
frame->gpu_arena, frame->cl,
|
||||||
|
StringFromArena(frame->dverts_arena),
|
||||||
|
.debug = StringF(frame->arena, "dverts [%F]", FmtSint(frame->tick))
|
||||||
|
);
|
||||||
|
G_ResourceHandle dvert_idxs_buff = G_PushBufferFromCpuCopy(
|
||||||
|
frame->gpu_arena, frame->cl,
|
||||||
|
StringFromArena(frame->dvert_idxs_arena),
|
||||||
|
.debug = StringF(frame->arena, "dvert idxs [%F]", FmtSint(frame->tick))
|
||||||
|
);
|
||||||
G_StructuredBufferRef dverts_ref = G_PushStructuredBufferRef(frame->gpu_arena, dverts_buff, V_DVert);
|
G_StructuredBufferRef dverts_ref = G_PushStructuredBufferRef(frame->gpu_arena, dverts_buff, V_DVert);
|
||||||
G_IndexBufferDesc dvert_idxs_ib = G_IdxBuff32(dvert_idxs_buff);
|
G_IndexBufferDesc dvert_idxs_ib = G_IdxBuff32(dvert_idxs_buff);
|
||||||
|
|
||||||
@ -4497,7 +4519,11 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
++emitter_idx;
|
++emitter_idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gpu_emitters = G_PushBufferFromCpuCopy(frame->gpu_arena, frame->cl, StringFromStructs(flattened_emitters, frame->emitters_count));
|
gpu_emitters = G_PushBufferFromCpuCopy(
|
||||||
|
frame->gpu_arena, frame->cl,
|
||||||
|
StringFromStructs(flattened_emitters, frame->emitters_count),
|
||||||
|
.debug = StringF(frame->arena, "emitters [%F]", FmtSint(frame->tick))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
G_StructuredBufferRef gpu_emitters_ref = G_PushStructuredBufferRef(frame->gpu_arena, gpu_emitters, V_Emitter);
|
G_StructuredBufferRef gpu_emitters_ref = G_PushStructuredBufferRef(frame->gpu_arena, gpu_emitters, V_Emitter);
|
||||||
|
|
||||||
@ -4573,7 +4599,11 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
G_ResourceHandle gpu_params = G_PushBufferFromCpuCopy(frame->gpu_arena, frame->cl, StringFromStruct(¶ms));
|
G_ResourceHandle gpu_params = G_PushBufferFromCpuCopy(
|
||||||
|
frame->gpu_arena, frame->cl,
|
||||||
|
StringFromStruct(¶ms),
|
||||||
|
.debug = StringF(frame->arena, "Gpu params [%F]", FmtSint(frame->tick))
|
||||||
|
);
|
||||||
G_StructuredBufferRef gpu_params_ref = G_PushStructuredBufferRef(frame->gpu_arena, gpu_params, V_GpuParams);
|
G_StructuredBufferRef gpu_params_ref = G_PushStructuredBufferRef(frame->gpu_arena, gpu_params, V_GpuParams);
|
||||||
|
|
||||||
// Upload tiles
|
// Upload tiles
|
||||||
@ -4680,12 +4710,9 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
G_DumbMemoryLayoutSync(frame->cl, shade_target, G_Layout_DirectQueue_ShaderRead);
|
G_DumbMemoryLayoutSync(frame->cl, shade_target, G_Layout_DirectQueue_ShaderRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Composite pass
|
//- Composite pass
|
||||||
|
|
||||||
G_DumbMemoryLayoutSync(frame->cl, screen_target, G_Layout_DirectQueue_RenderTargetWrite);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
G_Rasterize(
|
G_Rasterize(
|
||||||
frame->cl,
|
frame->cl,
|
||||||
|
|||||||
@ -25,11 +25,12 @@ ComputeShader2D(V_PrepareShadeCS, 8, 8)
|
|||||||
{
|
{
|
||||||
V_GpuParams params = G_Dereference<V_GpuParams>(V_ShaderConst_Params)[0];
|
V_GpuParams params = G_Dereference<V_GpuParams>(V_ShaderConst_Params)[0];
|
||||||
RWTexture2D<Vec4> shade = G_Dereference<Vec4>(params.shade_rw);
|
RWTexture2D<Vec4> shade = G_Dereference<Vec4>(params.shade_rw);
|
||||||
Vec2 shade_idx = SV_DispatchThreadID;
|
Vec2 shade_pos = SV_DispatchThreadID;
|
||||||
if (all(shade_idx < countof(shade)))
|
|
||||||
|
if (all(shade_pos < countof(shade)))
|
||||||
{
|
{
|
||||||
// Clear shade
|
// Clear shade
|
||||||
shade[shade_idx] = 0;
|
shade[shade_pos] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,26 +40,26 @@ ComputeShader2D(V_PrepareCellsCS, 8, 8)
|
|||||||
V_GpuParams params = G_Dereference<V_GpuParams>(V_ShaderConst_Params)[0];
|
V_GpuParams params = G_Dereference<V_GpuParams>(V_ShaderConst_Params)[0];
|
||||||
RWTexture2D<Vec4> cells = G_Dereference<Vec4>(params.cells);
|
RWTexture2D<Vec4> cells = G_Dereference<Vec4>(params.cells);
|
||||||
RWTexture2D<f32> drynesses = G_Dereference<f32>(params.drynesses);
|
RWTexture2D<f32> drynesses = G_Dereference<f32>(params.drynesses);
|
||||||
Vec2 cells_idx = SV_DispatchThreadID;
|
Vec2 cells_pos = SV_DispatchThreadID;
|
||||||
if (all(cells_idx < countof(cells)))
|
if (all(cells_pos < countof(cells)))
|
||||||
{
|
{
|
||||||
// Clear cell
|
// Clear cell
|
||||||
cells[cells_idx] = 0;
|
cells[cells_pos] = 0;
|
||||||
|
|
||||||
// Increase dryness
|
// Increase dryness
|
||||||
f32 dry_rate = params.dt * 0.1;
|
f32 dry_rate = params.dt * 0.1;
|
||||||
{
|
{
|
||||||
f32 old_dryness = drynesses[cells_idx];
|
f32 old_dryness = drynesses[cells_pos];
|
||||||
f32 new_dryness = lerp(old_dryness, 1, dry_rate);
|
f32 new_dryness = lerp(old_dryness, 1, dry_rate);
|
||||||
drynesses[cells_idx] = new_dryness;
|
drynesses[cells_pos] = new_dryness;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear stain
|
// Clear stain
|
||||||
if (params.should_clear_stains)
|
if (params.should_clear_stains)
|
||||||
{
|
{
|
||||||
RWTexture2D<Vec4> stains = G_Dereference<Vec4>(params.stains);
|
RWTexture2D<Vec4> stains = G_Dereference<Vec4>(params.stains);
|
||||||
stains[cells_idx] = 0;
|
stains[cells_pos] = 0;
|
||||||
drynesses[cells_idx] = 0;
|
drynesses[cells_pos] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -114,223 +115,11 @@ PixelShader(V_QuadPS, V_QuadPSOutput, V_QuadPSInput input)
|
|||||||
Texture2D<Vec4> tex = G_Dereference<Vec4>(quad.tex);
|
Texture2D<Vec4> tex = G_Dereference<Vec4>(quad.tex);
|
||||||
Vec4 albedo = tex.Sample(clamp_sampler, input.samp_uv);
|
Vec4 albedo = tex.Sample(clamp_sampler, input.samp_uv);
|
||||||
|
|
||||||
// Vec4 albedo = Color_Cyan;
|
|
||||||
|
|
||||||
V_QuadPSOutput output;
|
V_QuadPSOutput output;
|
||||||
output.sv_target0 = albedo;
|
output.sv_target0 = albedo;
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Backdrop
|
|
||||||
|
|
||||||
// ComputeShader2D(V_BackdropCS, 8, 8)
|
|
||||||
// {
|
|
||||||
// V_GpuParams params = G_Dereference<V_GpuParams>(V_ShaderConst_Params)[0];
|
|
||||||
// RWTexture2D<Vec4> screen = G_Dereference<Vec4>(params.screen_rw);
|
|
||||||
// Texture2D<P_TileKind> tiles = G_Dereference<P_TileKind>(params.tiles);
|
|
||||||
// SamplerState wrap_sampler = G_Dereference(params.pt_wrap_sampler);
|
|
||||||
|
|
||||||
// const Vec4 background_color_a = LinearFromSrgb(Vec4(0.30, 0.30, 0.30, 1));
|
|
||||||
// const Vec4 background_color_b = LinearFromSrgb(Vec4(0.15, 0.15, 0.15, 1));
|
|
||||||
|
|
||||||
// Vec2 screen_pos = SV_DispatchThreadID + Vec2(0.5, 0.5);
|
|
||||||
|
|
||||||
// Vec4 result = Vec4(0.025, 0.025, 0.025, 1);
|
|
||||||
// Vec2 world_pos = mul(params.af.screen_to_world, Vec3(screen_pos, 1));
|
|
||||||
// Vec2 cell_pos = floor(mul(params.af.world_to_cell, Vec3(world_pos, 1)));
|
|
||||||
// Vec2 tile_pos = mul(params.af.world_to_tile, Vec3(world_pos, 1));
|
|
||||||
|
|
||||||
// P_TileKind tile = tiles.Load(Vec3(tile_pos, 0));
|
|
||||||
|
|
||||||
// f32 half_thickness = 1;
|
|
||||||
// f32 half_world_bounds_size = P_WorldPitch * 0.5;
|
|
||||||
// Vec2 world_bounds_screen_p0 = mul(params.af.world_to_screen, Vec3(-half_world_bounds_size, -half_world_bounds_size, 1));
|
|
||||||
// Vec2 world_bounds_screen_p1 = mul(params.af.world_to_screen, Vec3(half_world_bounds_size, half_world_bounds_size, 1));
|
|
||||||
// b32 is_in_world_bounds =
|
|
||||||
// screen_pos.x > (world_bounds_screen_p0.x - half_thickness) &&
|
|
||||||
// screen_pos.y > (world_bounds_screen_p0.y - half_thickness) &&
|
|
||||||
// screen_pos.x < (world_bounds_screen_p1.x + half_thickness) &&
|
|
||||||
// screen_pos.y < (world_bounds_screen_p1.y + half_thickness);
|
|
||||||
|
|
||||||
// if (is_in_world_bounds)
|
|
||||||
// {
|
|
||||||
// // // Checkered grid
|
|
||||||
// // {
|
|
||||||
// // i32 color_idx = 0;
|
|
||||||
// // Vec4 colors[2] = {
|
|
||||||
// // background_color_a,
|
|
||||||
// // background_color_b
|
|
||||||
// // };
|
|
||||||
// // const f32 checker_size = 0.5;
|
|
||||||
// // Vec2 world_pos_modded = fmod(abs(world_pos), Vec2(checker_size * 2, checker_size * 2));
|
|
||||||
// // if (world_pos_modded.x < checker_size)
|
|
||||||
// // {
|
|
||||||
// // color_idx = !color_idx;
|
|
||||||
// // }
|
|
||||||
// // if (world_pos_modded.y < checker_size)
|
|
||||||
// // {
|
|
||||||
// // color_idx = !color_idx;
|
|
||||||
// // }
|
|
||||||
// // if (world_pos.x < 0)
|
|
||||||
// // {
|
|
||||||
// // color_idx = !color_idx;
|
|
||||||
// // }
|
|
||||||
// // if (world_pos.y < 0)
|
|
||||||
// // {
|
|
||||||
// // color_idx = !color_idx;
|
|
||||||
// // }
|
|
||||||
// // result = colors[color_idx];
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// // Tile test
|
|
||||||
// // TODO: Remove this
|
|
||||||
// {
|
|
||||||
// P_TileKind tile_tl = tiles.Load(Vec3(tile_pos.x - 1, tile_pos.y - 1, 0));
|
|
||||||
// P_TileKind tile_tr = tiles.Load(Vec3(tile_pos.x + 1, tile_pos.y - 1, 0));
|
|
||||||
// P_TileKind tile_br = tiles.Load(Vec3(tile_pos.x + 1, tile_pos.y + 1, 0));
|
|
||||||
// P_TileKind tile_bl = tiles.Load(Vec3(tile_pos.x - 1, tile_pos.y + 1, 0));
|
|
||||||
// P_TileKind tile_t = tiles.Load(Vec3(tile_pos.x, tile_pos.y - 1, 0));
|
|
||||||
// P_TileKind tile_r = tiles.Load(Vec3(tile_pos.x + 1, tile_pos.y, 0));
|
|
||||||
// P_TileKind tile_b = tiles.Load(Vec3(tile_pos.x, tile_pos.y + 1, 0));
|
|
||||||
// P_TileKind tile_l = tiles.Load(Vec3(tile_pos.x - 1, tile_pos.y, 0));
|
|
||||||
|
|
||||||
// f32 tile_edge_dist = Inf;
|
|
||||||
// P_TileKind edge_tile = tile;
|
|
||||||
// if (tile_tl != tile) { edge_tile = tile_tl; tile_edge_dist = min(tile_edge_dist, length(tile_pos - Vec2(floor(tile_pos.x), floor(tile_pos.y)))); }
|
|
||||||
// if (tile_tr != tile) { edge_tile = tile_tr; tile_edge_dist = min(tile_edge_dist, length(tile_pos - Vec2(ceil(tile_pos.x), floor(tile_pos.y)))); }
|
|
||||||
// if (tile_br != tile) { edge_tile = tile_br; tile_edge_dist = min(tile_edge_dist, length(tile_pos - Vec2(ceil(tile_pos.x), ceil(tile_pos.y)))); }
|
|
||||||
// if (tile_bl != tile) { edge_tile = tile_bl; tile_edge_dist = min(tile_edge_dist, length(tile_pos - Vec2(floor(tile_pos.x), ceil(tile_pos.y)))); }
|
|
||||||
// if (tile_l != tile) { edge_tile = tile_l; tile_edge_dist = min(tile_edge_dist, frac(tile_pos.x)); }
|
|
||||||
// if (tile_r != tile) { edge_tile = tile_r; tile_edge_dist = min(tile_edge_dist, 1.0 - frac(tile_pos.x)); }
|
|
||||||
// if (tile_t != tile) { edge_tile = tile_t; tile_edge_dist = min(tile_edge_dist, frac(tile_pos.y)); }
|
|
||||||
// if (tile_b != tile) { edge_tile = tile_b; tile_edge_dist = min(tile_edge_dist, 1.0 - frac(tile_pos.y)); }
|
|
||||||
|
|
||||||
// if (tile == P_TileKind_Wall)
|
|
||||||
// {
|
|
||||||
// Vec4 outer = LinearFromSrgb(Vec4(0.05, 0.05, 0.05, 1));
|
|
||||||
// Vec4 inner = LinearFromSrgb(Vec4(0.15, 0.15, 0.15, 1));
|
|
||||||
// result = lerp(outer, inner, smoothstep(0, 1, tile_edge_dist / 0.375));
|
|
||||||
// // result = lerp(outer, inner, smoothstep(0, 1, tile_edge_dist / 0.5));
|
|
||||||
// }
|
|
||||||
// else if (tile != P_TileKind_Empty)
|
|
||||||
// {
|
|
||||||
// SPR_Slice slice = params.tile_slices[tile];
|
|
||||||
// Texture2D<Vec4> tile_tex = G_Dereference<Vec4>(slice.tex);
|
|
||||||
// Vec4 tile_col = tile_tex.SampleLevel(wrap_sampler, world_pos, 0);
|
|
||||||
|
|
||||||
// result = tile_col;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // switch (tile)
|
|
||||||
// // {
|
|
||||||
// // default: break;
|
|
||||||
|
|
||||||
// // case P_TileKind_Floor:
|
|
||||||
// // {
|
|
||||||
// // result = Color_Blue;
|
|
||||||
// // } break;
|
|
||||||
|
|
||||||
// // case P_TileKind_Wall:
|
|
||||||
// // {
|
|
||||||
// // // result = Color_Red;
|
|
||||||
// // result = Color_Black;
|
|
||||||
// // } break;
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// // TODO: Remove this
|
|
||||||
// // Cells test
|
|
||||||
// {
|
|
||||||
// RWTexture2D<Vec4> stains = G_Dereference<Vec4>(params.stains);
|
|
||||||
// RWTexture2D<Vec4> cells = G_Dereference<Vec4>(params.cells);
|
|
||||||
// RWTexture2D<f32> drynesses = G_Dereference<f32>(params.drynesses);
|
|
||||||
|
|
||||||
// Vec4 stain = stains.Load(cell_pos);
|
|
||||||
// Vec4 cell = cells.Load(cell_pos);
|
|
||||||
// f32 dryness = drynesses[cell_pos];
|
|
||||||
|
|
||||||
// stain = V_DryColor(stain, dryness);
|
|
||||||
|
|
||||||
// // cell.rgb *= cell.a;
|
|
||||||
// // stain.rgb *= stain.a;
|
|
||||||
|
|
||||||
// result.rgb = (stain.rgb * stain.a) + (result.rgb * (1.0 - stain.a));
|
|
||||||
// result.a = (stain.a * 1) + (result.a * (1.0 - stain.a));
|
|
||||||
|
|
||||||
// result.rgb = (cell.rgb * cell.a) + (result.rgb * (1.0 - cell.a));
|
|
||||||
// result.a = (cell.a * 1) + (result.a * (1.0 - cell.a));
|
|
||||||
|
|
||||||
// // Vec4 cell = cells.Load(cell_pos);
|
|
||||||
// // if (cell.a != 0)
|
|
||||||
// // {
|
|
||||||
// // result = cell;
|
|
||||||
// // }
|
|
||||||
// // else
|
|
||||||
// // {
|
|
||||||
// // Vec4 stain = stains.Load(cell_pos);
|
|
||||||
// // if (stain.a != 0)
|
|
||||||
// // {
|
|
||||||
// // result = stain;
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// // // TODO: Remove this
|
|
||||||
// // // Cells test
|
|
||||||
// // {
|
|
||||||
// // RWTexture2D<Vec4> cells = G_Dereference<Vec4>(params.cells);
|
|
||||||
// // Vec2 cell_pos = floor(mul(params.af.world_to_cell, Vec3(world_pos, 1)));
|
|
||||||
// // Vec4 cell = cells.Load(cell_pos);
|
|
||||||
// // if (cell.a != 0)
|
|
||||||
// // {
|
|
||||||
// // result = cell;
|
|
||||||
// // }
|
|
||||||
// // else
|
|
||||||
// // {
|
|
||||||
// // RWTexture2D<Vec4> stains = G_Dereference<Vec4>(params.stains);
|
|
||||||
// // Vec4 stain = stains.Load(cell_pos);
|
|
||||||
// // if (stain.a != 0)
|
|
||||||
// // {
|
|
||||||
// // result = stain;
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// // TODO: Remove this
|
|
||||||
// // Stains test
|
|
||||||
// // {
|
|
||||||
// // RWTexture2D<V_ParticleKind> stains = G_Dereference<V_ParticleKind>(params.stains);
|
|
||||||
// // Vec2 cell_pos = mul(params.af.world_to_cell, Vec3(world_pos, 1));
|
|
||||||
// // V_ParticleKind stain = stains.Load(cell_pos);
|
|
||||||
|
|
||||||
// // if (stain == V_ParticleKind_Test)
|
|
||||||
// // {
|
|
||||||
// // // result = Color_Yellow;
|
|
||||||
// // // result = LinearFromSrgb(Vec4(0.5, 0.1, 0.1, 1));
|
|
||||||
// // // result = LinearFromSrgb(Vec4(0.5, 0.1, 0.1, 1));
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (all(screen_pos < countof(screen)))
|
|
||||||
// {
|
|
||||||
// screen[screen_pos] = result;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Particle simulation
|
//~ Particle simulation
|
||||||
|
|
||||||
@ -378,7 +167,9 @@ ComputeShader(V_SimParticlesCS, 64)
|
|||||||
V_Particle particle = particles[particle_idx];
|
V_Particle particle = particles[particle_idx];
|
||||||
if (particle.exists > 0)
|
if (particle.exists > 0)
|
||||||
{
|
{
|
||||||
// Initialize
|
//////////////////////////////
|
||||||
|
//- Initialize particle
|
||||||
|
|
||||||
if (particle.emitter_init_num != 0)
|
if (particle.emitter_init_num != 0)
|
||||||
{
|
{
|
||||||
V_Emitter emitter = G_Dereference<V_Emitter>(params.emitters)[particle.emitter_init_num - 1];
|
V_Emitter emitter = G_Dereference<V_Emitter>(params.emitters)[particle.emitter_init_num - 1];
|
||||||
@ -418,11 +209,15 @@ ComputeShader(V_SimParticlesCS, 64)
|
|||||||
particle.emitter_init_num = 0;
|
particle.emitter_init_num = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec2 cell_pos = floor(mul(params.af.world_to_cell, Vec3(particle.pos, 1)));
|
//////////////////////////////
|
||||||
b32 is_in_world_bounds = cell_pos.x >= 0 && cell_pos.y >= 0 && cell_pos.x < countof(stains).x && cell_pos.y < countof(stains).y;
|
//- Simulate particle
|
||||||
|
|
||||||
|
f32 prev_exists = particle.exists;
|
||||||
|
{
|
||||||
|
Vec2 cell_pos = mul(params.af.world_to_cell, Vec3(particle.pos, 1));
|
||||||
|
b32 is_in_world = all(cell_pos >= 0) && all(cell_pos < countof(cells));
|
||||||
|
|
||||||
// Simulate
|
// Simulate
|
||||||
f32 old_exists = particle.exists;
|
|
||||||
{
|
{
|
||||||
particle.pos += particle.velocity * params.dt;
|
particle.pos += particle.velocity * params.dt;
|
||||||
particle.velocity = lerp(particle.velocity, 0, particle.velocity_falloff * params.dt);
|
particle.velocity = lerp(particle.velocity, 0, particle.velocity_falloff * params.dt);
|
||||||
@ -435,23 +230,31 @@ ComputeShader(V_SimParticlesCS, 64)
|
|||||||
{
|
{
|
||||||
particle.exists = 0;
|
particle.exists = 0;
|
||||||
}
|
}
|
||||||
if (!is_in_world_bounds)
|
|
||||||
{
|
|
||||||
particle.exists = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Commit
|
//////////////////////////////
|
||||||
|
//- Commit particle
|
||||||
|
|
||||||
// FIXME: Atomic writes
|
// FIXME: Atomic writes
|
||||||
|
|
||||||
{
|
{
|
||||||
b32 should_stain = is_in_world_bounds && (
|
Vec2 cell_pos = mul(params.af.world_to_cell, Vec3(particle.pos, 1));
|
||||||
|
Vec2 screen_pos = mul(params.af.world_to_screen, Vec3(particle.pos, 1));
|
||||||
|
b32 is_in_world = all(cell_pos >= 0) && all(cell_pos < countof(cells));
|
||||||
|
b32 is_in_screen = all(screen_pos >= 0) && all(screen_pos < params.screen_dims);
|
||||||
|
|
||||||
|
Vec4 color = particle.color;
|
||||||
|
color.a *= prev_exists;
|
||||||
|
|
||||||
|
// Stain
|
||||||
|
if (is_in_world)
|
||||||
|
{
|
||||||
|
b32 should_stain = (
|
||||||
AnyBit(particle.flags, V_ParticleFlag_StainTrail) ||
|
AnyBit(particle.flags, V_ParticleFlag_StainTrail) ||
|
||||||
(AnyBit(particle.flags, V_ParticleFlag_StainOnPrune) && particle.exists == 0)
|
(AnyBit(particle.flags, V_ParticleFlag_StainOnPrune) && particle.exists == 0)
|
||||||
);
|
);
|
||||||
b32 should_draw = is_in_world_bounds;
|
|
||||||
|
|
||||||
Vec4 color = particle.color;
|
|
||||||
color.a *= old_exists;
|
|
||||||
|
|
||||||
// Stain
|
// Stain
|
||||||
if (should_stain)
|
if (should_stain)
|
||||||
@ -469,13 +272,19 @@ ComputeShader(V_SimParticlesCS, 64)
|
|||||||
stains[cell_pos] = new_stain;
|
stains[cell_pos] = new_stain;
|
||||||
drynesses[cell_pos] = 0;
|
drynesses[cell_pos] = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
|
{
|
||||||
|
b32 should_draw = is_in_world;
|
||||||
|
|
||||||
if (should_draw)
|
if (should_draw)
|
||||||
{
|
{
|
||||||
cells[cell_pos] = color;
|
cells[cell_pos] = color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
particles[particle_idx] = particle;
|
particles[particle_idx] = particle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -488,7 +297,7 @@ ComputeShader2D(V_ShadeCS, 8, 8)
|
|||||||
{
|
{
|
||||||
V_GpuParams params = G_Dereference<V_GpuParams>(V_ShaderConst_Params)[0];
|
V_GpuParams params = G_Dereference<V_GpuParams>(V_ShaderConst_Params)[0];
|
||||||
RWTexture2D<Vec4> shade_tex = G_Dereference<Vec4>(params.shade_rw);
|
RWTexture2D<Vec4> shade_tex = G_Dereference<Vec4>(params.shade_rw);
|
||||||
// Texture2D<Vec4> albedo_tex = G_Dereference<Vec4>(params.albedo_ro);
|
Texture2D<Vec4> albedo_tex = G_Dereference<Vec4>(params.albedo_ro);
|
||||||
Texture2D<P_TileKind> tiles = G_Dereference<P_TileKind>(params.tiles);
|
Texture2D<P_TileKind> tiles = G_Dereference<P_TileKind>(params.tiles);
|
||||||
RWTexture2D<Vec4> stains = G_Dereference<Vec4>(params.stains);
|
RWTexture2D<Vec4> stains = G_Dereference<Vec4>(params.stains);
|
||||||
RWTexture2D<f32> drynesses = G_Dereference<f32>(params.drynesses);
|
RWTexture2D<f32> drynesses = G_Dereference<f32>(params.drynesses);
|
||||||
@ -496,13 +305,13 @@ ComputeShader2D(V_ShadeCS, 8, 8)
|
|||||||
|
|
||||||
Vec2 shade_pos = SV_DispatchThreadID + Vec2(0.5, 0.5);
|
Vec2 shade_pos = SV_DispatchThreadID + Vec2(0.5, 0.5);
|
||||||
Vec2 world_pos = mul(params.af.shade_to_world, Vec3(shade_pos, 1));
|
Vec2 world_pos = mul(params.af.shade_to_world, Vec3(shade_pos, 1));
|
||||||
Vec2 cell_pos = floor(mul(params.af.world_to_cell, Vec3(world_pos, 1)));
|
Vec2 cell_pos = mul(params.af.world_to_cell, Vec3(world_pos, 1));
|
||||||
Vec2 tile_pos = mul(params.af.world_to_tile, Vec3(world_pos, 1));
|
Vec2 tile_pos = mul(params.af.world_to_tile, Vec3(world_pos, 1));
|
||||||
|
|
||||||
P_TileKind tile = tiles.Load(Vec3(tile_pos, 0));
|
P_TileKind tile = tiles.Load(Vec3(tile_pos, 0));
|
||||||
|
|
||||||
Vec2 half_world_dims = Vec2(P_WorldPitch, P_WorldPitch) * 0.5;
|
Vec2 half_world_dims = Vec2(P_WorldPitch, P_WorldPitch) * 0.5;
|
||||||
b32 is_in_world_bounds = all(world_pos > -half_world_dims) && all(world_pos < half_world_dims);
|
b32 is_in_world = all(cell_pos >= 0) && all(cell_pos < countof(stains));
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Compute albedo
|
//- Compute albedo
|
||||||
@ -543,7 +352,7 @@ VertexShader(V_CompositeVS, V_CompositePSInput)
|
|||||||
PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input)
|
PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input)
|
||||||
{
|
{
|
||||||
V_GpuParams params = G_Dereference<V_GpuParams>(V_ShaderConst_Params)[0];
|
V_GpuParams params = G_Dereference<V_GpuParams>(V_ShaderConst_Params)[0];
|
||||||
Texture2D<Vec4> shade_tex = G_Dereference<Vec4>(params.shade_ro);
|
// Texture2D<Vec4> shade_tex = G_Dereference<Vec4>(params.shade_ro);
|
||||||
Texture2D<Vec4> albedo_tex = G_Dereference<Vec4>(params.albedo_ro);
|
Texture2D<Vec4> albedo_tex = G_Dereference<Vec4>(params.albedo_ro);
|
||||||
RWTexture2D<Vec4> stains = G_Dereference<Vec4>(params.stains);
|
RWTexture2D<Vec4> stains = G_Dereference<Vec4>(params.stains);
|
||||||
RWTexture2D<Vec4> cells = G_Dereference<Vec4>(params.cells);
|
RWTexture2D<Vec4> cells = G_Dereference<Vec4>(params.cells);
|
||||||
@ -554,27 +363,27 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input)
|
|||||||
Vec2 screen_pos = input.sv_position.xy;
|
Vec2 screen_pos = input.sv_position.xy;
|
||||||
Vec2 world_pos = mul(params.af.screen_to_world, Vec3(screen_pos, 1));
|
Vec2 world_pos = mul(params.af.screen_to_world, Vec3(screen_pos, 1));
|
||||||
Vec2 tile_pos = mul(params.af.world_to_tile, Vec3(world_pos, 1));
|
Vec2 tile_pos = mul(params.af.world_to_tile, Vec3(world_pos, 1));
|
||||||
Vec2 cell_pos = floor(mul(params.af.world_to_cell, Vec3(world_pos, 1)));
|
Vec2 cell_pos = mul(params.af.world_to_cell, Vec3(world_pos, 1));
|
||||||
Vec2 shade_pos = mul(params.af.screen_to_shade, Vec3(screen_pos.xy, 1));
|
Vec2 shade_pos = mul(params.af.screen_to_shade, Vec3(screen_pos.xy, 1));
|
||||||
|
|
||||||
f32 half_thickness = 1;
|
|
||||||
Vec2 half_world_dims = Vec2(P_WorldPitch, P_WorldPitch) * 0.5;
|
Vec2 half_world_dims = Vec2(P_WorldPitch, P_WorldPitch) * 0.5;
|
||||||
Vec2 world_bounds_screen_p0 = mul(params.af.world_to_screen, Vec3(-half_world_dims.xy, 1));
|
Vec2 world_bounds_screen_p0 = mul(params.af.world_to_screen, Vec3(-half_world_dims.xy, 1));
|
||||||
Vec2 world_bounds_screen_p1 = mul(params.af.world_to_screen, Vec3(half_world_dims.xy, 1));
|
Vec2 world_bounds_screen_p1 = mul(params.af.world_to_screen, Vec3(half_world_dims.xy, 1));
|
||||||
b32 is_in_world_bounds = (
|
b32 is_in_world = all(cell_pos >= 0) && all(cell_pos < countof(cells));
|
||||||
screen_pos.x > (world_bounds_screen_p0.x - half_thickness) &&
|
|
||||||
screen_pos.y > (world_bounds_screen_p0.y - half_thickness) &&
|
|
||||||
screen_pos.x < (world_bounds_screen_p1.x + half_thickness) &&
|
|
||||||
screen_pos.y < (world_bounds_screen_p1.y + half_thickness)
|
|
||||||
);
|
|
||||||
|
|
||||||
P_TileKind tile = tiles.Load(Vec3(tile_pos, 0));
|
P_TileKind tile = tiles.Load(Vec3(tile_pos, 0));
|
||||||
P_TileKind equipped_tile = params.equipped_tile;
|
P_TileKind equipped_tile = params.equipped_tile;
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
//- World color
|
||||||
|
|
||||||
|
Vec4 world_color = Vec4(0.025, 0.025, 0.025, 1);
|
||||||
|
if (is_in_world)
|
||||||
|
{
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Shade color
|
//- Shade color
|
||||||
|
|
||||||
// Vec4 shade_color = 0;
|
Vec4 shade_color = 0;
|
||||||
// if (all(shade_pos >= Vec2(0, 0)) && all(shade_pos < countof(shade_tex)))
|
// if (all(shade_pos >= Vec2(0, 0)) && all(shade_pos < countof(shade_tex)))
|
||||||
// {
|
// {
|
||||||
// Vec2 shade_uv = shade_pos / countof(shade_tex);
|
// Vec2 shade_uv = shade_pos / countof(shade_tex);
|
||||||
@ -582,18 +391,17 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input)
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Albedo color
|
//- Albedo
|
||||||
|
|
||||||
Vec4 albedo_color = 0;
|
Vec4 albedo_color = 0;
|
||||||
{
|
{
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Tile color
|
//- Tile
|
||||||
|
|
||||||
// TODO: Remove this
|
// TODO: Remove this
|
||||||
|
|
||||||
b32 tile_is_wall = 0;
|
b32 tile_is_wall = 0;
|
||||||
Vec4 tile_color = Vec4(0.025, 0.025, 0.025, 1);
|
Vec4 tile_color = 0;
|
||||||
if (is_in_world_bounds)
|
|
||||||
{
|
{
|
||||||
P_TileKind tile_tl = tiles.Load(Vec3(tile_pos.x - 1, tile_pos.y - 1, 0));
|
P_TileKind tile_tl = tiles.Load(Vec3(tile_pos.x - 1, tile_pos.y - 1, 0));
|
||||||
P_TileKind tile_tr = tiles.Load(Vec3(tile_pos.x + 1, tile_pos.y - 1, 0));
|
P_TileKind tile_tr = tiles.Load(Vec3(tile_pos.x + 1, tile_pos.y - 1, 0));
|
||||||
@ -620,7 +428,6 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input)
|
|||||||
Vec4 outer = LinearFromSrgb(Vec4(0.05, 0.05, 0.05, 1));
|
Vec4 outer = LinearFromSrgb(Vec4(0.05, 0.05, 0.05, 1));
|
||||||
Vec4 inner = LinearFromSrgb(Vec4(0.15, 0.15, 0.15, 1));
|
Vec4 inner = LinearFromSrgb(Vec4(0.15, 0.15, 0.15, 1));
|
||||||
tile_color = lerp(outer, inner, smoothstep(0, 1, tile_edge_dist / 0.375));
|
tile_color = lerp(outer, inner, smoothstep(0, 1, tile_edge_dist / 0.375));
|
||||||
// tile_color = lerp(outer, inner, smoothstep(0, 1, tile_edge_dist / 0.5));
|
|
||||||
tile_is_wall = 1;
|
tile_is_wall = 1;
|
||||||
}
|
}
|
||||||
else if (tile != P_TileKind_Empty)
|
else if (tile != P_TileKind_Empty)
|
||||||
@ -661,12 +468,13 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Stain color
|
//- Stain
|
||||||
|
|
||||||
Vec4 stain_color = 0;
|
Vec4 stain_color = 0;
|
||||||
{
|
{
|
||||||
f32 dryness = drynesses.Load(cell_pos);
|
f32 dryness = drynesses.Load(cell_pos);
|
||||||
stain_color = V_DryColor(stains.Load(cell_pos), dryness);
|
Vec4 stain = stains.Load(cell_pos);
|
||||||
|
stain_color = V_DryColor(stain, dryness);
|
||||||
stain_color.rgb *= 1.0 - (0.75 * tile_is_wall); // Darken wall stains
|
stain_color.rgb *= 1.0 - (0.75 * tile_is_wall); // Darken wall stains
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -678,24 +486,41 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input)
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Compose albedo
|
//- Compose albedo
|
||||||
|
|
||||||
albedo_color = BlendPremul(!tile_is_wall * tile_color, albedo_color); // Blend floor tile
|
if (!tile_is_wall)
|
||||||
albedo_color = BlendPremul(!tile_is_wall * stain_color, albedo_color); // Blend floor stain
|
{
|
||||||
|
albedo_color = BlendPremul(tile_color, albedo_color); // Blend floor tile
|
||||||
|
albedo_color = BlendPremul(stain_color, albedo_color); // Blend floor stain
|
||||||
|
}
|
||||||
albedo_color = BlendPremul(albedo_tex_color, albedo_color);
|
albedo_color = BlendPremul(albedo_tex_color, albedo_color);
|
||||||
albedo_color = BlendPremul(tile_is_wall * tile_color, albedo_color); // Blend wall tile
|
if (tile_is_wall)
|
||||||
albedo_color = BlendPremul(tile_is_wall * stain_color, albedo_color); // Blend wall stain
|
{
|
||||||
|
albedo_color = BlendPremul(tile_color, albedo_color); // Blend wall tile
|
||||||
|
albedo_color = BlendPremul(stain_color, albedo_color); // Blend wall stain
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Particle color
|
//- Particle
|
||||||
|
|
||||||
// TODO: Remove this
|
// TODO: Remove this
|
||||||
|
|
||||||
Vec4 particle_color = 0;
|
Vec4 particle_color = cells.Load(cell_pos);
|
||||||
if (is_in_world_bounds)
|
|
||||||
{
|
//////////////////////////////
|
||||||
particle_color = cells.Load(cell_pos);
|
//- Compose world
|
||||||
|
|
||||||
|
// world_color = BlendPremul(shade_color, world_color);
|
||||||
|
world_color = BlendPremul(albedo_color, world_color);
|
||||||
|
world_color = BlendPremul(particle_color, world_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
//- Overlay color
|
||||||
|
|
||||||
|
Vec4 overlay_color = 0;
|
||||||
|
{
|
||||||
|
f32 half_thickness = 1;
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Tile selection overlay
|
//- Tile selection overlay
|
||||||
|
|
||||||
@ -749,7 +574,7 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input)
|
|||||||
//- Grid
|
//- Grid
|
||||||
|
|
||||||
Vec4 grid_color = 0;
|
Vec4 grid_color = 0;
|
||||||
if (is_in_world_bounds)
|
if (is_in_world)
|
||||||
{
|
{
|
||||||
// Grid outline
|
// Grid outline
|
||||||
if (V_ShaderConst_GpuFlags & V_GpuFlag_DebugDraw)
|
if (V_ShaderConst_GpuFlags & V_GpuFlag_DebugDraw)
|
||||||
@ -808,40 +633,43 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input)
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Crosshair
|
//- Crosshair
|
||||||
|
|
||||||
|
// TODO: Remove this
|
||||||
|
|
||||||
Vec4 crosshair_color = 0;
|
Vec4 crosshair_color = 0;
|
||||||
{
|
{
|
||||||
f32 screen_dist = length(params.screen_crosshair - screen_pos);
|
f32 dist = length(params.screen_crosshair - screen_pos);
|
||||||
|
if (dist < 4)
|
||||||
if (screen_dist < 5)
|
{
|
||||||
|
// Adaptive crosshair color based on underlying luminance
|
||||||
|
f32 world_luminance = LuminanceFromColor(world_color);
|
||||||
|
f32 adaptive_threshold = 0.5;
|
||||||
|
Vec4 adapted_crosshair_color = crosshair_color;
|
||||||
|
if (world_luminance <= adaptive_threshold)
|
||||||
{
|
{
|
||||||
crosshair_color = Color_White;
|
crosshair_color = Color_White;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
crosshair_color.rgb *= crosshair_color.a;
|
{
|
||||||
|
crosshair_color = InvertColor(Color_White);
|
||||||
|
}
|
||||||
|
crosshair_color = Premul(crosshair_color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Blend
|
//- Compose overlay
|
||||||
|
|
||||||
|
overlay_color = BlendPremul(selection_color, overlay_color);
|
||||||
|
overlay_color = BlendPremul(grid_color, overlay_color);
|
||||||
|
overlay_color = BlendPremul(crosshair_color, overlay_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
//- Compose result
|
||||||
|
|
||||||
Vec4 result = Vec4(0, 0, 0, 1);
|
Vec4 result = Vec4(0, 0, 0, 1);
|
||||||
// result = BlendPremul(shade_color, result);
|
result = BlendPremul(world_color, result);
|
||||||
result = BlendPremul(albedo_color, result);
|
result = BlendPremul(overlay_color, result);
|
||||||
result = BlendPremul(particle_color, result);
|
|
||||||
result = BlendPremul(selection_color, result);
|
|
||||||
result = BlendPremul(grid_color, result);
|
|
||||||
|
|
||||||
// Adaptively blend crosshair
|
|
||||||
{
|
|
||||||
f32 luminance = LuminanceFromColor(result);
|
|
||||||
f32 adaptive_threshold = 0.5;
|
|
||||||
Vec4 adapted_crosshair_color = crosshair_color;
|
|
||||||
if (luminance > adaptive_threshold)
|
|
||||||
{
|
|
||||||
adapted_crosshair_color = InvertColor(Unpremul(crosshair_color));
|
|
||||||
adapted_crosshair_color = Premul(adapted_crosshair_color);
|
|
||||||
}
|
|
||||||
result = BlendPremul(adapted_crosshair_color, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
result = Unpremul(result);
|
result = Unpremul(result);
|
||||||
|
|
||||||
|
|||||||
@ -430,6 +430,7 @@ void SPR_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame)
|
|||||||
G_Format_R8G8B8A8_Unorm_Srgb,
|
G_Format_R8G8B8A8_Unorm_Srgb,
|
||||||
atlas->dims,
|
atlas->dims,
|
||||||
G_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present,
|
G_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present,
|
||||||
|
.debug = Lit("Sprite atlas")
|
||||||
);
|
);
|
||||||
atlas->tex_ref = G_PushTexture2DRef(gpu_perm, atlas->tex);
|
atlas->tex_ref = G_PushTexture2DRef(gpu_perm, atlas->tex);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -89,7 +89,6 @@ typedef struct DWRITE_FONT_METRICS {
|
|||||||
UINT16 strikethroughThickness;
|
UINT16 strikethroughThickness;
|
||||||
} DWRITE_FONT_METRICS;
|
} DWRITE_FONT_METRICS;
|
||||||
|
|
||||||
|
|
||||||
typedef enum DWRITE_GRID_FIT_MODE {
|
typedef enum DWRITE_GRID_FIT_MODE {
|
||||||
DWRITE_GRID_FIT_MODE_DEFAULT = 0,
|
DWRITE_GRID_FIT_MODE_DEFAULT = 0,
|
||||||
DWRITE_GRID_FIT_MODE_DISABLED = 1,
|
DWRITE_GRID_FIT_MODE_DISABLED = 1,
|
||||||
|
|||||||
@ -1670,13 +1670,18 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
|
|||||||
G_Format_R16G16B16A16_Float,
|
G_Format_R16G16B16A16_Float,
|
||||||
monitor_size,
|
monitor_size,
|
||||||
G_Layout_DirectQueue_RenderTargetWrite,
|
G_Layout_DirectQueue_RenderTargetWrite,
|
||||||
.flags = G_ResourceFlag_AllowRenderTarget
|
.flags = G_ResourceFlag_AllowRenderTarget,
|
||||||
|
.debug = Lit("UI draw target")
|
||||||
);
|
);
|
||||||
G_Texture2DRef draw_target_ro = G_PushTexture2DRef(frame->gpu_arena, draw_target);
|
G_Texture2DRef draw_target_ro = G_PushTexture2DRef(frame->gpu_arena, draw_target);
|
||||||
|
|
||||||
// Rects
|
// Rects
|
||||||
u64 rects_count = ArenaCount(frame->rects_arena, UI_GpuRect);
|
u64 rects_count = ArenaCount(frame->rects_arena, UI_GpuRect);
|
||||||
G_ResourceHandle rects_buff = G_PushBufferFromCpuCopy(frame->gpu_arena, frame->cl, StringFromArena(frame->rects_arena));
|
G_ResourceHandle rects_buff = G_PushBufferFromCpuCopy(
|
||||||
|
frame->gpu_arena, frame->cl,
|
||||||
|
StringFromArena(frame->rects_arena),
|
||||||
|
.debug = Lit("UI rects")
|
||||||
|
);
|
||||||
G_StructuredBufferRef rects_ro = G_PushStructuredBufferRef(frame->gpu_arena, rects_buff, UI_GpuRect);
|
G_StructuredBufferRef rects_ro = G_PushStructuredBufferRef(frame->gpu_arena, rects_buff, UI_GpuRect);
|
||||||
|
|
||||||
// Params
|
// Params
|
||||||
@ -1689,7 +1694,11 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
|
|||||||
params.cursor_pos = frame->cursor_pos;
|
params.cursor_pos = frame->cursor_pos;
|
||||||
params.aa = TweakFloat("UI anti-aliasing", 1, 0, 1);
|
params.aa = TweakFloat("UI anti-aliasing", 1, 0, 1);
|
||||||
}
|
}
|
||||||
G_ResourceHandle params_buff = G_PushBufferFromCpuCopy(frame->gpu_arena, frame->cl, StringFromStruct(¶ms));
|
G_ResourceHandle params_buff = G_PushBufferFromCpuCopy(
|
||||||
|
frame->gpu_arena, frame->cl,
|
||||||
|
StringFromStruct(¶ms),
|
||||||
|
.debug = Lit("UI gpu params")
|
||||||
|
);
|
||||||
G_StructuredBufferRef params_ro = G_PushStructuredBufferRef(frame->gpu_arena, params_buff, UI_GpuParams);
|
G_StructuredBufferRef params_ro = G_PushStructuredBufferRef(frame->gpu_arena, params_buff, UI_GpuParams);
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user