light testing setup. backbuffer resize delay.
This commit is contained in:
parent
c6e70e201e
commit
fae10387cd
2
build.c
2
build.c
@ -957,7 +957,7 @@ void OnBuild(StringList cli_args)
|
|||||||
BuildStepSimpleCommandArg *bs_arg = ArenaPush(&perm, BuildStepSimpleCommandArg);
|
BuildStepSimpleCommandArg *bs_arg = ArenaPush(&perm, BuildStepSimpleCommandArg);
|
||||||
bs_arg->cmd = StringF(&perm, link_args_fmt, FmtStr(link_files_str), FmtStr(executable_file.full_path));
|
bs_arg->cmd = StringF(&perm, link_args_fmt, FmtStr(link_files_str), FmtStr(executable_file.full_path));
|
||||||
bs_arg->skip_flag = &src_success_flag;
|
bs_arg->skip_flag = &src_success_flag;
|
||||||
String step_name = Lit("Linking");
|
String step_name = Lit("Link");
|
||||||
AddStep(step_name, &BuildStepSimpleCommand, bs_arg);
|
AddStep(step_name, &BuildStepSimpleCommand, bs_arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ struct vs_instance {
|
|||||||
float2 uv0;
|
float2 uv0;
|
||||||
float2 uv1;
|
float2 uv1;
|
||||||
uint tint_srgb;
|
uint tint_srgb;
|
||||||
|
float emittance;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ps_input {
|
struct ps_input {
|
||||||
|
|||||||
@ -83,5 +83,5 @@
|
|||||||
/* TODO: Move these to user-configurable settings */
|
/* TODO: Move these to user-configurable settings */
|
||||||
|
|
||||||
#define AUDIO_ENABLED 0
|
#define AUDIO_ENABLED 0
|
||||||
#define VSYNC_ENABLED 0
|
#define VSYNC_ENABLED 1
|
||||||
#define USER_FPS_LIMIT 300
|
#define USER_FPS_LIMIT 300
|
||||||
|
|||||||
@ -49,6 +49,7 @@ void draw_texture(struct gpu_cmd_store store, struct draw_texture_params params)
|
|||||||
cmd.texture.texture = params.texture;
|
cmd.texture.texture = params.texture;
|
||||||
cmd.texture.clip = params.clip;
|
cmd.texture.clip = params.clip;
|
||||||
cmd.texture.tint = params.tint;
|
cmd.texture.tint = params.tint;
|
||||||
|
cmd.texture.emittance = params.emittance;
|
||||||
gpu_push_cmd(store, cmd);
|
gpu_push_cmd(store, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -32,6 +32,7 @@ struct draw_texture_params {
|
|||||||
struct sprite_tag sprite;
|
struct sprite_tag sprite;
|
||||||
struct clip_rect clip;
|
struct clip_rect clip;
|
||||||
u32 tint;
|
u32 tint;
|
||||||
|
f32 emittance;
|
||||||
};
|
};
|
||||||
|
|
||||||
void draw_texture(struct gpu_cmd_store store, struct draw_texture_params params);
|
void draw_texture(struct gpu_cmd_store store, struct draw_texture_params params);
|
||||||
|
|||||||
21
src/gpu.h
21
src/gpu.h
@ -42,16 +42,6 @@ void gpu_texture_clear(struct gpu_texture target_texture, u32 clear_color);
|
|||||||
|
|
||||||
struct v2i32 gpu_texture_get_size(struct gpu_texture texture);
|
struct v2i32 gpu_texture_get_size(struct gpu_texture texture);
|
||||||
|
|
||||||
/* ========================== *
|
|
||||||
* Backbuffer
|
|
||||||
* ========================== */
|
|
||||||
|
|
||||||
/* Returns a texture representing the internal backbuffer. Lifetime is managed by gpu layer. */
|
|
||||||
struct gpu_texture gpu_recreate_backbuffer(struct v2i32 size);
|
|
||||||
|
|
||||||
/* Presents the backbuffer to the screen */
|
|
||||||
void gpu_swap_backbuffer(i32 vsync);
|
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Cmd buffer
|
* Cmd buffer
|
||||||
* ========================== */
|
* ========================== */
|
||||||
@ -89,6 +79,7 @@ struct gpu_cmd_params {
|
|||||||
struct gpu_texture texture;
|
struct gpu_texture texture;
|
||||||
struct clip_rect clip;
|
struct clip_rect clip;
|
||||||
u32 tint;
|
u32 tint;
|
||||||
|
f32 emittance;
|
||||||
} texture;
|
} texture;
|
||||||
struct {
|
struct {
|
||||||
struct xform xf;
|
struct xform xf;
|
||||||
@ -144,4 +135,14 @@ void gpu_pass_state_release(struct gpu_pass_state gpu_pass_state);
|
|||||||
|
|
||||||
void gpu_run_pass(struct gpu_pass_state gpu_pass_state, struct gpu_pass_params params);
|
void gpu_run_pass(struct gpu_pass_state gpu_pass_state, struct gpu_pass_params params);
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Backbuffer
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
/* Returns a texture representing the internal backbuffer. Lifetime is managed by gpu layer. */
|
||||||
|
struct gpu_texture gpu_recreate_backbuffer(struct v2i32 size);
|
||||||
|
|
||||||
|
/* Presents the backbuffer to the screen */
|
||||||
|
void gpu_swap_backbuffer(i32 vsync);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
491
src/gpu_dx11.c
491
src/gpu_dx11.c
@ -26,18 +26,21 @@
|
|||||||
#pragma comment(lib, "dxguid")
|
#pragma comment(lib, "dxguid")
|
||||||
#pragma comment(lib, "d3dcompiler")
|
#pragma comment(lib, "d3dcompiler")
|
||||||
|
|
||||||
#define MAX_CMD_STORES 1024
|
|
||||||
|
|
||||||
/* FIXME: Enable this and resolve unreleased references */
|
/* FIXME: Enable this and resolve unreleased references */
|
||||||
#if RTC
|
#if RTC
|
||||||
# define DX11_DEBUG 0
|
# define DX11_DEBUG 1
|
||||||
# define DX11_SHADER_DEBUG 1
|
# define DX11_SHADER_DEBUG 1
|
||||||
#else
|
#else
|
||||||
# define DX11_DEBUG 0
|
# define DX11_DEBUG 0
|
||||||
# define DX11_SHADER_DEBUG 0
|
# define DX11_SHADER_DEBUG 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DX11_SWAPCHAIN_FLAGS (DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING | DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT)
|
#define DX11_BACKBUFFER_RECREATION_DELAY (1.0 / 30.0)
|
||||||
|
|
||||||
|
#define DX11_WAIT_FRAME_LATENCY 1
|
||||||
|
#define DX11_ALLOW_TEARING 1
|
||||||
|
|
||||||
|
#define DX11_SWAPCHAIN_FLAGS ((DX11_ALLOW_TEARING * DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING) | (DX11_WAIT_FRAME_LATENCY * DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT))
|
||||||
|
|
||||||
#define DX11_SWAPCHAIN_FORMAT (DXGI_FORMAT_R8G8B8A8_UNORM)
|
#define DX11_SWAPCHAIN_FORMAT (DXGI_FORMAT_R8G8B8A8_UNORM)
|
||||||
#define DX11_SWAPCHAIN_RTV_FORMAT (DXGI_FORMAT_R8G8B8A8_UNORM_SRGB)
|
#define DX11_SWAPCHAIN_RTV_FORMAT (DXGI_FORMAT_R8G8B8A8_UNORM_SRGB)
|
||||||
@ -61,6 +64,7 @@ struct dx11_shader {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct dx11_pass_state {
|
struct dx11_pass_state {
|
||||||
|
struct dx11_texture *albedo;
|
||||||
struct dx11_pass_state *next_free;
|
struct dx11_pass_state *next_free;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -157,16 +161,12 @@ struct dx11_cmd_store {
|
|||||||
struct dx11_cmd_store *next_free;
|
struct dx11_cmd_store *next_free;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dx11_format {
|
|
||||||
DXGI_FORMAT format;
|
|
||||||
u32 pixel_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dx11_texture {
|
struct dx11_texture {
|
||||||
ID3D11Texture2D *texture;
|
ID3D11Texture2D *texture;
|
||||||
ID3D11ShaderResourceView *srv;
|
ID3D11ShaderResourceView *srv;
|
||||||
ID3D11RenderTargetView *rtv;
|
ID3D11RenderTargetView *rtv;
|
||||||
b32 is_backbuffer;
|
b32 is_backbuffer;
|
||||||
|
struct v2i32 size;
|
||||||
struct dx11_texture *next_free;
|
struct dx11_texture *next_free;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -202,6 +202,7 @@ GLOBAL struct {
|
|||||||
IDXGISwapChain2 *swapchain;
|
IDXGISwapChain2 *swapchain;
|
||||||
HANDLE swapchain_waitable;
|
HANDLE swapchain_waitable;
|
||||||
struct dx11_texture backbuffer_texture;
|
struct dx11_texture backbuffer_texture;
|
||||||
|
i64 last_backbuffer_resize_ns;
|
||||||
|
|
||||||
ID3D11BlendState *blend_state;
|
ID3D11BlendState *blend_state;
|
||||||
ID3D11RasterizerState *rasterizer_state;
|
ID3D11RasterizerState *rasterizer_state;
|
||||||
@ -358,12 +359,12 @@ struct gpu_startup_receipt gpu_startup(struct sys_window *window)
|
|||||||
DXGI_SWAP_CHAIN_DESC1 desc = {
|
DXGI_SWAP_CHAIN_DESC1 desc = {
|
||||||
.Format = DX11_SWAPCHAIN_FORMAT,
|
.Format = DX11_SWAPCHAIN_FORMAT,
|
||||||
.SampleDesc = { 1, 0 },
|
.SampleDesc = { 1, 0 },
|
||||||
.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT,
|
.BufferUsage = DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT,
|
||||||
.BufferCount = 3,
|
.BufferCount = 3,
|
||||||
.Scaling = DXGI_SCALING_NONE,
|
.Scaling = DXGI_SCALING_NONE,
|
||||||
.Flags = DX11_SWAPCHAIN_FLAGS,
|
.Flags = DX11_SWAPCHAIN_FLAGS,
|
||||||
.AlphaMode = DXGI_ALPHA_MODE_IGNORE,
|
.AlphaMode = DXGI_ALPHA_MODE_IGNORE,
|
||||||
.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD,
|
.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD
|
||||||
};
|
};
|
||||||
|
|
||||||
IDXGISwapChain1 *swapchain1 = NULL;
|
IDXGISwapChain1 *swapchain1 = NULL;
|
||||||
@ -393,11 +394,13 @@ struct gpu_startup_receipt gpu_startup(struct sys_window *window)
|
|||||||
G.backbuffer_texture.is_backbuffer = true;
|
G.backbuffer_texture.is_backbuffer = true;
|
||||||
|
|
||||||
/* Create the swapchain waitable object */
|
/* Create the swapchain waitable object */
|
||||||
|
#if DX11_WAIT_FRAME_LATENCY
|
||||||
if (G.swapchain != NULL) {
|
if (G.swapchain != NULL) {
|
||||||
IDXGISwapChain2_SetMaximumFrameLatency(G.swapchain, 1);
|
IDXGISwapChain2_SetMaximumFrameLatency(G.swapchain, 1);
|
||||||
G.swapchain_waitable = IDXGISwapChain2_GetFrameLatencyWaitableObject(G.swapchain);
|
G.swapchain_waitable = IDXGISwapChain2_GetFrameLatencyWaitableObject(G.swapchain);
|
||||||
ASSERT(G.swapchain_waitable != NULL);
|
ASSERT(G.swapchain_waitable != NULL);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
struct string prof_ctx_name = LIT("D3d11 Context");
|
struct string prof_ctx_name = LIT("D3d11 Context");
|
||||||
(UNUSED)prof_ctx_name;
|
(UNUSED)prof_ctx_name;
|
||||||
@ -543,6 +546,7 @@ PACK(struct dx11_texture_instance {
|
|||||||
struct v2 uv0;
|
struct v2 uv0;
|
||||||
struct v2 uv1;
|
struct v2 uv1;
|
||||||
u32 tint_srgb;
|
u32 tint_srgb;
|
||||||
|
f32 emittance;
|
||||||
});
|
});
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -939,6 +943,162 @@ INTERNAL RESOURCE_WATCH_CALLBACK_FUNC_DEF(shader_resource_watch_callback, name)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Texture
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
INTERNAL enum DXGI_FORMAT dx11_format_from_gpu_format(enum gpu_texture_format gpu_format)
|
||||||
|
{
|
||||||
|
LOCAL_PERSIST const enum DXGI_FORMAT dx11_formats[NUM_GPU_TEXTURE_FORMATS] = {
|
||||||
|
[GPU_TEXTURE_FORMAT_R8G8B8A8_UNORM] = DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||||
|
[GPU_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB] = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
|
||||||
|
};
|
||||||
|
enum DXGI_FORMAT res = DXGI_FORMAT_UNKNOWN;
|
||||||
|
if ((u32)gpu_format < ARRAY_COUNT(dx11_formats)) {
|
||||||
|
res = dx11_formats[gpu_format];
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERNAL u32 pixel_size_from_dx11_format(enum DXGI_FORMAT dx11_format)
|
||||||
|
{
|
||||||
|
LOCAL_PERSIST const u32 pixel_sizes[] = {
|
||||||
|
[DXGI_FORMAT_R8G8B8A8_UNORM] = 4,
|
||||||
|
[DXGI_FORMAT_R8G8B8A8_UNORM_SRGB] = 4
|
||||||
|
};
|
||||||
|
u32 res = 0;
|
||||||
|
if ((u32)dx11_format < ARRAY_COUNT(pixel_sizes)) {
|
||||||
|
res = pixel_sizes[dx11_format];
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERNAL struct dx11_texture *dx11_texture_alloc(enum DXGI_FORMAT format, u32 flags, struct v2i32 size, void *initial_data)
|
||||||
|
{
|
||||||
|
struct dx11_texture *t = NULL;
|
||||||
|
{
|
||||||
|
struct sys_lock lock = sys_mutex_lock_e(&G.textures_mutex);
|
||||||
|
if (G.first_free_texture) {
|
||||||
|
t = G.first_free_texture;
|
||||||
|
G.first_free_texture = t->next_free;
|
||||||
|
} else {
|
||||||
|
t = arena_push_no_zero(&G.textures_arena, struct dx11_texture);
|
||||||
|
}
|
||||||
|
sys_mutex_unlock(&lock);
|
||||||
|
}
|
||||||
|
MEMZERO_STRUCT(t);
|
||||||
|
|
||||||
|
D3D11_TEXTURE2D_DESC desc = ZI;
|
||||||
|
desc.Width = max_i32(size.x, 1);
|
||||||
|
desc.Height = max_i32(size.y, 1);
|
||||||
|
desc.MipLevels = 1;
|
||||||
|
desc.ArraySize = 1;
|
||||||
|
desc.SampleDesc.Count = 1;
|
||||||
|
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
desc.CPUAccessFlags = 0;
|
||||||
|
desc.BindFlags = flags;
|
||||||
|
desc.Format = format;
|
||||||
|
|
||||||
|
/* Create texture */
|
||||||
|
ID3D11Texture2D *texture = NULL;
|
||||||
|
if (initial_data) {
|
||||||
|
u32 pixel_size = pixel_size_from_dx11_format(format);
|
||||||
|
D3D11_SUBRESOURCE_DATA subresource_data = { .pSysMem = initial_data, .SysMemPitch = size.x * pixel_size, .SysMemSlicePitch = 0 };
|
||||||
|
ID3D11Device_CreateTexture2D(G.dev, &desc, &subresource_data, &texture);
|
||||||
|
} else {
|
||||||
|
ID3D11Device_CreateTexture2D(G.dev, &desc, NULL, &texture);
|
||||||
|
}
|
||||||
|
ASSERT(texture != NULL);
|
||||||
|
t->texture = texture;
|
||||||
|
|
||||||
|
/* Create SRV */
|
||||||
|
if (t->texture && (flags & D3D11_BIND_SHADER_RESOURCE)) {
|
||||||
|
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc = ZI;
|
||||||
|
srv_desc.Format = desc.Format;
|
||||||
|
srv_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||||
|
srv_desc.Texture2D.MipLevels = desc.MipLevels;
|
||||||
|
ID3D11Device_CreateShaderResourceView(G.dev, (ID3D11Resource *)texture, &srv_desc, &t->srv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create RTV */
|
||||||
|
if (t->texture && (flags & D3D11_BIND_RENDER_TARGET)) {
|
||||||
|
ID3D11Device_CreateRenderTargetView(G.dev, (ID3D11Resource *)t->texture, NULL, &t->rtv);
|
||||||
|
}
|
||||||
|
|
||||||
|
t->size = size;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERNAL void dx11_texture_release(struct dx11_texture *t)
|
||||||
|
{
|
||||||
|
if (!t->is_backbuffer) {
|
||||||
|
{
|
||||||
|
struct sys_lock lock = sys_mutex_lock_e(&G.textures_mutex);
|
||||||
|
t->next_free = G.first_free_texture;
|
||||||
|
G.first_free_texture = t;
|
||||||
|
sys_mutex_unlock(&lock);
|
||||||
|
}
|
||||||
|
if (t->rtv) {
|
||||||
|
ID3D11RenderTargetView_Release(t->rtv);
|
||||||
|
}
|
||||||
|
if (t->srv) {
|
||||||
|
ID3D11ShaderResourceView_Release(t->srv);
|
||||||
|
}
|
||||||
|
if (t->texture) {
|
||||||
|
ID3D11Texture2D_Release(t->texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct gpu_texture gpu_texture_alloc(enum gpu_texture_format format, u32 flags, struct v2i32 size, void *initial_data)
|
||||||
|
{
|
||||||
|
__prof;
|
||||||
|
struct gpu_texture res = ZI;
|
||||||
|
|
||||||
|
/* Convert format to dx11 format */
|
||||||
|
enum DXGI_FORMAT dx11_format = dx11_format_from_gpu_format(format);
|
||||||
|
if (dx11_format == DXGI_FORMAT_UNKNOWN) {
|
||||||
|
/* Unknown format */
|
||||||
|
ASSERT(false);
|
||||||
|
sys_panic(LIT("Unknown dx11 texture format during texture allocation"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert flags to dx11 flags */
|
||||||
|
u32 dx11_flags = D3D11_BIND_SHADER_RESOURCE;
|
||||||
|
if (flags & GPU_TEXTURE_FLAG_TARGETABLE) {
|
||||||
|
dx11_flags |= D3D11_BIND_RENDER_TARGET;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dx11_texture *t = dx11_texture_alloc(dx11_format, dx11_flags, size, initial_data);
|
||||||
|
res.handle = (u64)t;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gpu_texture_release(struct gpu_texture t)
|
||||||
|
{
|
||||||
|
__prof;
|
||||||
|
dx11_texture_release((struct dx11_texture *)t.handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gpu_texture_clear(struct gpu_texture target_texture, u32 clear_color)
|
||||||
|
{
|
||||||
|
__prof;
|
||||||
|
struct dx11_texture *t = (struct dx11_texture *)target_texture.handle;
|
||||||
|
if (t->rtv) {
|
||||||
|
f32 r = (f32)((clear_color >> 0) & 0xFF) / 255.0f;
|
||||||
|
f32 g = (f32)((clear_color >> 8) & 0xFF) / 255.0f;
|
||||||
|
f32 b = (f32)((clear_color >> 16) & 0xFF) / 255.0f;
|
||||||
|
f32 a = (f32)((clear_color >> 24) & 0xFF) / 255.0f;
|
||||||
|
f32 fill[4] = { r, g, b, a };
|
||||||
|
ID3D11DeviceContext_ClearRenderTargetView(G.devcon, t->rtv, fill);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct v2i32 gpu_texture_get_size(struct gpu_texture texture)
|
||||||
|
{
|
||||||
|
return ((struct dx11_texture *)texture.handle)->size;
|
||||||
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Dx11 buffer
|
* Dx11 buffer
|
||||||
* ========================== */
|
* ========================== */
|
||||||
@ -1273,6 +1433,7 @@ void gpu_push_cmd(struct gpu_cmd_store gpu_cmd_store, struct gpu_cmd_params para
|
|||||||
instance->uv0 = params.texture.clip.p0;
|
instance->uv0 = params.texture.clip.p0;
|
||||||
instance->uv1 = params.texture.clip.p1;
|
instance->uv1 = params.texture.clip.p1;
|
||||||
instance->tint_srgb = params.texture.tint;
|
instance->tint_srgb = params.texture.tint;
|
||||||
|
instance->emittance = params.texture.emittance;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case GPU_CMD_KIND_DRAW_GRID:
|
case GPU_CMD_KIND_DRAW_GRID:
|
||||||
@ -1474,15 +1635,11 @@ void gpu_run_pass(struct gpu_pass_state gpu_pass_state, struct gpu_pass_params p
|
|||||||
__prof;
|
__prof;
|
||||||
__profscope_dx11(G.profiling_ctx, Run pass, RGB_F(0.5, 0.2, 0.2));
|
__profscope_dx11(G.profiling_ctx, Run pass, RGB_F(0.5, 0.2, 0.2));
|
||||||
struct sprite_scope *sprite_scope = sprite_scope_begin();
|
struct sprite_scope *sprite_scope = sprite_scope_begin();
|
||||||
struct dx11_pass_state *pass_state = (struct dx11_pass_state *)gpu_pass_state.handle;
|
struct dx11_pass_state *state = (struct dx11_pass_state *)gpu_pass_state.handle;
|
||||||
(UNUSED)pass_state;
|
|
||||||
|
|
||||||
struct dx11_texture *draw_target = (struct dx11_texture *)params.draw_target.handle;
|
|
||||||
struct rect viewport = params.draw_target_viewport;
|
struct rect viewport = params.draw_target_viewport;
|
||||||
|
|
||||||
/* Set render targets */
|
/* Set viewport */
|
||||||
ID3D11DeviceContext_OMSetRenderTargets(G.devcon, 1, &draw_target->rtv, NULL);
|
|
||||||
|
|
||||||
D3D11_VIEWPORT d3d11_viewport = ZI;
|
D3D11_VIEWPORT d3d11_viewport = ZI;
|
||||||
d3d11_viewport.Width = viewport.width;
|
d3d11_viewport.Width = viewport.width;
|
||||||
d3d11_viewport.Height = viewport.height;
|
d3d11_viewport.Height = viewport.height;
|
||||||
@ -1493,6 +1650,112 @@ void gpu_run_pass(struct gpu_pass_state gpu_pass_state, struct gpu_pass_params p
|
|||||||
ID3D11DeviceContext_RSSetViewports(G.devcon, 1, &d3d11_viewport);
|
ID3D11DeviceContext_RSSetViewports(G.devcon, 1, &d3d11_viewport);
|
||||||
|
|
||||||
struct mat4x4 vp_matrix = calculate_vp(XFORM_IDENT, viewport.width, viewport.height);
|
struct mat4x4 vp_matrix = calculate_vp(XFORM_IDENT, viewport.width, viewport.height);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* GI pass */
|
||||||
|
{
|
||||||
|
__profscope(GI pass);
|
||||||
|
__profscope_dx11(G.profiling_ctx, GI pass, RGB_F(0.5, 0.5, 0.5));
|
||||||
|
for (u64 cmd_stores_array_index = 0; cmd_stores_array_index < params.cmds_array.count; ++cmd_stores_array_index) {
|
||||||
|
struct dx11_cmd_store *store = (struct dx11_cmd_store *)params.cmds_array.cmds[cmd_stores_array_index]->handle;
|
||||||
|
for (struct dx11_cmd *cmd = store->gpu_first_cmd; cmd; cmd = cmd->next) {
|
||||||
|
enum gpu_cmd_kind cmd_kind = cmd->kind;
|
||||||
|
|
||||||
|
switch (cmd_kind) {
|
||||||
|
default: break;
|
||||||
|
|
||||||
|
case GPU_CMD_KIND_DRAW_VIEW:
|
||||||
|
{
|
||||||
|
__profscope(Set draw view);
|
||||||
|
vp_matrix = calculate_vp(cmd->view.xf, viewport.width, viewport.height);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case GPU_CMD_KIND_DRAW_TEXTURE:
|
||||||
|
{
|
||||||
|
__profscope(Draw texture emittance);
|
||||||
|
__profscope_dx11(G.profiling_ctx, Draw texture emittance, RGB_F(0.2, 0.5, 0.2));
|
||||||
|
struct dx11_shader *shader = &G.shaders[DX11_SHADER_KIND_TEXTURE];
|
||||||
|
if (shader->valid) {
|
||||||
|
struct dx11_texture *texture = NULL;
|
||||||
|
if (cmd->texture.texture.handle) {
|
||||||
|
/* Load texture if handle is set */
|
||||||
|
texture = (struct dx11_texture *)cmd->texture.texture.handle;
|
||||||
|
} else if (cmd->texture.sprite.hash) {
|
||||||
|
/* Otherwise load sprite */
|
||||||
|
struct sprite_texture *sprite_texture = sprite_texture_from_tag_async(sprite_scope, cmd->texture.sprite);
|
||||||
|
if (sprite_texture->loaded) {
|
||||||
|
texture = (struct dx11_texture *)sprite_texture->texture.handle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texture && texture->srv && shader->valid) {
|
||||||
|
struct dx11_buffer *constant_buffer = store->buffers.constant_buffer;
|
||||||
|
struct dx11_buffer *instance_buffer = store->buffers.texture.instance_buffer;
|
||||||
|
u32 instance_offset = cmd->texture.instance_offset;
|
||||||
|
u32 instance_count = cmd->texture.instance_count;
|
||||||
|
|
||||||
|
/* Bind shader */
|
||||||
|
ID3D11DeviceContext_VSSetShader(G.devcon, shader->vs, 0, 0);
|
||||||
|
ID3D11DeviceContext_PSSetShader(G.devcon, shader->ps, 0, 0);
|
||||||
|
|
||||||
|
/* Fill & bind constant buffer */
|
||||||
|
{
|
||||||
|
struct dx11_texture_uniform *uniform = dx11_buffer_push(constant_buffer, sizeof(struct dx11_texture_uniform));
|
||||||
|
uniform->vp = vp_matrix;
|
||||||
|
uniform->instance_offset = instance_offset;
|
||||||
|
dx11_buffer_submit(constant_buffer);
|
||||||
|
}
|
||||||
|
ID3D11DeviceContext_VSSetConstantBuffers(G.devcon, 0, 1, &constant_buffer->gpu_buffer);
|
||||||
|
ID3D11DeviceContext_PSSetConstantBuffers(G.devcon, 0, 1, &constant_buffer->gpu_buffer);
|
||||||
|
|
||||||
|
/* Bind dummy vertex buffer */
|
||||||
|
u32 zero = 0;
|
||||||
|
ID3D11DeviceContext_IASetVertexBuffers(G.devcon, 0, 1, &G.dummy_vertex_buffer->gpu_buffer, &zero, &zero);
|
||||||
|
ID3D11DeviceContext_IASetIndexBuffer(G.devcon, G.quad_index_buffer->gpu_buffer, DXGI_FORMAT_R16_UINT, zero);
|
||||||
|
|
||||||
|
/* Bind instance buffer */
|
||||||
|
ID3D11DeviceContext_VSSetShaderResources(G.devcon, 0, 1, &instance_buffer->srv);
|
||||||
|
ID3D11DeviceContext_PSSetShaderResources(G.devcon, 0, 1, &instance_buffer->srv);
|
||||||
|
|
||||||
|
/* Bind texture */
|
||||||
|
ID3D11DeviceContext_VSSetShaderResources(G.devcon, 1, 1, &texture->srv);
|
||||||
|
ID3D11DeviceContext_PSSetShaderResources(G.devcon, 1, 1, &texture->srv);
|
||||||
|
|
||||||
|
/* Bind RTV */
|
||||||
|
ID3D11DeviceContext_OMSetRenderTargets(G.devcon, 1, &draw_target->rtv, NULL);
|
||||||
|
|
||||||
|
/* Draw */
|
||||||
|
ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
|
ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0);
|
||||||
|
|
||||||
|
/* Unbind */
|
||||||
|
dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF | DX11_UNBIND_SRV | DX11_UNBIND_RTV);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct dx11_texture *final_tex = (struct dx11_texture *)params.draw_target.handle;
|
||||||
|
struct v2i32 final_tex_size = final_tex->size;
|
||||||
|
|
||||||
|
/* Allocate / resize albedo */
|
||||||
|
struct dx11_texture *albedo_tex = state->albedo;
|
||||||
|
if (!albedo_tex || !v2i32_eq(albedo_tex->size, final_tex->size)) {
|
||||||
|
if (albedo_tex) {
|
||||||
|
dx11_texture_release(albedo_tex);
|
||||||
|
}
|
||||||
|
albedo_tex = dx11_texture_alloc(DXGI_FORMAT_R8G8B8A8_UNORM, D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, final_tex_size, NULL);
|
||||||
|
state->albedo = albedo_tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Regular pass */
|
||||||
|
{
|
||||||
|
__profscope(Regular pass);
|
||||||
|
__profscope_dx11(G.profiling_ctx, Regular pass, RGB_F(0.2, 0.5, 0.5));
|
||||||
for (u64 cmd_stores_array_index = 0; cmd_stores_array_index < params.cmds_array.count; ++cmd_stores_array_index) {
|
for (u64 cmd_stores_array_index = 0; cmd_stores_array_index < params.cmds_array.count; ++cmd_stores_array_index) {
|
||||||
struct dx11_cmd_store *store = (struct dx11_cmd_store *)params.cmds_array.cmds[cmd_stores_array_index]->handle;
|
struct dx11_cmd_store *store = (struct dx11_cmd_store *)params.cmds_array.cmds[cmd_stores_array_index]->handle;
|
||||||
for (struct dx11_cmd *cmd = store->gpu_first_cmd; cmd; cmd = cmd->next) {
|
for (struct dx11_cmd *cmd = store->gpu_first_cmd; cmd; cmd = cmd->next) {
|
||||||
@ -1547,12 +1810,15 @@ void gpu_run_pass(struct gpu_pass_state gpu_pass_state, struct gpu_pass_params p
|
|||||||
ID3D11DeviceContext_IASetVertexBuffers(G.devcon, 0, 1, &vertex_buffer->gpu_buffer, &stride, &zero);
|
ID3D11DeviceContext_IASetVertexBuffers(G.devcon, 0, 1, &vertex_buffer->gpu_buffer, &stride, &zero);
|
||||||
ID3D11DeviceContext_IASetIndexBuffer(G.devcon, index_buffer->gpu_buffer, DXGI_FORMAT_R16_UINT, zero);
|
ID3D11DeviceContext_IASetIndexBuffer(G.devcon, index_buffer->gpu_buffer, DXGI_FORMAT_R16_UINT, zero);
|
||||||
|
|
||||||
|
/* Bind RTV */
|
||||||
|
ID3D11DeviceContext_OMSetRenderTargets(G.devcon, 1, &final_tex->rtv, NULL);
|
||||||
|
|
||||||
/* Draw */
|
/* Draw */
|
||||||
ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
ID3D11DeviceContext_DrawIndexed(G.devcon, index_count, index_offset, vertex_offset);
|
ID3D11DeviceContext_DrawIndexed(G.devcon, index_count, index_offset, vertex_offset);
|
||||||
|
|
||||||
/* Unbind */
|
/* Unbind */
|
||||||
dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_IA | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF);
|
dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_IA | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF | DX11_UNBIND_RTV);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -1607,12 +1873,15 @@ void gpu_run_pass(struct gpu_pass_state gpu_pass_state, struct gpu_pass_params p
|
|||||||
ID3D11DeviceContext_VSSetShaderResources(G.devcon, 1, 1, &texture->srv);
|
ID3D11DeviceContext_VSSetShaderResources(G.devcon, 1, 1, &texture->srv);
|
||||||
ID3D11DeviceContext_PSSetShaderResources(G.devcon, 1, 1, &texture->srv);
|
ID3D11DeviceContext_PSSetShaderResources(G.devcon, 1, 1, &texture->srv);
|
||||||
|
|
||||||
|
/* Bind RTV */
|
||||||
|
ID3D11DeviceContext_OMSetRenderTargets(G.devcon, 1, &final_tex->rtv, NULL);
|
||||||
|
|
||||||
/* Draw */
|
/* Draw */
|
||||||
ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0);
|
ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0);
|
||||||
|
|
||||||
/* Unbind */
|
/* Unbind */
|
||||||
dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF | DX11_UNBIND_SRV);
|
dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF | DX11_UNBIND_SRV | DX11_UNBIND_RTV);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -1651,12 +1920,15 @@ void gpu_run_pass(struct gpu_pass_state gpu_pass_state, struct gpu_pass_params p
|
|||||||
ID3D11DeviceContext_VSSetShaderResources(G.devcon, 0, 1, &instance_buffer->srv);
|
ID3D11DeviceContext_VSSetShaderResources(G.devcon, 0, 1, &instance_buffer->srv);
|
||||||
ID3D11DeviceContext_PSSetShaderResources(G.devcon, 0, 1, &instance_buffer->srv);
|
ID3D11DeviceContext_PSSetShaderResources(G.devcon, 0, 1, &instance_buffer->srv);
|
||||||
|
|
||||||
|
/* Bind RTV */
|
||||||
|
ID3D11DeviceContext_OMSetRenderTargets(G.devcon, 1, &final_tex->rtv, NULL);
|
||||||
|
|
||||||
/* Draw */
|
/* Draw */
|
||||||
ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0);
|
ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0);
|
||||||
|
|
||||||
/* Unbind */
|
/* Unbind */
|
||||||
dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF | DX11_UNBIND_SRV);
|
dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF | DX11_UNBIND_SRV | DX11_UNBIND_RTV);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -1694,177 +1966,25 @@ void gpu_run_pass(struct gpu_pass_state gpu_pass_state, struct gpu_pass_params p
|
|||||||
ID3D11DeviceContext_VSSetShaderResources(G.devcon, 0, 1, &instance_buffer->srv);
|
ID3D11DeviceContext_VSSetShaderResources(G.devcon, 0, 1, &instance_buffer->srv);
|
||||||
ID3D11DeviceContext_PSSetShaderResources(G.devcon, 0, 1, &instance_buffer->srv);
|
ID3D11DeviceContext_PSSetShaderResources(G.devcon, 0, 1, &instance_buffer->srv);
|
||||||
|
|
||||||
|
/* Bind RTV */
|
||||||
|
ID3D11DeviceContext_OMSetRenderTargets(G.devcon, 1, &final_tex->rtv, NULL);
|
||||||
|
|
||||||
/* Draw */
|
/* Draw */
|
||||||
ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0);
|
ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0);
|
||||||
|
|
||||||
/* Unbind */
|
/* Unbind */
|
||||||
dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF | DX11_UNBIND_SRV);
|
dx11_unbind(DX11_UNBIND_VS | DX11_UNBIND_PS | DX11_UNBIND_CBUFF | DX11_UNBIND_VBUFF | DX11_UNBIND_IBUFF | DX11_UNBIND_SRV | DX11_UNBIND_RTV);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* Unbind render target */
|
|
||||||
dx11_unbind(DX11_UNBIND_RTV);
|
|
||||||
|
|
||||||
sprite_scope_end(sprite_scope);
|
sprite_scope_end(sprite_scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
|
||||||
* Texture
|
|
||||||
* ========================== */
|
|
||||||
|
|
||||||
INTERNAL struct dx11_format dx11_format_from_gpu_format(enum gpu_texture_format format)
|
|
||||||
{
|
|
||||||
LOCAL_PERSIST struct dx11_format dx11_formats[NUM_GPU_TEXTURE_FORMATS] = {
|
|
||||||
[GPU_TEXTURE_FORMAT_R8G8B8A8_UNORM] = {
|
|
||||||
.format = DXGI_FORMAT_R8G8B8A8_UNORM,
|
|
||||||
.pixel_size = 4
|
|
||||||
},
|
|
||||||
[GPU_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB] = {
|
|
||||||
.format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
|
|
||||||
.pixel_size = 4
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dx11_format res = ZI;
|
|
||||||
if ((u32)format < ARRAY_COUNT(dx11_formats)) {
|
|
||||||
res = dx11_formats[format];
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
INTERNAL struct dx11_texture *dx11_texture_alloc(struct dx11_format format, u32 flags, struct v2i32 size, void *initial_data)
|
|
||||||
{
|
|
||||||
struct dx11_texture *t = NULL;
|
|
||||||
{
|
|
||||||
struct sys_lock lock = sys_mutex_lock_e(&G.textures_mutex);
|
|
||||||
if (G.first_free_texture) {
|
|
||||||
t = G.first_free_texture;
|
|
||||||
G.first_free_texture = t->next_free;
|
|
||||||
} else {
|
|
||||||
t = arena_push_no_zero(&G.textures_arena, struct dx11_texture);
|
|
||||||
}
|
|
||||||
sys_mutex_unlock(&lock);
|
|
||||||
}
|
|
||||||
MEMZERO_STRUCT(t);
|
|
||||||
|
|
||||||
D3D11_TEXTURE2D_DESC desc = ZI;
|
|
||||||
desc.Width = max_i32(size.x, 1);
|
|
||||||
desc.Height = max_i32(size.y, 1);
|
|
||||||
desc.MipLevels = 1;
|
|
||||||
desc.ArraySize = 1;
|
|
||||||
desc.SampleDesc.Count = 1;
|
|
||||||
desc.Usage = D3D11_USAGE_DEFAULT;
|
|
||||||
desc.CPUAccessFlags = 0;
|
|
||||||
desc.BindFlags = flags;
|
|
||||||
desc.Format = format.format;
|
|
||||||
|
|
||||||
/* Create texture */
|
|
||||||
ID3D11Texture2D *texture = NULL;
|
|
||||||
if (initial_data) {
|
|
||||||
D3D11_SUBRESOURCE_DATA subresource_data = { .pSysMem = initial_data, .SysMemPitch = size.x * format.pixel_size, .SysMemSlicePitch = 0 };
|
|
||||||
ID3D11Device_CreateTexture2D(G.dev, &desc, &subresource_data, &texture);
|
|
||||||
} else {
|
|
||||||
ID3D11Device_CreateTexture2D(G.dev, &desc, NULL, &texture);
|
|
||||||
}
|
|
||||||
ASSERT(texture != NULL);
|
|
||||||
t->texture = texture;
|
|
||||||
|
|
||||||
/* Create SRV */
|
|
||||||
if (t->texture && (flags & D3D11_BIND_SHADER_RESOURCE)) {
|
|
||||||
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc = ZI;
|
|
||||||
srv_desc.Format = desc.Format;
|
|
||||||
srv_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
|
||||||
srv_desc.Texture2D.MipLevels = desc.MipLevels;
|
|
||||||
ID3D11Device_CreateShaderResourceView(G.dev, (ID3D11Resource *)texture, &srv_desc, &t->srv);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create RTV */
|
|
||||||
if (t->texture && (flags & D3D11_BIND_RENDER_TARGET)) {
|
|
||||||
ID3D11Device_CreateRenderTargetView(G.dev, (ID3D11Resource *)t->texture, NULL, &t->rtv);
|
|
||||||
}
|
|
||||||
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
INTERNAL void dx11_texture_release(struct dx11_texture *t)
|
|
||||||
{
|
|
||||||
if (!t->is_backbuffer) {
|
|
||||||
{
|
|
||||||
struct sys_lock lock = sys_mutex_lock_e(&G.textures_mutex);
|
|
||||||
t->next_free = G.first_free_texture;
|
|
||||||
G.first_free_texture = t;
|
|
||||||
sys_mutex_unlock(&lock);
|
|
||||||
}
|
|
||||||
if (t->rtv) {
|
|
||||||
ID3D11RenderTargetView_Release(t->rtv);
|
|
||||||
}
|
|
||||||
if (t->srv) {
|
|
||||||
ID3D11ShaderResourceView_Release(t->srv);
|
|
||||||
}
|
|
||||||
if (t->texture) {
|
|
||||||
ID3D11Texture2D_Release(t->texture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct gpu_texture gpu_texture_alloc(enum gpu_texture_format format, u32 flags, struct v2i32 size, void *initial_data)
|
|
||||||
{
|
|
||||||
__prof;
|
|
||||||
struct gpu_texture res = ZI;
|
|
||||||
|
|
||||||
/* Convert format to dx11 format */
|
|
||||||
struct dx11_format dx11_format = dx11_format_from_gpu_format(format);
|
|
||||||
if (dx11_format.format == DXGI_FORMAT_UNKNOWN) {
|
|
||||||
/* Unknown format */
|
|
||||||
ASSERT(false);
|
|
||||||
sys_panic(LIT("Unknown dx11 texture format during texture allocation"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert flags to dx11 flags */
|
|
||||||
u32 dx11_flags = D3D11_BIND_SHADER_RESOURCE;
|
|
||||||
if (flags & GPU_TEXTURE_FLAG_TARGETABLE) {
|
|
||||||
dx11_flags |= D3D11_BIND_RENDER_TARGET;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dx11_texture *t = dx11_texture_alloc(dx11_format, dx11_flags, size, initial_data);
|
|
||||||
res.handle = (u64)t;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpu_texture_release(struct gpu_texture t)
|
|
||||||
{
|
|
||||||
__prof;
|
|
||||||
dx11_texture_release((struct dx11_texture *)t.handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpu_texture_clear(struct gpu_texture target_texture, u32 clear_color)
|
|
||||||
{
|
|
||||||
__prof;
|
|
||||||
struct dx11_texture *t = (struct dx11_texture *)target_texture.handle;
|
|
||||||
if (t->rtv) {
|
|
||||||
f32 r = (f32)((clear_color >> 0) & 0xFF) / 255.0f;
|
|
||||||
f32 g = (f32)((clear_color >> 8) & 0xFF) / 255.0f;
|
|
||||||
f32 b = (f32)((clear_color >> 16) & 0xFF) / 255.0f;
|
|
||||||
f32 a = (f32)((clear_color >> 24) & 0xFF) / 255.0f;
|
|
||||||
f32 fill[4] = { r, g, b, a };
|
|
||||||
ID3D11DeviceContext_ClearRenderTargetView(G.devcon, t->rtv, fill);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct v2i32 gpu_texture_get_size(struct gpu_texture texture)
|
|
||||||
{
|
|
||||||
struct v2i32 res = ZI;
|
|
||||||
D3D11_TEXTURE2D_DESC desc;
|
|
||||||
ID3D11Texture2D_GetDesc(((struct dx11_texture *)texture.handle)->texture, &desc);
|
|
||||||
res.x = desc.Width;
|
|
||||||
res.y = desc.Height;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Backbuffer
|
* Backbuffer
|
||||||
* ========================== */
|
* ========================== */
|
||||||
@ -1911,6 +2031,20 @@ struct gpu_texture gpu_recreate_backbuffer(struct v2i32 size)
|
|||||||
{
|
{
|
||||||
struct gpu_texture res = ZI;
|
struct gpu_texture res = ZI;
|
||||||
|
|
||||||
|
/* Delay backbuffer recreation so that we don't recreate it too quickly.
|
||||||
|
* It seems that doing this without a delay too often will cause windows
|
||||||
|
* to eventually just display a blackscreen rather than the backbuffer
|
||||||
|
* (e.g. when resizing for more than a few seconds). */
|
||||||
|
i64 now_ns = sys_time_ns();
|
||||||
|
if (G.last_backbuffer_resize_ns != 0) {
|
||||||
|
i64 next_resize_ns = G.last_backbuffer_resize_ns + NS_FROM_SECONDS(DX11_BACKBUFFER_RECREATION_DELAY);
|
||||||
|
if (now_ns < next_resize_ns) {
|
||||||
|
sys_sleep_precise(SECONDS_FROM_NS(next_resize_ns - now_ns));
|
||||||
|
now_ns = sys_time_ns();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
G.last_backbuffer_resize_ns = now_ns;
|
||||||
|
|
||||||
/* Release */
|
/* Release */
|
||||||
if (G.backbuffer_texture.texture != 0) {
|
if (G.backbuffer_texture.texture != 0) {
|
||||||
ID3D11RenderTargetView_Release(G.backbuffer_texture.rtv);
|
ID3D11RenderTargetView_Release(G.backbuffer_texture.rtv);
|
||||||
@ -1920,6 +2054,7 @@ struct gpu_texture gpu_recreate_backbuffer(struct v2i32 size)
|
|||||||
/* Resize */
|
/* Resize */
|
||||||
IDXGISwapChain_ResizeBuffers(G.swapchain, 0, size.x, size.y, DXGI_FORMAT_UNKNOWN, DX11_SWAPCHAIN_FLAGS);
|
IDXGISwapChain_ResizeBuffers(G.swapchain, 0, size.x, size.y, DXGI_FORMAT_UNKNOWN, DX11_SWAPCHAIN_FLAGS);
|
||||||
IDXGISwapChain_GetBuffer(G.swapchain, 0, &IID_ID3D11Texture2D, (LPVOID *)&G.backbuffer_texture.texture);
|
IDXGISwapChain_GetBuffer(G.swapchain, 0, &IID_ID3D11Texture2D, (LPVOID *)&G.backbuffer_texture.texture);
|
||||||
|
G.backbuffer_texture.size = size;
|
||||||
|
|
||||||
/* Create rtv */
|
/* Create rtv */
|
||||||
D3D11_RENDER_TARGET_VIEW_DESC rtv_desc = ZI;
|
D3D11_RENDER_TARGET_VIEW_DESC rtv_desc = ZI;
|
||||||
@ -1982,7 +2117,9 @@ void gpu_swap_backbuffer(i32 vsync)
|
|||||||
WaitForSingleObjectEx(G.swapchain_waitable, 1000, TRUE);
|
WaitForSingleObjectEx(G.swapchain_waitable, 1000, TRUE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
#if DX11_ALLOW_TEARING
|
||||||
flags = DXGI_PRESENT_ALLOW_TEARING;
|
flags = DXGI_PRESENT_ALLOW_TEARING;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu_capture_image_for_profiler();
|
gpu_capture_image_for_profiler();
|
||||||
|
|||||||
@ -145,10 +145,11 @@ enum sim_control_flag {
|
|||||||
SIM_CONTROL_FLAG_SPAWN1_TEST = 1 << 5,
|
SIM_CONTROL_FLAG_SPAWN1_TEST = 1 << 5,
|
||||||
SIM_CONTROL_FLAG_SPAWN2_TEST = 1 << 6,
|
SIM_CONTROL_FLAG_SPAWN2_TEST = 1 << 6,
|
||||||
SIM_CONTROL_FLAG_SPAWN3_TEST = 1 << 7,
|
SIM_CONTROL_FLAG_SPAWN3_TEST = 1 << 7,
|
||||||
SIM_CONTROL_FLAG_WALLS_TEST = 1 << 8,
|
SIM_CONTROL_FLAG_SPAWN4_TEST = 1 << 8,
|
||||||
SIM_CONTROL_FLAG_TILE_TEST = 1 << 9,
|
SIM_CONTROL_FLAG_WALLS_TEST = 1 << 9,
|
||||||
SIM_CONTROL_FLAG_EXPLODE_TEST = 1 << 10,
|
SIM_CONTROL_FLAG_TILE_TEST = 1 << 10,
|
||||||
SIM_CONTROL_FLAG_TELEPORT_TEST = 1 << 11,
|
SIM_CONTROL_FLAG_EXPLODE_TEST = 1 << 11,
|
||||||
|
SIM_CONTROL_FLAG_TELEPORT_TEST = 1 << 12,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sim_control {
|
struct sim_control {
|
||||||
|
|||||||
@ -66,6 +66,7 @@ enum sim_ent_prop {
|
|||||||
|
|
||||||
SEPROP_TEST,
|
SEPROP_TEST,
|
||||||
SEPROP_TEST_SOUND_EMITTER,
|
SEPROP_TEST_SOUND_EMITTER,
|
||||||
|
SEPROP_LIGHT_TEST,
|
||||||
|
|
||||||
SEPROP_COUNT
|
SEPROP_COUNT
|
||||||
};
|
};
|
||||||
|
|||||||
@ -327,6 +327,26 @@ INTERNAL void test_spawn_entities3(struct sim_ent *parent, struct v2 pos)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INTERNAL void test_spawn_entities4(struct sim_ent *parent, struct v2 pos)
|
||||||
|
{
|
||||||
|
(UNUSED)pos;
|
||||||
|
|
||||||
|
/* Light box */
|
||||||
|
struct sim_ent *e = sim_ent_alloc_sync_src(parent);
|
||||||
|
|
||||||
|
f32 r = 0;
|
||||||
|
struct v2 size = V2(2, 1);
|
||||||
|
struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
|
||||||
|
sim_ent_set_xform(e, xf);
|
||||||
|
|
||||||
|
e->sprite = sprite_tag_from_path(LIT("sprites/box.ase"));
|
||||||
|
e->layer = SIM_LAYER_SHOULDERS;
|
||||||
|
|
||||||
|
sim_ent_enable_prop(e, SEPROP_LIGHT_TEST);
|
||||||
|
|
||||||
|
e->sprite_tint = RGB_F(1, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
INTERNAL void test_spawn_tile(struct sim_snapshot *world, struct v2 world_pos)
|
INTERNAL void test_spawn_tile(struct sim_snapshot *world, struct v2 world_pos)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
@ -1026,6 +1046,16 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
test_spawn_entities3(root, pos);
|
test_spawn_entities3(root, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (flags & SIM_CONTROL_FLAG_SPAWN4_TEST) {
|
||||||
|
logf_debug("Spawn test 4");
|
||||||
|
u32 count = 1;
|
||||||
|
f32 spread = 0;
|
||||||
|
for (u32 j = 0; j < count; ++j) {
|
||||||
|
struct v2 pos = player->player_cursor_pos;
|
||||||
|
pos.y += (((f32)j / (f32)count) - 0.5) * spread;
|
||||||
|
test_spawn_entities4(root, pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (flags & SIM_CONTROL_FLAG_WALLS_TEST) {
|
if (flags & SIM_CONTROL_FLAG_WALLS_TEST) {
|
||||||
test_generate_walls(world);
|
test_generate_walls(world);
|
||||||
}
|
}
|
||||||
|
|||||||
15
src/user.c
15
src/user.c
@ -174,6 +174,7 @@ GLOBAL READONLY enum user_bind_kind g_binds[SYS_BTN_COUNT] = {
|
|||||||
[SYS_BTN_1] = USER_BIND_KIND_DEBUG_SPAWN1,
|
[SYS_BTN_1] = USER_BIND_KIND_DEBUG_SPAWN1,
|
||||||
[SYS_BTN_2] = USER_BIND_KIND_DEBUG_SPAWN2,
|
[SYS_BTN_2] = USER_BIND_KIND_DEBUG_SPAWN2,
|
||||||
[SYS_BTN_3] = USER_BIND_KIND_DEBUG_SPAWN3,
|
[SYS_BTN_3] = USER_BIND_KIND_DEBUG_SPAWN3,
|
||||||
|
[SYS_BTN_4] = USER_BIND_KIND_DEBUG_SPAWN4,
|
||||||
[SYS_BTN_G] = USER_BIND_KIND_DEBUG_WALLS,
|
[SYS_BTN_G] = USER_BIND_KIND_DEBUG_WALLS,
|
||||||
[SYS_BTN_N] = USER_BIND_KIND_DEBUG_STEP,
|
[SYS_BTN_N] = USER_BIND_KIND_DEBUG_STEP,
|
||||||
[SYS_BTN_Q] = USER_BIND_KIND_DEBUG_FOLLOW,
|
[SYS_BTN_Q] = USER_BIND_KIND_DEBUG_FOLLOW,
|
||||||
@ -596,6 +597,12 @@ INTERNAL SORT_COMPARE_FUNC_DEF(ent_draw_order_cmp, arg_a, arg_b, udata)
|
|||||||
|
|
||||||
i32 res = 0;
|
i32 res = 0;
|
||||||
|
|
||||||
|
if (res == 0) {
|
||||||
|
/* Sort by light */
|
||||||
|
b32 a_cmp = sim_ent_has_prop(a, SEPROP_LIGHT_TEST);
|
||||||
|
b32 b_cmp = sim_ent_has_prop(b, SEPROP_LIGHT_TEST);
|
||||||
|
res = (a_cmp > b_cmp) - (a_cmp < b_cmp);
|
||||||
|
}
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
/* Sort by layer */
|
/* Sort by layer */
|
||||||
i32 a_cmp = a->layer;
|
i32 a_cmp = a->layer;
|
||||||
@ -1272,9 +1279,11 @@ INTERNAL void user_update(void)
|
|||||||
|
|
||||||
/* TODO: Fade in placeholder if texture isn't loaded */
|
/* TODO: Fade in placeholder if texture isn't loaded */
|
||||||
if (sheet->loaded) {
|
if (sheet->loaded) {
|
||||||
|
b32 is_light = sim_ent_has_prop(ent, SEPROP_LIGHT_TEST);
|
||||||
|
f32 emittance = is_light ? 1.0 : 0.0;
|
||||||
u32 tint = ent->sprite_tint;
|
u32 tint = ent->sprite_tint;
|
||||||
struct sprite_sheet_frame frame = sprite_sheet_get_frame(sheet, ent->animation_frame);
|
struct sprite_sheet_frame frame = sprite_sheet_get_frame(sheet, ent->animation_frame);
|
||||||
struct draw_texture_params params = DRAW_TEXTURE_PARAMS(.xf = sprite_xform, .sprite = sprite, .tint = tint, .clip = frame.clip);
|
struct draw_texture_params params = DRAW_TEXTURE_PARAMS(.xf = sprite_xform, .sprite = sprite, .tint = tint, .clip = frame.clip, .emittance = emittance);
|
||||||
draw_texture(G.world_gpu_cmd_store, params);
|
draw_texture(G.world_gpu_cmd_store, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1823,6 +1832,7 @@ INTERNAL void user_update(void)
|
|||||||
struct bind_state spawn1_state = G.bind_states[USER_BIND_KIND_DEBUG_SPAWN1];
|
struct bind_state spawn1_state = G.bind_states[USER_BIND_KIND_DEBUG_SPAWN1];
|
||||||
struct bind_state spawn2_state = G.bind_states[USER_BIND_KIND_DEBUG_SPAWN2];
|
struct bind_state spawn2_state = G.bind_states[USER_BIND_KIND_DEBUG_SPAWN2];
|
||||||
struct bind_state spawn3_state = G.bind_states[USER_BIND_KIND_DEBUG_SPAWN3];
|
struct bind_state spawn3_state = G.bind_states[USER_BIND_KIND_DEBUG_SPAWN3];
|
||||||
|
struct bind_state spawn4_state = G.bind_states[USER_BIND_KIND_DEBUG_SPAWN4];
|
||||||
struct bind_state walls_state = G.bind_states[USER_BIND_KIND_DEBUG_WALLS];
|
struct bind_state walls_state = G.bind_states[USER_BIND_KIND_DEBUG_WALLS];
|
||||||
struct bind_state pause_state = G.bind_states[USER_BIND_KIND_DEBUG_PAUSE];
|
struct bind_state pause_state = G.bind_states[USER_BIND_KIND_DEBUG_PAUSE];
|
||||||
struct bind_state step_state = G.bind_states[USER_BIND_KIND_DEBUG_STEP];
|
struct bind_state step_state = G.bind_states[USER_BIND_KIND_DEBUG_STEP];
|
||||||
@ -1854,6 +1864,9 @@ INTERNAL void user_update(void)
|
|||||||
if (spawn3_state.num_presses_and_repeats) {
|
if (spawn3_state.num_presses_and_repeats) {
|
||||||
control.flags |= SIM_CONTROL_FLAG_SPAWN3_TEST;
|
control.flags |= SIM_CONTROL_FLAG_SPAWN3_TEST;
|
||||||
}
|
}
|
||||||
|
if (spawn4_state.num_presses_and_repeats) {
|
||||||
|
control.flags |= SIM_CONTROL_FLAG_SPAWN4_TEST;
|
||||||
|
}
|
||||||
if (walls_state.num_presses_and_repeats) {
|
if (walls_state.num_presses_and_repeats) {
|
||||||
control.flags |= SIM_CONTROL_FLAG_WALLS_TEST;
|
control.flags |= SIM_CONTROL_FLAG_WALLS_TEST;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,6 +32,7 @@ enum user_bind_kind {
|
|||||||
USER_BIND_KIND_DEBUG_SPAWN1,
|
USER_BIND_KIND_DEBUG_SPAWN1,
|
||||||
USER_BIND_KIND_DEBUG_SPAWN2,
|
USER_BIND_KIND_DEBUG_SPAWN2,
|
||||||
USER_BIND_KIND_DEBUG_SPAWN3,
|
USER_BIND_KIND_DEBUG_SPAWN3,
|
||||||
|
USER_BIND_KIND_DEBUG_SPAWN4,
|
||||||
USER_BIND_KIND_DEBUG_WALLS,
|
USER_BIND_KIND_DEBUG_WALLS,
|
||||||
USER_BIND_KIND_DEBUG_FOLLOW,
|
USER_BIND_KIND_DEBUG_FOLLOW,
|
||||||
USER_BIND_KIND_DEBUG_DRAW,
|
USER_BIND_KIND_DEBUG_DRAW,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user