mirror of
https://github.com/CTCaer/RetroArch.git
synced 2025-01-10 13:02:27 +00:00
Merge pull request #6204 from aliaspider/master
(D3D11) Implement slang shader specification using Spirv-Cross.
This commit is contained in:
commit
f096e667d8
112
Makefile.common
112
Makefile.common
@ -1153,54 +1153,18 @@ endif
|
||||
|
||||
ifeq ($(HAVE_VULKAN), 1)
|
||||
ifneq ($(findstring Win32,$(OS)),)
|
||||
GLSLANG_PLATFORM := Windows
|
||||
WANT_WGL = 1
|
||||
else
|
||||
GLSLANG_PLATFORM := Unix
|
||||
endif
|
||||
|
||||
GLSLANG_SOURCES := \
|
||||
$(wildcard $(DEPS_DIR)/glslang/*.cpp) \
|
||||
$(wildcard $(DEPS_DIR)/glslang/glslang/SPIRV/*.cpp) \
|
||||
$(wildcard $(DEPS_DIR)/glslang/glslang/glslang/GenericCodeGen/*.cpp) \
|
||||
$(wildcard $(DEPS_DIR)/glslang/glslang/OGLCompilersDLL/*.cpp) \
|
||||
$(wildcard $(DEPS_DIR)/glslang/glslang/glslang/MachineIndependent/*.cpp) \
|
||||
$(wildcard $(DEPS_DIR)/glslang/glslang/glslang/MachineIndependent/preprocessor/*.cpp) \
|
||||
$(wildcard $(DEPS_DIR)/glslang/glslang/hlsl/*.cpp) \
|
||||
$(wildcard $(DEPS_DIR)/glslang/glslang/glslang/OSDependent/$(GLSLANG_PLATFORM)/*.cpp)
|
||||
|
||||
SPIRV_CROSS_SOURCES := $(DEPS_DIR)/SPIRV-Cross/spirv_cross.cpp \
|
||||
$(DEPS_DIR)/SPIRV-Cross/spirv_cfg.cpp
|
||||
ifneq ($(findstring Win32,$(OS)),)
|
||||
WANT_WGL = 1
|
||||
# Trivial temporary workaround for MinGW and glslang.
|
||||
CXXFLAGS += -fpermissive
|
||||
endif
|
||||
|
||||
DEFINES += \
|
||||
-I$(DEPS_DIR)/glslang/glslang/glslang/OSDependent/$(GLSLANG_PLATFORM) \
|
||||
-I$(DEPS_DIR)/glslang/glslang/OGLCompilersDLL \
|
||||
-I$(DEPS_DIR)/glslang/glslang \
|
||||
-I$(DEPS_DIR)/glslang/glslang/glslang/MachineIndependent \
|
||||
-I$(DEPS_DIR)/glslang/glslang/glslang/Public \
|
||||
-I$(DEPS_DIR)/glslang/glslang/SPIRV \
|
||||
-I$(DEPS_DIR)/glslang \
|
||||
-I$(DEPS_DIR)/SPIRV-Cross
|
||||
|
||||
CXXFLAGS += -Wno-switch -Wno-sign-compare -fno-strict-aliasing -Wno-maybe-uninitialized -Wno-reorder -Wno-parentheses
|
||||
|
||||
GLSLANG_OBJ := $(GLSLANG_SOURCES:.cpp=.o)
|
||||
SPIRV_CROSS_OBJ := $(SPIRV_CROSS_SOURCES:.cpp=.o)
|
||||
|
||||
OBJ += gfx/drivers/vulkan.o \
|
||||
gfx/common/vulkan_common.o \
|
||||
$(LIBRETRO_COMM_DIR)/vulkan/vulkan_symbol_wrapper.o \
|
||||
gfx/drivers_font/vulkan_raster_font.o \
|
||||
gfx/drivers_shader/shader_vulkan.o \
|
||||
gfx/drivers_shader/glslang_util.o \
|
||||
gfx/drivers_shader/slang_reflection.o \
|
||||
gfx/drivers_shader/slang_preprocess.o \
|
||||
$(GLSLANG_OBJ) \
|
||||
$(SPIRV_CROSS_OBJ)
|
||||
gfx/drivers_shader/shader_vulkan.o
|
||||
|
||||
ifeq ($(HAVE_VULKAN_DISPLAY), 1)
|
||||
OBJ += gfx/drivers_context/khr_display_ctx.o
|
||||
@ -1209,20 +1173,12 @@ ifeq ($(HAVE_VULKAN), 1)
|
||||
OBJ += menu/drivers_display/menu_display_vulkan.o
|
||||
endif
|
||||
LIBS += -lstdc++
|
||||
DEFINES += -DHAVE_SLANG
|
||||
endif
|
||||
|
||||
ifeq ($(findstring 1, $(HAVE_VULKAN) $(HAVE_D3D10) $(HAVE_D3D11) $(HAVE_D3D12)),1)
|
||||
DEFINES += -DHAVE_VULKAN
|
||||
INCLUDE_DIRS += -Igfx/include
|
||||
endif
|
||||
|
||||
ifeq ($(findstring 1, $(HAVE_D3D10) $(HAVE_D3D11) $(HAVE_D3D12)),1)
|
||||
INCLUDE_DIRS += -Igfx/include/dxsdk
|
||||
endif
|
||||
|
||||
ifeq ($(WANT_WGL), 1)
|
||||
OBJ += gfx/drivers_context/wgl_ctx.o
|
||||
LIBS += -lcomctl32
|
||||
HAVE_SLANG = 1
|
||||
HAVE_GLSLANG = 1
|
||||
HAVE_SPIRV_CROSS = 1
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_OMAP), 1)
|
||||
@ -1305,6 +1261,9 @@ ifeq ($(HAVE_D3D11), 1)
|
||||
OBJ += gfx/drivers/d3d11.o gfx/common/d3d11_common.o \
|
||||
gfx/drivers_font/d3d11_font.o menu/drivers_display/menu_display_d3d11.o
|
||||
DEFINES += -DHAVE_D3D11
|
||||
HAVE_SLANG = 1
|
||||
HAVE_GLSLANG = 1
|
||||
HAVE_SPIRV_CROSS = 1
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_D3D12), 1)
|
||||
@ -1313,6 +1272,7 @@ ifeq ($(HAVE_D3D12), 1)
|
||||
endif
|
||||
|
||||
ifneq ($(findstring 1, $(HAVE_D3D10) $(HAVE_D3D11) $(HAVE_D3D12)),)
|
||||
INCLUDE_DIRS += -isystemgfx/include/dxsdk
|
||||
OBJ += gfx/common/d3dcompiler_common.o
|
||||
OBJ += gfx/common/dxgi_common.o
|
||||
CFLAGS += -Wno-unknown-pragmas
|
||||
@ -1355,6 +1315,58 @@ ifeq ($(HAVE_D3D_COMMON), 1)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SLANG),1)
|
||||
DEFINES += -DHAVE_SLANG
|
||||
OBJ += gfx/drivers_shader/slang_process.o
|
||||
OBJ += gfx/drivers_shader/slang_preprocess.o
|
||||
OBJ += gfx/drivers_shader/glslang_util.o
|
||||
OBJ += gfx/drivers_shader/slang_reflection.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_GLSLANG), 1)
|
||||
DEFINES += -DHAVE_GLSLANG
|
||||
|
||||
ifneq ($(findstring Win32,$(OS)),)
|
||||
GLSLANG_PLATFORM := Windows
|
||||
else
|
||||
GLSLANG_PLATFORM := Unix
|
||||
endif
|
||||
|
||||
INCLUDE_DIRS += \
|
||||
-I$(DEPS_DIR)/glslang/glslang/glslang/OSDependent/$(GLSLANG_PLATFORM) \
|
||||
-I$(DEPS_DIR)/glslang/glslang/OGLCompilersDLL \
|
||||
-I$(DEPS_DIR)/glslang/glslang \
|
||||
-I$(DEPS_DIR)/glslang/glslang/glslang/MachineIndependent \
|
||||
-I$(DEPS_DIR)/glslang/glslang/glslang/Public \
|
||||
-I$(DEPS_DIR)/glslang/glslang/SPIRV \
|
||||
-I$(DEPS_DIR)/glslang
|
||||
|
||||
GLSLANG_SOURCES := \
|
||||
$(wildcard $(DEPS_DIR)/glslang/*.cpp) \
|
||||
$(wildcard $(DEPS_DIR)/glslang/glslang/SPIRV/*.cpp) \
|
||||
$(wildcard $(DEPS_DIR)/glslang/glslang/glslang/GenericCodeGen/*.cpp) \
|
||||
$(wildcard $(DEPS_DIR)/glslang/glslang/OGLCompilersDLL/*.cpp) \
|
||||
$(wildcard $(DEPS_DIR)/glslang/glslang/glslang/MachineIndependent/*.cpp) \
|
||||
$(wildcard $(DEPS_DIR)/glslang/glslang/glslang/MachineIndependent/preprocessor/*.cpp) \
|
||||
$(wildcard $(DEPS_DIR)/glslang/glslang/hlsl/*.cpp) \
|
||||
$(wildcard $(DEPS_DIR)/glslang/glslang/glslang/OSDependent/$(GLSLANG_PLATFORM)/*.cpp)
|
||||
|
||||
OBJ += $(GLSLANG_SOURCES:.cpp=.o)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SPIRV_CROSS), 1)
|
||||
INCLUDE_DIRS += -I$(DEPS_DIR)/SPIRV-Cross
|
||||
OBJ += $(DEPS_DIR)/SPIRV-Cross/spirv_cross.o
|
||||
OBJ += $(DEPS_DIR)/SPIRV-Cross/spirv_cfg.o
|
||||
OBJ += $(DEPS_DIR)/SPIRV-Cross/spirv_glsl.o
|
||||
OBJ += $(DEPS_DIR)/SPIRV-Cross/spirv_hlsl.o
|
||||
endif
|
||||
|
||||
ifeq ($(WANT_WGL), 1)
|
||||
OBJ += gfx/drivers_context/wgl_ctx.o
|
||||
LIBS += -lcomctl32
|
||||
endif
|
||||
|
||||
#ifeq ($(HAVE_LIBXML2), 1)
|
||||
#LIBS += $(LIBXML2_LIBS)
|
||||
#DEFINES += $(LIBXML2_CFLAGS)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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++;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 };
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
};
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
409
gfx/drivers_shader/slang_process.cpp
Normal file
409
gfx/drivers_shader/slang_process.cpp
Normal 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;
|
||||
}
|
116
gfx/drivers_shader/slang_process.h
Normal file
116
gfx/drivers_shader/slang_process.h
Normal 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
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user