Merge pull request #6204 from aliaspider/master

(D3D11) Implement slang shader specification using Spirv-Cross.
This commit is contained in:
Twinaphex 2018-02-01 16:33:58 +01:00 committed by GitHub
commit f096e667d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 1512 additions and 329 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

@ -136,13 +136,16 @@ DXGI_FORMAT
d3d10_get_closest_match(D3D10Device device,
DXGI_FORMAT desired_format, UINT desired_format_support)
{
DXGI_FORMAT default_list[] = {desired_format, DXGI_FORMAT_UNKNOWN};
DXGI_FORMAT* format = dxgi_get_format_fallback_list(desired_format);
UINT format_support;
if(!format)
format = default_list;
while (*format != DXGI_FORMAT_UNKNOWN)
{
if (SUCCEEDED(D3D10CheckFormatSupport(device, *format,
&format_support)) &&
UINT format_support;
if (SUCCEEDED(D3D10CheckFormatSupport(device, *format, &format_support)) &&
((format_support & desired_format_support) == desired_format_support))
break;
format++;

View File

@ -13,6 +13,8 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "d3d11_common.h"
#include "d3dcompiler_common.h"
@ -57,21 +59,22 @@ 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;
UINT format_support = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE;
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)
@ -82,6 +85,11 @@ void d3d11_init_texture(D3D11Device device, d3d11_texture_t* texture)
}
}
if (texture->desc.BindFlags & D3D11_BIND_RENDER_TARGET)
format_support |= D3D11_FORMAT_SUPPORT_RENDER_TARGET;
texture->desc.Format = d3d11_get_closest_match(device, texture->desc.Format, format_support);
D3D11CreateTexture2D(device, &texture->desc, NULL, &texture->handle);
{
@ -93,6 +101,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 +113,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(
@ -134,10 +150,15 @@ void d3d11_update_texture(
DXGI_FORMAT
d3d11_get_closest_match(D3D11Device device, DXGI_FORMAT desired_format, UINT desired_format_support)
{
DXGI_FORMAT default_list[] = {desired_format, DXGI_FORMAT_UNKNOWN};
DXGI_FORMAT* format = dxgi_get_format_fallback_list(desired_format);
UINT format_support;
if(!format)
format = default_list;
while (*format != DXGI_FORMAT_UNKNOWN)
{
UINT format_support;
if (SUCCEEDED(D3D11CheckFormatSupport(device, *format, &format_support)) &&
((format_support & desired_format_support) == desired_format_support))
break;
@ -148,56 +169,65 @@ d3d11_get_closest_match(D3D11Device device, DXGI_FORMAT desired_format, UINT des
}
bool d3d11_init_shader(
D3D11Device device,
const void* src,
size_t size,
LPCSTR vs_entry,
LPCSTR ps_entry,
LPCSTR gs_entry,
D3D11_INPUT_ELEMENT_DESC* input_element_descs,
UINT num_elements,
d3d11_shader_t* out)
D3D11Device device,
const char* src,
size_t size,
const void* src_name,
LPCSTR vs_entry,
LPCSTR ps_entry,
LPCSTR gs_entry,
const D3D11_INPUT_ELEMENT_DESC* input_element_descs,
UINT num_elements,
d3d11_shader_t* out)
{
D3DBlob vs_code;
D3DBlob ps_code;
D3DBlob gs_code;
D3DBlob vs_code = NULL;
D3DBlob ps_code = NULL;
D3DBlob gs_code = NULL;
if (size) /* char array */
bool success = true;
if (!src) /* LPCWSTR filename */
{
if (!d3d_compile(src, size, 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;
if (vs_entry && !d3d_compile_from_file(src_name, vs_entry, "vs_5_0", &vs_code))
success = false;
if (ps_entry && !d3d_compile_from_file(src_name, ps_entry, "ps_5_0", &ps_code))
success = false;
if (gs_entry && !d3d_compile_from_file(src_name, gs_entry, "gs_5_0", &gs_code))
success = false;
}
else /* LPCWSTR filename */
else /* char array */
{
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))
return false;
if (gs_entry && !d3d_compile_from_file(src, gs_entry, "gs_5_0", &gs_code))
return false;
if (!size)
size = strlen(src);
if (vs_entry && !d3d_compile(src, size, src_name, vs_entry, "vs_5_0", &vs_code))
success = false;
if (ps_entry && !d3d_compile(src, size, src_name, ps_entry, "ps_5_0", &ps_code))
success = false;
if (gs_entry && !d3d_compile(src, size, src_name, gs_entry, "gs_5_0", &gs_code))
success = false;
}
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_code)
D3D11CreateVertexShader(
device, D3DGetBufferPointer(vs_code), D3DGetBufferSize(vs_code), NULL, &out->vs);
D3D11CreatePixelShader(
device, D3DGetBufferPointer(ps_code), D3DGetBufferSize(ps_code), NULL, &out->ps);
Release(ps_code);
if (ps_code)
D3D11CreatePixelShader(
device, D3DGetBufferPointer(ps_code), D3DGetBufferSize(ps_code), NULL, &out->ps);
if (gs_entry)
{
if (gs_code)
D3D11CreateGeometryShader(
device, D3DGetBufferPointer(gs_code), D3DGetBufferSize(gs_code), NULL, &out->gs);
Release(gs_code);
}
return true;
if (vs_code && input_element_descs)
D3D11CreateInputLayout(
device, input_element_descs, num_elements, D3DGetBufferPointer(vs_code),
D3DGetBufferSize(vs_code), &out->layout);
Release(vs_code);
Release(ps_code);
Release(gs_code);
return success;
}

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)
{
@ -1906,12 +1912,12 @@ static INLINE HRESULT D3D11CreateDepthStencilView(
return device->lpVtbl->CreateDepthStencilView(device, resource, desc, depth_stencil_view);
}
static INLINE HRESULT D3D11CreateInputLayout(
D3D11Device device,
D3D11_INPUT_ELEMENT_DESC* input_element_descs,
UINT num_elements,
void* shader_bytecode_with_input_signature,
SIZE_T bytecode_length,
D3D11InputLayout* input_layout)
D3D11Device device,
const D3D11_INPUT_ELEMENT_DESC* input_element_descs,
UINT num_elements,
void* shader_bytecode_with_input_signature,
SIZE_T bytecode_length,
D3D11InputLayout* input_layout)
{
return device->lpVtbl->CreateInputLayout(
device, input_element_descs, num_elements, shader_bytecode_with_input_signature,
@ -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,9 @@ 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;
bool resize_fbos;
d3d11_shader_t shaders[GFX_MAX_SHADERS];
struct
{
d3d11_shader_t shader;
@ -2523,10 +2531,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];
uint32_t 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,34 +2584,21 @@ 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);
static INLINE DXGI_FORMAT
d3d11_get_closest_match_texture2D(D3D11Device device, DXGI_FORMAT desired_format)
{
return d3d11_get_closest_match(
device, 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,
size_t size,
LPCSTR vs_entry,
LPCSTR ps_entry,
LPCSTR gs_entry,
D3D11_INPUT_ELEMENT_DESC* input_element_descs,
UINT num_elements,
d3d11_shader_t* out);
D3D11Device device,
const char* src,
size_t size,
const void* src_name,
LPCSTR vs_entry,
LPCSTR ps_entry,
LPCSTR gs_entry,
const D3D11_INPUT_ELEMENT_DESC* input_element_descs,
UINT num_elements,
d3d11_shader_t* out);
static INLINE void d3d11_release_shader(d3d11_shader_t* shader)
{
@ -2571,6 +2607,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 +2629,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

@ -435,10 +435,10 @@ bool d3d12_init_pipeline(d3d12_video_t* d3d12)
},
};
if (!d3d_compile(stock, sizeof(stock), "VSMain", "vs_5_0", &vs_code))
if (!d3d_compile(stock, sizeof(stock), NULL, "VSMain", "vs_5_0", &vs_code))
return false;
if (!d3d_compile(stock, sizeof(stock), "PSMain", "ps_5_0", &ps_code))
if (!d3d_compile(stock, sizeof(stock), NULL, "PSMain", "ps_5_0", &ps_code))
return false;
{
@ -631,8 +631,12 @@ void d3d12_create_fullscreen_quad_vbo(
DXGI_FORMAT d3d12_get_closest_match(
D3D12Device device, DXGI_FORMAT desired_format, D3D12_FORMAT_SUPPORT1 desired_format_support)
{
DXGI_FORMAT default_list[] = {desired_format, DXGI_FORMAT_UNKNOWN};
DXGI_FORMAT* format = dxgi_get_format_fallback_list(desired_format);
if(!format)
format = default_list;
while (*format != DXGI_FORMAT_UNKNOWN)
{
D3D12_FEATURE_DATA_FORMAT_SUPPORT format_support = { *format };

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,12 +96,34 @@ 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
bool d3d_compile(const char* src, size_t size, LPCSTR entrypoint, LPCSTR target, D3DBlob* out)
bool d3d_compile(const char* src, size_t size, LPCSTR src_name, LPCSTR entrypoint, LPCSTR target, D3DBlob* out)
{
D3DBlob error_msg;
UINT compileflags = 0;
@ -112,7 +133,7 @@ bool d3d_compile(const char* src, size_t size, LPCSTR entrypoint, LPCSTR target,
#endif
if (FAILED(D3DCompile(
src, size, NULL, NULL, NULL, entrypoint, target, compileflags, 0, out, &error_msg)))
src, size, src_name, NULL, NULL, entrypoint, target, compileflags, 0, out, &error_msg)))
{
if (error_msg)
{

View File

@ -55,5 +55,5 @@ D3DUnregisterDestructionCallback(D3DDestructionNotifier destruction_notifier, UI
#endif
/* end of auto-generated */
bool d3d_compile(const char* src, size_t size, LPCSTR entrypoint, LPCSTR target, D3DBlob* out);
bool d3d_compile(const char* src, size_t size, LPCSTR src_name, LPCSTR entrypoint, LPCSTR target, D3DBlob* out);
bool d3d_compile_from_file(LPCWSTR filename, LPCSTR entrypoint, LPCSTR target, D3DBlob* out);

View File

@ -55,16 +55,37 @@ HRESULT WINAPI CreateDXGIFactory1(REFIID riid, void** ppFactory)
DXGI_FORMAT* dxgi_get_format_fallback_list(DXGI_FORMAT format)
{
static DXGI_FORMAT format_unknown = DXGI_FORMAT_UNKNOWN;
switch ((unsigned)format)
{
case DXGI_FORMAT_R32G32B32A32_FLOAT:
{
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,
@ -106,9 +127,9 @@ DXGI_FORMAT* dxgi_get_format_fallback_list(DXGI_FORMAT format)
return formats;
}
default:
assert(0);
break;
}
return &format_unknown;
return NULL;
}
#define FORMAT_PROCESS_( \
@ -330,3 +351,54 @@ void dxgi_input_driver(const char* name, const input_driver_t** input, void** in
*input_data = input_dinput.init(name);
*input = *input_data ? &input_dinput : NULL;
}
DXGI_FORMAT glslang_format_to_dxgi(glslang_format fmt)
{
#undef FMT_
#define FMT_(x) case SLANG_FORMAT_##x: return DXGI_FORMAT_##x
#undef FMT2
#define FMT2(x,y) case SLANG_FORMAT_##x: return y
switch (fmt)
{
FMT_(R8_UNORM);
FMT_(R8_SINT);
FMT_(R8_UINT);
FMT_(R8G8_UNORM);
FMT_(R8G8_SINT);
FMT_(R8G8_UINT);
FMT_(R8G8B8A8_UNORM);
FMT_(R8G8B8A8_SINT);
FMT_(R8G8B8A8_UINT);
FMT2(R8G8B8A8_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB);
FMT2(A2B10G10R10_UNORM_PACK32, DXGI_FORMAT_R10G10B10A2_UNORM);
FMT2(A2B10G10R10_UINT_PACK32, DXGI_FORMAT_R10G10B10A2_UNORM);
FMT_(R16_UINT);
FMT_(R16_SINT);
FMT2(R16_SFLOAT, DXGI_FORMAT_R16_FLOAT);
FMT_(R16G16_UINT);
FMT_(R16G16_SINT);
FMT2(R16G16_SFLOAT, DXGI_FORMAT_R16G16_FLOAT);
FMT_(R16G16B16A16_UINT);
FMT_(R16G16B16A16_SINT);
FMT2(R16G16B16A16_SFLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT);
FMT_(R32_UINT);
FMT_(R32_SINT);
FMT2(R32_SFLOAT, DXGI_FORMAT_R32_FLOAT);
FMT_(R32G32_UINT);
FMT_(R32G32_SINT);
FMT2(R32G32_SFLOAT, DXGI_FORMAT_R32G32_FLOAT);
FMT_(R32G32B32A32_UINT);
FMT_(R32G32B32A32_SINT);
FMT2(R32G32B32A32_SFLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT);
case SLANG_FORMAT_UNKNOWN:
default:
break;
}
return DXGI_FORMAT_UNKNOWN;
}

View File

@ -770,6 +770,7 @@ static INLINE HRESULT DXGICreateFactory(DXGIFactory* factory)
/* internal */
#include "../video_driver.h"
#include "../drivers_shader/glslang_util.h"
#define DXGI_COLOR_RGBA(r, g, b, a) (((UINT32)(a) << 24) | ((UINT32)(b) << 16) | ((UINT32)(g) << 8) | ((UINT32)(r) << 0))
@ -794,6 +795,8 @@ void dxgi_copy(
void dxgi_update_title(video_frame_info_t* video_info);
void dxgi_input_driver(const char* name, const input_driver_t** input, void** input_data);
DXGI_FORMAT glslang_format_to_dxgi(glslang_format fmt);
RETRO_END_DECLS
#if 1

View File

@ -236,8 +236,8 @@ d3d10_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
D3D10_INPUT_PER_VERTEX_DATA, 0 },
};
d3d_compile(stock, sizeof(stock), "VSMain", "vs_4_0", &vs_code);
d3d_compile(stock, sizeof(stock), "PSMain", "ps_4_0", &ps_code);
d3d_compile(stock, sizeof(stock), NULL, "VSMain", "vs_4_0", &vs_code);
d3d_compile(stock, sizeof(stock), NULL, "PSMain", "ps_4_0", &ps_code);
D3D10CreateVertexShader(
d3d10->device, D3DGetBufferPointer(vs_code), D3DGetBufferSize(vs_code), &d3d10->vs);

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,242 @@ static void d3d11_update_viewport(void* data, bool force_full)
d3d11->frame.viewport.Height = d3d11->vp.height;
d3d11->frame.viewport.MaxDepth = 0.0f;
d3d11->frame.viewport.MaxDepth = 1.0f;
if (d3d11->frame.output_size.x != d3d11->vp.width ||
d3d11->frame.output_size.y != d3d11->vp.height)
d3d11->resize_fbos = true;
d3d11->frame.output_size.x = d3d11->vp.width;
d3d11->frame.output_size.y = d3d11->vp.height;
d3d11->frame.output_size.z = 1.0f / d3d11->vp.width;
d3d11->frame.output_size.w = 1.0f / d3d11->vp.height;
d3d11->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] = {
SL_TEXTURE_MAP(
SLANG_TEXTURE_SEMANTIC_ORIGINAL, d3d11->frame.texture, d3d11->pass[i].sampler,
d3d11->frame.texture.size_data),
SL_TEXTURE_MAP(
SLANG_TEXTURE_SEMANTIC_SOURCE, *source, d3d11->pass[i].sampler,
source->size_data),
SL_TEXTURE_MAP(
SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY, 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 = (texture_map_t)SL_TEXTURE_MAP_ARRAY(
SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT, j, d3d11->pass[j].rt,
d3d11->pass[i].sampler, d3d11->pass[j].rt.size_data);
ptr++;
}
for (int j = 0; j < d3d11->shader_preset->luts; j++)
{
*ptr = (texture_map_t)SL_TEXTURE_MAP_ARRAY(
SLANG_TEXTURE_SEMANTIC_USER, j, d3d11->luts[j], d3d11->luts[j].sampler,
d3d11->luts[j].size_data);
ptr++;
}
}
uniform_map_t uniform_map[] = {
SL_UNIFORM_MAP(SLANG_SEMANTIC_MVP, d3d11->mvp),
SL_UNIFORM_MAP(SLANG_SEMANTIC_OUTPUT, d3d11->pass[i].rt.size_data),
SL_UNIFORM_MAP(SLANG_SEMANTIC_FRAME_COUNT, d3d11->pass[i].frame_count),
SL_UNIFORM_MAP(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 },
};
#ifdef DEBUG
bool save_hlsl = true;
#else
bool save_hlsl = false;
#endif
const char* vs_src = d3d11->shader_preset->pass[i].source.string.vertex;
const char* ps_src = d3d11->shader_preset->pass[i].source.string.fragment;
const char* vs_ext = ".vs.hlsl";
const char* ps_ext = ".ps.hlsl";
int base_len = strlen(d3d11->shader_preset->pass[i].source.path) - strlen(".slang");
char* vs_filename = (char*)malloc(base_len + strlen(vs_ext) + 1);
char* ps_filename = (char*)malloc(base_len + strlen(ps_ext) + 1);
strncpy(vs_filename, d3d11->shader_preset->pass[i].source.path, base_len);
strncpy(ps_filename, d3d11->shader_preset->pass[i].source.path, base_len);
strncpy(vs_filename + base_len, vs_ext, strlen(vs_ext) + 1);
strncpy(ps_filename + base_len, ps_ext, strlen(ps_ext) + 1);
if (!d3d11_init_shader(
d3d11->device, vs_src, 0, vs_filename, "main", NULL, NULL, desc, countof(desc),
&d3d11->pass[i].shader))
save_hlsl = true;
if (!d3d11_init_shader(
d3d11->device, ps_src, 0, ps_filename, NULL, "main", NULL, NULL, 0,
&d3d11->pass[i].shader))
save_hlsl = true;
if (save_hlsl)
{
FILE* fp = fopen(vs_filename, "w");
fwrite(vs_src, 1, strlen(vs_src), fp);
fclose(fp);
fp = fopen(ps_filename, "w");
fwrite(ps_src, 1, strlen(ps_src), fp);
fclose(fp);
}
free(vs_filename);
free(ps_filename);
free(d3d11->shader_preset->pass[i].source.string.vertex);
free(d3d11->shader_preset->pass[i].source.string.fragment);
d3d11->shader_preset->pass[i].source.string.vertex = NULL;
d3d11->shader_preset->pass[i].source.string.fragment = NULL;
if (!d3d11->pass[i].shader.vs || !d3d11->pass[i].shader.ps)
goto error;
}
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 };
image.supports_rgba = true;
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 = DXGI_FORMAT_R8G8B8A8_UNORM;
d3d11_init_texture(d3d11->device, &d3d11->luts[i]);
d3d11_update_texture(
d3d11->ctx, image.width, image.height, 0, DXGI_FORMAT_R8G8B8A8_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 +319,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 +368,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;
@ -221,9 +450,8 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
d3d11->vsync = video->vsync;
d3d11->format = video->rgb32 ? DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM;
d3d11->frame.texture.desc.Format =
d3d11_get_closest_match_texture2D(d3d11->device, d3d11->format);
d3d11->frame.texture.desc.Usage = D3D11_USAGE_DEFAULT;
d3d11->frame.texture.desc.Format = d3d11->format;
d3d11->frame.texture.desc.Usage = D3D11_USAGE_DEFAULT;
d3d11->menu.texture.desc.Usage = D3D11_USAGE_DEFAULT;
@ -243,6 +471,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);
{
@ -305,7 +534,7 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
;
if (!d3d11_init_shader(
d3d11->device, shader, sizeof(shader), "VSMain", "PSMain", NULL, desc,
d3d11->device, shader, sizeof(shader), NULL, "VSMain", "PSMain", NULL, desc,
countof(desc), &d3d11->shaders[VIDEO_SHADER_STOCK_BLEND]))
goto error;
}
@ -333,11 +562,11 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
;
if (!d3d11_init_shader(
d3d11->device, shader, sizeof(shader), "VSMain", "PSMain", "GSMain", desc,
d3d11->device, shader, sizeof(shader), NULL, "VSMain", "PSMain", "GSMain", desc,
countof(desc), &d3d11->sprites.shader))
goto error;
if (!d3d11_init_shader(
d3d11->device, shader, sizeof(shader), "VSMain", "PSMainA8", "GSMain", desc,
d3d11->device, shader, sizeof(shader), NULL, "VSMain", "PSMainA8", "GSMain", desc,
countof(desc), &d3d11->sprites.shader_font))
goto error;
}
@ -355,13 +584,13 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
;
if (!d3d11_init_shader(
d3d11->device, ribbon, sizeof(ribbon), "VSMain", "PSMain", NULL, desc,
d3d11->device, ribbon, sizeof(ribbon), NULL, "VSMain", "PSMain", NULL, desc,
countof(desc), &d3d11->shaders[VIDEO_SHADER_MENU]))
goto error;
if (!d3d11_init_shader(
d3d11->device, ribbon_simple, sizeof(ribbon_simple), "VSMain", "PSMain", NULL, desc,
countof(desc), &d3d11->shaders[VIDEO_SHADER_MENU_2]))
d3d11->device, ribbon_simple, sizeof(ribbon_simple), NULL, "VSMain", "PSMain", NULL,
desc, countof(desc), &d3d11->shaders[VIDEO_SHADER_MENU_2]))
goto error;
}
@ -387,21 +616,21 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
;
if (!d3d11_init_shader(
d3d11->device, simple_snow, sizeof(simple_snow), "VSMain", "PSMain", NULL, desc,
countof(desc), &d3d11->shaders[VIDEO_SHADER_MENU_3]))
d3d11->device, simple_snow, sizeof(simple_snow), NULL, "VSMain", "PSMain", NULL,
desc, countof(desc), &d3d11->shaders[VIDEO_SHADER_MENU_3]))
goto error;
if (!d3d11_init_shader(
d3d11->device, snow, sizeof(snow), "VSMain", "PSMain", NULL, desc, countof(desc),
&d3d11->shaders[VIDEO_SHADER_MENU_4]))
d3d11->device, snow, sizeof(snow), NULL, "VSMain", "PSMain", NULL, desc,
countof(desc), &d3d11->shaders[VIDEO_SHADER_MENU_4]))
goto error;
if (!d3d11_init_shader(
d3d11->device, bokeh, sizeof(bokeh), "VSMain", "PSMain", NULL, desc, countof(desc),
&d3d11->shaders[VIDEO_SHADER_MENU_5]))
d3d11->device, bokeh, sizeof(bokeh), NULL, "VSMain", "PSMain", NULL, desc,
countof(desc), &d3d11->shaders[VIDEO_SHADER_MENU_5]))
goto error;
if (!d3d11_init_shader(
d3d11->device, snowflake, sizeof(snowflake), "VSMain", "PSMain", NULL, desc,
d3d11->device, snowflake, sizeof(snowflake), NULL, "VSMain", "PSMain", NULL, desc,
countof(desc), &d3d11->shaders[VIDEO_SHADER_MENU_6]))
goto error;
}
@ -442,12 +671,129 @@ 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:
if (pass->fbo.scale_x)
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:
if (pass->fbo.scale_y)
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 = glslang_format_to_dxgi(d3d11->pass[i].semantics.format);
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->texture_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;
}
}
}
d3d11->resize_fbos = false;
return true;
#if 0
error:
d3d11_free_shader_preset(d3d11);
return false;
#endif
}
static bool d3d11_gfx_frame(
void* data,
@ -474,6 +820,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 +833,105 @@ 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->resize_fbos || !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->size)
{
if (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, SLANG_NUM_BINDINGS, d3d11->pass[i].textures);
D3D11SetPShaderSamplers(d3d11->ctx, 0, SLANG_NUM_BINDINGS, 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);
@ -524,6 +941,7 @@ static bool d3d11_gfx_frame(
if (d3d11->menu.fullscreen)
D3D11SetViewports(d3d11->ctx, 1, &d3d11->viewport);
d3d11_set_shader(d3d11->ctx, &d3d11->shaders[VIDEO_SHADER_STOCK_BLEND]);
D3D11SetVertexBuffer(d3d11->ctx, 0, d3d11->menu.vbo, sizeof(d3d11_vertex_t), 0);
D3D11SetVShaderConstantBuffers(d3d11->ctx, 0, 1, &d3d11->ubo);
d3d11_set_texture_and_sampler(d3d11->ctx, 0, &d3d11->menu.texture);
@ -594,13 +1012,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)
@ -622,22 +1041,22 @@ static void d3d11_set_menu_texture_frame(
void* data, const void* frame, bool rgb32, unsigned width, unsigned height, float alpha)
{
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
int pitch = width * (rgb32 ? sizeof(uint32_t) : sizeof(uint16_t));
DXGI_FORMAT format = rgb32 ? DXGI_FORMAT_B8G8R8A8_UNORM : DXGI_FORMAT_EX_A4R4G4B4_UNORM;
if (d3d11->menu.texture.desc.Width != width || d3d11->menu.texture.desc.Height != height)
{
d3d11->menu.texture.desc.Format = d3d11_get_closest_match_texture2D(d3d11->device, format);
d3d11->menu.texture.desc.Format = format;
d3d11->menu.texture.desc.Width = width;
d3d11->menu.texture.desc.Height = height;
d3d11_init_texture(d3d11->device, &d3d11->menu.texture);
}
d3d11_update_texture(d3d11->ctx, width, height, pitch, format, frame, &d3d11->menu.texture);
d3d11_update_texture(d3d11->ctx, width, height, 0, format, frame, &d3d11->menu.texture);
d3d11->menu.texture.sampler = config_get_ptr()->bools.menu_linear_filter
? d3d11->sampler_linear
: d3d11->sampler_nearest;
}
static void d3d11_set_menu_texture_enable(void* data, bool state, bool full_screen)
{
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
@ -684,14 +1103,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)
{
@ -711,8 +1130,7 @@ static uintptr_t d3d11_gfx_load_texture(
texture->desc.Width = image->width;
texture->desc.Height = image->height;
texture->desc.Format =
d3d11_get_closest_match_texture2D(d3d11->device, DXGI_FORMAT_B8G8R8A8_UNORM);
texture->desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
d3d11_init_texture(d3d11->device, texture);
@ -754,7 +1172,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

@ -54,8 +54,7 @@ d3d11_font_init_font(void* data, const char* font_path, float font_size, bool is
font->texture.sampler = d3d11->sampler_linear;
font->texture.desc.Width = font->atlas->width;
font->texture.desc.Height = font->atlas->height;
font->texture.desc.Format =
d3d11_get_closest_match_texture2D(d3d11->device, DXGI_FORMAT_A8_UNORM);
font->texture.desc.Format = DXGI_FORMAT_A8_UNORM;
d3d11_init_texture(d3d11->device, &font->texture);
d3d11_update_texture(
d3d11->ctx, font->atlas->width, font->atlas->height, font->atlas->width,

View File

@ -29,7 +29,7 @@
#include "config.h"
#endif
#include "glslang_util.hpp"
#include "glslang_util.h"
#ifdef HAVE_VULKAN
#include "glslang.hpp"
#endif
@ -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

@ -17,13 +17,14 @@
#define GLSLANG_UTIL_HPP
#include <stdint.h>
#include <vector>
#include <string>
#include <retro_common_api.h>
enum glslang_format
typedef enum glslang_format
{
SLANG_FORMAT_UNKNOWN = 0,
// 8-bit
SLANG_FORMAT_R8_UNORM = 0,
SLANG_FORMAT_R8_UNORM,
SLANG_FORMAT_R8_UINT,
SLANG_FORMAT_R8_SINT,
SLANG_FORMAT_R8G8_UNORM,
@ -60,8 +61,18 @@ enum glslang_format
SLANG_FORMAT_R32G32B32A32_SINT,
SLANG_FORMAT_R32G32B32A32_SFLOAT,
SLANG_FORMAT_UNKNOWN
};
SLANG_FORMAT_MAX
}glslang_format;
RETRO_BEGIN_DECLS
const char *glslang_format_to_string(glslang_format fmt);
RETRO_END_DECLS
#ifdef __cplusplus
#include <vector>
#include <string>
struct glslang_parameter
{
@ -88,11 +99,11 @@ struct glslang_output
};
bool glslang_compile_shader(const char *shader_path, glslang_output *output);
const char *glslang_format_to_string(enum glslang_format fmt);
// Helpers for internal use.
bool glslang_read_shader_file(const char *path, std::vector<std::string> *output, bool root_file);
bool glslang_parse_meta(const std::vector<std::string> &lines, glslang_meta *meta);
#endif
#endif

View File

@ -15,7 +15,7 @@
*/
#include "shader_vulkan.h"
#include "glslang_util.hpp"
#include "glslang_util.h"
#include <vector>
#include <memory>
#include <functional>
@ -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

@ -14,7 +14,7 @@
*/
#include "slang_preprocess.h"
#include "glslang_util.hpp"
#include "glslang_util.h"
#include <vector>
#include <string>
#include <algorithm>
@ -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.h"
bool slang_preprocess_parse_parameters(glslang_meta& meta,
struct video_shader *shader);
#endif
#endif

View File

@ -0,0 +1,409 @@
#include <fstream>
#include <iostream>
#include <spirv_hlsl.hpp>
#include <stdint.h>
#include "verbosity.h"
#include "glslang_util.h"
#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;
}
template <typename M, typename S>
static string get_semantic_name(const unordered_map<string, M>* map, S semantic, unsigned index)
{
for (const pair<string, M>& m : *map)
{
if (m.second.semantic == semantic && m.second.index == index)
return m.first;
}
return string();
}
static string
get_semantic_name(slang_reflection& reflection, slang_semantic semantic, unsigned index)
{
static const char* names[] = {
"MVP",
"OutputSize",
"FinalViewportSize",
"FrameCount",
};
if ((int)semantic < sizeof(names) / sizeof(*names))
return std::string(names[semantic]);
return get_semantic_name(reflection.semantic_map, semantic, index);
}
static string
get_semantic_name(slang_reflection& reflection, slang_texture_semantic semantic, unsigned index)
{
static const char* names[] = {
"Original", "Source", "OriginalHistory", "PassOutput", "PassFeedback",
};
if ((int)semantic < (int)SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY)
return std::string(names[semantic]);
else if ((int)semantic < sizeof(names) / sizeof(*names))
return std::string(names[semantic]) + to_string(index);
return get_semantic_name(reflection.texture_semantic_map, semantic, index);
}
static string get_size_semantic_name(
slang_reflection& reflection, slang_texture_semantic semantic, unsigned index)
{
static const char* names[] = {
"OriginalSize", "SourceSize", "OriginalHistorySize", "PassOutputSize", "PassFeedbackSize",
};
if ((int)semantic < (int)SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY)
return std::string(names[semantic]);
if ((int)semantic < sizeof(names) / sizeof(*names))
return std::string(names[semantic]) + to_string(index);
return get_semantic_name(reflection.texture_semantic_uniform_map, semantic, index);
}
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> uniform_semantic_map;
for (unsigned i = 0; i < shader_info->num_parameters; i++)
{
if (!set_unique_map(
uniform_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 = &uniform_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;
}
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, uniform_map->id,
src.num_components * (unsigned)sizeof(float) };
string uniform_id = get_semantic_name(sl_reflection, uniform_map->semantic, 0);
strncpy(uniform.id, uniform_id.c_str(), sizeof(uniform.id));
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,
"shader_info->parameter[i].current", sizeof(float) };
string uniform_id = get_semantic_name(sl_reflection, SLANG_SEMANTIC_FLOAT_PARAMETER, i);
strncpy(uniform.id, uniform_id.c_str(), sizeof(uniform.id));
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->index < sl_reflection.semantic_textures[texture_map->semantic].size())
{
slang_texture_semantic_meta& src =
sl_reflection.semantic_textures[texture_map->semantic][texture_map->index];
if (src.stage_mask)
{
texture_sem_t texture = { texture_map->texture_data, texture_map->texture_id,
texture_map->sampler_data, texture_map->sampler_id };
texture.stage_mask = src.stage_mask;
texture.binding = src.binding;
string id = get_semantic_name(sl_reflection, texture_map->semantic, texture_map->index);
strncpy(texture.id, id.c_str(), sizeof(texture.id));
textures.push_back(texture);
uniform_sem_t uniform = { texture_map->size_data, texture_map->size_id,
4 * sizeof(float) };
string uniform_id =
get_size_semantic_name(sl_reflection, texture_map->semantic, texture_map->index);
strncpy(uniform.id, uniform_id.c_str(), sizeof(uniform.id));
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;
out->format = output.meta.rt_format;
if (out->format == SLANG_FORMAT_UNKNOWN)
{
if (pass.fbo.srgb_fbo)
out->format = SLANG_FORMAT_R8G8B8A8_SRGB;
else if (pass.fbo.fp_fbo)
out->format = SLANG_FORMAT_R16G16B16A16_SFLOAT;
else
out->format = SLANG_FORMAT_R8G8B8A8_UNORM;
}
pass.source.string.vertex = NULL;
pass.source.string.fragment = NULL;
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;
/* 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 = strdup(vs_code.c_str());
pass.source.string.fragment = strdup(ps_code.c_str());
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]: SPIRV-Cross 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,116 @@
/* 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"
#include "glslang_util.h"
typedef struct
{
enum slang_semantic semantic;
void* data;
const char* id;
} uniform_map_t;
typedef struct
{
enum slang_texture_semantic semantic;
int index;
void* texture_data;
const char* texture_id;
void* sampler_data;
const char* sampler_id;
void* size_data;
const char* size_id;
} texture_map_t;
#define SL_UNIFORM_MAP(sem, data) \
{ \
sem, &data, #data \
}
#define SL_TEXTURE_MAP_ARRAY(sem, index, tex, sampl, size) \
{ \
sem, index, &tex, #tex, &sampl, #sampl, &size, #size \
}
#define SL_TEXTURE_MAP(sem, tex, sampl, size) SL_TEXTURE_MAP_ARRAY(sem, 0, tex, sampl, size)
typedef struct
{
texture_map_t* texture_map;
uniform_map_t* uniform_map;
} semantics_map_t;
typedef struct
{
void* data;
const char* data_id;
unsigned size;
unsigned offset;
char id[64];
} uniform_sem_t;
typedef struct
{
void* texture_data;
const char* texture_id;
void* sampler_data;
const char* sampler_id;
unsigned stage_mask;
unsigned binding;
char id[64];
} 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;
cbuffer_sem_t cbuffers[SLANG_CBUFFER_MAX];
glslang_format format;
} 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)
{
@ -673,7 +673,7 @@ bool slang_reflect_spirv(const std::vector<uint32_t> &vertex,
}
catch (const std::exception &e)
{
RARCH_ERR("[slang]: spir2cross threw exception: %s.\n", e.what());
RARCH_ERR("[slang]: SPIRV-Cross threw exception: %s.\n", e.what());
return false;
}
}

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

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