diff --git a/Makefile.common b/Makefile.common index 49dd6d3292..62039e6871 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1153,54 +1153,18 @@ endif ifeq ($(HAVE_VULKAN), 1) ifneq ($(findstring Win32,$(OS)),) - GLSLANG_PLATFORM := Windows - WANT_WGL = 1 - else - GLSLANG_PLATFORM := Unix - endif - - GLSLANG_SOURCES := \ - $(wildcard $(DEPS_DIR)/glslang/*.cpp) \ - $(wildcard $(DEPS_DIR)/glslang/glslang/SPIRV/*.cpp) \ - $(wildcard $(DEPS_DIR)/glslang/glslang/glslang/GenericCodeGen/*.cpp) \ - $(wildcard $(DEPS_DIR)/glslang/glslang/OGLCompilersDLL/*.cpp) \ - $(wildcard $(DEPS_DIR)/glslang/glslang/glslang/MachineIndependent/*.cpp) \ - $(wildcard $(DEPS_DIR)/glslang/glslang/glslang/MachineIndependent/preprocessor/*.cpp) \ - $(wildcard $(DEPS_DIR)/glslang/glslang/hlsl/*.cpp) \ - $(wildcard $(DEPS_DIR)/glslang/glslang/glslang/OSDependent/$(GLSLANG_PLATFORM)/*.cpp) - - SPIRV_CROSS_SOURCES := $(DEPS_DIR)/SPIRV-Cross/spirv_cross.cpp \ - $(DEPS_DIR)/SPIRV-Cross/spirv_cfg.cpp - ifneq ($(findstring Win32,$(OS)),) + WANT_WGL = 1 # Trivial temporary workaround for MinGW and glslang. CXXFLAGS += -fpermissive endif - DEFINES += \ - -I$(DEPS_DIR)/glslang/glslang/glslang/OSDependent/$(GLSLANG_PLATFORM) \ - -I$(DEPS_DIR)/glslang/glslang/OGLCompilersDLL \ - -I$(DEPS_DIR)/glslang/glslang \ - -I$(DEPS_DIR)/glslang/glslang/glslang/MachineIndependent \ - -I$(DEPS_DIR)/glslang/glslang/glslang/Public \ - -I$(DEPS_DIR)/glslang/glslang/SPIRV \ - -I$(DEPS_DIR)/glslang \ - -I$(DEPS_DIR)/SPIRV-Cross - CXXFLAGS += -Wno-switch -Wno-sign-compare -fno-strict-aliasing -Wno-maybe-uninitialized -Wno-reorder -Wno-parentheses - GLSLANG_OBJ := $(GLSLANG_SOURCES:.cpp=.o) - SPIRV_CROSS_OBJ := $(SPIRV_CROSS_SOURCES:.cpp=.o) - OBJ += gfx/drivers/vulkan.o \ gfx/common/vulkan_common.o \ $(LIBRETRO_COMM_DIR)/vulkan/vulkan_symbol_wrapper.o \ gfx/drivers_font/vulkan_raster_font.o \ - gfx/drivers_shader/shader_vulkan.o \ - gfx/drivers_shader/glslang_util.o \ - gfx/drivers_shader/slang_reflection.o \ - gfx/drivers_shader/slang_preprocess.o \ - $(GLSLANG_OBJ) \ - $(SPIRV_CROSS_OBJ) + gfx/drivers_shader/shader_vulkan.o ifeq ($(HAVE_VULKAN_DISPLAY), 1) OBJ += gfx/drivers_context/khr_display_ctx.o @@ -1209,20 +1173,12 @@ ifeq ($(HAVE_VULKAN), 1) OBJ += menu/drivers_display/menu_display_vulkan.o endif LIBS += -lstdc++ - DEFINES += -DHAVE_SLANG -endif - -ifeq ($(findstring 1, $(HAVE_VULKAN) $(HAVE_D3D10) $(HAVE_D3D11) $(HAVE_D3D12)),1) + DEFINES += -DHAVE_VULKAN INCLUDE_DIRS += -Igfx/include -endif -ifeq ($(findstring 1, $(HAVE_D3D10) $(HAVE_D3D11) $(HAVE_D3D12)),1) - INCLUDE_DIRS += -Igfx/include/dxsdk -endif - -ifeq ($(WANT_WGL), 1) - OBJ += gfx/drivers_context/wgl_ctx.o -LIBS += -lcomctl32 + HAVE_SLANG = 1 + HAVE_GLSLANG = 1 + HAVE_SPIRV_CROSS = 1 endif ifeq ($(HAVE_OMAP), 1) @@ -1305,6 +1261,9 @@ ifeq ($(HAVE_D3D11), 1) OBJ += gfx/drivers/d3d11.o gfx/common/d3d11_common.o \ gfx/drivers_font/d3d11_font.o menu/drivers_display/menu_display_d3d11.o DEFINES += -DHAVE_D3D11 + HAVE_SLANG = 1 + HAVE_GLSLANG = 1 + HAVE_SPIRV_CROSS = 1 endif ifeq ($(HAVE_D3D12), 1) @@ -1313,6 +1272,7 @@ ifeq ($(HAVE_D3D12), 1) endif ifneq ($(findstring 1, $(HAVE_D3D10) $(HAVE_D3D11) $(HAVE_D3D12)),) + INCLUDE_DIRS += -isystemgfx/include/dxsdk OBJ += gfx/common/d3dcompiler_common.o OBJ += gfx/common/dxgi_common.o CFLAGS += -Wno-unknown-pragmas @@ -1355,6 +1315,58 @@ ifeq ($(HAVE_D3D_COMMON), 1) endif endif +ifeq ($(HAVE_SLANG),1) + DEFINES += -DHAVE_SLANG + OBJ += gfx/drivers_shader/slang_process.o + OBJ += gfx/drivers_shader/slang_preprocess.o + OBJ += gfx/drivers_shader/glslang_util.o + OBJ += gfx/drivers_shader/slang_reflection.o +endif + +ifeq ($(HAVE_GLSLANG), 1) + DEFINES += -DHAVE_GLSLANG + + ifneq ($(findstring Win32,$(OS)),) + GLSLANG_PLATFORM := Windows + else + GLSLANG_PLATFORM := Unix + endif + + INCLUDE_DIRS += \ + -I$(DEPS_DIR)/glslang/glslang/glslang/OSDependent/$(GLSLANG_PLATFORM) \ + -I$(DEPS_DIR)/glslang/glslang/OGLCompilersDLL \ + -I$(DEPS_DIR)/glslang/glslang \ + -I$(DEPS_DIR)/glslang/glslang/glslang/MachineIndependent \ + -I$(DEPS_DIR)/glslang/glslang/glslang/Public \ + -I$(DEPS_DIR)/glslang/glslang/SPIRV \ + -I$(DEPS_DIR)/glslang + + GLSLANG_SOURCES := \ + $(wildcard $(DEPS_DIR)/glslang/*.cpp) \ + $(wildcard $(DEPS_DIR)/glslang/glslang/SPIRV/*.cpp) \ + $(wildcard $(DEPS_DIR)/glslang/glslang/glslang/GenericCodeGen/*.cpp) \ + $(wildcard $(DEPS_DIR)/glslang/glslang/OGLCompilersDLL/*.cpp) \ + $(wildcard $(DEPS_DIR)/glslang/glslang/glslang/MachineIndependent/*.cpp) \ + $(wildcard $(DEPS_DIR)/glslang/glslang/glslang/MachineIndependent/preprocessor/*.cpp) \ + $(wildcard $(DEPS_DIR)/glslang/glslang/hlsl/*.cpp) \ + $(wildcard $(DEPS_DIR)/glslang/glslang/glslang/OSDependent/$(GLSLANG_PLATFORM)/*.cpp) + + OBJ += $(GLSLANG_SOURCES:.cpp=.o) +endif + +ifeq ($(HAVE_SPIRV_CROSS), 1) + INCLUDE_DIRS += -I$(DEPS_DIR)/SPIRV-Cross + OBJ += $(DEPS_DIR)/SPIRV-Cross/spirv_cross.o + OBJ += $(DEPS_DIR)/SPIRV-Cross/spirv_cfg.o + OBJ += $(DEPS_DIR)/SPIRV-Cross/spirv_glsl.o + OBJ += $(DEPS_DIR)/SPIRV-Cross/spirv_hlsl.o +endif + +ifeq ($(WANT_WGL), 1) + OBJ += gfx/drivers_context/wgl_ctx.o + LIBS += -lcomctl32 +endif + #ifeq ($(HAVE_LIBXML2), 1) #LIBS += $(LIBXML2_LIBS) #DEFINES += $(LIBXML2_CFLAGS) diff --git a/Makefile.msvc b/Makefile.msvc index 93c9177ae2..b21810c96f 100644 --- a/Makefile.msvc +++ b/Makefile.msvc @@ -20,6 +20,10 @@ HAVE_D3D12 := 1 HAVE_CG := 1 HAVE_OPENGL := 1 HAVE_VULKAN := 1 +HAVE_XAUDIO := 1 +HAVE_XINPUT := 1 +HAVE_WASAPI := 0 +HAVE_THREAD_STORAGE := 1 HAVE_RPNG := 1 HAVE_ZLIB := 1 @@ -52,13 +56,11 @@ HAVE_KEYMAPPER := 1 HAVE_SHADERPIPELINE := 1 include Makefile.common -CFLAGS := $(filter-out -Wno-unknown-pragmas,$(CFLAGS)) -CXXFLAGS := $(filter-out -fpermissive -Wno-switch -Wno-sign-compare -fno-strict-aliasing -Wno-maybe-uninitialized -Wno-reorder -Wno-parentheses,$(CXXFLAGS)) -CXXFLAGS += $(CFLAGS) -LIBS := $(filter-out -lstdc++,$(LIBS)) -ifeq ($(HAVE_VULKAN),1) - DEFINES += -DHAVE_VULKAN -endif +INCLUDE_DIRS := $(patsubst -isystem%,-I%,$(INCLUDE_DIRS)) +CFLAGS := $(filter-out -Wno-unknown-pragmas,$(CFLAGS)) +CXXFLAGS := $(filter-out -fpermissive -Wno-switch -Wno-sign-compare -fno-strict-aliasing -Wno-maybe-uninitialized -Wno-reorder -Wno-parentheses,$(CXXFLAGS)) +CXXFLAGS += $(CFLAGS) +LIBS := $(filter-out -lstdc++,$(LIBS)) ifeq ($(ARCH),x64) ARCH := amd64 @@ -138,13 +140,13 @@ LDFLAGS += -nologo -wx -nxcompat -machine:$(TARGET_ARCH2) ifeq ($(DEBUG),1) -FLAGS += -GS -Gy -Od -RTC1 -D_SECURE_SCL=1 -Zi -FLAGS += -MDd -LDFLAGS += -DEBUG -DEFINES += -DDEBUG -D_DEBUG + FLAGS += -GS -Gy -Od -RTC1 -D_SECURE_SCL=1 -Zi + FLAGS += -MDd + LDFLAGS += -DEBUG + DEFINES += -DDEBUG -D_DEBUG else -FLAGS += -GS- -Gy- -O2 -Ob2 -GF -GT -Oy -Ot -D_SECURE_SCL=0 -FLAGS += -MD + FLAGS += -GS- -Gy- -O2 -Ob2 -GF -GT -Oy -Ot -D_SECURE_SCL=0 + FLAGS += -MD endif @@ -167,7 +169,6 @@ ifeq ($(GRIFFIN_BUILD), 1) OBJ := griffin/griffin.o griffin/griffin_cpp.o DEFINES += -DHAVE_GRIFFIN -DUSE_MATH_DEFINES else - DEFINES += -DWANT_GLSLANG BLACKLIST := OBJ := $(filter-out $(BLACKLIST),$(OBJ)) endif @@ -252,9 +253,7 @@ $(BUILD_DIR)/$(TARGET): $(OBJ) .$(TARGET).last @touch .$(TARGET).last $(Q)$(LD) $(OBJ) $(LDFLAGS) $(LIBS) -out:$(BUILD_DIR)/$(TARGET) -%.depend: ; -%.last: ; -%.h : ; +%.h %.hpp %.depend %.last: ; clean: rm -f $(OBJ) $(TARGET) diff --git a/configuration.c b/configuration.c index 13b48bc148..e7a8cae859 100644 --- a/configuration.c +++ b/configuration.c @@ -2266,6 +2266,7 @@ static bool check_shader_compatibility(enum file_path_enum enum_idx) settings_t *settings = config_get_ptr(); if (string_is_equal(settings->arrays.video_driver, "vulkan") || + string_is_equal(settings->arrays.video_driver, "d3d11") || string_is_equal(settings->arrays.video_driver, "gx2")) { if (enum_idx != FILE_PATH_SLANGP_EXTENSION) diff --git a/gfx/common/d3d11_common.c b/gfx/common/d3d11_common.c index 6866c5d3d8..8ed858a041 100644 --- a/gfx/common/d3d11_common.c +++ b/gfx/common/d3d11_common.c @@ -57,21 +57,21 @@ HRESULT WINAPI D3D11CreateDeviceAndSwapChain( void d3d11_init_texture(D3D11Device device, d3d11_texture_t* texture) { - Release(texture->handle); - Release(texture->staging); - Release(texture->view); + bool is_render_target = texture->desc.BindFlags & D3D11_BIND_RENDER_TARGET; + + d3d11_release_texture(texture); texture->desc.MipLevels = 1; texture->desc.ArraySize = 1; texture->desc.SampleDesc.Count = 1; texture->desc.SampleDesc.Quality = 0; - texture->desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + texture->desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; texture->desc.CPUAccessFlags = texture->desc.Usage == D3D11_USAGE_DYNAMIC ? D3D11_CPU_ACCESS_WRITE : 0; if (texture->desc.MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS) { - texture->desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + texture->desc.BindFlags |= D3D11_BIND_RENDER_TARGET; unsigned width = texture->desc.Width >> 5; unsigned height = texture->desc.Height >> 5; while (width && height) @@ -93,6 +93,9 @@ void d3d11_init_texture(D3D11Device device, d3d11_texture_t* texture) D3D11CreateTexture2DShaderResourceView(device, texture->handle, &view_desc, &texture->view); } + if (is_render_target) + D3D11CreateTexture2DRenderTargetView(device, texture->handle, NULL, &texture->rt_view); + else { D3D11_TEXTURE2D_DESC desc = texture->desc; desc.MipLevels = 1; @@ -102,6 +105,11 @@ void d3d11_init_texture(D3D11Device device, d3d11_texture_t* texture) desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; D3D11CreateTexture2D(device, &desc, NULL, &texture->staging); } + + texture->size_data.x = texture->desc.Width; + texture->size_data.y = texture->desc.Height; + texture->size_data.z = 1.0f / texture->desc.Width; + texture->size_data.w = 1.0f / texture->desc.Height; } void d3d11_update_texture( @@ -162,35 +170,44 @@ bool d3d11_init_shader( D3DBlob ps_code; D3DBlob gs_code; - if (size) /* char array */ + if (size < 0) /* LPCWSTR filename */ { - if (!d3d_compile(src, size, vs_entry, "vs_5_0", &vs_code)) + if (vs_entry && !d3d_compile_from_file(src, vs_entry, "vs_5_0", &vs_code)) return false; - if (!d3d_compile(src, size, ps_entry, "ps_5_0", &ps_code)) - return false; - if (gs_entry && !d3d_compile(src, size, gs_entry, "gs_5_0", &gs_code)) - return false; - } - else /* LPCWSTR filename */ - { - if (!d3d_compile_from_file(src, vs_entry, "vs_5_0", &vs_code)) - return false; - if (!d3d_compile_from_file(src, ps_entry, "ps_5_0", &ps_code)) + if (ps_entry && !d3d_compile_from_file(src, ps_entry, "ps_5_0", &ps_code)) return false; if (gs_entry && !d3d_compile_from_file(src, gs_entry, "gs_5_0", &gs_code)) return false; } + else /* char array */ + { + if (!size) + size = strlen(src); - D3D11CreateVertexShader( - device, D3DGetBufferPointer(vs_code), D3DGetBufferSize(vs_code), NULL, &out->vs); - D3D11CreateInputLayout( - device, input_element_descs, num_elements, D3DGetBufferPointer(vs_code), - D3DGetBufferSize(vs_code), &out->layout); - Release(vs_code); + if (vs_entry && !d3d_compile(src, size, vs_entry, "vs_5_0", &vs_code)) + return false; + if (ps_entry && !d3d_compile(src, size, ps_entry, "ps_5_0", &ps_code)) + return false; + if (gs_entry && !d3d_compile(src, size, gs_entry, "gs_5_0", &gs_code)) + return false; + } - D3D11CreatePixelShader( - device, D3DGetBufferPointer(ps_code), D3DGetBufferSize(ps_code), NULL, &out->ps); - Release(ps_code); + if (vs_entry) + { + D3D11CreateVertexShader( + device, D3DGetBufferPointer(vs_code), D3DGetBufferSize(vs_code), NULL, &out->vs); + D3D11CreateInputLayout( + device, input_element_descs, num_elements, D3DGetBufferPointer(vs_code), + D3DGetBufferSize(vs_code), &out->layout); + Release(vs_code); + } + + if (ps_entry) + { + D3D11CreatePixelShader( + device, D3DGetBufferPointer(ps_code), D3DGetBufferSize(ps_code), NULL, &out->ps); + Release(ps_code); + } if (gs_entry) { diff --git a/gfx/common/d3d11_common.h b/gfx/common/d3d11_common.h index a01a1e48d6..49a39613d8 100644 --- a/gfx/common/d3d11_common.h +++ b/gfx/common/d3d11_common.h @@ -20,17 +20,21 @@ #include "dxgi_common.h" #include -typedef ID3D11InputLayout* D3D11InputLayout; -typedef ID3D11RasterizerState* D3D11RasterizerState; -typedef ID3D11DepthStencilState* D3D11DepthStencilState; -typedef ID3D11BlendState* D3D11BlendState; -typedef ID3D11PixelShader* D3D11PixelShader; -typedef ID3D11SamplerState* D3D11SamplerState; -typedef ID3D11VertexShader* D3D11VertexShader; -typedef ID3D11DomainShader* D3D11DomainShader; -typedef ID3D11HullShader* D3D11HullShader; -typedef ID3D11ComputeShader* D3D11ComputeShader; -typedef ID3D11GeometryShader* D3D11GeometryShader; +typedef const ID3D11ShaderResourceView* D3D11ShaderResourceViewRef; +typedef const ID3D11SamplerState* D3D11SamplerStateRef; +typedef const ID3D11BlendState* D3D11BlendStateRef; + +typedef ID3D11InputLayout* D3D11InputLayout; +typedef ID3D11RasterizerState* D3D11RasterizerState; +typedef ID3D11DepthStencilState* D3D11DepthStencilState; +typedef ID3D11BlendState* D3D11BlendState; +typedef ID3D11PixelShader* D3D11PixelShader; +typedef ID3D11SamplerState* D3D11SamplerState; +typedef ID3D11VertexShader* D3D11VertexShader; +typedef ID3D11DomainShader* D3D11DomainShader; +typedef ID3D11HullShader* D3D11HullShader; +typedef ID3D11ComputeShader* D3D11ComputeShader; +typedef ID3D11GeometryShader* D3D11GeometryShader; /* auto-generated */ @@ -68,6 +72,7 @@ typedef ID3D11SwitchToRef* D3D11SwitchToRef; typedef ID3D11TracingDevice* D3D11TracingDevice; typedef ID3D11InfoQueue* D3D11InfoQueue; +#if !defined(__cplusplus) || defined(CINTERFACE) static INLINE void D3D11SetResourceEvictionPriority(D3D11Resource resource, UINT eviction_priority) { resource->lpVtbl->SetEvictionPriority(resource, eviction_priority); @@ -196,16 +201,16 @@ static INLINE void D3D11SetVShaderConstantBuffers( D3D11DeviceContext device_context, UINT start_slot, UINT num_buffers, - D3D11Buffer* const constant_buffers) + const D3D11Buffer* constant_buffers) { device_context->lpVtbl->VSSetConstantBuffers( device_context, start_slot, num_buffers, constant_buffers); } static INLINE void D3D11SetPShaderResources( - D3D11DeviceContext device_context, - UINT start_slot, - UINT num_views, - D3D11ShaderResourceView* const shader_resource_views) + D3D11DeviceContext device_context, + UINT start_slot, + UINT num_views, + ID3D11ShaderResourceView* const* shader_resource_views) { device_context->lpVtbl->PSSetShaderResources( device_context, start_slot, num_views, shader_resource_views); @@ -220,12 +225,13 @@ static INLINE void D3D11SetPShader( device_context, pixel_shader, class_instances, num_class_instances); } static INLINE void D3D11SetPShaderSamplers( - D3D11DeviceContext device_context, - UINT start_slot, - UINT num_samplers, - D3D11SamplerState* const samplers) + D3D11DeviceContext device_context, + UINT start_slot, + UINT num_samplers, + D3D11SamplerStateRef* samplers) { - device_context->lpVtbl->PSSetSamplers(device_context, start_slot, num_samplers, samplers); + device_context->lpVtbl->PSSetSamplers( + device_context, start_slot, num_samplers, (D3D11SamplerState* const)samplers); } static INLINE void D3D11SetVShader( D3D11DeviceContext device_context, @@ -270,7 +276,7 @@ static INLINE void D3D11SetPShaderConstantBuffers( D3D11DeviceContext device_context, UINT start_slot, UINT num_buffers, - D3D11Buffer* const constant_buffers) + const D3D11Buffer* constant_buffers) { device_context->lpVtbl->PSSetConstantBuffers( device_context, start_slot, num_buffers, constant_buffers); @@ -284,7 +290,7 @@ static INLINE void D3D11SetVertexBuffers( D3D11DeviceContext device_context, UINT start_slot, UINT num_buffers, - D3D11Buffer* const vertex_buffers, + const D3D11Buffer* vertex_buffers, UINT* strides, UINT* offsets) { @@ -2402,13 +2408,24 @@ D3D11UnmapBuffer(D3D11DeviceContext device_context, D3D11Buffer buffer, UINT sub { device_context->lpVtbl->Unmap(device_context, (D3D11Resource)buffer, subresource); } +#endif /* internal */ + #include #include #include #include #include "../video_driver.h" +#include "../drivers_shader/slang_process.h" + +typedef struct +{ + float x; + float y; + float z; + float w; +} float4_t; typedef struct d3d11_vertex_t { @@ -2422,8 +2439,10 @@ typedef struct D3D11Texture2D handle; D3D11Texture2D staging; D3D11_TEXTURE2D_DESC desc; + D3D11RenderTargetView rt_view; D3D11ShaderResourceView view; - D3D11SamplerState sampler; + D3D11SamplerStateRef sampler; + float4_t size_data; } d3d11_texture_t; typedef struct @@ -2463,9 +2482,10 @@ typedef struct ALIGN(16) float time; } d3d11_uniform_t; -static_assert(!(sizeof(d3d11_uniform_t) & 0xF), "sizeof(d3d11_uniform_t) must be a multiple of 16"); +static_assert( + (!(sizeof(d3d11_uniform_t) & 0xF)), "sizeof(d3d11_uniform_t) must be a multiple of 16"); -typedef struct +typedef struct d3d11_shader_t { D3D11VertexShader vs; D3D11PixelShader ps; @@ -2499,21 +2519,8 @@ typedef struct bool resize_chain; bool keep_aspect; bool resize_viewport; - struct - { - d3d11_texture_t texture; - D3D11Buffer vbo; - bool enabled; - bool fullscreen; - } menu; - struct - { - d3d11_texture_t texture; - D3D11Buffer vbo; - D3D11Buffer ubo; - D3D11_VIEWPORT viewport; - int rotation; - } frame; + d3d11_shader_t shaders[GFX_MAX_SHADERS]; + struct { d3d11_shader_t shader; @@ -2523,10 +2530,51 @@ typedef struct int capacity; bool enabled; } sprites; - d3d11_shader_t shaders[GFX_MAX_SHADERS]; + + struct + { + d3d11_texture_t texture; + D3D11Buffer vbo; + bool enabled; + bool fullscreen; + } menu; + + struct + { + d3d11_texture_t texture; + D3D11Buffer vbo; + D3D11Buffer ubo; + D3D11_VIEWPORT viewport; + float4_t output_size; + int rotation; + } frame; + + struct + { + d3d11_shader_t shader; + D3D11SamplerStateRef sampler; + D3D11Buffer buffers[SLANG_CBUFFER_MAX]; + d3d11_texture_t rt; + D3D11_VIEWPORT viewport; + pass_semantics_t semantics; + D3D11ShaderResourceViewRef textures[SLANG_NUM_BINDINGS]; + D3D11SamplerStateRef samplers[SLANG_NUM_BINDINGS]; + float frame_count; + } pass[GFX_MAX_SHADERS]; + + struct video_shader* shader_preset; + d3d11_texture_t luts[GFX_MAX_TEXTURES]; } d3d11_video_t; void d3d11_init_texture(D3D11Device device, d3d11_texture_t* texture); +static INLINE void d3d11_release_texture(d3d11_texture_t* texture) +{ + Release(texture->handle); + Release(texture->staging); + Release(texture->view); + Release(texture->rt_view); +} + void d3d11_update_texture( D3D11DeviceContext ctx, int width, @@ -2535,6 +2583,7 @@ void d3d11_update_texture( DXGI_FORMAT format, const void* data, d3d11_texture_t* texture); + DXGI_FORMAT d3d11_get_closest_match( D3D11Device device, DXGI_FORMAT desired_format, UINT desired_format_support); @@ -2546,13 +2595,6 @@ d3d11_get_closest_match_texture2D(D3D11Device device, DXGI_FORMAT desired_format D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE); } -static INLINE void -d3d11_set_texture_and_sampler(D3D11DeviceContext ctx, UINT slot, d3d11_texture_t* texture) -{ - D3D11SetPShaderResources(ctx, slot, 1, &texture->view); - D3D11SetPShaderSamplers(ctx, slot, 1, &texture->sampler); -} - bool d3d11_init_shader( D3D11Device device, const void* src, @@ -2571,6 +2613,13 @@ static INLINE void d3d11_release_shader(d3d11_shader_t* shader) Release(shader->ps); Release(shader->gs); } +#if !defined(__cplusplus) || defined(CINTERFACE) +static INLINE void +d3d11_set_texture_and_sampler(D3D11DeviceContext ctx, UINT slot, d3d11_texture_t* texture) +{ + D3D11SetPShaderResources(ctx, slot, 1, &texture->view); + D3D11SetPShaderSamplers(ctx, slot, 1, &texture->sampler); +} static INLINE void d3d11_set_shader(D3D11DeviceContext ctx, d3d11_shader_t* shader) { @@ -2586,15 +2635,16 @@ static INLINE void D3D11SetVertexBuffer( UINT stride, UINT offset) { - D3D11SetVertexBuffers(device_context, slot, 1, (ID3D11Buffer** const)&vertex_buffer, &stride, &offset); + D3D11SetVertexBuffers(device_context, slot, 1, &vertex_buffer, &stride, &offset); } static INLINE void D3D11SetVShaderConstantBuffer( D3D11DeviceContext device_context, UINT slot, D3D11Buffer const constant_buffer) { - D3D11SetVShaderConstantBuffers(device_context, slot, 1, (ID3D11Buffer** const)&constant_buffer); + D3D11SetVShaderConstantBuffers(device_context, slot, 1, &constant_buffer); } static INLINE void D3D11SetPShaderConstantBuffer( D3D11DeviceContext device_context, UINT slot, D3D11Buffer const constant_buffer) { - D3D11SetPShaderConstantBuffers(device_context, slot, 1, (ID3D11Buffer** const)&constant_buffer); + D3D11SetPShaderConstantBuffers(device_context, slot, 1, &constant_buffer); } +#endif diff --git a/gfx/common/d3dcompiler_common.c b/gfx/common/d3dcompiler_common.c index f26a07b9a3..be489a8497 100644 --- a/gfx/common/d3dcompiler_common.c +++ b/gfx/common/d3dcompiler_common.c @@ -52,7 +52,7 @@ HRESULT WINAPI D3DCompile( d3dcompiler_dll = dylib_load(*dll_name++); if (!d3dcompiler_dll) - goto error; + return TYPE_E_CANTLOADLIBRARY; if (!fp) fp = (pD3DCompile)dylib_proc(d3dcompiler_dll, "D3DCompile"); @@ -62,7 +62,6 @@ HRESULT WINAPI D3DCompile( pSrcData, SrcDataSize, pSourceName, pDefines, pInclude, pEntrypoint, pTarget, Flags1, Flags2, ppCode, ppErrorMsgs); -error: return TYPE_E_CANTLOADLIBRARY; } @@ -87,7 +86,7 @@ HRESULT WINAPI D3DCompileFromFile( d3dcompiler_dll = dylib_load(*dll_name++); if (!d3dcompiler_dll) - goto error; + return TYPE_E_CANTLOADLIBRARY; if (!fp) fp = (pD3DCompileFromFile)dylib_proc(d3dcompiler_dll, "D3DCompileFromFile"); @@ -97,7 +96,29 @@ HRESULT WINAPI D3DCompileFromFile( pFileName, pDefines, pInclude, pEntrypoint, pTarget, Flags1, Flags2, ppCode, ppErrorMsgs); -error: + return TYPE_E_CANTLOADLIBRARY; +} + +HRESULT WINAPI + D3DReflect(LPCVOID pSrcData, SIZE_T SrcDataSize, REFIID pInterface, void** ppReflector) +{ + typedef HRESULT(WINAPI * pD3DCompileFromFile)( + LPCVOID pSrcData, SIZE_T SrcDataSize, REFIID pInterface, void** ppReflector); + static pD3DCompileFromFile fp; + + const char** dll_name = d3dcompiler_dll_list; + while (!d3dcompiler_dll && *dll_name) + d3dcompiler_dll = dylib_load(*dll_name++); + + if (!d3dcompiler_dll) + return TYPE_E_CANTLOADLIBRARY; + + if (!fp) + fp = (pD3DCompileFromFile)dylib_proc(d3dcompiler_dll, "D3DReflect"); + + if (fp) + return fp(pSrcData, SrcDataSize, pInterface, ppReflector); + return TYPE_E_CANTLOADLIBRARY; } #endif diff --git a/gfx/common/dxgi_common.c b/gfx/common/dxgi_common.c index 4b68a99ed1..20cbaac0f6 100644 --- a/gfx/common/dxgi_common.c +++ b/gfx/common/dxgi_common.c @@ -59,12 +59,35 @@ DXGI_FORMAT* dxgi_get_format_fallback_list(DXGI_FORMAT format) switch ((unsigned)format) { + case DXGI_FORMAT_R32G32B32A32_FLOAT: + { + static DXGI_FORMAT formats[] = { DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R32G32B32_FLOAT, DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_UNKNOWN }; + return formats; + } + case DXGI_FORMAT_R16G16B16A16_FLOAT: + { + static DXGI_FORMAT formats[] = { DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32_FLOAT, DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_UNKNOWN }; + return formats; + } case DXGI_FORMAT_R8G8B8A8_UNORM: { static DXGI_FORMAT formats[] = { DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8X8_UNORM, DXGI_FORMAT_UNKNOWN }; return formats; } + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + { + static DXGI_FORMAT formats[] = { DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8X8_UNORM, DXGI_FORMAT_UNKNOWN }; + return formats; + } case DXGI_FORMAT_B8G8R8A8_UNORM: { static DXGI_FORMAT formats[] = { DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, diff --git a/gfx/drivers/d3d11.c b/gfx/drivers/d3d11.c index 2b513842a6..624fc163ab 100644 --- a/gfx/drivers/d3d11.c +++ b/gfx/drivers/d3d11.c @@ -1,4 +1,4 @@ -/* RetroArch - A frontend for libretro. +/* RetroArch - A frontend for libretro. * Copyright (C) 2014-2018 - Ali Bouhlel * * RetroArch is free software: you can redistribute it and/or modify it under the terms @@ -17,6 +17,7 @@ #include #include +#include #include "../../driver.h" #include "../../verbosity.h" @@ -24,11 +25,15 @@ #include "../video_driver.h" #include "../font_driver.h" #include "../common/win32_common.h" +#include "../../performance_counters.h" +#include "../../menu/menu_driver.h" +#include "../video_shader_parse.h" +#include "../drivers_shader/slang_preprocess.h" + #include "../common/d3d11_common.h" #include "../common/dxgi_common.h" #include "../common/d3dcompiler_common.h" -#include "../../performance_counters.h" -#include "../../menu/menu_driver.h" +#include "../drivers_shader/slang_process.h" static void d3d11_set_filtering(void* data, unsigned index, bool smooth) { @@ -42,8 +47,8 @@ static void d3d11_set_filtering(void* data, unsigned index, bool smooth) static void d3d11_gfx_set_rotation(void* data, unsigned rotation) { - math_matrix_4x4 rot; - d3d11_video_t* d3d11 = (d3d11_video_t*)data; + math_matrix_4x4 rot; + d3d11_video_t* d3d11 = (d3d11_video_t*)data; if (!d3d11) return; @@ -71,10 +76,203 @@ 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; + 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; } +static void d3d11_free_shader_preset(d3d11_video_t* d3d11) +{ + if (!d3d11->shader_preset) + return; + + for (int i = 0; i < d3d11->shader_preset->passes; i++) + { + free(d3d11->shader_preset->pass[i].source.string.vertex); + free(d3d11->shader_preset->pass[i].source.string.fragment); + d3d11_release_shader(&d3d11->pass[i].shader); + d3d11_release_texture(&d3d11->pass[i].rt); + free(d3d11->pass[i].semantics.textures); + for (int j = 0; j < SLANG_CBUFFER_MAX; j++) + { + free(d3d11->pass[i].semantics.cbuffers[j].uniforms); + Release(d3d11->pass[i].buffers[j]); + } + } + + memset(d3d11->pass, 0, sizeof(d3d11->pass)); + + for (int i = 0; i < d3d11->shader_preset->luts; i++) + d3d11_release_texture(&d3d11->luts[i]); + + memset(d3d11->luts, 0, sizeof(d3d11->luts)); + + free(d3d11->shader_preset); + d3d11->shader_preset = NULL; +} + +static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const char* path) +{ + d3d11_video_t* d3d11 = (d3d11_video_t*)data; + + if (!d3d11) + return false; + + D3D11Flush(d3d11->ctx); + d3d11_free_shader_preset(d3d11); + + if (!path) + return true; + + if (type != RARCH_SHADER_SLANG) + { + RARCH_WARN("Only .slang or .slangp shaders are supported. Falling back to stock.\n"); + return false; + } + + config_file_t* conf = config_file_new(path); + + if (!conf) + return false; + + d3d11->shader_preset = calloc(1, sizeof(*d3d11->shader_preset)); + + if (!video_shader_read_conf_cgp(conf, d3d11->shader_preset)) + goto error; + + video_shader_resolve_relative(d3d11->shader_preset, path); + + d3d11_texture_t* source = &d3d11->frame.texture; + for (int i = 0; i < d3d11->shader_preset->passes; i++) + { + { + /* no history support yet */ + texture_map_t texture_map[3 + GFX_MAX_SHADERS + GFX_MAX_TEXTURES + 1] = { + { SLANG_TEXTURE_SEMANTIC_ORIGINAL, 0, &d3d11->frame.texture, &d3d11->pass[i].sampler, + &d3d11->frame.texture.size_data }, + { SLANG_TEXTURE_SEMANTIC_SOURCE, 0, source, &d3d11->pass[i].sampler, + &source->size_data }, + { SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY, 0, &d3d11->frame.texture, + &d3d11->pass[i].sampler, &d3d11->frame.texture.size_data }, + }; + + { + texture_map_t* ptr = texture_map; + while (ptr->texture_data) + ptr++; + + for (int j = 0; j < i; j++) + { + ptr->semantic = SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT; + ptr->id = j; + ptr->texture_data = &d3d11->pass[j].rt; + ptr->sampler_data = &d3d11->pass[i].sampler; + ptr++; + } + + for (int j = 0; j < d3d11->shader_preset->luts; j++) + { + ptr->semantic = SLANG_TEXTURE_SEMANTIC_USER; + ptr->id = j; + ptr->texture_data = &d3d11->luts[j]; + ptr->size_data = &d3d11->luts[j].size_data; + ptr->sampler_data = &d3d11->luts[j].sampler; + ptr++; + } + } + + uniform_map_t uniform_map[] = { + { SLANG_SEMANTIC_MVP, &d3d11->mvp }, + { SLANG_SEMANTIC_OUTPUT, &d3d11->pass[i].rt.size_data }, + { SLANG_SEMANTIC_FRAME_COUNT, &d3d11->pass[i].frame_count }, + { SLANG_SEMANTIC_FINAL_VIEWPORT, &d3d11->frame.output_size }, + { 0 } + }; + + semantics_map_t semantics_map = { texture_map, uniform_map }; + + if (!slang_process( + d3d11->shader_preset, i, RARCH_SHADER_HLSL, 50, &semantics_map, + &d3d11->pass[i].semantics)) + goto error; + } + + { + static const D3D11_INPUT_ELEMENT_DESC desc[] = { + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d11_vertex_t, position), + D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 1, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d11_vertex_t, texcoord), + D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; + + if (!d3d11_init_shader( + d3d11->device, d3d11->shader_preset->pass[i].source.string.vertex, 0, "main", + NULL, NULL, desc, countof(desc), &d3d11->pass[i].shader)) + goto error; + free(d3d11->shader_preset->pass[i].source.string.vertex); + d3d11->shader_preset->pass[i].source.string.vertex = NULL; + + if (!d3d11_init_shader( + d3d11->device, d3d11->shader_preset->pass[i].source.string.fragment, 0, NULL, + "main", NULL, NULL, 0, &d3d11->pass[i].shader)) + goto error; + + free(d3d11->shader_preset->pass[i].source.string.fragment); + d3d11->shader_preset->pass[i].source.string.fragment = NULL; + } + + for (int j = 0; j < SLANG_CBUFFER_MAX; j++) + { + D3D11_BUFFER_DESC desc = { + .ByteWidth = d3d11->pass[i].semantics.cbuffers[j].size, + .Usage = D3D11_USAGE_DYNAMIC, + .BindFlags = D3D11_BIND_CONSTANT_BUFFER, + .CPUAccessFlags = D3D11_CPU_ACCESS_WRITE, + }; + + if (!desc.ByteWidth) + continue; + + D3D11CreateBuffer(d3d11->device, &desc, NULL, &d3d11->pass[i].buffers[j]); + } + + source = &d3d11->pass[i].rt; + } + + for (int i = 0; i < d3d11->shader_preset->luts; i++) + { + struct texture_image image = { 0 }; + + if (!image_texture_load(&image, d3d11->shader_preset->lut[i].path)) + goto error; + d3d11->luts[i].desc.Width = image.width; + d3d11->luts[i].desc.Height = image.height; + d3d11->luts[i].desc.Format = + d3d11_get_closest_match_texture2D(d3d11->device, DXGI_FORMAT_B8G8R8A8_UNORM); + d3d11_init_texture(d3d11->device, &d3d11->luts[i]); + d3d11_update_texture( + d3d11->ctx, image.width, image.height, 0, DXGI_FORMAT_B8G8R8A8_UNORM, image.pixels, + &d3d11->luts[i]); + image_texture_free(&image); + + d3d11->luts[i].sampler = d3d11->shader_preset->lut[i].filter == RARCH_FILTER_NEAREST + ? d3d11->sampler_nearest + : d3d11->sampler_linear; + } + + video_shader_resolve_current_parameters(conf, d3d11->shader_preset); + config_file_free(conf); + + return true; + +error: + d3d11_free_shader_preset(d3d11); + return false; +} + static void d3d11_gfx_free(void* data) { d3d11_video_t* d3d11 = (d3d11_video_t*)data; @@ -82,25 +280,17 @@ static void d3d11_gfx_free(void* data) if (!d3d11) return; + d3d11_free_shader_preset(d3d11); + + d3d11_release_texture(&d3d11->frame.texture); Release(d3d11->frame.ubo); - Release(d3d11->frame.texture.view); - Release(d3d11->frame.texture.handle); - Release(d3d11->frame.texture.staging); Release(d3d11->frame.vbo); - Release(d3d11->menu.texture.handle); - Release(d3d11->menu.texture.staging); - Release(d3d11->menu.texture.view); + d3d11_release_texture(&d3d11->menu.texture); Release(d3d11->menu.vbo); - Release(d3d11->sprites.shader.vs); - Release(d3d11->sprites.shader.ps); - Release(d3d11->sprites.shader.gs); - Release(d3d11->sprites.shader.layout); - Release(d3d11->sprites.shader_font.vs); - Release(d3d11->sprites.shader_font.ps); - Release(d3d11->sprites.shader_font.gs); - Release(d3d11->sprites.shader_font.layout); + d3d11_release_shader(&d3d11->sprites.shader); + d3d11_release_shader(&d3d11->sprites.shader_font); Release(d3d11->sprites.vbo); d3d11_release_shader(&d3d11->shaders[VIDEO_SHADER_STOCK_BLEND]); @@ -139,11 +329,11 @@ static void d3d11_gfx_free(void* data) static void* d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** input_data) { - WNDCLASSEX wndclass = { 0 }; - MONITORINFOEX current_mon; - HMONITOR hm_to_use; - settings_t* settings = config_get_ptr(); - d3d11_video_t* d3d11 = (d3d11_video_t*)calloc(1, sizeof(*d3d11)); + WNDCLASSEX wndclass = { 0 }; + MONITORINFOEX current_mon; + HMONITOR hm_to_use; + settings_t* settings = config_get_ptr(); + d3d11_video_t* d3d11 = (d3d11_video_t*)calloc(1, sizeof(*d3d11)); if (!d3d11) return NULL; @@ -243,6 +433,7 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i D3D11CreateBuffer(d3d11->device, &desc, &ubo_data, &d3d11->ubo); D3D11CreateBuffer(d3d11->device, &desc, NULL, &d3d11->frame.ubo); } + d3d11_gfx_set_rotation(d3d11, 0); { @@ -442,12 +633,132 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i font_driver_init_osd(d3d11, false, video->is_threaded, FONT_DRIVER_RENDER_D3D11_API); + if (settings->bools.video_shader_enable) + { + const char* ext = path_get_extension(settings->paths.path_shader); + + if (ext && !strncmp(ext, "slang", 5)) + d3d11_gfx_set_shader(d3d11, RARCH_SHADER_SLANG, settings->paths.path_shader); + } + return d3d11; error: d3d11_gfx_free(d3d11); return NULL; } +static bool d3d11_init_frame_textures(d3d11_video_t* d3d11, unsigned width, unsigned height) +{ + if (d3d11->shader_preset) + { + for (int i = 0; i < d3d11->shader_preset->passes; i++) + { + d3d11_release_texture(&d3d11->pass[i].rt); + memset(&d3d11->pass[i].rt, 0x00, sizeof(d3d11->pass[i].rt)); + } + } + + d3d11->frame.texture.desc.Width = width; + d3d11->frame.texture.desc.Height = height; + d3d11_init_texture(d3d11->device, &d3d11->frame.texture); + + if (d3d11->shader_preset) + { + for (int i = 0; i < d3d11->shader_preset->passes; i++) + { + struct video_shader_pass* pass = &d3d11->shader_preset->pass[i]; + + switch (pass->fbo.type_x) + { + case RARCH_SCALE_INPUT: + width *= pass->fbo.scale_x; + break; + + case RARCH_SCALE_VIEWPORT: + width = d3d11->vp.width * pass->fbo.scale_x; + break; + + case RARCH_SCALE_ABSOLUTE: + width = pass->fbo.abs_x; + break; + + default: + break; + } + + switch (pass->fbo.type_y) + { + case RARCH_SCALE_INPUT: + height *= pass->fbo.scale_y; + break; + + case RARCH_SCALE_VIEWPORT: + height = d3d11->vp.height * pass->fbo.scale_y; + break; + + case RARCH_SCALE_ABSOLUTE: + height = pass->fbo.abs_y; + break; + + default: + break; + } + + if (!width) + width = d3d11->vp.width; + + if (!height) + height = d3d11->vp.height; + + d3d11->pass[i].viewport.Width = width; + d3d11->pass[i].viewport.Height = height; + d3d11->pass[i].viewport.MaxDepth = 1.0; + 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 = d3d11_get_closest_match( + d3d11->device, + pass->fbo.fp_fbo ? DXGI_FORMAT_R32G32B32A32_FLOAT + : pass->fbo.srgb_fbo ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB + : DXGI_FORMAT_R8G8B8A8_UNORM, + D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE | + D3D11_FORMAT_SUPPORT_RENDER_TARGET); + + if ((i != (d3d11->shader_preset->passes - 1)) || (width != d3d11->vp.width) || + (height != d3d11->vp.height)) + { + d3d11_init_texture(d3d11->device, &d3d11->pass[i].rt); + } + else + { + d3d11->pass[i].rt.size_data.x = width; + d3d11->pass[i].rt.size_data.y = height; + d3d11->pass[i].rt.size_data.z = 1.0f / width; + d3d11->pass[i].rt.size_data.w = 1.0f / height; + } + + d3d11->pass[i].sampler = pass->filter == RARCH_FILTER_NEAREST ? d3d11->sampler_nearest + : d3d11->sampler_linear; + + for (int j = 0; j < d3d11->pass[i].semantics.texture_count; j++) + { + texture_sem_t* texture_sem = &d3d11->pass[i].semantics.textures[j]; + D3D11ShaderResourceView view = ((d3d11_texture_t*)texture_sem->data)->view; + D3D11SamplerStateRef sampler = *(D3D11SamplerStateRef*)texture_sem->sampler_data; + + d3d11->pass[i].textures[texture_sem->binding] = view; + d3d11->pass[i].samplers[texture_sem->binding] = sampler; + } + } + } + + return true; +#if 0 +error: + d3d11_free_shader_preset(d3d11); + return false; +#endif +} static bool d3d11_gfx_frame( void* data, @@ -474,6 +785,7 @@ static bool d3d11_gfx_frame( Release(backBuffer); D3D11SetRenderTargets(d3d11->ctx, 1, &d3d11->renderTargetView, NULL); + d3d11->viewport.Width = video_info->width; d3d11->viewport.Height = video_info->height; @@ -486,35 +798,108 @@ static bool d3d11_gfx_frame( } PERF_START(); - D3D11ClearRenderTargetView(d3d11->ctx, d3d11->renderTargetView, d3d11->clearcolor); - d3d11_set_shader(d3d11->ctx, &d3d11->shaders[VIDEO_SHADER_STOCK_BLEND]); - D3D11SetPrimitiveTopology(d3d11->ctx, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - - if (frame && width && height) - { - if (d3d11->frame.texture.desc.Width != width || d3d11->frame.texture.desc.Height != height) - { - d3d11->frame.texture.desc.Width = width; - d3d11->frame.texture.desc.Height = height; - d3d11_init_texture(d3d11->device, &d3d11->frame.texture); - } - - d3d11_update_texture( - d3d11->ctx, width, height, pitch, d3d11->format, frame, &d3d11->frame.texture); - } #if 0 /* custom viewport doesn't call apply_state_changes, so we can't rely on this for now */ if (d3d11->resize_viewport) #endif d3d11_update_viewport(d3d11, false); - D3D11SetViewports(d3d11->ctx, 1, &d3d11->frame.viewport); - d3d11_set_texture_and_sampler(d3d11->ctx, 0, &d3d11->frame.texture); + D3D11SetPrimitiveTopology(d3d11->ctx, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + if (frame && width && height) + { + if (d3d11->frame.texture.desc.Width != width || d3d11->frame.texture.desc.Height != height) + d3d11_init_frame_textures(d3d11, width, height); + + d3d11_update_texture( + d3d11->ctx, width, height, pitch, d3d11->format, frame, &d3d11->frame.texture); + } D3D11SetVertexBuffer(d3d11->ctx, 0, d3d11->frame.vbo, sizeof(d3d11_vertex_t), 0); - D3D11SetVShaderConstantBuffers(d3d11->ctx, 0, 1, &d3d11->frame.ubo); - D3D11SetBlendState(d3d11->ctx, d3d11->blend_disable, NULL, D3D11_DEFAULT_SAMPLE_MASK); + + /* todo: single pass shaders can also have an empty rt texture */ + if (d3d11->shader_preset && !d3d11->pass[0].rt.handle) + d3d11_init_frame_textures(d3d11, width, height); + + d3d11_texture_t* texture = &d3d11->frame.texture; + + if (d3d11->shader_preset) + { + for (int i = 0; i < d3d11->shader_preset->passes; i++) + { + if (d3d11->shader_preset->pass[i].frame_count_mod) + d3d11->pass[i].frame_count = + frame_count % d3d11->shader_preset->pass[i].frame_count_mod; + else + d3d11->pass[i].frame_count = frame_count; + + for (int j = 0; j < SLANG_CBUFFER_MAX; j++) + { + D3D11Buffer buffer = d3d11->pass[i].buffers[j]; + cbuffer_sem_t* buffer_sem = &d3d11->pass[i].semantics.cbuffers[j]; + + if (buffer_sem->stage_mask && buffer_sem->uniforms) + { + D3D11_MAPPED_SUBRESOURCE res; + uniform_sem_t* uniform = buffer_sem->uniforms; + + D3D11MapBuffer(d3d11->ctx, buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &res); + while (uniform->data) + { + memcpy((uint8_t*)res.pData + uniform->offset, uniform->data, uniform->size); + uniform++; + } + D3D11UnmapBuffer(d3d11->ctx, buffer, 0); + + if (buffer_sem->stage_mask & SLANG_STAGE_VERTEX_MASK) + D3D11SetVShaderConstantBuffers(d3d11->ctx, buffer_sem->binding, 1, &buffer); + + if (buffer_sem->stage_mask & SLANG_STAGE_FRAGMENT_MASK) + D3D11SetPShaderConstantBuffers(d3d11->ctx, buffer_sem->binding, 1, &buffer); + } + } + + d3d11_set_shader(d3d11->ctx, &d3d11->pass[i].shader); + + D3D11RenderTargetView null_rt = NULL; + D3D11SetRenderTargets(d3d11->ctx, 1, &null_rt, NULL); + D3D11SetPShaderResources( + d3d11->ctx, 0, d3d11->pass[i].semantics.texture_binding_max + 1, + d3d11->pass[i].textures); + D3D11SetPShaderSamplers( + d3d11->ctx, 0, d3d11->pass[i].semantics.texture_binding_max + 1, + d3d11->pass[i].samplers); + + if (d3d11->pass[i].rt.handle) + { + D3D11SetRenderTargets(d3d11->ctx, 1, &d3d11->pass[i].rt.rt_view, NULL); + D3D11ClearRenderTargetView(d3d11->ctx, d3d11->pass[i].rt.rt_view, d3d11->clearcolor); + D3D11SetViewports(d3d11->ctx, 1, &d3d11->pass[i].viewport); + + D3D11Draw(d3d11->ctx, 4, 0); + texture = &d3d11->pass[i].rt; + } + else + { + texture = NULL; + break; + } + } + D3D11SetRenderTargets(d3d11->ctx, 1, &d3d11->renderTargetView, NULL); + } + + if (texture) + { + d3d11_set_shader(d3d11->ctx, &d3d11->shaders[VIDEO_SHADER_STOCK_BLEND]); + D3D11SetPShaderResources(d3d11->ctx, 0, 1, &texture->view); + D3D11SetPShaderSamplers(d3d11->ctx, 0, 1, &d3d11->frame.texture.sampler); + D3D11SetVShaderConstantBuffers(d3d11->ctx, 0, 1, &d3d11->frame.ubo); + } + + D3D11ClearRenderTargetView(d3d11->ctx, d3d11->renderTargetView, d3d11->clearcolor); + D3D11SetViewports(d3d11->ctx, 1, &d3d11->frame.viewport); + D3D11Draw(d3d11->ctx, 4, 0); D3D11SetBlendState(d3d11->ctx, d3d11->blend_enable, NULL, D3D11_DEFAULT_SAMPLE_MASK); @@ -594,13 +979,14 @@ static bool d3d11_gfx_has_windowed(void* data) return true; } -static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const char* path) +static struct video_shader* d3d11_gfx_get_current_shader(void* data) { - (void)data; - (void)type; - (void)path; + d3d11_video_t* d3d11 = (d3d11_video_t*)data; - return false; + if (!d3d11) + return NULL; + + return d3d11->shader_preset; } static void d3d11_gfx_viewport_info(void* data, struct video_viewport* vp) @@ -684,14 +1070,14 @@ 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_texture_t *texture = NULL; - d3d11_video_t* d3d11 = (d3d11_video_t*)video_data; - struct texture_image* image = (struct texture_image*)data; + d3d11_texture_t* texture = NULL; + d3d11_video_t* d3d11 = (d3d11_video_t*)video_data; + struct texture_image* image = (struct texture_image*)data; if (!d3d11) return 0; - texture = (d3d11_texture_t*)calloc(1, sizeof(*texture)); + texture = (d3d11_texture_t*)calloc(1, sizeof(*texture)); switch (filter_type) { @@ -754,7 +1140,7 @@ static const video_poke_interface_t d3d11_poke_interface = { d3d11_gfx_set_osd_msg, NULL, /* show_mouse */ NULL, /* grab_mouse_toggle */ - NULL, /* get_current_shader */ + d3d11_gfx_get_current_shader, NULL, /* get_current_software_framebuffer */ NULL, /* get_hw_render_interface */ }; diff --git a/gfx/drivers_shader/glslang_util.cpp b/gfx/drivers_shader/glslang_util.cpp index 617a186d11..cb7ec20bc4 100644 --- a/gfx/drivers_shader/glslang_util.cpp +++ b/gfx/drivers_shader/glslang_util.cpp @@ -368,13 +368,8 @@ bool glslang_parse_meta(const vector &lines, glslang_meta *meta) return true; } -#ifdef HAVE_VULKAN -#if defined(_MSC_VER) && !defined(WANT_GLSLANG) -bool glslang_compile_shader(const char *shader_path, glslang_output *output) -{ - return false; -} -#else + +#if defined(HAVE_GLSLANG) && !defined(HAVE_GRIFFIN) bool glslang_compile_shader(const char *shader_path, glslang_output *output) { vector lines; @@ -403,5 +398,9 @@ bool glslang_compile_shader(const char *shader_path, glslang_output *output) return true; } -#endif +#else +bool glslang_compile_shader(const char *shader_path, glslang_output *output) +{ + return false; +} #endif diff --git a/gfx/drivers_shader/shader_vulkan.cpp b/gfx/drivers_shader/shader_vulkan.cpp index 605f786302..4e0747b12b 100644 --- a/gfx/drivers_shader/shader_vulkan.cpp +++ b/gfx/drivers_shader/shader_vulkan.cpp @@ -28,7 +28,7 @@ #include #include -#include "slang_reflection.hpp" +#include "slang_reflection.h" #include "../video_driver.h" #include "../../verbosity.h" @@ -863,8 +863,8 @@ bool vulkan_filter_chain::init_feedback() return true; } -template -static bool set_unique_map(M &m, const string &name, const P &p) +template +static bool set_unique_map(unordered_map &m, const string &name, const P &p) { auto itr = m.find(name); if (itr != end(m)) diff --git a/gfx/drivers_shader/slang_preprocess.cpp b/gfx/drivers_shader/slang_preprocess.cpp index a3c8061df0..d116f95f78 100644 --- a/gfx/drivers_shader/slang_preprocess.cpp +++ b/gfx/drivers_shader/slang_preprocess.cpp @@ -23,17 +23,9 @@ using namespace std; -bool slang_preprocess_parse_parameters(const char *shader_path, +bool slang_preprocess_parse_parameters(glslang_meta& meta, struct video_shader *shader) { - glslang_meta meta; - vector lines; - if (!glslang_read_shader_file(shader_path, &lines, true)) - return false; - - if (!glslang_parse_meta(lines, &meta)) - return false; - unsigned old_num_parameters = shader->num_parameters; // Assumes num_parameters is initialized to something sane. @@ -85,3 +77,17 @@ bool slang_preprocess_parse_parameters(const char *shader_path, return true; } +bool slang_preprocess_parse_parameters(const char *shader_path, + struct video_shader *shader) +{ + glslang_meta meta; + vector lines; + if (!glslang_read_shader_file(shader_path, &lines, true)) + return false; + + if (!glslang_parse_meta(lines, &meta)) + return false; + + return slang_preprocess_parse_parameters(meta, shader); +} + diff --git a/gfx/drivers_shader/slang_preprocess.h b/gfx/drivers_shader/slang_preprocess.h index d2c94de12d..4cb423af0a 100644 --- a/gfx/drivers_shader/slang_preprocess.h +++ b/gfx/drivers_shader/slang_preprocess.h @@ -30,5 +30,13 @@ bool slang_preprocess_parse_parameters(const char *shader_path, RETRO_END_DECLS +#ifdef __cplusplus + +#include "glslang_util.hpp" + +bool slang_preprocess_parse_parameters(glslang_meta& meta, + struct video_shader *shader); +#endif + #endif diff --git a/gfx/drivers_shader/slang_process.cpp b/gfx/drivers_shader/slang_process.cpp new file mode 100644 index 0000000000..faaa4dc57f --- /dev/null +++ b/gfx/drivers_shader/slang_process.cpp @@ -0,0 +1,332 @@ + +#include +#include +#include +#include + +#include "verbosity.h" +#include "glslang_util.hpp" +#include "slang_preprocess.h" +#include "slang_reflection.h" +#include "slang_process.h" + +using namespace spirv_cross; +using namespace std; + +template +static bool set_unique_map(unordered_map& m, const string& name, const P& p) +{ + auto itr = m.find(name); + if (itr != end(m)) + { + RARCH_ERR("[slang]: Alias \"%s\" already exists.\n", name.c_str()); + return false; + } + + m[name] = p; + return true; +} + +static bool slang_process_reflection( + const Compiler* vs_compiler, + const Compiler* ps_compiler, + const ShaderResources& vs_resources, + const ShaderResources& ps_resources, + video_shader* shader_info, + unsigned pass_number, + const semantics_map_t* semantics_map, + pass_semantics_t* out) +{ + unordered_map texture_semantic_map; + unordered_map texture_semantic_uniform_map; + + string name = shader_info->pass[pass_number].alias; + + if (!set_unique_map( + texture_semantic_map, name, + slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT, pass_number })) + return false; + + if (!set_unique_map( + texture_semantic_uniform_map, name + "Size", + slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT, pass_number })) + return false; + + if (!set_unique_map( + texture_semantic_map, name + "Feedback", + slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_PASS_FEEDBACK, pass_number })) + return false; + + if (!set_unique_map( + texture_semantic_uniform_map, name + "FeedbackSize", + slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_PASS_FEEDBACK, pass_number })) + return false; + + for (unsigned i = 0; i < shader_info->luts; i++) + { + if (!set_unique_map( + texture_semantic_map, shader_info->lut[i].id, + slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_USER, i })) + return false; + + if (!set_unique_map( + texture_semantic_uniform_map, string(shader_info->lut[i].id) + "Size", + slang_texture_semantic_map{ SLANG_TEXTURE_SEMANTIC_USER, i })) + return false; + } + + unordered_map semantic_map; + for (unsigned i = 0; i < shader_info->num_parameters; i++) + { + if (!set_unique_map( + semantic_map, shader_info->parameters[i].id, { SLANG_SEMANTIC_FLOAT_PARAMETER, i })) + return false; + } + + slang_reflection sl_reflection; + sl_reflection.pass_number = pass_number; + sl_reflection.texture_semantic_map = &texture_semantic_map; + sl_reflection.texture_semantic_uniform_map = &texture_semantic_uniform_map; + sl_reflection.semantic_map = &semantic_map; + + if (!slang_reflect(*vs_compiler, *ps_compiler, vs_resources, ps_resources, &sl_reflection)) + { + RARCH_ERR("[slang]: Failed to reflect SPIR-V. Resource usage is inconsistent with " + "expectations.\n"); + 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; + out->cbuffers[SLANG_CBUFFER_PC].stage_mask = sl_reflection.push_constant_stage_mask; + out->cbuffers[SLANG_CBUFFER_PC].binding = sl_reflection.ubo_binding ? 0 : 1; + out->cbuffers[SLANG_CBUFFER_PC].size = (sl_reflection.push_constant_size + 0xF) & ~0xF; + + vector uniforms[SLANG_CBUFFER_MAX]; + vector textures; + + uniform_map_t* uniform_map = semantics_map->uniform_map; + while (uniform_map->data) + { + slang_semantic_meta& src = sl_reflection.semantics[uniform_map->semantic]; + uniform_sem_t uniform = { uniform_map->data, src.num_components * (unsigned)sizeof(float) }; + + if (src.push_constant) + { + uniform.offset = src.push_constant_offset; + uniforms[SLANG_CBUFFER_PC].push_back(uniform); + } + else if (src.uniform) + { + uniform.offset = src.ubo_offset; + uniforms[SLANG_CBUFFER_UBO].push_back(uniform); + } + uniform_map++; + } + + /* TODO: this is emitting more uniforms than actally needed for this pass */ + for (int i = 0; i < sl_reflection.semantic_float_parameters.size(); i++) + { + slang_semantic_meta& src = sl_reflection.semantic_float_parameters[i]; + uniform_sem_t uniform = { &shader_info->parameters[i].current, sizeof(float) }; + + if (src.push_constant) + { + uniform.offset = src.push_constant_offset; + uniforms[SLANG_CBUFFER_PC].push_back(uniform); + } + else if (src.uniform) + { + uniform.offset = src.ubo_offset; + uniforms[SLANG_CBUFFER_UBO].push_back(uniform); + } + } + + texture_map_t* texture_map = semantics_map->texture_map; + while (texture_map->texture_data) + { + if (texture_map->id < sl_reflection.semantic_textures[texture_map->semantic].size()) + { + slang_texture_semantic_meta& src = + sl_reflection.semantic_textures[texture_map->semantic][texture_map->id]; + + if (src.stage_mask) + { + texture_sem_t texture = { texture_map->texture_data, texture_map->sampler_data }; + texture.stage_mask = src.stage_mask; + texture.binding = src.binding; + if (out->texture_binding_max < src.binding) + out->texture_binding_max = src.binding; + textures.push_back(texture); + + uniform_sem_t uniform = { texture_map->size_data, 4 * sizeof(float) }; + if (src.push_constant) + { + uniform.offset = src.push_constant_offset; + uniforms[SLANG_CBUFFER_PC].push_back(uniform); + } + else if (src.uniform) + { + uniform.offset = src.ubo_offset; + uniforms[SLANG_CBUFFER_UBO].push_back(uniform); + } + } + } + texture_map++; + } + + out->texture_count = textures.size(); + + textures.push_back({ NULL }); + out->textures = (texture_sem_t*)malloc(textures.size() * sizeof(*textures.data())); + memcpy(out->textures, textures.data(), textures.size() * sizeof(*textures.data())); + + for (int i = 0; i < SLANG_CBUFFER_MAX; i++) + { + if (uniforms[i].empty()) + continue; + + out->cbuffers[i].uniform_count = uniforms[i].size(); + + uniforms[i].push_back({ NULL }); + out->cbuffers[i].uniforms = + (uniform_sem_t*)malloc(uniforms[i].size() * sizeof(*uniforms[i].data())); + memcpy( + out->cbuffers[i].uniforms, uniforms[i].data(), + uniforms[i].size() * sizeof(*uniforms[i].data())); + } + + return true; +} + +bool slang_process( + video_shader* shader_info, + unsigned pass_number, + enum rarch_shader_type dst_type, + unsigned version, + const semantics_map_t* semantics_map, + pass_semantics_t* out) +{ + Compiler* vs_compiler = NULL; + Compiler* ps_compiler = NULL; + video_shader_pass& pass = shader_info->pass[pass_number]; + glslang_output output; + + if (!glslang_compile_shader(pass.source.path, &output)) + return false; + + if (!slang_preprocess_parse_parameters(output.meta, shader_info)) + return false; + + pass.source.string.vertex = NULL; + pass.source.string.fragment = NULL; + + try + { + ShaderResources vs_resources; + ShaderResources ps_resources; + string vs_code; + string ps_code; + + if (dst_type == RARCH_SHADER_HLSL || dst_type == RARCH_SHADER_CG) + { + vs_compiler = new CompilerHLSL(output.vertex); + ps_compiler = new CompilerHLSL(output.fragment); + } + else + { + vs_compiler = new CompilerGLSL(output.vertex); + ps_compiler = new CompilerGLSL(output.fragment); + } + + vs_resources = vs_compiler->get_shader_resources(); + ps_resources = ps_compiler->get_shader_resources(); + + if (dst_type == RARCH_SHADER_HLSL || dst_type == RARCH_SHADER_CG) + { + CompilerHLSL::Options options; + CompilerHLSL* vs = (CompilerHLSL*)vs_compiler; + CompilerHLSL* ps = (CompilerHLSL*)ps_compiler; + options.shader_model = version; + vs->set_options(options); + ps->set_options(options); + + std::vector vs_attrib_remap; +#if 0 + /* remaps vertex shader output too so disable for now */ + vs_attrib_remap.push_back({ 0, "POSITION" }); + vs_attrib_remap.push_back({ 1, "TEXCOORD" }); +#endif + /* not exactly a vertex attribute but this remaps + * float2 FragCoord :TEXCOORD# to float4 FragCoord : SV_POSITION */ + std::vector ps_attrib_remap; + for (Resource& resource : ps_resources.stage_inputs) + { + if (ps->get_name(resource.id) == "FragCoord") + { + uint32_t location = ps->get_decoration(resource.id, spv::DecorationLocation); + ps_attrib_remap.push_back({ location, "SV_Position" }); + } + } + VariableTypeRemapCallback ps_var_remap_cb = + [](const SPIRType& type, const std::string& var_name, std::string& name_of_type) { + if (var_name == "FragCoord") + name_of_type = "float4"; + }; + ps->set_variable_type_remap_callback(ps_var_remap_cb); + + vs_code = vs->compile(vs_attrib_remap); + ps_code = ps->compile(ps_attrib_remap); + } + else if (shader_info->type == RARCH_SHADER_GLSL) + { + CompilerGLSL::Options options; + CompilerGLSL* vs = (CompilerGLSL*)vs_compiler; + CompilerGLSL* ps = (CompilerGLSL*)ps_compiler; + options.version = version; + ps->set_options(options); + vs->set_options(options); + + vs_code = vs->compile(); + ps_code = ps->compile(); + } + else + goto error; + + pass.source.string.vertex = (char*)malloc(vs_code.size() + 1); + memcpy(pass.source.string.vertex, vs_code.c_str(), vs_code.size() + 1); + + pass.source.string.fragment = (char*)malloc(ps_code.size() + 1); + memcpy(pass.source.string.fragment, ps_code.c_str(), ps_code.size() + 1); + + if (!slang_process_reflection( + vs_compiler, ps_compiler, vs_resources, ps_resources, shader_info, pass_number, + semantics_map, out)) + goto error; + + } catch (const std::exception& e) + { + RARCH_ERR("[slang]: spir2cross threw exception: %s.\n", e.what()); + goto error; + } + + delete vs_compiler; + delete ps_compiler; + + return true; + +error: + free(pass.source.string.vertex); + free(pass.source.string.fragment); + + pass.source.string.vertex = NULL; + pass.source.string.fragment = NULL; + + delete vs_compiler; + delete ps_compiler; + + return false; +} diff --git a/gfx/drivers_shader/slang_process.h b/gfx/drivers_shader/slang_process.h new file mode 100644 index 0000000000..fd3226e904 --- /dev/null +++ b/gfx/drivers_shader/slang_process.h @@ -0,0 +1,94 @@ +/* RetroArch - A frontend fror libretro. + * Copyright (C) 2014-2018 - Ali Bouhlel + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#ifndef __GLSLANG_PROCESS_H__ +#define __GLSLANG_PROCESS_H__ + +#include +#include +#include + +#include "../video_shader_parse.h" +#include "slang_reflection.h" + +typedef struct +{ + enum slang_semantic semantic; + void* data; +} uniform_map_t; + +typedef struct +{ + enum slang_texture_semantic semantic; + int id; + void* texture_data; + void* sampler_data; + void* size_data; +} texture_map_t; + +typedef struct +{ + texture_map_t* texture_map; + uniform_map_t* uniform_map; +} semantics_map_t; + +typedef struct +{ + void* data; + unsigned size; + unsigned offset; +} uniform_sem_t; + +typedef struct +{ + void* data; + void* sampler_data; + unsigned stage_mask; + unsigned binding; +} texture_sem_t; + +typedef struct +{ + unsigned stage_mask; + unsigned binding; + unsigned size; + int uniform_count; + uniform_sem_t* uniforms; +} cbuffer_sem_t; + +typedef struct +{ + int texture_count; + texture_sem_t* textures; + int texture_binding_max; + cbuffer_sem_t cbuffers[SLANG_CBUFFER_MAX]; +} pass_semantics_t; + +#define SLANG_STAGE_VERTEX_MASK (1 << 0) +#define SLANG_STAGE_FRAGMENT_MASK (1 << 1) + +RETRO_BEGIN_DECLS + +bool slang_process( + struct video_shader* shader_info, + unsigned pass_number, + enum rarch_shader_type dst_type, + unsigned version, + const semantics_map_t* semantics_map, + pass_semantics_t* out); + +RETRO_END_DECLS + +#endif diff --git a/gfx/drivers_shader/slang_reflection.cpp b/gfx/drivers_shader/slang_reflection.cpp index 1f97091c9b..a9b1adc37c 100644 --- a/gfx/drivers_shader/slang_reflection.cpp +++ b/gfx/drivers_shader/slang_reflection.cpp @@ -14,7 +14,7 @@ */ #include "spirv_cross.hpp" -#include "slang_reflection.hpp" +#include "slang_reflection.h" #include #include #include @@ -335,7 +335,7 @@ static bool add_active_buffer_ranges(const Compiler &compiler, const Resource &r break; default: - if (!set_ubo_offset(reflection, sem, range.offset, type.vecsize, push_constant)) + if (!set_ubo_offset(reflection, sem, range.offset, type.vecsize * type.columns, push_constant)) return false; break; } @@ -360,7 +360,7 @@ static bool add_active_buffer_ranges(const Compiler &compiler, const Resource &r return true; } -static bool slang_reflect(const Compiler &vertex_compiler, const Compiler &fragment_compiler, +bool slang_reflect(const Compiler &vertex_compiler, const Compiler &fragment_compiler, const ShaderResources &vertex, const ShaderResources &fragment, slang_reflection *reflection) { diff --git a/gfx/drivers_shader/slang_reflection.hpp b/gfx/drivers_shader/slang_reflection.h similarity index 90% rename from gfx/drivers_shader/slang_reflection.hpp rename to gfx/drivers_shader/slang_reflection.h index a9799e3c51..40e96f37a5 100644 --- a/gfx/drivers_shader/slang_reflection.hpp +++ b/gfx/drivers_shader/slang_reflection.h @@ -13,12 +13,8 @@ * If not, see . */ -#ifndef SLANG_REFLECTION_HPP -#define SLANG_REFLECTION_HPP - -#include -#include -#include +#ifndef SLANG_REFLECTION_H_ +#define SLANG_REFLECTION_H_ // Textures with built-in meaning. enum slang_texture_semantic @@ -80,9 +76,23 @@ enum slang_stage SLANG_STAGE_FRAGMENT_MASK = 1 << 1 }; +enum slang_constant_buffer +{ + SLANG_CBUFFER_UBO = 0, + SLANG_CBUFFER_PC, + SLANG_CBUFFER_MAX, +}; + /* Vulkan minimum limit. */ #define SLANG_NUM_BINDINGS 16 +#ifdef __cplusplus + +#include +#include +#include +#include "spirv_cross.hpp" + struct slang_texture_semantic_meta { size_t ubo_offset = 0; @@ -141,5 +151,10 @@ bool slang_reflect_spirv(const std::vector &vertex, const std::vector &fragment, slang_reflection *reflection); +bool slang_reflect(const spirv_cross::Compiler &vertex_compiler, const spirv_cross::Compiler &fragment_compiler, + const spirv_cross::ShaderResources &vertex, const spirv_cross::ShaderResources &fragment, + slang_reflection *reflection); + +#endif #endif diff --git a/gfx/video_driver.c b/gfx/video_driver.c index 29c8970140..8991f251df 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -591,6 +591,17 @@ static void video_context_driver_reset(void) if (current_video_context.has_focus) video_driver_cb_has_focus = video_context_has_focus; + + + if(current_video_context_api == GFX_CTX_NONE) + { + const char *video_driver = video_driver_get_ident(); + + if(string_is_equal(video_driver, "d3d11")) + current_video_context_api = GFX_CTX_DIRECT3D11_API; + else if(string_is_equal(video_driver, "gx2")) + current_video_context_api = GFX_CTX_GX2_API; + } } bool video_context_driver_set(const gfx_ctx_driver_t *data) @@ -632,6 +643,8 @@ void video_context_driver_destroy(void) current_video_context.bind_hw_render = NULL; current_video_context.get_context_data = NULL; current_video_context.make_current = NULL; + + current_video_context_api = GFX_CTX_NONE; } /** diff --git a/gfx/video_driver.h b/gfx/video_driver.h index 211f41fca3..c134c48d77 100644 --- a/gfx/video_driver.h +++ b/gfx/video_driver.h @@ -97,9 +97,11 @@ enum gfx_ctx_api GFX_CTX_OPENGL_ES_API, GFX_CTX_DIRECT3D8_API, GFX_CTX_DIRECT3D9_API, + GFX_CTX_DIRECT3D11_API, GFX_CTX_OPENVG_API, GFX_CTX_VULKAN_API, - GFX_CTX_GDI_API + GFX_CTX_GDI_API, + GFX_CTX_GX2_API, }; enum display_metric_types diff --git a/gfx/video_shader_parse.c b/gfx/video_shader_parse.c index e19abc7290..92daf520ae 100644 --- a/gfx/video_shader_parse.c +++ b/gfx/video_shader_parse.c @@ -1157,12 +1157,8 @@ enum rarch_shader_type video_shader_parse_type(const char *path, break; case FILE_TYPE_SHADER_SLANG: case FILE_TYPE_SHADER_PRESET_SLANGP: -#ifdef __wiiu__ - return RARCH_SHADER_SLANG; -#else shader_type = RARCH_SHADER_SLANG; break; -#endif default: break; } @@ -1178,7 +1174,9 @@ enum rarch_shader_type video_shader_parse_type(const char *path, if (cg_supported && shader_type == RARCH_SHADER_CG) return shader_type; break; + case GFX_CTX_DIRECT3D11_API: case GFX_CTX_VULKAN_API: + case GFX_CTX_GX2_API: if (shader_type == RARCH_SHADER_SLANG) return shader_type; break; diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 3d311fc984..ba819786a9 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -3103,7 +3103,7 @@ static int menu_displaylist_parse_options( MENU_SETTING_ACTION, 0, 0); #endif -#ifdef HAVE_VULKAN +#ifdef HAVE_SLANG menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_UPDATE_SLANG_SHADERS), msg_hash_to_str(MENU_ENUM_LABEL_UPDATE_SLANG_SHADERS),