1
0
mirror of https://github.com/libretro/RetroArch synced 2024-07-03 00:38:44 +00:00

(D3D11) Implement slang shader specification using Spirv-Cross.

(incomplete)
This commit is contained in:
aliaspider 2018-01-31 01:08:36 +01:00
parent b228775b0d
commit 5bc78d3ad5
20 changed files with 1214 additions and 238 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)
{

View File

@ -20,17 +20,21 @@
#include "dxgi_common.h"
#include <d3d11.h>
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 <assert.h>
#include <stdbool.h>
#include <retro_math.h>
#include <gfx/math/matrix_4x4.h>
#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

View File

@ -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

View File

@ -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,

View File

@ -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 <string/stdstring.h>
#include <gfx/scaler/pixconv.h>
#include <file/file_path.h>
#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 */
};

View File

@ -368,13 +368,8 @@ bool glslang_parse_meta(const vector<string> &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<string> 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

View File

@ -28,7 +28,7 @@
#include <formats/image.h>
#include <retro_miscellaneous.h>
#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 <typename M, typename P>
static bool set_unique_map(M &m, const string &name, const P &p)
template <typename P>
static bool set_unique_map(unordered_map<string, P> &m, const string &name, const P &p)
{
auto itr = m.find(name);
if (itr != end(m))

View File

@ -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<string> 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<string> 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);
}

View File

@ -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

View File

@ -0,0 +1,332 @@
#include <fstream>
#include <iostream>
#include <spirv_hlsl.hpp>
#include <stdint.h>
#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 <typename P>
static bool set_unique_map(unordered_map<string, P>& 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<string, slang_texture_semantic_map> texture_semantic_map;
unordered_map<string, slang_texture_semantic_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<string, slang_semantic_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<uniform_sem_t> uniforms[SLANG_CBUFFER_MAX];
vector<texture_sem_t> 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<HLSLVertexAttributeRemap> 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<HLSLVertexAttributeRemap> 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;
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef __GLSLANG_PROCESS_H__
#define __GLSLANG_PROCESS_H__
#include <stdint.h>
#include <boolean.h>
#include <retro_common_api.h>
#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

View File

@ -14,7 +14,7 @@
*/
#include "spirv_cross.hpp"
#include "slang_reflection.hpp"
#include "slang_reflection.h"
#include <vector>
#include <algorithm>
#include <stdio.h>
@ -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)
{

View File

@ -13,12 +13,8 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SLANG_REFLECTION_HPP
#define SLANG_REFLECTION_HPP
#include <string>
#include <unordered_map>
#include <stdint.h>
#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 <string>
#include <unordered_map>
#include <stdint.h>
#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<uint32_t> &vertex,
const std::vector<uint32_t> &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

View File

@ -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;
}
/**

View File

@ -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

View File

@ -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;

View File

@ -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),