From 3865856aa2907bed3135546f7804b7aa2c766fae Mon Sep 17 00:00:00 2001 From: aliaspider Date: Thu, 1 Feb 2018 15:07:12 +0100 Subject: [PATCH] (D3D11) add support for `#pragma format` in slang shaders. --- gfx/common/d3d10_common.c | 9 ++- gfx/common/d3d11_common.c | 9 ++- gfx/common/d3d12_common.c | 4 ++ gfx/common/dxgi_common.c | 57 +++++++++++++++++-- gfx/common/dxgi_common.h | 3 + gfx/drivers/d3d11.c | 19 +++---- gfx/drivers_shader/glslang_util.cpp | 2 +- .../{glslang_util.hpp => glslang_util.h} | 19 +++++-- gfx/drivers_shader/shader_vulkan.cpp | 2 +- gfx/drivers_shader/slang_preprocess.cpp | 2 +- gfx/drivers_shader/slang_preprocess.h | 2 +- gfx/drivers_shader/slang_process.cpp | 16 +++++- gfx/drivers_shader/slang_process.h | 2 + 13 files changed, 115 insertions(+), 31 deletions(-) rename gfx/drivers_shader/{glslang_util.hpp => glslang_util.h} (92%) diff --git a/gfx/common/d3d10_common.c b/gfx/common/d3d10_common.c index ae59782065..5d91071db6 100644 --- a/gfx/common/d3d10_common.c +++ b/gfx/common/d3d10_common.c @@ -136,13 +136,16 @@ DXGI_FORMAT d3d10_get_closest_match(D3D10Device device, DXGI_FORMAT desired_format, UINT desired_format_support) { + DXGI_FORMAT default_list[] = {desired_format, DXGI_FORMAT_UNKNOWN}; DXGI_FORMAT* format = dxgi_get_format_fallback_list(desired_format); - UINT format_support; + + if(!format) + format = default_list; while (*format != DXGI_FORMAT_UNKNOWN) { - if (SUCCEEDED(D3D10CheckFormatSupport(device, *format, - &format_support)) && + UINT format_support; + if (SUCCEEDED(D3D10CheckFormatSupport(device, *format, &format_support)) && ((format_support & desired_format_support) == desired_format_support)) break; format++; diff --git a/gfx/common/d3d11_common.c b/gfx/common/d3d11_common.c index 6d7787c8e4..29db2222f5 100644 --- a/gfx/common/d3d11_common.c +++ b/gfx/common/d3d11_common.c @@ -13,6 +13,8 @@ * If not, see . */ +#include + #include "d3d11_common.h" #include "d3dcompiler_common.h" @@ -148,10 +150,15 @@ void d3d11_update_texture( DXGI_FORMAT d3d11_get_closest_match(D3D11Device device, DXGI_FORMAT desired_format, UINT desired_format_support) { + DXGI_FORMAT default_list[] = {desired_format, DXGI_FORMAT_UNKNOWN}; DXGI_FORMAT* format = dxgi_get_format_fallback_list(desired_format); - UINT format_support; + + if(!format) + format = default_list; + while (*format != DXGI_FORMAT_UNKNOWN) { + UINT format_support; if (SUCCEEDED(D3D11CheckFormatSupport(device, *format, &format_support)) && ((format_support & desired_format_support) == desired_format_support)) break; diff --git a/gfx/common/d3d12_common.c b/gfx/common/d3d12_common.c index 47f98b02bc..a92986b5c2 100644 --- a/gfx/common/d3d12_common.c +++ b/gfx/common/d3d12_common.c @@ -631,8 +631,12 @@ void d3d12_create_fullscreen_quad_vbo( DXGI_FORMAT d3d12_get_closest_match( D3D12Device device, DXGI_FORMAT desired_format, D3D12_FORMAT_SUPPORT1 desired_format_support) { + DXGI_FORMAT default_list[] = {desired_format, DXGI_FORMAT_UNKNOWN}; DXGI_FORMAT* format = dxgi_get_format_fallback_list(desired_format); + if(!format) + format = default_list; + while (*format != DXGI_FORMAT_UNKNOWN) { D3D12_FEATURE_DATA_FORMAT_SUPPORT format_support = { *format }; diff --git a/gfx/common/dxgi_common.c b/gfx/common/dxgi_common.c index 20cbaac0f6..dae80ff877 100644 --- a/gfx/common/dxgi_common.c +++ b/gfx/common/dxgi_common.c @@ -55,8 +55,6 @@ HRESULT WINAPI CreateDXGIFactory1(REFIID riid, void** ppFactory) DXGI_FORMAT* dxgi_get_format_fallback_list(DXGI_FORMAT format) { - static DXGI_FORMAT format_unknown = DXGI_FORMAT_UNKNOWN; - switch ((unsigned)format) { case DXGI_FORMAT_R32G32B32A32_FLOAT: @@ -129,9 +127,9 @@ DXGI_FORMAT* dxgi_get_format_fallback_list(DXGI_FORMAT format) return formats; } default: - assert(0); + break; } - return &format_unknown; + return NULL; } #define FORMAT_PROCESS_( \ @@ -353,3 +351,54 @@ void dxgi_input_driver(const char* name, const input_driver_t** input, void** in *input_data = input_dinput.init(name); *input = *input_data ? &input_dinput : NULL; } + +DXGI_FORMAT glslang_format_to_dxgi(glslang_format fmt) +{ +#undef FMT_ +#define FMT_(x) case SLANG_FORMAT_##x: return DXGI_FORMAT_##x +#undef FMT2 +#define FMT2(x,y) case SLANG_FORMAT_##x: return y + + switch (fmt) + { + FMT_(R8_UNORM); + FMT_(R8_SINT); + FMT_(R8_UINT); + FMT_(R8G8_UNORM); + FMT_(R8G8_SINT); + FMT_(R8G8_UINT); + FMT_(R8G8B8A8_UNORM); + FMT_(R8G8B8A8_SINT); + FMT_(R8G8B8A8_UINT); + FMT2(R8G8B8A8_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); + + FMT2(A2B10G10R10_UNORM_PACK32, DXGI_FORMAT_R10G10B10A2_UNORM); + FMT2(A2B10G10R10_UINT_PACK32, DXGI_FORMAT_R10G10B10A2_UNORM); + + FMT_(R16_UINT); + FMT_(R16_SINT); + FMT2(R16_SFLOAT, DXGI_FORMAT_R16_FLOAT); + FMT_(R16G16_UINT); + FMT_(R16G16_SINT); + FMT2(R16G16_SFLOAT, DXGI_FORMAT_R16G16_FLOAT); + FMT_(R16G16B16A16_UINT); + FMT_(R16G16B16A16_SINT); + FMT2(R16G16B16A16_SFLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT); + + FMT_(R32_UINT); + FMT_(R32_SINT); + FMT2(R32_SFLOAT, DXGI_FORMAT_R32_FLOAT); + FMT_(R32G32_UINT); + FMT_(R32G32_SINT); + FMT2(R32G32_SFLOAT, DXGI_FORMAT_R32G32_FLOAT); + FMT_(R32G32B32A32_UINT); + FMT_(R32G32B32A32_SINT); + FMT2(R32G32B32A32_SFLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT); + + case SLANG_FORMAT_UNKNOWN: + default: + break; + } + + return DXGI_FORMAT_UNKNOWN; +} diff --git a/gfx/common/dxgi_common.h b/gfx/common/dxgi_common.h index 7978604ea9..d5f09e78f4 100644 --- a/gfx/common/dxgi_common.h +++ b/gfx/common/dxgi_common.h @@ -770,6 +770,7 @@ static INLINE HRESULT DXGICreateFactory(DXGIFactory* factory) /* internal */ #include "../video_driver.h" +#include "../drivers_shader/glslang_util.h" #define DXGI_COLOR_RGBA(r, g, b, a) (((UINT32)(a) << 24) | ((UINT32)(b) << 16) | ((UINT32)(g) << 8) | ((UINT32)(r) << 0)) @@ -794,6 +795,8 @@ void dxgi_copy( void dxgi_update_title(video_frame_info_t* video_info); void dxgi_input_driver(const char* name, const input_driver_t** input, void** input_data); +DXGI_FORMAT glslang_format_to_dxgi(glslang_format fmt); + RETRO_END_DECLS #if 1 diff --git a/gfx/drivers/d3d11.c b/gfx/drivers/d3d11.c index ee1068a144..559518a2d2 100644 --- a/gfx/drivers/d3d11.c +++ b/gfx/drivers/d3d11.c @@ -76,14 +76,14 @@ static void d3d11_update_viewport(void* data, bool force_full) d3d11->frame.viewport.Height = d3d11->vp.height; d3d11->frame.viewport.MaxDepth = 0.0f; d3d11->frame.viewport.MaxDepth = 1.0f; - if(d3d11->frame.output_size.x != d3d11->vp.width || - d3d11->frame.output_size.y != d3d11->vp.height) + if (d3d11->frame.output_size.x != d3d11->vp.width || + d3d11->frame.output_size.y != d3d11->vp.height) d3d11->resize_fbos = true; - d3d11->frame.output_size.x = d3d11->vp.width; - d3d11->frame.output_size.y = d3d11->vp.height; - d3d11->frame.output_size.z = 1.0f / d3d11->vp.width; - d3d11->frame.output_size.w = 1.0f / d3d11->vp.height; + d3d11->frame.output_size.x = d3d11->vp.width; + d3d11->frame.output_size.y = d3d11->vp.height; + d3d11->frame.output_size.z = 1.0f / d3d11->vp.width; + d3d11->frame.output_size.w = 1.0f / d3d11->vp.height; d3d11->resize_viewport = false; } @@ -754,10 +754,7 @@ static bool d3d11_init_frame_textures(d3d11_video_t* d3d11, unsigned width, unsi d3d11->pass[i].rt.desc.Width = width; d3d11->pass[i].rt.desc.Height = height; d3d11->pass[i].rt.desc.BindFlags = D3D11_BIND_RENDER_TARGET; - d3d11->pass[i].rt.desc.Format = pass->fbo.fp_fbo ? DXGI_FORMAT_R32G32B32A32_FLOAT - : pass->fbo.srgb_fbo - ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB - : DXGI_FORMAT_R8G8B8A8_UNORM; + d3d11->pass[i].rt.desc.Format = glslang_format_to_dxgi(d3d11->pass[i].semantics.format); if ((i != (d3d11->shader_preset->passes - 1)) || (width != d3d11->vp.width) || (height != d3d11->vp.height)) @@ -830,7 +827,7 @@ static bool d3d11_gfx_frame( d3d11->resize_chain = false; d3d11->resize_viewport = true; - video_driver_set_size(&video_info->width, &video_info->height); + video_driver_set_size(&video_info->width, &video_info->height); } PERF_START(); diff --git a/gfx/drivers_shader/glslang_util.cpp b/gfx/drivers_shader/glslang_util.cpp index cb7ec20bc4..3094fb00ae 100644 --- a/gfx/drivers_shader/glslang_util.cpp +++ b/gfx/drivers_shader/glslang_util.cpp @@ -29,7 +29,7 @@ #include "config.h" #endif -#include "glslang_util.hpp" +#include "glslang_util.h" #ifdef HAVE_VULKAN #include "glslang.hpp" #endif diff --git a/gfx/drivers_shader/glslang_util.hpp b/gfx/drivers_shader/glslang_util.h similarity index 92% rename from gfx/drivers_shader/glslang_util.hpp rename to gfx/drivers_shader/glslang_util.h index a9a42f1ee8..e937e34d7a 100644 --- a/gfx/drivers_shader/glslang_util.hpp +++ b/gfx/drivers_shader/glslang_util.h @@ -17,10 +17,9 @@ #define GLSLANG_UTIL_HPP #include -#include -#include +#include -enum glslang_format +typedef enum glslang_format { // 8-bit SLANG_FORMAT_R8_UNORM = 0, @@ -61,7 +60,17 @@ enum glslang_format SLANG_FORMAT_R32G32B32A32_SFLOAT, SLANG_FORMAT_UNKNOWN -}; +}glslang_format; + +RETRO_BEGIN_DECLS + +const char *glslang_format_to_string(glslang_format fmt); + +RETRO_END_DECLS + +#ifdef __cplusplus +#include +#include struct glslang_parameter { @@ -88,11 +97,11 @@ struct glslang_output }; bool glslang_compile_shader(const char *shader_path, glslang_output *output); -const char *glslang_format_to_string(enum glslang_format fmt); // Helpers for internal use. bool glslang_read_shader_file(const char *path, std::vector *output, bool root_file); bool glslang_parse_meta(const std::vector &lines, glslang_meta *meta); +#endif #endif diff --git a/gfx/drivers_shader/shader_vulkan.cpp b/gfx/drivers_shader/shader_vulkan.cpp index 4e0747b12b..d7d86258e9 100644 --- a/gfx/drivers_shader/shader_vulkan.cpp +++ b/gfx/drivers_shader/shader_vulkan.cpp @@ -15,7 +15,7 @@ */ #include "shader_vulkan.h" -#include "glslang_util.hpp" +#include "glslang_util.h" #include #include #include diff --git a/gfx/drivers_shader/slang_preprocess.cpp b/gfx/drivers_shader/slang_preprocess.cpp index d116f95f78..ec4daa666e 100644 --- a/gfx/drivers_shader/slang_preprocess.cpp +++ b/gfx/drivers_shader/slang_preprocess.cpp @@ -14,7 +14,7 @@ */ #include "slang_preprocess.h" -#include "glslang_util.hpp" +#include "glslang_util.h" #include #include #include diff --git a/gfx/drivers_shader/slang_preprocess.h b/gfx/drivers_shader/slang_preprocess.h index 4cb423af0a..61291e9341 100644 --- a/gfx/drivers_shader/slang_preprocess.h +++ b/gfx/drivers_shader/slang_preprocess.h @@ -32,7 +32,7 @@ RETRO_END_DECLS #ifdef __cplusplus -#include "glslang_util.hpp" +#include "glslang_util.h" bool slang_preprocess_parse_parameters(glslang_meta& meta, struct video_shader *shader); diff --git a/gfx/drivers_shader/slang_process.cpp b/gfx/drivers_shader/slang_process.cpp index 4d23ae8dc7..1f06c43551 100644 --- a/gfx/drivers_shader/slang_process.cpp +++ b/gfx/drivers_shader/slang_process.cpp @@ -5,7 +5,7 @@ #include #include "verbosity.h" -#include "glslang_util.hpp" +#include "glslang_util.h" #include "slang_preprocess.h" #include "slang_reflection.h" #include "slang_process.h" @@ -151,8 +151,6 @@ static bool slang_process_reflection( return false; } - memset(out, 0x00, sizeof(*out)); - out->cbuffers[SLANG_CBUFFER_UBO].stage_mask = sl_reflection.ubo_stage_mask; out->cbuffers[SLANG_CBUFFER_UBO].binding = sl_reflection.ubo_binding; out->cbuffers[SLANG_CBUFFER_UBO].size = (sl_reflection.ubo_size + 0xF) & ~0xF; @@ -295,6 +293,18 @@ bool slang_process( if (!slang_preprocess_parse_parameters(output.meta, shader_info)) return false; + out->format = output.meta.rt_format; + + if (out->format == SLANG_FORMAT_UNKNOWN) + { + if (pass.fbo.srgb_fbo) + out->format = SLANG_FORMAT_R8G8B8A8_SRGB; + else if (pass.fbo.fp_fbo) + out->format = SLANG_FORMAT_R16G16B16A16_SFLOAT; + else + out->format = SLANG_FORMAT_R8G8B8A8_UNORM; + } + pass.source.string.vertex = NULL; pass.source.string.fragment = NULL; diff --git a/gfx/drivers_shader/slang_process.h b/gfx/drivers_shader/slang_process.h index 9fafd71ed6..f6ec33a908 100644 --- a/gfx/drivers_shader/slang_process.h +++ b/gfx/drivers_shader/slang_process.h @@ -22,6 +22,7 @@ #include "../video_shader_parse.h" #include "slang_reflection.h" +#include "glslang_util.h" typedef struct { @@ -94,6 +95,7 @@ typedef struct int texture_count; texture_sem_t* textures; cbuffer_sem_t cbuffers[SLANG_CBUFFER_MAX]; + glslang_format format; } pass_semantics_t; #define SLANG_STAGE_VERTEX_MASK (1 << 0)