move shader structs into shared header

This commit is contained in:
jacob 2025-06-18 20:48:09 -05:00
parent 1e06520d99
commit 99431ebdfa
5 changed files with 145 additions and 165 deletions

View File

@ -1,3 +1,5 @@
#include "sh/sh_common.h"
#define DECL(t, n) t n : n #define DECL(t, n) t n : n
#define PI 3.14159265359 #define PI 3.14159265359

View File

@ -1,18 +1,5 @@
#include "sh/common.hlsl" #include "sh/common.hlsl"
struct sh_material_constants {
float4x4 projection;
uint instance_offset;
};
struct sh_material_instance {
float2x3 xf;
float2 uv0;
float2 uv1;
uint tint_srgb;
float emittance;
};
/* ========================== * /* ========================== *
* Root Signature * Root Signature
* ========================== */ * ========================== */

73
res/sh/sh_common.h Normal file
View File

@ -0,0 +1,73 @@
#if SH_CPU
/* ========================== *
* CPU
* ========================== */
#define SH_STRUCT(s) PACK(struct s)
#define SH_DECL(t, n) struct CAT(sh_, t) n
struct sh_uint { u32 v; };
INLINE struct sh_uint sh_uint_from_u32(u32 v)
{
return (struct sh_uint) { .v = v };
}
struct sh_float { f32 v; };
INLINE struct sh_float sh_float_from_f32(f32 v)
{
return (struct sh_float) { .v = v };
}
struct sh_float2 { f32 v[2]; };
INLINE struct sh_float2 sh_float2_from_v2(struct v2 v)
{
return (struct sh_float2) { .v[0] = v.x, .v[1] = v.y };
}
struct sh_float4x4 { f32 v[4][4]; };
INLINE struct sh_float4x4 sh_float4x4_from_mat4x4(struct mat4x4 v)
{
struct sh_float4x4 res;
CT_ASSERT(sizeof(res) == sizeof(v));
MEMCPY(&res, v.e, sizeof(res));
return res;
}
struct sh_float2x3 { f32 v[2][3]; };
INLINE struct sh_float2x3 sh_float2x3_from_xform(struct xform v)
{
struct sh_float2x3 res;
CT_ASSERT(sizeof(res) == sizeof(v));
MEMCPY(&res, &v, sizeof(res));
return res;
}
#else
/* ========================== *
* GPU
* ========================== */
#define SH_STRUCT(s) struct s
#define SH_DECL(t, n) t n
#endif
/* ========================== *
* Material shader structs
* ========================== */
SH_STRUCT(sh_material_constants {
SH_DECL(float4x4, projection);
SH_DECL(uint, instance_offset);
});
SH_STRUCT(sh_material_instance {
SH_DECL(float2x3, xf);
SH_DECL(float2, uv0);
SH_DECL(float2, uv1);
SH_DECL(uint, tint_srgb);
SH_DECL(float, emittance);
});

View File

@ -1767,7 +1767,6 @@ void gpu_dispatch(struct gpu_dispatch_params params)
/* Draw */ /* Draw */
ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
/* FIXME: Set StartInstanceLocation parameter here rather than passing instance_offset into CBV */
ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0); ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0);
/* Unbind */ /* Unbind */
@ -1816,7 +1815,6 @@ void gpu_dispatch(struct gpu_dispatch_params params)
/* Draw */ /* Draw */
ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
/* FIXME: Set StartInstanceLocation parameter here rather than passing instance_offset into CBV */
ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0); ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0);
/* Unbind */ /* Unbind */
@ -1864,7 +1862,6 @@ void gpu_dispatch(struct gpu_dispatch_params params)
/* Draw */ /* Draw */
ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); ID3D11DeviceContext_IASetPrimitiveTopology(G.devcon, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
/* FIXME: Set StartInstanceLocation parameter here rather than passing instance_offset into CBV */
ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0); ID3D11DeviceContext_DrawIndexedInstanced(G.devcon, 6, instance_count, 0, 0, 0);
/* Unbind */ /* Unbind */

View File

