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, " \
|
"addressW = TEXTURE_ADDRESS_CLAMP, " \
|
||||||
"maxAnisotropy = 1)"
|
"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);
|
StructuredBuffer<struct sh_material_instance> g_instances : register(t0);
|
||||||
Texture2D g_nuri_textures[] : register(t1);
|
Texture2D g_nuri_textures[] : register(t1);
|
||||||
|
|
||||||
|
|||||||
@ -51,7 +51,17 @@ INLINE struct sh_float2x3 sh_float2x3_from_xform(struct xform v)
|
|||||||
#endif
|
#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 {
|
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);
|
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);
|
struct v2i32 gp_texture_get_size(struct gp_handle texture);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
|
|||||||
165
src/gp_dx12.c
165
src/gp_dx12.c
@ -641,6 +641,12 @@ INTERNAL READONLY struct pipeline_desc g_pipeline_descs[] = {
|
|||||||
.name = "material",
|
.name = "material",
|
||||||
.vs = { "sh/material.hlsl", "vs" },
|
.vs = { "sh/material.hlsl", "vs" },
|
||||||
.ps = { "sh/material.hlsl", "ps" }
|
.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)
|
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
|
* 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);
|
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 gp_texture_get_size(struct gp_handle resource)
|
||||||
{
|
{
|
||||||
struct v2i32 res = ZI;
|
struct v2i32 res = ZI;
|
||||||
@ -2077,24 +2099,7 @@ void gp_dispatch(struct gp_dispatch_params params)
|
|||||||
/* Upload descriptor heap */
|
/* Upload descriptor heap */
|
||||||
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 */
|
struct mat4x4 vp_matrix = calculate_vp(params.draw_target_view, params.draw_target_viewport.width, params.draw_target_viewport.height);
|
||||||
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);
|
|
||||||
|
|
||||||
/* Create temporary descriptor heap */
|
/* Create temporary descriptor heap */
|
||||||
/* NOTE: This should always occur after buffers are submitted */
|
/* 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);
|
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 2, descriptor_heap->gp_handle);
|
||||||
|
|
||||||
/* Setup Rasterizer State */
|
/* Setup Rasterizer State */
|
||||||
ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &d3d12_viewport);
|
D3D12_VIEWPORT viewport = viewport_from_rect(params.draw_target_viewport);
|
||||||
ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &d3d12_scissor);
|
D3D12_RECT scissor = scissor_from_rect(params.draw_target_viewport);
|
||||||
|
ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport);
|
||||||
|
ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor);
|
||||||
|
|
||||||
/* Draw */
|
/* Draw */
|
||||||
ID3D12GraphicsCommandList_IASetPrimitiveTopology(cl->cl, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
ID3D12GraphicsCommandList_IASetPrimitiveTopology(cl->cl, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
@ -2287,51 +2294,75 @@ INTERNAL struct dx12_resource *update_swapchain(struct sys_window *window, struc
|
|||||||
return G.swapchain_resources[G.swapchain_frame_index];
|
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)
|
INTERNAL void present_blit(struct dx12_resource *dst, struct dx12_resource *src, struct xform src_xf)
|
||||||
{
|
{
|
||||||
/* FIXME: Remove this */
|
__prof;
|
||||||
static struct gp_handle flow = ZI;
|
struct pipeline_scope *pipeline_scope = pipeline_scope_begin();
|
||||||
if (!flow.gen) {
|
struct pipeline *blit_pipeline = pipeline_from_name(pipeline_scope, LIT("blit"));
|
||||||
flow = gp_flow_alloc();
|
if (blit_pipeline->valid) {
|
||||||
}
|
struct command_list *cl = command_list_open(G.cq_direct);
|
||||||
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);
|
/* Upload dummmy vert & index buffer */
|
||||||
draw_texture(flow, params);
|
/* 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);
|
||||||
/* FIXME: Clear backbuffer */
|
}
|
||||||
|
pipeline_scope_end(pipeline_scope);
|
||||||
/* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void gp_present(struct sys_window *window, 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)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -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);
|
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 */
|
/* Render world to user texture */
|
||||||
{
|
{
|
||||||
struct gp_dispatch_params params = ZI;
|
struct gp_dispatch_params params = ZI;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user