blue noise testing
This commit is contained in:
parent
4aabab35e7
commit
05008ca5ab
@ -86,7 +86,8 @@ SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input)
|
|||||||
|
|
||||||
/* Texture */
|
/* Texture */
|
||||||
if (input.vs.tex_nurid >= 0) {
|
if (input.vs.tex_nurid >= 0) {
|
||||||
albedo *= g_textures[NURID(input.vs.tex_nurid)].Sample(g_sampler, input.vs.uv);
|
Texture2D<float4> tex = g_textures[NURID(input.vs.tex_nurid)];
|
||||||
|
albedo *= tex.Sample(g_sampler, input.vs.uv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Grid */
|
/* Grid */
|
||||||
|
|||||||
@ -18,6 +18,12 @@ INLINE struct sh_int sh_int_from_i32(i32 v)
|
|||||||
return (struct sh_int) { .v = v };
|
return (struct sh_int) { .v = v };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct sh_uint2 { u32 v[2]; };
|
||||||
|
INLINE struct sh_uint2 sh_uint2_from_u32(u32 a, u32 b)
|
||||||
|
{
|
||||||
|
return (struct sh_uint2) { .v[0] = a, .v[1] = b };
|
||||||
|
}
|
||||||
|
|
||||||
struct sh_float { f32 v; };
|
struct sh_float { f32 v; };
|
||||||
INLINE struct sh_float sh_float_from_f32(f32 v)
|
INLINE struct sh_float sh_float_from_f32(f32 v)
|
||||||
{
|
{
|
||||||
@ -64,6 +70,15 @@ INLINE struct sh_float2x3 sh_float2x3_from_xform(struct xform v)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Global textures
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
/* Blue noise */
|
||||||
|
#define SH_BLUE_NOISE_TEX_ID 0
|
||||||
|
#define SH_BLUE_NOISE_TEX_WIDTH 1024
|
||||||
|
#define SH_BLUE_NOISE_TEX_HEIGHT 1024
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Material shader structures
|
* Material shader structures
|
||||||
* ========================== */
|
* ========================== */
|
||||||
@ -114,7 +129,8 @@ SH_ASSERT_32BIT(struct sh_flood_constants, 6); /* Expected 32bit root constant
|
|||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
SH_STRUCT(sh_shade_constants {
|
SH_STRUCT(sh_shade_constants {
|
||||||
SH_DECL(uint, tick);
|
SH_DECL(float2, camera_offset);
|
||||||
|
SH_DECL(uint2, seed);
|
||||||
SH_DECL(uint, albedo_tex_urid);
|
SH_DECL(uint, albedo_tex_urid);
|
||||||
SH_DECL(uint, emittance_tex_urid);
|
SH_DECL(uint, emittance_tex_urid);
|
||||||
SH_DECL(uint, emittance_flood_tex_urid);
|
SH_DECL(uint, emittance_flood_tex_urid);
|
||||||
@ -124,7 +140,7 @@ SH_STRUCT(sh_shade_constants {
|
|||||||
SH_DECL(float, exposure);
|
SH_DECL(float, exposure);
|
||||||
SH_DECL(float, gamma);
|
SH_DECL(float, gamma);
|
||||||
});
|
});
|
||||||
SH_ASSERT_32BIT(struct sh_shade_constants, 9); /* Expected 32bit root constant size in shader */
|
SH_ASSERT_32BIT(struct sh_shade_constants, 12); /* Expected 32bit root constant size in shader */
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Shape shader structures
|
* Shape shader structures
|
||||||
|
|||||||
@ -5,25 +5,24 @@
|
|||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
#define ROOTSIG \
|
#define ROOTSIG \
|
||||||
"RootConstants(num32BitConstants = 9, b0), " \
|
"RootConstants(num32BitConstants = 12, b0), " \
|
||||||
"DescriptorTable(SRV(t0, space = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
|
"DescriptorTable(SRV(t0, space = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
|
||||||
"DescriptorTable(SRV(t0, space = 1, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
|
"DescriptorTable(SRV(t0, space = 1, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
|
||||||
"DescriptorTable(UAV(u0, space = 2, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
|
"DescriptorTable(UAV(u0, space = 2, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
|
||||||
\
|
\
|
||||||
\
|
|
||||||
"StaticSampler(s0, " \
|
"StaticSampler(s0, " \
|
||||||
"filter = FILTER_MIN_MAG_MIP_POINT, " \
|
"filter = FILTER_MIN_MAG_MIP_POINT, " \
|
||||||
"addressU = TEXTURE_ADDRESS_CLAMP, " \
|
"addressU = TEXTURE_ADDRESS_WRAP, " \
|
||||||
"addressV = TEXTURE_ADDRESS_CLAMP, " \
|
"addressV = TEXTURE_ADDRESS_WRAP, " \
|
||||||
"addressW = TEXTURE_ADDRESS_CLAMP, " \
|
"addressW = TEXTURE_ADDRESS_WRAP, " \
|
||||||
"maxAnisotropy = 1)"
|
"maxAnisotropy = 1)"
|
||||||
|
|
||||||
ConstantBuffer<struct sh_shade_constants> g_constants : register(b0);
|
ConstantBuffer<struct sh_shade_constants> g_constants : register(b0);
|
||||||
Texture2D<float4> g_gbuff_textures[] : register(t0, space0);
|
Texture2D<float4> g_textures_float4[] : register(t0, space0);
|
||||||
Texture2D<uint2> g_emittance_flood_textures[] : register(t0, space1);
|
Texture2D<uint2> g_textures_uint2[] : register(t0, space1);
|
||||||
RWTexture2D<float4> g_write_textures[]: register(u0, space2);
|
RWTexture2D<float4> g_write_textures[]: register(u0, space2);
|
||||||
|
|
||||||
SamplerState g_sampler : register(s0);
|
SamplerState g_noise_sampler : register(s0);
|
||||||
|
|
||||||
struct cs_input {
|
struct cs_input {
|
||||||
DECLS(uint3, SV_DispatchThreadID);
|
DECLS(uint3, SV_DispatchThreadID);
|
||||||
@ -33,14 +32,22 @@ struct cs_input {
|
|||||||
* Lighting
|
* Lighting
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
#define SAMPLES 4
|
#define SAMPLES 8
|
||||||
#define MARCHES 16
|
#define MARCHES 16
|
||||||
#define AMBIENT float4(0, 0, 0, 0)
|
#define AMBIENT float4(0, 0, 0, 0)
|
||||||
|
|
||||||
|
float rand_float_from_float2(float2 pos) {
|
||||||
|
// pos += uint2(g_constants.seed.x % g_constants.tex_width, g_constants.seed.x % g_constants.tex_height);
|
||||||
|
Texture2D<float4> noise_tex = g_textures_float4[SH_BLUE_NOISE_TEX_ID];
|
||||||
|
float2 uv = pos / float2(SH_BLUE_NOISE_TEX_WIDTH, SH_BLUE_NOISE_TEX_HEIGHT);
|
||||||
|
float4 v = noise_tex.SampleLevel(g_noise_sampler, uv, 0);
|
||||||
|
return v.r;
|
||||||
|
}
|
||||||
|
|
||||||
INLINE float4 get_light_in_dir(uint2 ray_start, float2 ray_dir)
|
INLINE float4 get_light_in_dir(uint2 ray_start, float2 ray_dir)
|
||||||
{
|
{
|
||||||
Texture2D<uint2> flood_tex = g_emittance_flood_textures[g_constants.emittance_flood_tex_urid];
|
Texture2D<uint2> flood_tex = g_textures_uint2[g_constants.emittance_flood_tex_urid];
|
||||||
Texture2D<float4> emittance_tex = g_gbuff_textures[g_constants.emittance_tex_urid];
|
Texture2D<float4> emittance_tex = g_textures_float4[g_constants.emittance_tex_urid];
|
||||||
|
|
||||||
float4 result = AMBIENT;
|
float4 result = AMBIENT;
|
||||||
float2 at_float = ray_start;
|
float2 at_float = ray_start;
|
||||||
@ -49,7 +56,7 @@ INLINE float4 get_light_in_dir(uint2 ray_start, float2 ray_dir)
|
|||||||
uint2 flood = flood_tex[at_uint];
|
uint2 flood = flood_tex[at_uint];
|
||||||
float2 dist_vec = at_float - (float2)flood;
|
float2 dist_vec = at_float - (float2)flood;
|
||||||
float dist = length(dist_vec);
|
float dist = length(dist_vec);
|
||||||
if (dist <= 1) {
|
if (dist < 1) {
|
||||||
result = emittance_tex[flood];
|
result = emittance_tex[flood];
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
@ -64,15 +71,15 @@ INLINE float4 get_light_in_dir(uint2 ray_start, float2 ray_dir)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
float rand_float_from_float2(float2 pos) {
|
|
||||||
return frac(sin(dot(pos.xy, float2(12.9898,78.233))) * 43758.5453123);
|
|
||||||
}
|
|
||||||
|
|
||||||
INLINE float4 get_light_at_pos(uint2 pos)
|
INLINE float4 get_light_at_pos(uint2 pos)
|
||||||
{
|
{
|
||||||
float4 result = 0;
|
float4 result = 0;
|
||||||
for (int i = 0; i < SAMPLES; ++i) {
|
for (uint i = 0; i < SAMPLES; ++i) {
|
||||||
float angle = TAU * (((float)i + rand_float_from_float2(pos + (float)i)) / ((float)SAMPLES - 1));
|
float angle = ((((float)i + rand_float_from_float2((float2)pos + (float)i)) / SAMPLES)) * TAU;
|
||||||
|
|
||||||
|
// float angle = (rand_float_from_float2(pos)) * TAU;
|
||||||
|
// float angle = (((float)i / SAMPLES)) * TAU;
|
||||||
|
// float angle = (rand_float_from_float2(pos)) * TAU;
|
||||||
float2 dir = float2(cos(angle), sin(angle));
|
float2 dir = float2(cos(angle), sin(angle));
|
||||||
float4 light_in_dir = get_light_in_dir(pos, dir);
|
float4 light_in_dir = get_light_in_dir(pos, dir);
|
||||||
result += light_in_dir;
|
result += light_in_dir;
|
||||||
@ -105,19 +112,22 @@ SH_ENTRY(ROOTSIG) void cs(struct cs_input input)
|
|||||||
return; /* Overflow */
|
return; /* Overflow */
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture2D<float4> albedo_tex = g_gbuff_textures[g_constants.albedo_tex_urid];
|
Texture2D<float4> albedo_tex = g_textures_float4[g_constants.albedo_tex_urid];
|
||||||
RWTexture2D<float4> write_tex = g_write_textures[g_constants.write_tex_urid];
|
RWTexture2D<float4> write_tex = g_write_textures[g_constants.write_tex_urid];
|
||||||
|
|
||||||
float4 albedo = albedo_tex[id];
|
float4 color = float4(1, 1, 1, 1);
|
||||||
float4 lighting = get_light_at_pos(id);
|
|
||||||
float4 color = albedo * lighting;
|
|
||||||
|
|
||||||
/* Tone map */
|
/* Apply albedo */
|
||||||
|
color *= albedo_tex[id];
|
||||||
|
|
||||||
|
/* Apply lighting */
|
||||||
|
color *= get_light_at_pos(id);
|
||||||
|
|
||||||
|
/* Apply tone map */
|
||||||
/* TODO: Dynamic exposure based on average scene luminance */
|
/* TODO: Dynamic exposure based on average scene luminance */
|
||||||
color *= g_constants.exposure;
|
color.rgb = tone_map(color.rgb) * g_constants.exposure;
|
||||||
color.rgb = tone_map(color.rgb);
|
|
||||||
|
|
||||||
/* Gamma correct */
|
/* Apply gamma correction */
|
||||||
color = pow(abs(color), 1/g_constants.gamma);
|
color = pow(abs(color), 1/g_constants.gamma);
|
||||||
|
|
||||||
write_tex[id] = color;
|
write_tex[id] = color;
|
||||||
|
|||||||
BIN
res/sprite/noise.ase
(Stored with Git LFS)
Normal file
BIN
res/sprite/noise.ase
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
res/sprite/tile.ase
(Stored with Git LFS)
BIN
res/sprite/tile.ase
(Stored with Git LFS)
Binary file not shown.
13
src/ase.c
13
src/ase.c
@ -269,7 +269,14 @@ INTERNAL void inflate(u8 *dst, u8 *encoded)
|
|||||||
u8 btype = consume_bits(&bb, 2);
|
u8 btype = consume_bits(&bb, 2);
|
||||||
switch (btype) {
|
switch (btype) {
|
||||||
case BLOCK_TYPE_UNCOMPRESSED: {
|
case BLOCK_TYPE_UNCOMPRESSED: {
|
||||||
sys_panic(LIT("Unsupported block type while inflating ase: BLOCK_TYPE_UNCOMPRESSED"));
|
skip_bits(&bb, (8 - (bb.cur_bit % 8)) % 8);
|
||||||
|
i16 len = consume_bits(&bb, 16);
|
||||||
|
i16 nlen = consume_bits(&bb, 16);
|
||||||
|
ASSERT(len == ~nlen); /* Validation */
|
||||||
|
(UNUSED)nlen;
|
||||||
|
while (len-- > 0) {
|
||||||
|
*dst++ = consume_bits(&bb, 8);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case BLOCK_TYPE_COMPRESSED_FIXED:
|
case BLOCK_TYPE_COMPRESSED_FIXED:
|
||||||
@ -361,9 +368,9 @@ INTERNAL void inflate(u8 *dst, u8 *encoded)
|
|||||||
u32 extra_bits = consume_bits(&bb, dist_entry.bits_used);
|
u32 extra_bits = consume_bits(&bb, dist_entry.bits_used);
|
||||||
distance += extra_bits;
|
distance += extra_bits;
|
||||||
}
|
}
|
||||||
u8 *source = dst - distance;
|
u8 *src = dst - distance;
|
||||||
while (length--) {
|
while (length--) {
|
||||||
*dst++ = *source++;
|
*dst++ = *src++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
|||||||
13
src/common.h
13
src/common.h
@ -189,15 +189,15 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t);
|
|||||||
#define INLINE static inline
|
#define INLINE static inline
|
||||||
|
|
||||||
#if COMPILER_MSVC
|
#if COMPILER_MSVC
|
||||||
# define FORCE_INLINE static inline __forceinline
|
# define FORCE_INLINE inline __forceinline
|
||||||
#else
|
#else
|
||||||
# define FORCE_INLINE static inline __attribute((always_inline))
|
# define FORCE_INLINE inline __attribute((always_inline))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if COMPILER_MSVC
|
#if COMPILER_MSVC
|
||||||
# define NO_INLINE __declspec(noinline)
|
# define FORCE_NO_INLINE __declspec(noinline)
|
||||||
#else
|
#else
|
||||||
# define NO_INLINE __attribute__((noinline))
|
# define FORCE_NO_INLINE __attribute__((noinline))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Separate `static` usage into different keywords for easier grepping */
|
/* Separate `static` usage into different keywords for easier grepping */
|
||||||
@ -578,6 +578,11 @@ struct v2i32 {
|
|||||||
i32 x, y;
|
i32 x, y;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define V3I32(x, y, z) CPPCOMPAT_INITLIST_TYPE(struct v3i32) { (x), (y), (z) }
|
||||||
|
struct v3i32 {
|
||||||
|
i32 x, y, z;
|
||||||
|
};
|
||||||
|
|
||||||
struct xform {
|
struct xform {
|
||||||
struct v2 bx; /* X basis vector (x axis) */
|
struct v2 bx; /* X basis vector (x axis) */
|
||||||
struct v2 by; /* Y basis vector (y axis)*/
|
struct v2 by; /* Y basis vector (y axis)*/
|
||||||
|
|||||||
1
src/gp.h
1
src/gp.h
@ -34,6 +34,7 @@ void gp_resource_release(struct gp_resource *resource);
|
|||||||
|
|
||||||
enum gp_texture_format {
|
enum gp_texture_format {
|
||||||
GP_TEXTURE_FORMAT_NONE,
|
GP_TEXTURE_FORMAT_NONE,
|
||||||
|
GP_TEXTURE_FORMAT_R8_UNORM,
|
||||||
GP_TEXTURE_FORMAT_R8G8B8A8_UNORM,
|
GP_TEXTURE_FORMAT_R8G8B8A8_UNORM,
|
||||||
GP_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB,
|
GP_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB,
|
||||||
GP_TEXTURE_FORMAT_R16G16B16A16_FLOAT,
|
GP_TEXTURE_FORMAT_R16G16B16A16_FLOAT,
|
||||||
|
|||||||
171
src/gp_dx12.c
171
src/gp_dx12.c
@ -12,6 +12,7 @@
|
|||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
#include "gstat.h"
|
#include "gstat.h"
|
||||||
#include "snc.h"
|
#include "snc.h"
|
||||||
|
#include "ase.h"
|
||||||
|
|
||||||
/* Include common shader types */
|
/* Include common shader types */
|
||||||
#define SH_CPU 1
|
#define SH_CPU 1
|
||||||
@ -72,6 +73,10 @@
|
|||||||
# define DX12_SHADER_DEBUG 0
|
# define DX12_SHADER_DEBUG 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Internal structs
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
struct shader_desc {
|
struct shader_desc {
|
||||||
struct string file;
|
struct string file;
|
||||||
struct string func;
|
struct string func;
|
||||||
@ -276,6 +281,41 @@ struct fenced_release_data {
|
|||||||
void *ptr;
|
void *ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Internal procs
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
INTERNAL SYS_EXIT_FUNC(gp_shutdown);
|
||||||
|
|
||||||
|
INTERNAL void dx12_init_device(void);
|
||||||
|
|
||||||
|
INTERNAL void dx12_init_objects(void);
|
||||||
|
|
||||||
|
INTERNAL void dx12_init_pipelines(void);
|
||||||
|
|
||||||
|
INTERNAL void dx12_init_noise(void);
|
||||||
|
|
||||||
|
INTERNAL struct cpu_descriptor_heap *cpu_descriptor_heap_alloc(enum D3D12_DESCRIPTOR_HEAP_TYPE type);
|
||||||
|
|
||||||
|
INTERNAL void command_queue_release(struct command_queue *cq);
|
||||||
|
|
||||||
|
INTERNAL SYS_JOB_DEF(dx12_evictor_job, _);
|
||||||
|
|
||||||
|
INTERNAL void fenced_release(void *data, enum fenced_release_kind kind);
|
||||||
|
|
||||||
|
struct command_queue_alloc_job_sig { struct command_queue_desc *descs_in; struct command_queue **cqs_out; };
|
||||||
|
INTERNAL SYS_JOB_DEF(command_queue_alloc_job, job);
|
||||||
|
|
||||||
|
struct pipeline_alloc_job_sig { struct pipeline_desc *descs_in; struct pipeline **pipelines_out; };
|
||||||
|
INTERNAL SYS_JOB_DEF(pipeline_alloc_job, job);
|
||||||
|
|
||||||
|
struct dx12_upload_job_sig { struct dx12_resource *resource; void *data; };
|
||||||
|
INTERNAL SYS_JOB_DEF(dx12_upload_job, job);
|
||||||
|
|
||||||
|
#if RESOURCE_RELOADING
|
||||||
|
INTERNAL RESOURCE_WATCH_CALLBACK_FUNC_DEF(pipeline_resource_watch_callback, name);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Global state
|
* Global state
|
||||||
* ========================== */
|
* ========================== */
|
||||||
@ -351,25 +391,6 @@ GLOBAL struct {
|
|||||||
* Startup
|
* Startup
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
INTERNAL SYS_EXIT_FUNC(gp_shutdown);
|
|
||||||
INTERNAL void dx12_init_device(void);
|
|
||||||
INTERNAL void dx12_init_objects(void);
|
|
||||||
INTERNAL void dx12_init_pipelines(void);
|
|
||||||
INTERNAL struct cpu_descriptor_heap *cpu_descriptor_heap_alloc(enum D3D12_DESCRIPTOR_HEAP_TYPE type);
|
|
||||||
INTERNAL void command_queue_release(struct command_queue *cq);
|
|
||||||
INTERNAL SYS_JOB_DEF(dx12_evictor_job, _);
|
|
||||||
INTERNAL void fenced_release(void *data, enum fenced_release_kind kind);
|
|
||||||
|
|
||||||
struct command_queue_alloc_job_sig { struct command_queue_desc *descs_in; struct command_queue **cqs_out; };
|
|
||||||
INTERNAL SYS_JOB_DEF(command_queue_alloc_job, job);
|
|
||||||
|
|
||||||
struct pipeline_alloc_job_sig { struct pipeline_desc *descs_in; struct pipeline **pipelines_out; };
|
|
||||||
INTERNAL SYS_JOB_DEF(pipeline_alloc_job, job);
|
|
||||||
|
|
||||||
#if RESOURCE_RELOADING
|
|
||||||
INTERNAL RESOURCE_WATCH_CALLBACK_FUNC_DEF(pipeline_resource_watch_callback, name);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void gp_startup(void)
|
void gp_startup(void)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
@ -400,9 +421,11 @@ void gp_startup(void)
|
|||||||
G.fenced_releases_arena = arena_alloc(GIBI(64));
|
G.fenced_releases_arena = arena_alloc(GIBI(64));
|
||||||
|
|
||||||
/* Initialize dx12 */
|
/* Initialize dx12 */
|
||||||
|
/* TODO: Parallelize phases */
|
||||||
dx12_init_device();
|
dx12_init_device();
|
||||||
dx12_init_objects();
|
dx12_init_objects();
|
||||||
dx12_init_pipelines();
|
dx12_init_pipelines();
|
||||||
|
dx12_init_noise();
|
||||||
|
|
||||||
/* Register callbacks */
|
/* Register callbacks */
|
||||||
#if RESOURCE_RELOADING
|
#if RESOURCE_RELOADING
|
||||||
@ -772,6 +795,46 @@ INTERNAL void dx12_init_pipelines(void)
|
|||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Noise texture initialization
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
INTERNAL void dx12_init_noise(void)
|
||||||
|
{
|
||||||
|
struct arena_temp scratch = scratch_begin_no_conflict();
|
||||||
|
|
||||||
|
/* Decode */
|
||||||
|
struct ase_decode_image_result decoded = ZI;
|
||||||
|
{
|
||||||
|
struct resource texture_rs = resource_open(LIT("sprite/noise.ase"));
|
||||||
|
if (resource_exists(&texture_rs)) {
|
||||||
|
decoded = ase_decode_image(scratch.arena, resource_get_data(&texture_rs));
|
||||||
|
} else {
|
||||||
|
sys_panic(LIT("Noise texture not found"));
|
||||||
|
}
|
||||||
|
resource_close(&texture_rs);
|
||||||
|
}
|
||||||
|
if (decoded.success) {
|
||||||
|
/* Initialize */
|
||||||
|
if (decoded.image.width != SH_BLUE_NOISE_TEX_WIDTH || decoded.image.height != SH_BLUE_NOISE_TEX_HEIGHT) {
|
||||||
|
sys_panic(string_format(scratch.arena,
|
||||||
|
LIT("Noise texture has unexpected dimensions (expected %Fx%F, got %Fx%F)"),
|
||||||
|
FMT_UINT(SH_BLUE_NOISE_TEX_WIDTH), FMT_UINT(SH_BLUE_NOISE_TEX_HEIGHT),
|
||||||
|
FMT_UINT(decoded.image.width), FMT_UINT(decoded.image.height)));
|
||||||
|
|
||||||
|
}
|
||||||
|
struct dx12_resource *r = (struct dx12_resource *)gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(decoded.image.width, decoded.image.height), decoded.image.pixels);
|
||||||
|
if (r->srv_descriptor->index != SH_BLUE_NOISE_TEX_ID) {
|
||||||
|
sys_panic(string_format(scratch.arena,
|
||||||
|
LIT("Noise texture has unexpected descriptor index (expected %F, got %F)"),
|
||||||
|
FMT_UINT(SH_BLUE_NOISE_TEX_ID), FMT_UINT(r->srv_descriptor->index)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sys_panic(LIT("Failed to decode noise texture"));
|
||||||
|
}
|
||||||
|
scratch_end(scratch);
|
||||||
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Shader compilation
|
* Shader compilation
|
||||||
* ========================== */
|
* ========================== */
|
||||||
@ -2250,6 +2313,7 @@ struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, s
|
|||||||
}
|
}
|
||||||
struct dxgi_format_info { DXGI_FORMAT format; u32 size; };
|
struct dxgi_format_info { DXGI_FORMAT format; u32 size; };
|
||||||
LOCAL_PERSIST const struct dxgi_format_info formats[] = {
|
LOCAL_PERSIST const struct dxgi_format_info formats[] = {
|
||||||
|
[GP_TEXTURE_FORMAT_R8_UNORM] = { DXGI_FORMAT_R8_UNORM, 1 },
|
||||||
[GP_TEXTURE_FORMAT_R8G8B8A8_UNORM] = { DXGI_FORMAT_R8G8B8A8_UNORM, 4 },
|
[GP_TEXTURE_FORMAT_R8G8B8A8_UNORM] = { DXGI_FORMAT_R8G8B8A8_UNORM, 4 },
|
||||||
[GP_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB] = { DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 4 },
|
[GP_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB] = { DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 4 },
|
||||||
[GP_TEXTURE_FORMAT_R16G16B16A16_FLOAT] = { DXGI_FORMAT_R16G16B16A16_FLOAT, 8 }
|
[GP_TEXTURE_FORMAT_R16G16B16A16_FLOAT] = { DXGI_FORMAT_R16G16B16A16_FLOAT, 8 }
|
||||||
@ -2298,6 +2362,39 @@ struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, s
|
|||||||
|
|
||||||
/* Upload texture */
|
/* Upload texture */
|
||||||
if (initial_data) {
|
if (initial_data) {
|
||||||
|
/* TODO: Make wait optional */
|
||||||
|
struct snc_counter counter = ZI;
|
||||||
|
struct dx12_upload_job_sig sig = ZI;
|
||||||
|
sig.resource = r;
|
||||||
|
sig.data = initial_data;
|
||||||
|
sys_run(1, dx12_upload_job, &sig, SYS_POOL_INHERIT, SYS_PRIORITY_INHERIT, &counter);
|
||||||
|
snc_counter_wait(&counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (struct gp_resource *)r;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct v2i32 gp_texture_get_size(struct gp_resource *resource)
|
||||||
|
{
|
||||||
|
struct dx12_resource *r = (struct dx12_resource *)resource;
|
||||||
|
return r->texture_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Upload
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
INTERNAL SYS_JOB_DEF(dx12_upload_job, job)
|
||||||
|
{
|
||||||
|
struct dx12_upload_job_sig *sig = job.sig;
|
||||||
|
struct dx12_resource *r = sig->resource;
|
||||||
|
void *data = sig->data;
|
||||||
|
|
||||||
|
ASSERT(r->state == D3D12_RESOURCE_STATE_COPY_DEST);
|
||||||
|
|
||||||
|
D3D12_RESOURCE_DESC desc = ZI;
|
||||||
|
ID3D12Resource_GetDesc(r->resource, &desc);
|
||||||
|
|
||||||
u64 upload_size = 0;
|
u64 upload_size = 0;
|
||||||
u64 upload_row_size = 0;
|
u64 upload_row_size = 0;
|
||||||
u32 upload_num_rows = 0;
|
u32 upload_num_rows = 0;
|
||||||
@ -2328,11 +2425,9 @@ struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, s
|
|||||||
upload_desc.SampleDesc.Quality = 0;
|
upload_desc.SampleDesc.Quality = 0;
|
||||||
D3D12_RESOURCE_STATES upload_initial_state = D3D12_RESOURCE_STATE_GENERIC_READ;
|
D3D12_RESOURCE_STATES upload_initial_state = D3D12_RESOURCE_STATE_GENERIC_READ;
|
||||||
|
|
||||||
/* FIXME: Release */
|
|
||||||
upload = dx12_resource_alloc(upload_heap_props, upload_heap_flags, upload_desc, upload_initial_state, upload_view_flags);
|
upload = dx12_resource_alloc(upload_heap_props, upload_heap_flags, upload_desc, upload_initial_state, upload_view_flags);
|
||||||
|
|
||||||
/* Copy to upload heap */
|
/* Copy to upload heap */
|
||||||
/* FIXME: Copy based on footprint */
|
|
||||||
{
|
{
|
||||||
D3D12_RANGE read_range = ZI;
|
D3D12_RANGE read_range = ZI;
|
||||||
void *mapped = 0;
|
void *mapped = 0;
|
||||||
@ -2342,9 +2437,9 @@ struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, s
|
|||||||
sys_panic(LIT("Failed to map texture upload resource"));
|
sys_panic(LIT("Failed to map texture upload resource"));
|
||||||
}
|
}
|
||||||
u8 *dst = (u8 *)mapped + footprint.Offset;
|
u8 *dst = (u8 *)mapped + footprint.Offset;
|
||||||
u8 *src = initial_data;
|
u8 *src = data;
|
||||||
for (u32 y = 0; y < upload_num_rows; ++y) {
|
for (u32 y = 0; y < upload_num_rows; ++y) {
|
||||||
memcpy(dst + y * footprint.Footprint.RowPitch, src + y * size.x * pixel_size, size.x * pixel_size);
|
MEMCPY(dst + y * footprint.Footprint.RowPitch, src + y * upload_row_size, upload_row_size);
|
||||||
}
|
}
|
||||||
ID3D12Resource_Unmap(upload->resource, 0, 0);
|
ID3D12Resource_Unmap(upload->resource, 0, 0);
|
||||||
}
|
}
|
||||||
@ -2371,25 +2466,18 @@ struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, s
|
|||||||
}
|
}
|
||||||
u64 fence_target = command_list_close(cl);
|
u64 fence_target = command_list_close(cl);
|
||||||
|
|
||||||
/* Submit wait job */
|
/* Wait on fence so we know it's safe to release upload heap */
|
||||||
/* TODO: Make wait optional */
|
|
||||||
if (ID3D12Fence_GetCompletedValue(cq->submit_fence) < fence_target) {
|
if (ID3D12Fence_GetCompletedValue(cq->submit_fence) < fence_target) {
|
||||||
struct dx12_wait_fence_job_sig sig = ZI;
|
struct dx12_wait_fence_job_sig wait_sig = ZI;
|
||||||
sig.fence = cq->submit_fence;
|
wait_sig.fence = cq->submit_fence;
|
||||||
sig.target = fence_target;
|
wait_sig.target = fence_target;
|
||||||
struct snc_counter counter = ZI;
|
struct snc_counter counter = ZI;
|
||||||
sys_run(1, dx12_wait_fence_job, &sig, SYS_POOL_FLOATING, SYS_PRIORITY_LOW, &counter);
|
sys_run(1, dx12_wait_fence_job, &wait_sig, SYS_POOL_FLOATING, SYS_PRIORITY_LOW, &counter);
|
||||||
snc_counter_wait(&counter);
|
snc_counter_wait(&counter);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return (struct gp_resource *)r;
|
/* Release upload heap now */
|
||||||
}
|
dx12_resource_release_now(upload);
|
||||||
|
|
||||||
struct v2i32 gp_texture_get_size(struct gp_resource *resource)
|
|
||||||
{
|
|
||||||
struct dx12_resource *r = (struct dx12_resource *)resource;
|
|
||||||
return r->texture_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -2516,6 +2604,7 @@ INTERNAL D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle_from_descriptor(struct descripto
|
|||||||
|
|
||||||
struct render_sig {
|
struct render_sig {
|
||||||
struct arena *arena;
|
struct arena *arena;
|
||||||
|
struct rand_state rand;
|
||||||
|
|
||||||
/* Material instances */
|
/* Material instances */
|
||||||
u32 num_material_instance_descs;
|
u32 num_material_instance_descs;
|
||||||
@ -2539,8 +2628,6 @@ struct render_sig {
|
|||||||
struct dx12_resource *emittance;
|
struct dx12_resource *emittance;
|
||||||
struct dx12_resource *emittance_flood_a;
|
struct dx12_resource *emittance_flood_a;
|
||||||
struct dx12_resource *emittance_flood_b;
|
struct dx12_resource *emittance_flood_b;
|
||||||
|
|
||||||
u32 tick;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct material_instance_desc {
|
struct material_instance_desc {
|
||||||
@ -2588,7 +2675,6 @@ INTERNAL struct render_sig *render_sig_alloc(void)
|
|||||||
sig->ui_rect_instance_descs_arena = arena_alloc(GIBI(1));
|
sig->ui_rect_instance_descs_arena = arena_alloc(GIBI(1));
|
||||||
sig->ui_shape_verts_arena = arena_alloc(GIBI(1));
|
sig->ui_shape_verts_arena = arena_alloc(GIBI(1));
|
||||||
sig->ui_shape_indices_arena = arena_alloc(GIBI(1));
|
sig->ui_shape_indices_arena = arena_alloc(GIBI(1));
|
||||||
sig->tick = 1;
|
|
||||||
|
|
||||||
return sig;
|
return sig;
|
||||||
}
|
}
|
||||||
@ -2612,8 +2698,6 @@ INTERNAL void render_sig_reset(struct render_sig *sig)
|
|||||||
/* Reset grids */
|
/* Reset grids */
|
||||||
sig->num_material_grid_descs = 0;
|
sig->num_material_grid_descs = 0;
|
||||||
arena_reset(sig->material_grid_descs_arena);
|
arena_reset(sig->material_grid_descs_arena);
|
||||||
|
|
||||||
++sig->tick;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gp_render_sig *gp_render_sig_alloc(void)
|
struct gp_render_sig *gp_render_sig_alloc(void)
|
||||||
@ -2995,7 +3079,8 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re
|
|||||||
/* Set constants */
|
/* Set constants */
|
||||||
struct sh_shade_constants constants = ZI;
|
struct sh_shade_constants constants = ZI;
|
||||||
/* TODO: Remove this */
|
/* TODO: Remove this */
|
||||||
constants.tick = sh_uint_from_u32(sig->tick);
|
constants.camera_offset = sh_float2_from_v2(params.draw_target_view.og);
|
||||||
|
constants.seed = sh_uint2_from_u32((u32)rand_u64_from_state(&sig->rand), (u32)rand_u64_from_state(&sig->rand));
|
||||||
constants.albedo_tex_urid = sh_uint_from_u32(sig->albedo->srv_descriptor->index);
|
constants.albedo_tex_urid = sh_uint_from_u32(sig->albedo->srv_descriptor->index);
|
||||||
constants.emittance_tex_urid = sh_uint_from_u32(sig->emittance->srv_descriptor->index);
|
constants.emittance_tex_urid = sh_uint_from_u32(sig->emittance->srv_descriptor->index);
|
||||||
constants.emittance_flood_tex_urid = sh_uint_from_u32(emittance_flood_read->srv_descriptor->index);
|
constants.emittance_flood_tex_urid = sh_uint_from_u32(emittance_flood_read->srv_descriptor->index);
|
||||||
|
|||||||
@ -145,10 +145,10 @@ INLINE void __prof_dx12_zone_cleanup_func(TracyCD3D12ZoneCtx *ctx) { ___tracy_d3
|
|||||||
#endif /* PROFILING_CAPTURE_FRAME_IMAGE */
|
#endif /* PROFILING_CAPTURE_FRAME_IMAGE */
|
||||||
|
|
||||||
#ifdef TRACY_FIBERS
|
#ifdef TRACY_FIBERS
|
||||||
/* Tracy fiber methods are wrapped in NO_INLINE because otherwise issues can arise
|
/* Tracy fiber methods are wrapped in FORCE_NO_INLINE because otherwise issues can arise
|
||||||
* accross fiber context boundaries during optimization */
|
* accross fiber context boundaries during optimization */
|
||||||
NO_INLINE INLINE void __prof_fiber_enter(char *fiber_name, i32 profiler_group) { TracyCFiberEnterWithHint(fiber_name, profiler_group); }
|
FORCE_NO_INLINE INLINE void __prof_fiber_enter(char *fiber_name, i32 profiler_group) { TracyCFiberEnterWithHint(fiber_name, profiler_group); }
|
||||||
NO_INLINE INLINE void __prof_fiber_leave(void) { TracyCFiberLeave; }
|
FORCE_NO_INLINE INLINE void __prof_fiber_leave(void) { TracyCFiberLeave; }
|
||||||
#else
|
#else
|
||||||
# define __prof_fiber_enter(fiber_name, profiler_group)
|
# define __prof_fiber_enter(fiber_name, profiler_group)
|
||||||
# define __prof_fiber_leave()
|
# define __prof_fiber_leave()
|
||||||
|
|||||||
@ -255,14 +255,15 @@ INTERNAL void test_spawn_entities2(struct sim_ent *parent, struct v2 pos)
|
|||||||
struct sim_ent *e = sim_ent_alloc_sync_src(parent);
|
struct sim_ent *e = sim_ent_alloc_sync_src(parent);
|
||||||
|
|
||||||
f32 rot = 0;
|
f32 rot = 0;
|
||||||
struct v2 size = V2(1, 0.5);
|
struct v2 size = V2(1, 1);
|
||||||
struct xform xf = XFORM_TRS(.t = pos, .r = rot, .s = size);
|
struct xform xf = XFORM_TRS(.t = pos, .r = rot, .s = size);
|
||||||
sim_ent_set_xform(e, xf);
|
sim_ent_set_xform(e, xf);
|
||||||
|
|
||||||
e->sprite = sprite_tag_from_path(LIT("sprite/box.ase"));
|
e->sprite = sprite_tag_from_path(LIT("sprite/tile.ase"));
|
||||||
e->layer = SIM_LAYER_SHOULDERS;
|
e->layer = SIM_LAYER_SHOULDERS;
|
||||||
|
|
||||||
e->sprite_tint = ALPHA32_F(COLOR_BLUE, 0.75);
|
//e->sprite_tint = ALPHA32_F(COLOR_BLUE, 0.75);
|
||||||
|
e->sprite_tint = ALPHA32_F(COLOR_WHITE, 1);
|
||||||
|
|
||||||
sim_ent_enable_prop(e, SEPROP_SOLID);
|
sim_ent_enable_prop(e, SEPROP_SOLID);
|
||||||
struct quad collider_quad = quad_from_rect(RECT(-0.5, -0.5, 1, 1));
|
struct quad collider_quad = quad_from_rect(RECT(-0.5, -0.5, 1, 1));
|
||||||
|
|||||||
@ -927,7 +927,7 @@ INTERNAL void fiber_release(struct job_pool *pool, struct fiber *fiber)
|
|||||||
tm_unlock(&pool->free_fibers_lock);
|
tm_unlock(&pool->free_fibers_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE struct fiber *fiber_from_id(i16 id)
|
INTERNAL FORCE_INLINE struct fiber *fiber_from_id(i16 id)
|
||||||
{
|
{
|
||||||
if (id <= 0) {
|
if (id <= 0) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -936,6 +936,13 @@ FORCE_INLINE struct fiber *fiber_from_id(i16 id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INTERNAL FORCE_NO_INLINE void fiber_resume(struct fiber *fiber)
|
||||||
|
{
|
||||||
|
MemoryBarrier();
|
||||||
|
SwitchToFiber(fiber->addr);
|
||||||
|
MemoryBarrier();
|
||||||
|
}
|
||||||
|
|
||||||
i16 sys_current_fiber_id(void)
|
i16 sys_current_fiber_id(void)
|
||||||
{
|
{
|
||||||
return (i16)(i64)GetFiberData();
|
return (i16)(i64)GetFiberData();
|
||||||
@ -953,29 +960,20 @@ INTERNAL void job_fiber_yield(struct fiber *fiber, struct fiber *parent_fiber)
|
|||||||
ASSERT(parent_fiber->id > 0);
|
ASSERT(parent_fiber->id > 0);
|
||||||
{
|
{
|
||||||
__prof_fiber_leave();
|
__prof_fiber_leave();
|
||||||
MemoryBarrier();
|
fiber_resume(parent_fiber);
|
||||||
SwitchToFiber(parent_fiber->addr);
|
|
||||||
MemoryBarrier();
|
|
||||||
__prof_fiber_enter(fiber->name_cstr, PROF_THREAD_GROUP_FIBERS - MEBI(fiber->job_pool) + KIBI(1) + fiber->id);
|
__prof_fiber_enter(fiber->name_cstr, PROF_THREAD_GROUP_FIBERS - MEBI(fiber->job_pool) + KIBI(1) + fiber->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL void job_fiber_resume(struct fiber *fiber)
|
|
||||||
{
|
|
||||||
MemoryBarrier();
|
|
||||||
SwitchToFiber(fiber->addr);
|
|
||||||
MemoryBarrier();
|
|
||||||
}
|
|
||||||
|
|
||||||
INTERNAL void job_fiber_entry(void *id_ptr)
|
INTERNAL void job_fiber_entry(void *id_ptr)
|
||||||
{
|
{
|
||||||
i16 id = (i32)(i64)id_ptr;
|
i16 id = (i32)(i64)id_ptr;
|
||||||
struct fiber *fiber = fiber_from_id(id);
|
volatile struct fiber *fiber = fiber_from_id(id);
|
||||||
__prof_fiber_enter(fiber->name_cstr, PROF_THREAD_GROUP_FIBERS - MEBI(fiber->job_pool) + KIBI(1) + fiber->id);
|
__prof_fiber_enter(fiber->name_cstr, PROF_THREAD_GROUP_FIBERS - MEBI(fiber->job_pool) + KIBI(1) + fiber->id);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* Run job */
|
/* Run job */
|
||||||
{
|
{
|
||||||
volatile struct yield_param *yield_param = fiber->yield_param;
|
struct yield_param *yield_param = fiber->yield_param;
|
||||||
yield_param->kind = YIELD_KIND_NONE;
|
yield_param->kind = YIELD_KIND_NONE;
|
||||||
struct sys_job_data data = ZI;
|
struct sys_job_data data = ZI;
|
||||||
data.id = fiber->job_id;
|
data.id = fiber->job_id;
|
||||||
@ -986,17 +984,21 @@ INTERNAL void job_fiber_entry(void *id_ptr)
|
|||||||
MemoryBarrier();
|
MemoryBarrier();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Yield */
|
/* Job completed, yield */
|
||||||
{
|
{
|
||||||
volatile struct yield_param *yield_param = fiber->yield_param;
|
/* Decrement job counter */
|
||||||
yield_param->kind = YIELD_KIND_DONE;
|
struct snc_counter *job_counter = fiber->job_counter;
|
||||||
|
if (job_counter) {
|
||||||
|
snc_counter_add(job_counter, -1);
|
||||||
|
}
|
||||||
|
/* Yield to worker */
|
||||||
|
fiber->yield_param->kind = YIELD_KIND_DONE;
|
||||||
struct fiber *parent_fiber = fiber_from_id(fiber->parent_id);
|
struct fiber *parent_fiber = fiber_from_id(fiber->parent_id);
|
||||||
job_fiber_yield(fiber, parent_fiber);
|
job_fiber_yield((struct fiber *)fiber, parent_fiber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void sys_run(i32 count, sys_job_func *func, void *sig, enum sys_pool pool_kind, enum sys_priority priority, struct snc_counter *counter)
|
void sys_run(i32 count, sys_job_func *func, void *sig, enum sys_pool pool_kind, enum sys_priority priority, struct snc_counter *counter)
|
||||||
{
|
{
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
@ -1189,7 +1191,7 @@ INTERNAL THREAD_DEF(job_worker_entry, worker_ctx_arg)
|
|||||||
job_fiber->yield_param = &yield;
|
job_fiber->yield_param = &yield;
|
||||||
b32 done = 0;
|
b32 done = 0;
|
||||||
while (!done) {
|
while (!done) {
|
||||||
job_fiber_resume(job_fiber);
|
fiber_resume(job_fiber);
|
||||||
switch (yield.kind) {
|
switch (yield.kind) {
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
@ -1330,9 +1332,6 @@ INTERNAL THREAD_DEF(job_worker_entry, worker_ctx_arg)
|
|||||||
|
|
||||||
case YIELD_KIND_DONE:
|
case YIELD_KIND_DONE:
|
||||||
{
|
{
|
||||||
if (job_counter) {
|
|
||||||
snc_counter_add(job_counter, -1);
|
|
||||||
}
|
|
||||||
done = 1;
|
done = 1;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user