@ -12,6 +12,10 @@
#include "resource.h" #include "resource.h"
#include "atomic.h" #include "atomic.h"
/* Include common shader types */
#define SH_CPU 1
#include "../res/sh/sh_common.h"
#pragma warning(push, 0) #pragma warning(push, 0)
# define UNICODE # define UNICODE
# define COBJMACROS # define COBJMACROS
@ -28,9 +32,6 @@
#pragma comment(lib, "dxguid") #pragma comment(lib, "dxguid")
#pragma comment(lib, "d3dcompiler") #pragma comment(lib, "d3dcompiler")
#define SH_CPU 1
#define VT lpVtbl
//#define DX12_WAIT_FRAME_LATENCY 1 //#define DX12_WAIT_FRAME_LATENCY 1
//#define DX12_SWAPCHAIN_FLAGS ((DX12_ALLOW_TEARING * DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING) | (DX12_WAIT_FRAME_LATENCY * DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT)) //#define DX12_SWAPCHAIN_FLAGS ((DX12_ALLOW_TEARING * DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING) | (DX12_WAIT_FRAME_LATENCY * DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT))
@ -242,10 +243,8 @@ GLOBAL struct {
/* Swapchain */ /* Swapchain */
u32 swapchain_frame_index; u32 swapchain_frame_index;
ID3D12CommandAllocator *swapchain_ca;
IDXGISwapChain3 *swapchain; IDXGISwapChain3 *swapchain;
ID3D12DescriptorHeap *swapchain_rtv_heap; struct dx12_resource *swapchain_resources[DX12_SWAPCHAIN_BUFFER_COUNT];
ID3D12Resource *swapchain_buffers[DX12_SWAPCHAIN_BUFFER_COUNT];
/* Dummy vertex buffer */ /* Dummy vertex buffer */
struct dx12_resource *dummy_vertex_buffer; struct dx12_resource *dummy_vertex_buffer;
@ -266,6 +265,8 @@ INTERNAL void dx12_init_pipelines(void);
INTERNAL struct cpu_descriptor_heap *cpu_descriptor_heap_alloc(enum D3D12_DESCRIPTOR_HEAP_TYPE type); 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 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 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 gpu_startup_receipt gpu_startup(struct work_startup_receipt *work_sr, struct sys_window *window) struct gpu_startup_receipt gpu_startup(struct work_startup_receipt *work_sr, struct sys_window *window)
{ {
@ -364,12 +365,10 @@ INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(gpu_shutdown)
__prof; __prof;
#if DX12_DEBUG #if DX12_DEBUG
/* Release objects to make live object reporting less noisy */ /* Release objects to make live object reporting less noisy */
for (u64 i = 0; i < ARRAY_COUNT(G.swapchain_buffers); ++i) { for (u64 i = 0; i < ARRAY_COUNT(G.swapchain_resources); ++i) {
ID3D12Resource_Release(G.swapchain_buffers[i]); dx12_resource_release(G.swapchain_resources[i]);
} }
ID3D12DescriptorHeap_Release(G.swapchain_rtv_heap);
IDXGISwapChain3_Release(G.swapchain); IDXGISwapChain3_Release(G.swapchain);
ID3D12CommandAllocator_Release(G.swapchain_ca);
command_queue_release(G.cq_copy_background); command_queue_release(G.cq_copy_background);
command_queue_release(G.cq_copy_critical); command_queue_release(G.cq_copy_critical);
command_queue_release(G.cq_compute); command_queue_release(G.cq_compute);
@ -633,14 +632,6 @@ INTERNAL void dx12_init_swapchain(struct sys_window *window)
{ {
HRESULT hr = 0; HRESULT hr = 0;
/* Create swapchain command allocator */
{
hr = ID3D12Device_CreateCommandAllocator(G.device, D3D12_COMMAND_LIST_TYPE_DIRECT, &IID_ID3D12CommandAllocator, (void **)&G.swapchain_ca);
if (FAILED(hr)) {
dx12_init_error(LIT("Failed to create swapchain command allocator"));
}
}
/* Create swapchain */ /* Create swapchain */
{ {
HWND hwnd = (HWND)sys_window_get_internal_handle(window); HWND hwnd = (HWND)sys_window_get_internal_handle(window);
@ -677,30 +668,15 @@ INTERNAL void dx12_init_swapchain(struct sys_window *window)
IDXGISwapChain1_Release(swapchain1); IDXGISwapChain1_Release(swapchain1);
} }
/* Create swapchain RTV heap */
{
D3D12_DESCRIPTOR_HEAP_DESC desc = ZI;
desc.NumDescriptors = DX12_SWAPCHAIN_BUFFER_COUNT;
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
hr = ID3D12Device_CreateDescriptorHeap(G.device, &desc, &IID_ID3D12DescriptorHeap, (void **)&G.swapchain_rtv_heap);
if (FAILED(hr)) {
dx12_init_error(LIT("Failed to create swapchain RTV heap"));
}
}
/* Create swacphain RTVs */ /* Create swacphain RTVs */
{ {
D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle = ZI;
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(G.swapchain_rtv_heap, &rtv_handle);
for (u32 i = 0; i < DX12_SWAPCHAIN_BUFFER_COUNT; ++i) { for (u32 i = 0; i < DX12_SWAPCHAIN_BUFFER_COUNT; ++i) {
hr = IDXGISwapChain3_GetBuffer(G.swapchain, i, &IID_ID3D12Resource, (void **)&G.swapchain_buffers[i]); ID3D12Resource *resource = NULL;
hr = IDXGISwapChain3_GetBuffer(G.swapchain, i, &IID_ID3D12Resource, (void **)&resource);
if (FAILED(hr)) { if (FAILED(hr)) {
dx12_init_error(LIT("Failed to get swapchain buffer")); dx12_init_error(LIT("Failed to get swapchain buffer"));
} }
ID3D12Device_CreateRenderTargetView(G.device, G.swapchain_buffers[i], NULL, rtv_handle); G.swapchain_resources[i] = dx12_resource_alloc_from_swapchain_buffer(resource);
rtv_handle.ptr += G.desc_sizes[D3D12_DESCRIPTOR_HEAP_TYPE_RTV];
} }
} }
} }
@ -718,6 +694,7 @@ INTERNAL void dx12_init_swapchain(struct sys_window *window)
/* ============= */ /* ============= */
/* Material pipeline */ /* Material pipeline */
#if 0
PACK(struct fx_material_constant { PACK(struct fx_material_constant {
struct mat4x4 vp; struct mat4x4 vp;
u32 instance_offset; u32 instance_offset;
@ -730,6 +707,7 @@ PACK(struct fx_material_instance {
u32 tint_srgb; u32 tint_srgb;
f32 emittance; f32 emittance;
}); });
#endif
/* ============= */ /* ============= */
/* Grid pipeline */ /* Grid pipeline */
@ -777,8 +755,8 @@ struct dx12_include_handler {
ID3DInclude d3d_handler; ID3DInclude d3d_handler;
ID3DIncludeVtbl vtbl; ID3DIncludeVtbl vtbl;
struct pipeline *pipeline; struct pipeline *pipeline;
b32 has_open_resource; u64 num_open_resources;
struct resource res; struct resource open_resources[1024];
}; };
INTERNAL HRESULT dx12_include_open(ID3DInclude *d3d_handler, D3D_INCLUDE_TYPE include_type, LPCSTR name_cstr, LPCVOID parent_data, LPCVOID *data_out, UINT *data_len_out) INTERNAL HRESULT dx12_include_open(ID3DInclude *d3d_handler, D3D_INCLUDE_TYPE include_type, LPCSTR name_cstr, LPCVOID parent_data, LPCVOID *data_out, UINT *data_len_out)
@ -790,15 +768,15 @@ INTERNAL HRESULT dx12_include_open(ID3DInclude *d3d_handler, D3D_INCLUDE_TYPE in
struct dx12_include_handler *handler = (struct dx12_include_handler *)d3d_handler; struct dx12_include_handler *handler = (struct dx12_include_handler *)d3d_handler;
struct string name = string_from_cstr_no_limit((char *)name_cstr); struct string name = string_from_cstr_no_limit((char *)name_cstr);
if (handler->has_open_resource) { if (handler->num_open_resources >= ARRAY_COUNT(handler->open_resources)) {
sys_panic(LIT("Dx11 include handler somehow already has a resource open")); sys_panic(LIT("Dx12 include handler resource overflow"));
} }
struct resource res = resource_open(name); struct resource *res = &handler->open_resources[handler->num_open_resources++];
if (resource_exists(&res)) { *res = resource_open(name);
handler->res = res; if (resource_exists(res)) {
handler->has_open_resource = true; ++handler->num_open_resources;
struct string data = resource_get_data(&res); struct string data = resource_get_data(res);
*data_out = data.text; *data_out = data.text;
*data_len_out = data.len; *data_len_out = data.len;
result = S_OK; result = S_OK;
@ -818,29 +796,32 @@ INTERNAL HRESULT dx12_include_close(ID3DInclude *d3d_handler, LPCVOID data)
__prof; __prof;
(UNUSED)data; (UNUSED)data;
struct dx12_include_handler *handler = (struct dx12_include_handler *)d3d_handler; struct dx12_include_handler *handler = (struct dx12_include_handler *)d3d_handler;
if (handler->has_open_resource) { for (u64 i = 0; i < handler->num_open_resources; ++i) {
resource_close(&handler->res); struct resource *res = &handler->open_resources[i];
handler->has_open_resource = false; resource_close(res);
} }
handler->num_open_resources = 0;
return S_OK; return S_OK;
} }
INTERNAL struct dx12_include_handler dx12_include_handler_alloc(struct pipeline *pipeline) INTERNAL struct dx12_include_handler *dx12_include_handler_alloc(struct arena *arena, struct pipeline *pipeline)
{ {
struct dx12_include_handler handler = ZI; struct dx12_include_handler *handler = arena_push(arena, struct dx12_include_handler);
handler.d3d_handler.lpVtbl = &handler.vtbl; handler->d3d_handler.lpVtbl = &handler->vtbl;
handler.vtbl.Open = dx12_include_open; handler->vtbl.Open = dx12_include_open;
handler.vtbl.Close = dx12_include_close; handler->vtbl.Close = dx12_include_close;
handler.pipeline = pipeline; handler->pipeline = pipeline;
return handler; return handler;
} }
INTERNAL void dx12_include_handler_release(struct dx12_include_handler *handler) INTERNAL void dx12_include_handler_release(struct dx12_include_handler *handler)
{ {
if (handler->has_open_resource) { for (u64 i = 0; i < handler->num_open_resources; ++i) {
ASSERT(false); /* Resource should have been closed by handler by now */ ASSERT(false); /* Resource should have been closed by handler by now */
resource_close(&handler->res); struct resource *res = &handler->open_resources[i];
resource_close(res);
} }
handler->num_open_resources = 0;
} }
enum shader_compile_task_kind { enum shader_compile_task_kind {
@ -883,7 +864,7 @@ INTERNAL WORK_TASK_FUNC_DEF(shader_compile_task, comp_arg_raw)
struct string func_name = string_from_cstr_no_limit(shader_desc.func); struct string func_name = string_from_cstr_no_limit(shader_desc.func);
if (resource_exists(shader_res)) { if (resource_exists(shader_res)) {
struct dx12_include_handler include_handler = dx12_include_handler_alloc(pipeline); struct dx12_include_handler *include_handler = dx12_include_handler_alloc(scratch.arena, pipeline);
u32 d3d_compile_flags = 0; u32 d3d_compile_flags = 0;
#if DX12_SHADER_DEBUG #if DX12_SHADER_DEBUG
@ -915,11 +896,11 @@ INTERNAL WORK_TASK_FUNC_DEF(shader_compile_task, comp_arg_raw)
{ "SH_CPU", "0" }, { "SH_CPU", "0" },
{ NULL, NULL } { NULL, NULL }
}; };
HRESULT hr = D3DCompile(shader_src.text, shader_src.len, friendly_name_cstr, defines, (ID3DInclude *)&include_handler, shader_desc.func, target, d3d_compile_flags, 0, &blob, &error_blob); HRESULT hr = D3DCompile(shader_src.text, shader_src.len, friendly_name_cstr, defines, (ID3DInclude *)include_handler, shader_desc.func, target, d3d_compile_flags, 0, &blob, &error_blob);
success = SUCCEEDED(hr) && !error_blob; success = SUCCEEDED(hr) && !error_blob;
} }
dx12_include_handler_release(&include_handler); dx12_include_handler_release(include_handler);
} }
#if 0 #if 0
@ -1634,6 +1615,31 @@ INTERNAL struct dx12_resource *dx12_resource_alloc(D3D12_HEAP_PROPERTIES heap_pr
return r; return r;
} }
INTERNAL struct dx12_resource *dx12_resource_alloc_from_swapchain_buffer(ID3D12Resource *buff)
{
struct dx12_resource *r = NULL;
{
struct sys_lock lock = sys_mutex_lock_e(G.resources_mutex);
if (G.first_free_resource) {
r = G.first_free_resource;
G.first_free_resource = r->next_free;
} else {
r = arena_push_no_zero(G.resources_arena, struct dx12_resource);
}
sys_mutex_unlock(&lock);
}
MEMZERO_STRUCT(r);
/* FIXME: Initialize dx12 resource struct here */
r->resource = buff;
r->rtv_descriptor = descriptor_alloc(G.rtv_heap);
ID3D12Device_CreateRenderTargetView(G.device, r->resource, NULL, r->rtv_descriptor->handle);
return r;
}
INTERNAL void dx12_resource_release(struct dx12_resource *t) INTERNAL void dx12_resource_release(struct dx12_resource *t)
{ {
(UNUSED)t; (UNUSED)t;
@ -1738,12 +1744,7 @@ void gpu_dispatch(struct gpu_dispatch_params params)
struct command_queue *cq = G.cq_direct; struct command_queue *cq = G.cq_direct;
struct command_list *cl = command_list_open(cq); struct command_list *cl = command_list_open(cq);
/* Push buffers */
#if 0
{
dx12_buffer_submit(plan->material_instances);
}
#endif
struct command_descriptor_heap *descriptor_heap = command_list_push_descriptor_heap(cl, G.cbv_srv_uav_heap); struct command_descriptor_heap *descriptor_heap = command_list_push_descriptor_heap(cl, G.cbv_srv_uav_heap);
/* Viewport */ /* Viewport */
@ -1784,6 +1785,9 @@ void gpu_dispatch(struct gpu_dispatch_params params)
} }
#endif #endif
/* Bind instance buffer */
//ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 1, instance_buffer->gpu_handle);
/* Bind descriptor heap */ /* Bind descriptor heap */
ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap }; ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap };
ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, ARRAY_COUNT(heaps), heaps); ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, ARRAY_COUNT(heaps), heaps);
@ -1811,89 +1815,6 @@ void gpu_dispatch(struct gpu_dispatch_params params)
/* Execute command list */ /* Execute command list */
command_list_close(cl); command_list_close(cl);
#if 0
__prof;
struct sprite_scope *sprite_scope = sprite_scope_begin();
struct dx11_dispatch_state *state = (struct dx11_dispatch_state *)gpu_dispatch_state.v;
struct rect viewport = params.draw_target_viewport;
/* Set viewport */
D3D11_VIEWPORT d3d11_viewport = ZI;
d3d11_viewport.Width = viewport.width;
d3d11_viewport.Height = viewport.height;
d3d11_viewport.MinDepth = 0.0f;
d3d11_viewport.MaxDepth = 1.0f;
d3d11_viewport.TopLeftX = viewport.x;
d3d11_viewport.TopLeftY = viewport.y;
ID3D11DeviceContext_RSSetViewports(G.devcon, 1, &d3d11_viewport);
struct dx12_resource *final_tex = (struct dx12_resource *)params.draw_target.v;
struct v2i32 final_tex_size = final_tex->size;
/* Texture pass */
{
__profscope(Texture pass);
struct dx11_shader *shader = &G.shaders[DX11_SHADER_KIND_TEXTURE];
if (shader->valid) {
struct dx12_resource *texture = NULL;
if (cmd->texture.texture.v) {
/* Load texture if handle is set */
texture = (struct dx12_resource *)cmd->texture.texture.v;
} 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 dx12_resource *)sprite_texture->texture.v;
}
}
if (texture && texture->srv) {
struct dx11_buffer *instance_buffer = list->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 SRVs */
ID3D11ShaderResourceView *srvs[] = { instance_buffer->srv, texture->srv };
ID3D11DeviceContext_VSSetShaderResources(G.devcon, 0, ARRAY_COUNT(srvs), srvs);
ID3D11DeviceContext_PSSetShaderResources(G.devcon, 0, ARRAY_COUNT(srvs), srvs);
/* Bind RTVs */
ID3D11RenderTargetView *rtvs[] = { final_tex->rtv };
ID3D11DeviceContext_OMSetRenderTargets(G.devcon, ARRAY_COUNT(rtvs), rtvs, 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);
}
}
}
sprite_scope_end(sprite_scope);
#endif
} }
/* ========================== * /* ========================== *