From 427003fa3b4b631d03a0029b5c36264452d7ba68 Mon Sep 17 00:00:00 2001 From: aliaspider Date: Thu, 25 Jan 2018 09:48:07 +0100 Subject: [PATCH] (D3D11) add ribbon shader. - it doesn't look quite right though. --- Makefile.msvc | 1 + gfx/common/d3d11_common.h | 27 +++++ gfx/drivers/d3d11.c | 109 +++++++++++++---- gfx/drivers/d3d_shaders/ribbon_sm4.hlsl.h | 78 ++++++++++++ gfx/video_driver.h | 2 +- menu/drivers_display/menu_display_d3d11.c | 140 +++++++++++++++++++++- 6 files changed, 329 insertions(+), 28 deletions(-) create mode 100644 gfx/drivers/d3d_shaders/ribbon_sm4.hlsl.h diff --git a/Makefile.msvc b/Makefile.msvc index 1807342397..8dd970b0d4 100644 --- a/Makefile.msvc +++ b/Makefile.msvc @@ -49,6 +49,7 @@ HAVE_OVERLAY := 1 HAVE_LANGEXTRA := 1 HAVE_CHEEVOS := 1 HAVE_KEYMAPPER := 1 +HAVE_SHADERPIPELINE := 1 include Makefile.common CFLAGS := $(filter-out -Wno-unknown-pragmas,$(CFLAGS)) diff --git a/gfx/common/d3d11_common.h b/gfx/common/d3d11_common.h index 3220e83fef..5edd6e938e 100644 --- a/gfx/common/d3d11_common.h +++ b/gfx/common/d3d11_common.h @@ -2491,6 +2491,26 @@ typedef struct } params; } d3d11_sprite_t; +#ifndef ALIGN +#ifdef _MSC_VER +#define ALIGN(x) __declspec(align(x)) +#else +#define ALIGN(x) __attribute__((aligned(x))) +#endif +#endif + +ALIGN(16) +typedef struct +{ + math_matrix_4x4 mvp; + struct + { + float width; + float height; + } OutputSize; + float time; +} d3d11_uniform_t; + typedef struct { unsigned cur_mon_id; @@ -2502,12 +2522,18 @@ typedef struct D3D11RenderTargetView renderTargetView; D3D11InputLayout layout; D3D11Buffer ubo; + d3d11_uniform_t ubo_values; D3D11VertexShader vs; D3D11PixelShader ps; D3D11SamplerState sampler_nearest; D3D11SamplerState sampler_linear; D3D11BlendState blend_enable; D3D11BlendState blend_disable; + D3D11BlendState blend_pipeline; + D3D11Buffer menu_pipeline_vbo; + D3D11VertexShader ribbon_vs; + D3D11PixelShader ribbon_ps; + D3D11InputLayout ribbon_layout; math_matrix_4x4 mvp, mvp_no_rot; struct video_viewport vp; D3D11_VIEWPORT viewport; @@ -2544,6 +2570,7 @@ typedef struct int capacity; bool enabled; } sprites; + } d3d11_video_t; void d3d11_init_texture(D3D11Device device, d3d11_texture_t* texture); diff --git a/gfx/drivers/d3d11.c b/gfx/drivers/d3d11.c index 0e2db2f3c7..b7d3a33d97 100644 --- a/gfx/drivers/d3d11.c +++ b/gfx/drivers/d3d11.c @@ -46,13 +46,13 @@ static void d3d11_gfx_set_rotation(void* data, unsigned rotation) math_matrix_4x4* mvp; d3d11_video_t* d3d11 = (d3d11_video_t*)data; - if(!d3d11) + if (!d3d11) return; d3d11->frame.rotation = rotation; matrix_4x4_rotate_z(rot, d3d11->frame.rotation * (M_PI / 2.0f)); - matrix_4x4_multiply(d3d11->mvp, rot, d3d11->mvp_no_rot); + matrix_4x4_multiply(d3d11->mvp, rot, d3d11->ubo_values.mvp); D3D11_MAPPED_SUBRESOURCE mapped_ubo; D3D11MapBuffer(d3d11->ctx, d3d11->frame.ubo, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_ubo); @@ -101,9 +101,15 @@ static void d3d11_gfx_free(void* data) Release(d3d11->sprites.vbo); Release(d3d11->sprites.layout); + Release(d3d11->menu_pipeline_vbo); + Release(d3d11->ribbon_vs); + Release(d3d11->ribbon_ps); + Release(d3d11->ribbon_layout); + Release(d3d11->ubo); Release(d3d11->blend_enable); Release(d3d11->blend_disable); + Release(d3d11->blend_pipeline); Release(d3d11->sampler_nearest); Release(d3d11->sampler_linear); Release(d3d11->ps); @@ -213,18 +219,21 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i d3d11_get_closest_match_texture2D(d3d11->device, d3d11->format); d3d11->frame.texture.desc.Usage = D3D11_USAGE_DEFAULT; - d3d11->menu.texture.desc.Usage = D3D11_USAGE_DEFAULT; + d3d11->menu.texture.desc.Usage = D3D11_USAGE_DEFAULT; - matrix_4x4_ortho(d3d11->mvp_no_rot, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f); + matrix_4x4_ortho(d3d11->ubo_values.mvp, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f); + + d3d11->ubo_values.OutputSize.width = d3d11->viewport.Width; + d3d11->ubo_values.OutputSize.height = d3d11->viewport.Height; { D3D11_BUFFER_DESC desc = { - .ByteWidth = sizeof(math_matrix_4x4), + .ByteWidth = sizeof(d3d11->ubo_values), .Usage = D3D11_USAGE_DYNAMIC, .BindFlags = D3D11_BIND_CONSTANT_BUFFER, .CPUAccessFlags = D3D11_CPU_ACCESS_WRITE, }; - D3D11_SUBRESOURCE_DATA ubo_data = { &d3d11->mvp_no_rot }; + D3D11_SUBRESOURCE_DATA ubo_data = { &d3d11->ubo_values.mvp }; D3D11CreateBuffer(d3d11->device, &desc, &ubo_data, &d3d11->ubo); D3D11CreateBuffer(d3d11->device, &desc, NULL, &d3d11->frame.ubo); } @@ -354,6 +363,7 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i L"gfx/drivers/d3d_shaders/sprite_sm4.hlsl", "GSMain", "gs_5_0", &gs_code)) goto error; #endif + D3D11CreateVertexShader( d3d11->device, D3DGetBufferPointer(vs_code), D3DGetBufferSize(vs_code), NULL, &d3d11->sprites.vs); @@ -376,6 +386,43 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i Release(gs_code); } + { + D3DBlob vs_code; + D3DBlob ps_code; + + static const char shader[] = +#include "d3d_shaders/ribbon_sm4.hlsl.h" + ; + + D3D11_INPUT_ELEMENT_DESC desc[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; +#if 1 + d3d_compile(shader, sizeof(shader), "VSMain", "vs_5_0", &vs_code); + d3d_compile(shader, sizeof(shader), "PSMain", "ps_5_0", &ps_code); +#else + if (!d3d_compile_from_file( + L"gfx/drivers/d3d_shaders/ribbon_sm4.hlsl", "VSMain", "vs_5_0", &vs_code)) + goto error; + if (!d3d_compile_from_file( + L"gfx/drivers/d3d_shaders/ribbon_sm4.hlsl", "PSMain", "ps_5_0", &ps_code)) + goto error; +#endif + + D3D11CreateVertexShader( + d3d11->device, D3DGetBufferPointer(vs_code), D3DGetBufferSize(vs_code), NULL, + &d3d11->ribbon_vs); + D3D11CreatePixelShader( + d3d11->device, D3DGetBufferPointer(ps_code), D3DGetBufferSize(ps_code), NULL, + &d3d11->ribbon_ps); + D3D11CreateInputLayout( + d3d11->device, desc, countof(desc), D3DGetBufferPointer(vs_code), + D3DGetBufferSize(vs_code), &d3d11->ribbon_layout); + + Release(vs_code); + Release(ps_code); + } + { D3D11_BLEND_DESC blend_desc = { .AlphaToCoverageEnable = FALSE, @@ -393,6 +440,11 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i }, }; D3D11CreateBlendState(d3d11->device, &blend_desc, &d3d11->blend_enable); + + blend_desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; + blend_desc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE; + D3D11CreateBlendState(d3d11->device, &blend_desc, &d3d11->blend_pipeline); + blend_desc.RenderTarget[0].BlendEnable = FALSE; D3D11CreateBlendState(d3d11->device, &blend_desc, &d3d11->blend_disable); } @@ -400,7 +452,6 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i D3D11_RASTERIZER_DESC desc = { .FillMode = D3D11_FILL_SOLID, .CullMode = D3D11_CULL_NONE, - .DepthClipEnable = TRUE, }; D3D11CreateRasterizerState(d3d11->device, &desc, &d3d11->state); } @@ -443,6 +494,9 @@ static bool d3d11_gfx_frame( d3d11->viewport.Width = video_info->width; d3d11->viewport.Height = video_info->height; + d3d11->ubo_values.OutputSize.width = d3d11->viewport.Width; + d3d11->ubo_values.OutputSize.height = d3d11->viewport.Height; + d3d11->resize_chain = false; d3d11->resize_viewport = true; video_driver_set_size(&video_info->width, &video_info->height); @@ -509,6 +563,8 @@ static bool d3d11_gfx_frame( D3D11SetPrimitiveTopology(d3d11->ctx, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); D3D11SetVertexBuffers(d3d11->ctx, 0, 1, &d3d11->sprites.vbo, &sprite_stride, &offset); D3D11SetBlendState(d3d11->ctx, d3d11->blend_enable, NULL, D3D11_DEFAULT_SAMPLE_MASK); + D3D11SetVShaderConstantBuffers(d3d11->ctx, 0, 1, &d3d11->ubo); + D3D11SetPShaderConstantBuffers(d3d11->ctx, 0, 1, &d3d11->ubo); d3d11->sprites.enabled = true; @@ -607,8 +663,9 @@ static void d3d11_set_menu_texture_frame( } d3d11_update_texture(d3d11->ctx, width, height, pitch, format, frame, &d3d11->menu.texture); - d3d11->menu.texture.sampler = config_get_ptr()->bools.menu_linear_filter ? d3d11->sampler_linear - : d3d11->sampler_nearest; + d3d11->menu.texture.sampler = config_get_ptr()->bools.menu_linear_filter + ? d3d11->sampler_linear + : d3d11->sampler_nearest; } static void d3d11_set_menu_texture_enable(void* data, bool state, bool full_screen) { @@ -656,32 +713,32 @@ static void d3d11_gfx_set_osd_msg( static uintptr_t d3d11_gfx_load_texture( void* video_data, void* data, bool threaded, enum texture_filter_type filter_type) { - d3d11_video_t* d3d11 = (d3d11_video_t*)video_data; - struct texture_image* image = (struct texture_image*)data; + d3d11_video_t* d3d11 = (d3d11_video_t*)video_data; + struct texture_image* image = (struct texture_image*)data; if (!d3d11) return 0; d3d11_texture_t* texture = calloc(1, sizeof(*texture)); - switch(filter_type) + switch (filter_type) { - case TEXTURE_FILTER_MIPMAP_LINEAR: - texture->desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; - /* fallthrough */ - case TEXTURE_FILTER_LINEAR: - texture->sampler = d3d11->sampler_linear; - break; - case TEXTURE_FILTER_MIPMAP_NEAREST: - texture->desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; - /* fallthrough */ - case TEXTURE_FILTER_NEAREST: - texture->sampler = d3d11->sampler_nearest; - break; + case TEXTURE_FILTER_MIPMAP_LINEAR: + texture->desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; + /* fallthrough */ + case TEXTURE_FILTER_LINEAR: + texture->sampler = d3d11->sampler_linear; + break; + case TEXTURE_FILTER_MIPMAP_NEAREST: + texture->desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; + /* fallthrough */ + case TEXTURE_FILTER_NEAREST: + texture->sampler = d3d11->sampler_nearest; + break; } - texture->desc.Width = image->width; - texture->desc.Height = image->height; + texture->desc.Width = image->width; + texture->desc.Height = image->height; texture->desc.Format = d3d11_get_closest_match_texture2D(d3d11->device, DXGI_FORMAT_B8G8R8A8_UNORM); diff --git a/gfx/drivers/d3d_shaders/ribbon_sm4.hlsl.h b/gfx/drivers/d3d_shaders/ribbon_sm4.hlsl.h new file mode 100644 index 0000000000..f50f725d2e --- /dev/null +++ b/gfx/drivers/d3d_shaders/ribbon_sm4.hlsl.h @@ -0,0 +1,78 @@ + +#define SRC(src) #src +SRC( + + struct PSInput + { + float4 position : SV_POSITION; + float3 vEC : TEXCOORD; + }; + + struct UBO + { + float4x4 modelViewProj; + float2 Outputsize; + float time; + }; + uniform UBO global; + + float iqhash(float n) + { + return frac(sin(n) * 43758.5453); + } + + float noise(float3 x) + { + float3 p = floor(x); + float3 f = frac(x); + f = f * f * (3.0 - 2.0 * f); + float n = p.x + p.y * 57.0 + 113.0 * p.z; + return lerp(lerp(lerp(iqhash(n), iqhash(n + 1.0), f.x), + lerp(iqhash(n + 57.0), iqhash(n + 58.0), f.x), f.y), + lerp(lerp(iqhash(n + 113.0), iqhash(n + 114.0), f.x), + lerp(iqhash(n + 170.0), iqhash(n + 171.0), f.x), f.y), f.z); + } + + float xmb_noise2(float3 x) + { + return cos(x.z * 4.0) * cos(x.z + global.time / 10.0 + x.x); + } + + PSInput VSMain(float2 position : POSITION) + { + float3 v = float3(position.x, 0.0, 1.0-position.y); + float3 v2 = v; + float3 v3 = v; + + v.y = xmb_noise2(v2) / 8.0; + + v3.x -= global.time / 5.0; + v3.x /= 4.0; + + v3.z -= global.time / 10.0; + v3.y -= global.time / 100.0; + + v.z -= noise(v3 * 7.0) / 15.0; + v.y -= noise(v3 * 7.0) / 15.0 + cos(v.x * 2.0 - global.time / 2.0) / 5.0 - 0.3; + v.y = -v.y; + + PSInput output; + output.position = float4(v.xy, 0.0, 1.0); + output.vEC = v; + return output; + } + + float4 PSMain(PSInput input) : SV_TARGET + { + const float3 up = float3(0.0, 0.0, 1.0); + float3 x = ddx(input.vEC); + float3 y = ddy(input.vEC); + float3 normal = normalize(cross(x, y)); + float c = 1.0 - dot(normal, up); + c = (1.0 - cos(c * c)) / 13.0; + return float4(c, c, c, 1.0); + // return float4(c, c, c, c); + // return float4(1.0, 1.0, 1.0, c); + // return float4(1.0, 0.0, 1.0, 1.0); + }; +) diff --git a/gfx/video_driver.h b/gfx/video_driver.h index 41d7c9772a..211f41fca3 100644 --- a/gfx/video_driver.h +++ b/gfx/video_driver.h @@ -43,7 +43,7 @@ #define RARCH_SCALE_BASE 256 -#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) || defined(HAVE_SLANG) +#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_D3D11) #ifndef HAVE_SHADER_MANAGER #define HAVE_SHADER_MANAGER #endif diff --git a/menu/drivers_display/menu_display_d3d11.c b/menu/drivers_display/menu_display_d3d11.c index 91102fa413..9d716f4ff8 100644 --- a/menu/drivers_display/menu_display_d3d11.c +++ b/menu/drivers_display/menu_display_d3d11.c @@ -47,7 +47,79 @@ static void menu_display_d3d11_draw(void* data) return; if (draw->pipeline.id) + { + switch (draw->pipeline.id) + { + case VIDEO_SHADER_MENU: + D3D11SetInputLayout(d3d11->ctx, d3d11->ribbon_layout); + D3D11SetVShader(d3d11->ctx, d3d11->ribbon_vs, NULL, 0); + D3D11SetPShader(d3d11->ctx, d3d11->ribbon_ps, NULL, 0); + D3D11SetGShader(d3d11->ctx, NULL, NULL, 0); + break; +#if 0 + case VIDEO_SHADER_MENU_2: + D3D11SetVShader(d3d11->ctx, d3d11->ribbon_simple_vs, NULL, 0); + D3D11SetPShader(d3d11->ctx, d3d11->ribbon_simple_ps, NULL, 0); + D3D11SetGShader(d3d11->ctx, NULL, NULL, 0); + break; + case VIDEO_SHADER_MENU_3: + D3D11SetVShader(d3d11->ctx, d3d11->snow_simple_vs, NULL, 0); + D3D11SetPShader(d3d11->ctx, d3d11->snow_simple_ps, NULL, 0); + D3D11SetGShader(d3d11->ctx, NULL, NULL, 0); + break; + case VIDEO_SHADER_MENU_4: + D3D11SetVShader(d3d11->ctx, d3d11->snow_vs, NULL, 0); + D3D11SetPShader(d3d11->ctx, d3d11->snow_ps, NULL, 0); + D3D11SetGShader(d3d11->ctx, NULL, NULL, 0); + break; + case VIDEO_SHADER_MENU_5: + D3D11SetVShader(d3d11->ctx, d3d11->bokeh_vs, NULL, 0); + D3D11SetPShader(d3d11->ctx, d3d11->bokeh_ps, NULL, 0); + D3D11SetGShader(d3d11->ctx, NULL, NULL, 0); + break; + case VIDEO_SHADER_MENU_6: + D3D11SetVShader(d3d11->ctx, d3d11->snowflake_vs, NULL, 0); + D3D11SetPShader(d3d11->ctx, d3d11->snowflake_ps, NULL, 0); + D3D11SetGShader(d3d11->ctx, NULL, NULL, 0); + break; +#endif + default: + break; + } + + switch (draw->pipeline.id) + { + case VIDEO_SHADER_MENU: +#if 0 + case VIDEO_SHADER_MENU_2: +#endif + D3D11Draw(d3d11->ctx, draw->coords->vertices, 0); + D3D11SetBlendState(d3d11->ctx, d3d11->blend_enable, NULL, D3D11_DEFAULT_SAMPLE_MASK); +#if 0 + case VIDEO_SHADER_MENU_3: + case VIDEO_SHADER_MENU_4: + case VIDEO_SHADER_MENU_5: + case VIDEO_SHADER_MENU_6: + D3D11Draw(d3d11->ctx, 1, 0); + break; +#endif + } + + { + UINT stride = sizeof(d3d11_sprite_t); + UINT offset = 0; + + D3D11SetVertexBuffers(d3d11->ctx, 0, 1, &d3d11->sprites.vbo, &stride, &offset); + } + + D3D11SetInputLayout(d3d11->ctx, d3d11->sprites.layout); + D3D11SetPrimitiveTopology(d3d11->ctx, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); + D3D11SetVShader(d3d11->ctx, d3d11->sprites.vs, NULL, 0); + D3D11SetPShader(d3d11->ctx, d3d11->sprites.ps, NULL, 0); + D3D11SetGShader(d3d11->ctx, d3d11->sprites.gs, NULL, 0); + return; + } if (!d3d11->sprites.enabled) return; @@ -99,7 +171,73 @@ static void menu_display_d3d11_draw(void* data) return; } -static void menu_display_d3d11_draw_pipeline(void* data) {} +static void menu_display_d3d11_draw_pipeline(void* data) +{ + menu_display_ctx_draw_t* draw = (menu_display_ctx_draw_t*)data; + d3d11_video_t* d3d11 = (d3d11_video_t*)video_driver_get_ptr(false); + + video_coord_array_t* ca = NULL; + + if (!d3d11 || !draw) + return; + + switch (draw->pipeline.id) + { + case VIDEO_SHADER_MENU: +#if 0 + case VIDEO_SHADER_MENU_2: +#endif + { + ca = menu_display_get_coords_array(); + + if (!d3d11->menu_pipeline_vbo) + { + D3D11_BUFFER_DESC desc = { + .Usage = D3D11_USAGE_IMMUTABLE, + .ByteWidth = ca->coords.vertices * 2 * sizeof(float), + .BindFlags = D3D11_BIND_VERTEX_BUFFER, + }; + D3D11_SUBRESOURCE_DATA vertexData = { ca->coords.vertex }; + D3D11CreateBuffer(d3d11->device, &desc, &vertexData, &d3d11->menu_pipeline_vbo); + } + + draw->coords->vertices = ca->coords.vertices; + + { + UINT stride = 2 * sizeof(float); + UINT offset = 0; + D3D11SetVertexBuffers(d3d11->ctx, 0, 1, &d3d11->menu_pipeline_vbo, &stride, &offset); + } + D3D11SetBlendState(d3d11->ctx, d3d11->blend_pipeline, NULL, D3D11_DEFAULT_SAMPLE_MASK); + } + break; +#if 0 + case VIDEO_SHADER_MENU_3: + case VIDEO_SHADER_MENU_4: + case VIDEO_SHADER_MENU_5: + case VIDEO_SHADER_MENU_6: + { + UINT stride = sizeof(d3d11_sprite_t); + UINT offset = 0; + D3D11SetVertexBuffers(d3d11->ctx, 0, 1, &d3d11->frame.vbo, &stride, &offset); + D3D11SetInputLayout(d3d11->ctx, d3d11->layout); + } + break; +#endif + default: + return; + } + + D3D11SetPrimitiveTopology(d3d11->ctx, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + d3d11->ubo_values.time += 0.01f; + { + D3D11_MAPPED_SUBRESOURCE mapped_ubo; + D3D11MapBuffer(d3d11->ctx, d3d11->ubo, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_ubo); + *(d3d11_uniform_t*)mapped_ubo.pData = d3d11->ubo_values; + D3D11UnmapBuffer(d3d11->ctx, d3d11->ubo, 0); + } +} static void menu_display_d3d11_restore_clear_color(void) {}