blit shader
This commit is contained in:
parent
01aff521da
commit
214e794ec4
69
res/sh/blit.hlsl
Normal file
69
res/sh/blit.hlsl
Normal file
@ -0,0 +1,69 @@
|
||||
#include "sh/common.hlsl"
|
||||
|
||||
/* ========================== *
|
||||
* Root signature
|
||||
* ========================== */
|
||||
|
||||
#define ROOTSIG \
|
||||
"RootConstants(num32BitConstants=17, b0), " \
|
||||
"DescriptorTable(SRV(t0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \
|
||||
"StaticSampler(s0, " \
|
||||
"filter = FILTER_MIN_MAG_MIP_POINT, " \
|
||||
"addressU = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"addressV = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"addressW = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"maxAnisotropy = 1)"
|
||||
|
||||
ConstantBuffer<struct sh_blit_constants> g_constants : register(b0);
|
||||
Texture2D g_nuri_textures[] : register(t0);
|
||||
|
||||
SamplerState g_sampler : register(s0);
|
||||
|
||||
/* ========================== *
|
||||
* Vertex shader
|
||||
* ========================== */
|
||||
|
||||
struct vs_input {
|
||||
DECL(uint, SV_VertexID);
|
||||
};
|
||||
|
||||
struct vs_output {
|
||||
DECL(float4, SV_Position);
|
||||
DECL(float2, uv);
|
||||
};
|
||||
|
||||
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)
|
||||
};
|
||||
|
||||
float2 vert = unit_quad_verts[input.SV_VertexID];
|
||||
|
||||
struct vs_output output;
|
||||
output.SV_Position = mul(g_constants.projection, float4(vert, 0, 1));
|
||||
output.uv = vert + 0.5;
|
||||
return output;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Pixel shader
|
||||
* ========================== */
|
||||
|
||||
struct ps_input {
|
||||
struct vs_output vs;
|
||||
};
|
||||
|
||||
struct ps_output {
|
||||
DECL(float4, SV_Target);
|
||||
};
|
||||
|
||||
SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input)
|
||||
{
|
||||
struct ps_output output;
|
||||
output.SV_Target = g_nuri_textures[g_constants.texture_id].Sample(g_sampler, input.vs.uv);
|
||||
return output;
|
||||
}
|
||||
@ -15,7 +15,7 @@
|
||||
"addressW = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"maxAnisotropy = 1)"
|
||||
|
||||
cbuffer cb : register(b0) { struct sh_material_constants g_constants; };
|
||||
ConstantBuffer<struct sh_material_constants> g_constants : register(b0);
|
||||
StructuredBuffer<struct sh_material_instance> g_instances : register(t0);
|
||||
Texture2D g_nuri_textures[] : register(t1);
|
||||
|
||||
|
||||
@ -51,7 +51,17 @@ INLINE struct sh_float2x3 sh_float2x3_from_xform(struct xform v)
|
||||
#endif
|
||||
|
||||
/* ========================== *
|
||||
* Material shader structs
|
||||
* Blit shader structures
|
||||
* ========================== */
|
||||
|
||||
SH_STRUCT(sh_blit_constants {
|
||||
SH_DECL(float4x4, projection);
|
||||
SH_DECL(uint, texture_id);
|
||||
});
|
||||
SH_ASSERT_32BIT(struct sh_blit_constants, 17); /* Expected 32bit root constant size in shader */
|
||||
|
||||
/* ========================== *
|
||||
* Material shader structures
|
||||
* ========================== */
|
||||
|
||||
SH_STRUCT(sh_material_constants {
|
||||
|
||||
2
src/gp.h
2
src/gp.h
@ -57,8 +57,6 @@ enum gp_texture_flag {
|
||||
|
||||
struct gp_handle gp_texture_alloc(enum gp_texture_format format, u32 flags, struct v2i32 size, void *initial_data);
|
||||
|
||||
void gp_texture_clear(struct gp_handle target_texture, u32 clear_color);
|
||||
|
||||
struct v2i32 gp_texture_get_size(struct gp_handle texture);
|
||||
|
||||
/* ========================== *
|
||||
|
||||
167
src/gp_dx12.c
167
src/gp_dx12.c
@ -641,6 +641,12 @@ INTERNAL READONLY struct pipeline_desc g_pipeline_descs[] = {
|
||||
.name = "material",
|
||||
.vs = { "sh/material.hlsl", "vs" },
|
||||
.ps = { "sh/material.hlsl", "ps" }
|
||||
},
|
||||
/* Blit pipeline */
|
||||
{
|
||||
.name = "blit",
|
||||
.vs = { "sh/blit.hlsl", "vs" },
|
||||
.ps = { "sh/blit.hlsl", "ps" }
|
||||
}
|
||||
};
|
||||
|
||||
@ -1844,7 +1850,7 @@ INTERNAL struct command_buffer *command_list_push_buffer(struct command_list *cl
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Command root constant
|
||||
* Util
|
||||
* ========================== */
|
||||
|
||||
INTERNAL void command_list_set_root_constant(struct command_list *cl, void *src, u32 size)
|
||||
@ -1862,6 +1868,28 @@ INTERNAL void command_list_set_root_constant(struct command_list *cl, void *src,
|
||||
}
|
||||
}
|
||||
|
||||
INTERNAL struct D3D12_VIEWPORT viewport_from_rect(struct rect r)
|
||||
{
|
||||
struct D3D12_VIEWPORT viewport = ZI;
|
||||
viewport.TopLeftX = r.x;
|
||||
viewport.TopLeftY = r.y;
|
||||
viewport.Width = r.width;
|
||||
viewport.Height = r.height;
|
||||
viewport.MinDepth = 0.0f;
|
||||
viewport.MaxDepth = 1.0f;
|
||||
return viewport;
|
||||
}
|
||||
|
||||
INTERNAL D3D12_RECT scissor_from_rect(struct rect r)
|
||||
{
|
||||
D3D12_RECT scissor = ZI;
|
||||
scissor.left = r.x;
|
||||
scissor.top = r.y;
|
||||
scissor.right = r.x + r.width;
|
||||
scissor.bottom = r.y + r.height;
|
||||
return scissor;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Texture
|
||||
* ========================== */
|
||||
@ -2017,12 +2045,6 @@ struct gp_handle gp_texture_alloc(enum gp_texture_format format, u32 flags, stru
|
||||
return handle_alloc(DX12_HANDLE_KIND_RESOURCE, r);
|
||||
}
|
||||
|
||||
void gp_texture_clear(struct gp_handle target_resource, u32 clear_color)
|
||||
{
|
||||
(UNUSED)target_resource;
|
||||
(UNUSED)clear_color;
|
||||
}
|
||||
|
||||
struct v2i32 gp_texture_get_size(struct gp_handle resource)
|
||||
{
|
||||
struct v2i32 res = ZI;
|
||||
@ -2077,24 +2099,7 @@ void gp_dispatch(struct gp_dispatch_params params)
|
||||
/* Upload descriptor heap */
|
||||
struct command_descriptor_heap *descriptor_heap = command_list_push_descriptor_heap(cl, G.cbv_srv_uav_heap);
|
||||
|
||||
/* Viewport */
|
||||
struct rect viewport = params.draw_target_viewport;
|
||||
struct D3D12_VIEWPORT d3d12_viewport = ZI;
|
||||
d3d12_viewport.TopLeftX = viewport.x;
|
||||
d3d12_viewport.TopLeftY = viewport.y;
|
||||
d3d12_viewport.Width = viewport.width;
|
||||
d3d12_viewport.Height = viewport.height;
|
||||
d3d12_viewport.MinDepth = 0.0f;
|
||||
d3d12_viewport.MaxDepth = 1.0f;
|
||||
|
||||
/* Scissor */
|
||||
D3D12_RECT d3d12_scissor = ZI;
|
||||
d3d12_scissor.left = viewport.x;
|
||||
d3d12_scissor.top = viewport.y;
|
||||
d3d12_scissor.right = viewport.x + viewport.width;
|
||||
d3d12_scissor.bottom = viewport.y + viewport.height;
|
||||
|
||||
struct mat4x4 vp_matrix = calculate_vp(params.draw_target_view, viewport.width, viewport.height);
|
||||
struct mat4x4 vp_matrix = calculate_vp(params.draw_target_view, params.draw_target_viewport.width, params.draw_target_viewport.height);
|
||||
|
||||
/* Create temporary descriptor heap */
|
||||
/* NOTE: This should always occur after buffers are submitted */
|
||||
@ -2132,8 +2137,10 @@ void gp_dispatch(struct gp_dispatch_params params)
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 2, descriptor_heap->gp_handle);
|
||||
|
||||
/* Setup Rasterizer State */
|
||||
ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &d3d12_viewport);
|
||||
ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &d3d12_scissor);
|
||||
D3D12_VIEWPORT viewport = viewport_from_rect(params.draw_target_viewport);
|
||||
D3D12_RECT scissor = scissor_from_rect(params.draw_target_viewport);
|
||||
ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport);
|
||||
ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor);
|
||||
|
||||
/* Draw */
|
||||
ID3D12GraphicsCommandList_IASetPrimitiveTopology(cl->cl, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
@ -2287,52 +2294,76 @@ INTERNAL struct dx12_resource *update_swapchain(struct sys_window *window, struc
|
||||
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();
|
||||
__prof;
|
||||
struct pipeline_scope *pipeline_scope = pipeline_scope_begin();
|
||||
struct pipeline *blit_pipeline = pipeline_from_name(pipeline_scope, LIT("blit"));
|
||||
if (blit_pipeline->valid) {
|
||||
struct command_list *cl = command_list_open(G.cq_direct);
|
||||
{
|
||||
/* Upload dummmy vert & index buffer */
|
||||
/* TODO: Make these static */
|
||||
/* Dummy vertex buffer */
|
||||
LOCAL_PERSIST u16 quad_indices[6] = { 0, 1, 2, 0, 2, 3 };
|
||||
struct command_buffer *dummy_vertex_buffer = command_list_push_buffer(cl, STRING(0, 0));
|
||||
struct command_buffer *quad_index_buffer = command_list_push_buffer(cl, STRING_FROM_ARRAY(quad_indices));
|
||||
D3D12_VERTEX_BUFFER_VIEW dummy_vertex_buffer_view = ZI;
|
||||
dummy_vertex_buffer_view.BufferLocation = dummy_vertex_buffer->resource->gpu_address;
|
||||
D3D12_INDEX_BUFFER_VIEW quad_index_buffer_view = ZI;
|
||||
quad_index_buffer_view.BufferLocation = quad_index_buffer->resource->gpu_address;
|
||||
quad_index_buffer_view.Format = DXGI_FORMAT_R16_UINT;
|
||||
quad_index_buffer_view.SizeInBytes = sizeof(quad_indices);
|
||||
|
||||
/* Upload descriptor heap */
|
||||
struct command_descriptor_heap *descriptor_heap = command_list_push_descriptor_heap(cl, G.cbv_srv_uav_heap);
|
||||
|
||||
struct rect viewport_rect = RECT_FROM_V2(V2(0, 0), V2(dst->texture_size.x, dst->texture_size.y));
|
||||
D3D12_VIEWPORT viewport = viewport_from_rect(viewport_rect);
|
||||
D3D12_RECT scissor = scissor_from_rect(viewport_rect);
|
||||
struct mat4x4 vp_matrix = calculate_vp(src_xf, viewport.Width, viewport.Height);
|
||||
|
||||
/* Transition dst to render target */
|
||||
dx12_resource_barrier(cl->cl, dst, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
ID3D12GraphicsCommandList_OMSetRenderTargets(cl->cl, 1, &dst->rtv_descriptor->handle, false, NULL);
|
||||
|
||||
/* Clear */
|
||||
f32 clear_color[] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(cl->cl, dst->rtv_descriptor->handle, clear_color, 0, NULL);
|
||||
|
||||
/* Bind pipeline */
|
||||
ID3D12GraphicsCommandList_SetPipelineState(cl->cl, blit_pipeline->pso);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, blit_pipeline->rootsig);
|
||||
|
||||
/* Set root constants */
|
||||
struct sh_blit_constants constants = ZI;
|
||||
constants.projection = sh_float4x4_from_mat4x4(vp_matrix);
|
||||
constants.texture_id = sh_uint_from_u32(src->srv_descriptor->index);
|
||||
command_list_set_root_constant(cl, &constants, sizeof(constants));
|
||||
|
||||
/* Bind descriptor heap */
|
||||
ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap };
|
||||
ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, ARRAY_COUNT(heaps), heaps);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 1, descriptor_heap->gp_handle);
|
||||
|
||||
/* Setup Rasterizer State */
|
||||
ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport);
|
||||
ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor);
|
||||
|
||||
/* Draw */
|
||||
ID3D12GraphicsCommandList_IASetPrimitiveTopology(cl->cl, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
ID3D12GraphicsCommandList_IASetVertexBuffers(cl->cl, 0, 1, &dummy_vertex_buffer_view);
|
||||
ID3D12GraphicsCommandList_IASetIndexBuffer(cl->cl, &quad_index_buffer_view);
|
||||
ID3D12GraphicsCommandList_DrawIndexedInstanced(cl->cl, 6, 1, 0, 0, 0);
|
||||
|
||||
/* Set dst to presentable */
|
||||
dx12_resource_barrier(cl->cl, dst, D3D12_RESOURCE_STATE_PRESENT);
|
||||
}
|
||||
command_list_close(cl);
|
||||
}
|
||||
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);
|
||||
|
||||
/* 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;
|
||||
params.clear_target = true;
|
||||
gp_dispatch(params);
|
||||
pipeline_scope_end(pipeline_scope);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void gp_present(struct sys_window *window, struct v2i32 backbuffer_resolution, struct gp_handle texture, struct xform texture_xf, i32 vsync)
|
||||
{
|
||||
query_memory_info();
|
||||
|
||||
@ -2069,9 +2069,6 @@ INTERNAL void user_update(void)
|
||||
G.user_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, GP_TEXTURE_FLAG_TARGETABLE, user_resolution, NULL);
|
||||
}
|
||||
|
||||
/* Clear textures */
|
||||
gp_texture_clear(G.user_texture, 0);
|
||||
|
||||
/* Render world to user texture */
|
||||
{
|
||||
struct gp_dispatch_params params = ZI;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user