dx12 present testing

This commit is contained in:
jacob 2025-06-19 22:24:56 -05:00
parent 92258b6f3e
commit b96465191e
12 changed files with 241 additions and 297 deletions

View File

@ -7,7 +7,7 @@
#define NURI(i) NonUniformResourceIndex(i)
#if !SH_CPU
# define INLINE
# define INLINE /* For intellisense */
#endif
/* Linear color from normalized sRGB */

View File

@ -1,106 +0,0 @@
#include "shaders/common.hlsl"
struct vs_instance {
float2x3 xf;
float line_thickness;
float line_spacing;
float2 offset;
uint bg0_srgb;
uint bg1_srgb;
uint line_srgb;
uint x_srgb;
uint y_srgb;
};
struct ps_input {
DESV(float4, screen_pos, SV_POSITION);
DECL(float, line_thickness);
DECL(float, line_spacing);
DECL(float2, offset);
DECL(float4, bg0_lin);
DECL(float4, bg1_lin);
DECL(float4, line_lin);
DECL(float4, x_lin);
DECL(float4, y_lin);
};
/* ========================== *
* Globals
* ========================== */
StructuredBuffer<vs_instance> g_instance_buffer : register(t0);
cbuffer constants : register(b0)
{
float4x4 g_projection;
uint g_instance_offset;
};
/* ========================== *
* Vertex shader
* ========================== */
static const float2 G_quad_verts[4] = {
float2(-0.5f, -0.5f),
float2( 0.5f, -0.5f),
float2( 0.5f, 0.5f),
float2(-0.5f, 0.5f)
};
ps_input vs_main(uint instance_id : SV_InstanceID, uint vertex_id : SV_VertexID)
{
vs_instance instance = g_instance_buffer[g_instance_offset + instance_id];
float2 vert = G_quad_verts[vertex_id];
float2 world_pos = mul(instance.xf, float3(vert, 1)).xy;
ps_input output;
output.screen_pos = mul(g_projection, float4(world_pos, 0, 1));
output.line_thickness = instance.line_thickness;
output.line_spacing = instance.line_spacing;
output.offset = instance.offset;
output.bg0_lin = linear_from_srgb32(instance.bg0_srgb);
output.bg1_lin = linear_from_srgb32(instance.bg1_srgb);
output.line_lin = linear_from_srgb32(instance.line_srgb);
output.x_lin = linear_from_srgb32(instance.x_srgb);
output.y_lin = linear_from_srgb32(instance.y_srgb);
return output;
}
/* ========================== *
* Pixel shader
* ========================== */
float4 ps_main(ps_input input) : SV_TARGET
{
float2 grid_pos = input.screen_pos.xy + input.offset;
float half_thickness = input.line_thickness / 2;
float spacing = input.line_spacing;
float4 color = input.bg0_lin;
float2 v = abs(round(grid_pos / spacing) * spacing - grid_pos);
float dist = min(v.x, v.y);
if (grid_pos.y <= half_thickness && grid_pos.y >= -half_thickness) {
color = input.x_lin;
} else if (grid_pos.x <= half_thickness && grid_pos.x >= -half_thickness) {
color = input.y_lin;
} else if (dist < half_thickness) {
color = input.line_lin;
} else {
bool checker = false;
uint cell_x = (uint)(abs(grid_pos.x) / spacing) + (grid_pos.x < 0);
uint cell_y = (uint)(abs(grid_pos.y) / spacing) + (grid_pos.y < 0);
if (cell_x % 2 == 0) {
checker = cell_y % 2 == 0;
} else {
checker = cell_y % 2 == 1;
}
if (checker) {
color = input.bg1_lin;
}
}
return color;
}

View File

@ -1,7 +1,7 @@
#include "sh/common.hlsl"
/* ========================== *
* Root Signature
* Root signature
* ========================== */
#define ROOTSIG \
@ -24,13 +24,6 @@ SamplerState g_sampler : register(s0);
* Vertex shader
* ========================== */
static const float2 g_quad_verts[4] = {
float2(-0.5f, -0.5f),
float2( 0.5f, -0.5f),
float2( 0.5f, 0.5f),
float2(-0.5f, 0.5f)
};
struct vs_input {
DECL(uint, SV_InstanceID);
DECL(uint, SV_VertexID);
@ -45,8 +38,15 @@ struct vs_output {
SH_ENTRY(ROOTSIG) struct vs_output vs(struct vs_input input)
{
static const float2 unit_quad_verts[4] = {
float2(-0.5f, -0.5f),
float2(0.5f, -0.5f),
float2(0.5f, 0.5f),
float2(-0.5f, 0.5f)
};
struct sh_material_instance instance = g_instances[g_constants.instance_offset + input.SV_InstanceID];
float2 vert = g_quad_verts[input.SV_VertexID];
float2 vert = unit_quad_verts[input.SV_VertexID];
float2 world_pos = mul(instance.xf, float3(vert, 1)).xy;
struct vs_output output;

View File

@ -1,42 +0,0 @@
#include "shaders/common.hlsl"
struct vs_input {
DECL(float4, pos);
DECL(float4, color_srgb);
};
struct ps_input {
DESV(float4, screen_pos, SV_POSITION);
DECL(float4, color_lin);
};
/* ========================== *
* Globals
* ========================== */
cbuffer constants : register(b0)
{
float4x4 g_projection;
};
/* ========================== *
* Vertex shader
* ========================== */
ps_input vs_main(vs_input input)
{
ps_input output;
output.screen_pos = mul(g_projection, float4(input.pos.xy, 0.f, 1.f));
output.color_lin = linear_from_srgb(input.color_srgb);
return output;
}
/* ========================== *
* Pixel shader
* ========================== */
float4 ps_main(ps_input input) : SV_TARGET
{
return input.color_lin;
}

View File

@ -6,8 +6,7 @@
#define SH_STRUCT(s) PACK(struct s)
#define SH_DECL(t, n) struct CAT(sh_, t) n
#define SH_ENTRY static /* For intellisense */
#define SH_ENTRY(rootsig) static
struct sh_uint { u32 v; };
INLINE struct sh_uint sh_uint_from_u32(u32 v)

View File

@ -1,51 +0,0 @@
#include "shaders/common.hlsl"
struct vs_instance {
float2x3 xf;
};
struct ps_input {
DESV(float4, screen_pos, SV_POSITION);
};
/* ========================== *
* Globals
* ========================== */
StructuredBuffer<vs_instance> g_instance_buffer : register(t0);
cbuffer constants : register(b0)
{
float4x4 g_projection;
uint g_instance_offset;
};
/* ========================== *
* Vertex shader
* ========================== */
static const float2 G_quad_verts[4] = {
float2(-0.5f, -0.5f),
float2( 0.5f, -0.5f),
float2( 0.5f, 0.5f),
float2(-0.5f, 0.5f)
};
ps_input vs_main(uint instance_id : SV_InstanceID, uint vertex_id : SV_VertexID)
{
vs_instance instance = g_instance_buffer[g_instance_offset + instance_id];
float2 vert = G_quad_verts[vertex_id];
float2 world_pos = mul(instance.xf, float3(vert, 1)).xy;
ps_input output;
output.screen_pos = mul(g_projection, float4(world_pos, 0, 1));
return output;
}
/* ========================== *
* Pixel shader
* ========================== */
float4 ps_main(ps_input input) : SV_TARGET
{
return float4(0, 0, 0, 0);
}

View File

@ -323,7 +323,7 @@ void app_entry_point(struct string args_str)
struct host_startup_receipt host_sr = host_startup(&sock_sr);
struct resource_startup_receipt resource_sr = resource_startup();
struct work_startup_receipt work_sr = work_startup(worker_count);
struct gp_startup_receipt gp_sr = gp_startup(&work_sr, window);
struct gp_startup_receipt gp_sr = gp_startup(&work_sr);
struct asset_cache_startup_receipt asset_cache_sr = asset_cache_startup(&work_sr);
struct ttf_startup_receipt ttf_sr = ttf_startup();
struct font_startup_receipt font_sr = font_startup(&work_sr, &gp_sr, &asset_cache_sr, &ttf_sr, &resource_sr);

View File

@ -96,4 +96,4 @@
#define AUDIO_ENABLED 0
#define VSYNC_ENABLED 0
#define USER_FPS_LIMIT 300
#define USER_FPS_LIMIT 30

View File

@ -9,7 +9,7 @@ struct work_startup_receipt;
* ========================== */
struct gp_startup_receipt { i32 _; };
struct gp_startup_receipt gp_startup(struct work_startup_receipt *work_sr, struct sys_window *window);
struct gp_startup_receipt gp_startup(struct work_startup_receipt *work_sr);
/* ========================== *
* Handle
@ -133,6 +133,6 @@ void gp_dispatch(struct gp_dispatch_params params);
/* 1. Ensures the backbuffer is at size `backbuffer_resolution`
* 2. Blits `texture` to the backbuffer using `texture_xf` (applied to centered unit square)
* 3. Presents the backbuffer */
void gp_present(struct v2i32 backbuffer_resolution, struct gp_handle texture, struct xform texture_xf, i32 vsync);
void gp_present(struct sys_window *window, struct v2i32 backbuffer_resolution, struct gp_handle texture, struct xform texture_xf, i32 vsync);
#endif

View File

@ -318,6 +318,7 @@ struct gp_startup_receipt gp_startup(struct work_startup_receipt *work_sr, struc
/* Create D3D11 device & context */
{
__profscope(Create device);
#if DX11_DEBUG
u32 flags = D3D11_CREATE_DEVICE_DEBUG;
#else
@ -362,6 +363,7 @@ struct gp_startup_receipt gp_startup(struct work_startup_receipt *work_sr, struc
/* Create swap chain */
{
__profscope(Create swapchain);
HWND hwnd = (HWND)sys_window_get_internal_handle(window);
/* Get DXGI device from D3D11 device */
@ -1966,18 +1968,16 @@ INTERNAL void present_blit(struct dx11_texture *dst, struct dx11_texture *src, s
draw_texture(G.present_blit_flow, params);
}
/* Clear textures */
/* Clear texture */
gp_texture_clear(dst_texture_handle, RGBA32_F(0, 0, 0, 1));
/* Render to backbuffer texture */
{
struct gp_dispatch_params params = ZI;
params.flow = G.present_blit_flow;
params.draw_target = dst_texture_handle;
params.draw_target_viewport = RECT_FROM_V2(V2(0, 0), V2(dst->size.x, dst->size.y));
params.draw_target_view = XFORM_IDENT;
gp_dispatch(params);
}
}
void gp_present(struct v2i32 backbuffer_resolution, struct gp_handle texture, struct xform texture_xf, i32 vsync)

View File

@ -14,6 +14,7 @@
#include "util.h"
#include "rand.h"
#include "sprite.h"
#include "gstat.h"
/* Include common shader types */
#define SH_CPU 1
@ -254,6 +255,9 @@ GLOBAL struct {
/* Factory */
IDXGIFactory6 *factory;
/* Adapter */
IDXGIAdapter1 *adapter;
/* Device */
ID3D12Device *device;
@ -273,6 +277,8 @@ GLOBAL struct {
struct command_queue *cq_copy_background;
/* Swapchain */
HWND swapchain_hwnd;
struct v2i32 swapchain_resolution;
u32 swapchain_frame_index;
IDXGISwapChain3 *swapchain;
struct dx12_resource *swapchain_resources[DX12_SWAPCHAIN_BUFFER_COUNT];
@ -285,15 +291,13 @@ GLOBAL struct {
INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(gp_shutdown);
INTERNAL void dx12_init_device(void);
INTERNAL void dx12_init_objects(void);
INTERNAL void dx12_init_swapchain(struct sys_window *window);
INTERNAL void dx12_init_pipelines(void);
INTERNAL struct cpu_descriptor_heap *cpu_descriptor_heap_alloc(enum D3D12_DESCRIPTOR_HEAP_TYPE type);
INTERNAL struct command_queue *command_queue_alloc(enum D3D12_COMMAND_LIST_TYPE type, enum D3D12_COMMAND_QUEUE_PRIORITY priority);
INTERNAL void command_queue_release(struct command_queue *cq);
INTERNAL struct dx12_resource *dx12_resource_alloc_from_swapchain_buffer(ID3D12Resource *buff);
INTERNAL void dx12_resource_release(struct dx12_resource *resource);
struct gp_startup_receipt gp_startup(struct work_startup_receipt *work_sr, struct sys_window *window)
struct gp_startup_receipt gp_startup(struct work_startup_receipt *work_sr)
{
__prof;
(UNUSED)work_sr;
@ -317,13 +321,8 @@ struct gp_startup_receipt gp_startup(struct work_startup_receipt *work_sr, struc
/* Initialize dx12 */
dx12_init_device();
dx12_init_objects();
dx12_init_swapchain(window);
dx12_init_pipelines();
/* Init dummy buffers */
/* TODO */
/* Register callbacks */
app_register_exit_callback(gp_shutdown);
@ -503,12 +502,12 @@ INTERNAL void dx12_init_device(void)
/* Create device */
{
IDXGIAdapter1 *adapter = NULL;
ID3D12Device *device = NULL;
struct string error = LIT("Could not initialize GPU device.");
struct string first_gpu_name = ZI;
u32 adapter_index = 0;
while (true) {
IDXGIAdapter1 *adapter = NULL;
hr = IDXGIFactory6_EnumAdapterByGpuPreference(G.factory, adapter_index, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, &IID_IDXGIAdapter1, (void **)&adapter);
if (SUCCEEDED(hr)) {
DXGI_ADAPTER_DESC1 desc;
@ -518,8 +517,6 @@ INTERNAL void dx12_init_device(void)
}
hr = D3D12CreateDevice((IUnknown *)adapter, D3D_FEATURE_LEVEL_12_0, &IID_ID3D12Device, (void **)&device);
if (SUCCEEDED(hr)) {
IDXGIAdapter1_Release(adapter);
adapter = NULL;
break;
}
ID3D12Device_Release(device);
@ -538,6 +535,7 @@ INTERNAL void dx12_init_device(void)
}
dx12_init_error(error);
}
G.adapter = adapter;
G.device = device;
}
@ -597,63 +595,6 @@ INTERNAL void dx12_init_objects(void)
G.cq_copy_background = command_queue_alloc(D3D12_COMMAND_LIST_TYPE_COPY, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL);
}
/* ========================== *
* Dx12 swapchain initialization
* ========================== */
INTERNAL void dx12_init_swapchain(struct sys_window *window)
{
HRESULT hr = 0;
/* Create swapchain */
{
HWND hwnd = (HWND)sys_window_get_internal_handle(window);
DXGI_SWAP_CHAIN_DESC1 desc = {
.Format = DX12_SWAPCHAIN_FORMAT,
.SampleDesc = { 1, 0 },
.BufferUsage = DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT,
.BufferCount = DX12_SWAPCHAIN_BUFFER_COUNT,
.Scaling = DXGI_SCALING_NONE,
.Flags = DX12_SWAPCHAIN_FLAGS,
.AlphaMode = DXGI_ALPHA_MODE_IGNORE,
.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD
};
/* Create swapchain1 */
IDXGISwapChain1 *swapchain1 = NULL;
hr = IDXGIFactory2_CreateSwapChainForHwnd(G.factory, (IUnknown *)G.cq_direct->cq, hwnd, &desc, NULL, NULL, &swapchain1);
if (FAILED(hr)) {
dx12_init_error(LIT("Failed to create IDXGISwapChain1"));
}
/* Upgrade to swapchain3 */
hr = IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain3, (void **)&G.swapchain);
if (FAILED(hr)) {
dx12_init_error(LIT("Failed to create IDXGISwapChain3"));
}
/* Disable Alt+Enter changing monitor resolution to match window size */
IDXGIFactory_MakeWindowAssociation(G.factory, hwnd, DXGI_MWA_NO_ALT_ENTER);
/* Get initial frame index */
G.swapchain_frame_index = IDXGISwapChain3_GetCurrentBackBufferIndex(G.swapchain);
IDXGISwapChain1_Release(swapchain1);
}
/* Create swacphain RTVs */
{
for (u32 i = 0; i < DX12_SWAPCHAIN_BUFFER_COUNT; ++i) {
ID3D12Resource *resource = NULL;
hr = IDXGISwapChain3_GetBuffer(G.swapchain, i, &IID_ID3D12Resource, (void **)&resource);
if (FAILED(hr)) {
dx12_init_error(LIT("Failed to get swapchain buffer"));
}
G.swapchain_resources[i] = dx12_resource_alloc_from_swapchain_buffer(resource);
}
}
}
/* ========================== *
* Dx12 pipeline initialization
* ========================== */
@ -1069,6 +1010,7 @@ INTERNAL WORK_TASK_FUNC_DEF(pipeline_load_task, load_arg_raw)
pso_desc.NumRenderTargets = 1;
pso_desc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
pso_desc.SampleDesc.Count = 1;
pso_desc.SampleDesc.Quality = 0;
hr = ID3D12Device_CreateGraphicsPipelineState(G.device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso);
if (FAILED(hr)) {
error_str = LIT("Failed to create pipeline state object");
@ -1187,6 +1129,7 @@ INTERNAL struct descriptor *descriptor_alloc(struct cpu_descriptor_heap *dh)
MEMZERO_STRUCT(d);
d->heap = dh;
d->handle = handle;
d->index = index;
return d;
}
@ -1366,7 +1309,7 @@ INTERNAL struct dx12_resource *dx12_resource_alloc(D3D12_HEAP_PROPERTIES heap_pr
return r;
}
INTERNAL struct dx12_resource *dx12_resource_alloc_from_swapchain_buffer(ID3D12Resource *buff)
INTERNAL struct dx12_resource *dx12_resource_alloc_from_swapchain_buffer(ID3D12Resource *buff, struct v2i32 texture_size)
{
struct dx12_resource *r = NULL;
{
@ -1384,8 +1327,10 @@ INTERNAL struct dx12_resource *dx12_resource_alloc_from_swapchain_buffer(ID3D12R
/* FIXME: Initialize dx12 resource struct here */
r->resource = buff;
r->rtv_descriptor = descriptor_alloc(G.rtv_heap);
r->texture_size = texture_size;
r->state = D3D12_RESOURCE_STATE_PRESENT; /* FIXME */
ID3D12Device_CreateRenderTargetView(G.device, r->resource, NULL, r->rtv_descriptor->handle);
return r;
@ -1396,6 +1341,11 @@ INTERNAL void dx12_resource_release(struct dx12_resource *t)
(UNUSED)t;
}
INTERNAL void dx12_resource_release_now(struct dx12_resource *t)
{
(UNUSED)t;
}
INTERNAL enum D3D12_RESOURCE_STATES dx12_resource_barrier(ID3D12GraphicsCommandList *cl, struct dx12_resource *resource, enum D3D12_RESOURCE_STATES state)
{
enum D3D12_RESOURCE_STATES old_state = resource->state;
@ -1451,6 +1401,7 @@ struct gp_handle gp_texture_alloc(enum gp_texture_format format, u32 flags, stru
desc.DepthOrArraySize = 1;
desc.MipLevels = 1;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
if (flags & GP_TEXTURE_FLAG_TARGETABLE) {
desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
view_flags |= DX12_RESOURCE_VIEW_FLAG_RTV;
@ -1848,7 +1799,7 @@ INTERNAL struct command_buffer *command_list_push_buffer(struct command_list *cl
desc.DepthOrArraySize = 1;
desc.MipLevels = 1;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
D3D12_RESOURCE_STATES initial_state = D3D12_RESOURCE_STATE_GENERIC_READ;
cb->resource = dx12_resource_alloc(heap_props, heap_flags, desc, initial_state, view_flags);
@ -1991,12 +1942,205 @@ void gp_dispatch(struct gp_dispatch_params params)
arena_reset(flow->material_instances_arena);
}
/* ========================== *
* Swapchain
* ========================== */
/* ========================== *
* Present
* ========================== */
void gp_present(struct v2i32 backbuffer_resolution, struct gp_handle texture, struct xform texture_xf, i32 vsync)
#if 0
#if GSTAT_ENABLED || PROFILING
INTERNAL void query_memory_info(void)
{
HRESULT hr = 0;
IDXGIAdapter3 *dxgiAdapter3 = NULL;
struct DXGI_QUERY_VIDEO_MEMORY_INFO info = ZI;
if (SUCCEEDED(hr)) {
hr = IDXGIAdapter_QueryInterface(G.adapter, &IID_IDXGIAdapter3, (void **)&dxgiAdapter3);
ASSERT(SUCCEEDED(hr));
}
if (SUCCEEDED(hr)) {
IDXGIAdapter3_QueryVideoMemoryInfo(dxgiAdapter3, 0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &info);
{
u64 vram = info.CurrentUsage;
u64 budget = info.Budget;
(UNUSED)vram;
(UNUSED)budget;
#if GSTAT_ENABLED
{
gstat_set(GSTAT_VRAM_USAGE, vram);
gstat_set(GSTAT_VRAM_BUDGET, budget);
}
#endif
#if PROFILING
{
LOCAL_PERSIST char *vram_plot_name = NULL;
LOCAL_PERSIST u64 prev_vram = 0;
if (!vram_plot_name) {
vram_plot_name = "Video memory usage";
__prof_plot_init(vram_plot_name, __prof_plot_type_memory, 1, 1, 0);
}
if (vram != prev_vram) {
__prof_plot_i(vram_plot_name, vram);
}
prev_vram = vram;
}
#endif
}
}
if (dxgiAdapter3) {
IDXGIAdapter_Release(dxgiAdapter3);
}
}
#else
INTERNAL void query_memory_info(void)
{
}
#endif
#endif
INTERNAL struct dx12_resource *update_swapchain(struct sys_window *window, struct v2i32 resolution)
{
__prof;
HWND hwnd = (HWND)sys_window_get_internal_handle(window);
b32 should_rebuild = !v2i32_eq(G.swapchain_resolution, resolution);
if (should_rebuild) {
HRESULT hr = 0;
if (G.swapchain) {
ASSERT(hwnd == G.swapchain_hwnd);
/* Resize existing swapchain */
/* FIXME: Fence */
/* Release resources */
for (u32 i = 0; i < ARRAY_COUNT(G.swapchain_resources); ++i) {
struct dx12_resource *resource = G.swapchain_resources[i];
dx12_resource_release_now(resource);
}
/* Resize buffers */
IDXGISwapChain_ResizeBuffers(G.swapchain, 0, resolution.x, resolution.y, DXGI_FORMAT_UNKNOWN, DX12_SWAPCHAIN_FLAGS);
} else {
/* Create swapchain1 */
IDXGISwapChain1 *swapchain1 = NULL;
{
DXGI_SWAP_CHAIN_DESC1 desc = ZI;
desc.Format = DX12_SWAPCHAIN_FORMAT;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.BufferUsage = DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT;
desc.BufferCount = DX12_SWAPCHAIN_BUFFER_COUNT;
desc.Scaling = DXGI_SCALING_NONE;
desc.Flags = DX12_SWAPCHAIN_FLAGS;
desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
hr = IDXGIFactory2_CreateSwapChainForHwnd(G.factory, (IUnknown *)G.cq_direct->cq, hwnd, &desc, NULL, NULL, &swapchain1);
if (FAILED(hr)) {
dx12_init_error(LIT("Failed to create IDXGISwapChain1"));
}
}
/* Upgrade to swapchain3 */
hr = IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain3, (void **)&G.swapchain);
if (FAILED(hr)) {
dx12_init_error(LIT("Failed to create IDXGISwapChain3"));
}
/* Disable Alt+Enter changing monitor resolution to match window size */
IDXGIFactory_MakeWindowAssociation(G.factory, hwnd, DXGI_MWA_NO_ALT_ENTER);
IDXGISwapChain1_Release(swapchain1);
G.swapchain_hwnd = hwnd;
}
/* Allocate swapchain resources */
for (u32 i = 0; i < ARRAY_COUNT(G.swapchain_resources); ++i) {
ID3D12Resource *resource = NULL;
hr = IDXGISwapChain3_GetBuffer(G.swapchain, i, &IID_ID3D12Resource, (void **)&resource);
if (FAILED(hr)) {
/* TODO: Don't panic */
dx12_init_error(LIT("Failed to get swapchain buffer"));
}
G.swapchain_resources[i] = dx12_resource_alloc_from_swapchain_buffer(resource, resolution);
}
G.swapchain_resolution = resolution;
}
G.swapchain_frame_index = IDXGISwapChain3_GetCurrentBackBufferIndex(G.swapchain);
return G.swapchain_resources[G.swapchain_frame_index];
}
/* FIXME: Remove this */
#include "draw.h"
INTERNAL void present_blit(struct dx12_resource *dst, struct dx12_resource *src, struct xform src_xf)
{
/* FIXME: Remove this */
static struct gp_handle flow = ZI;
if (!flow.gen) {
flow = gp_flow_alloc();
}
#if 0
struct gp_handle dst_texture_handle = handle_alloc(DX12_HANDLE_KIND_RESOURCE, dst);
struct gp_handle src_texture_handle = handle_alloc(DX12_HANDLE_KIND_RESOURCE, src);
#endif
/* Draw texture to backbuffer texture */
/* TODO: Specialized blit shader */
{
struct draw_texture_params params = DRAW_TEXTURE_PARAMS(.xf = src_xf, .texture = src_texture_handle);
draw_texture(flow, params);
}
/* FIXME: Clear backbuffer */
/* Render to backbuffer texture */
struct gp_dispatch_params params = ZI;
params.flow = flow;
params.draw_target = dst_texture_handle;
params.draw_target_viewport = RECT_FROM_V2(V2(0, 0), V2(dst->texture_size.x, dst->texture_size.y));
params.draw_target_view = XFORM_IDENT;
gp_dispatch(params);
}
void gp_present(struct sys_window *window, struct v2i32 backbuffer_resolution, struct gp_handle texture, struct xform texture_xf, i32 vsync)
{
sys_sleep(0.1);
#if 0
/* FIXME: Remove this */
static b32 bla = false;
static ID3D12Fence *fence = ZI;
static u64 fence_value = 0;
if (!bla) {
bla = true;
ID3D12Device_CreateFence(G.device, 0, 0, &IID_ID3D12Fence, (void **)&fence);
}
++fence_value;
ID3D12CommandQueue_Signal(G.cq_direct->cq, fence, fence_value);
HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL);
ID3D12Fence_SetEventOnCompletion(fence, fence_value, event);
WaitForSingleObject(event, INFINITE);
CloseHandle(event);
#endif
struct dx12_resource *backbuffer_resource = update_swapchain(window, backbuffer_resolution);
struct dx12_resource *texture_resource = handle_get_data(texture, DX12_HANDLE_KIND_RESOURCE);
/* Blit */
present_blit(backbuffer_resource, texture_resource, texture_xf);
/* Present */
HRESULT hr = IDXGISwapChain3_Present(G.swapchain, 0, 0);
if (!SUCCEEDED(hr)) {
ASSERT(false);
}
(UNUSED)backbuffer_resolution;
(UNUSED)texture;
(UNUSED)texture_xf;

View File

@ -2093,7 +2093,7 @@ INTERNAL void user_update(void)
}
/* Present user texture */
gp_present(backbuffer_resolution, G.user_texture, XFORM_TRS(.t = v2_mul(G.screen_size, 0.5), .s = G.user_size), VSYNC_ENABLED);
gp_present(G.window, backbuffer_resolution, G.user_texture, XFORM_TRS(.t = v2_mul(G.screen_size, 0.5), .s = G.user_size), VSYNC_ENABLED);
}
/* ========================== *