mirror of
https://github.com/libretro/snes9x.git
synced 2024-11-27 18:40:39 +00:00
Working Win32/Vulkan shader support.
This commit is contained in:
parent
89bbf08c74
commit
2c7d5f7a4d
@ -18,10 +18,10 @@ int mipmap_levels_for_size(int width, int height)
|
||||
|
||||
void trim(string_view &view)
|
||||
{
|
||||
while (view.length() > 0 && isspace(view.at(0)))
|
||||
while (view.length() > 0 && isspace((unsigned char)view.at(0)))
|
||||
view.remove_prefix(1);
|
||||
|
||||
while (view.length() > 0 && isspace(view.at(view.length() - 1)))
|
||||
while (view.length() > 0 && isspace((unsigned char)view.at(view.length() - 1)))
|
||||
view.remove_suffix(1);
|
||||
}
|
||||
|
||||
|
@ -390,6 +390,21 @@ void COpenGL::SetSwapInterval(int frames)
|
||||
wglSwapIntervalEXT(frames);
|
||||
}
|
||||
|
||||
std::vector<GLSLParam>* COpenGL::GetShaderParameters(void)
|
||||
{
|
||||
if (shader_type == OGL_SHADER_GLSL && initDone)
|
||||
return &glslShader->param;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::function<void(const char *)> COpenGL::GetShaderParametersSaveFunction()
|
||||
{
|
||||
return [&](const char *filename) {
|
||||
this->glslShader->save(filename);
|
||||
};
|
||||
}
|
||||
|
||||
bool COpenGL::ApplyDisplayChanges(void)
|
||||
{
|
||||
if(wglSwapIntervalEXT) {
|
||||
|
@ -16,6 +16,8 @@
|
||||
#include "wglext.h"
|
||||
#include "IS9xDisplayOutput.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
enum current_ogl_shader_type { OGL_SHADER_NONE, OGL_SHADER_GLSL, OGL_SHADER_CG, OGL_SHADER_GLSL_OLD};
|
||||
|
||||
class COpenGL : public IS9xDisplayOutput
|
||||
@ -83,10 +85,8 @@ public:
|
||||
void SetSnes9xColorFormat(void);
|
||||
void EnumModes(std::vector<dMode> *modeVector);
|
||||
void SetSwapInterval(int frames);
|
||||
GLSLShader *GetActiveShader()
|
||||
{
|
||||
return glslShader;
|
||||
}
|
||||
std::vector<GLSLParam> *GetShaderParameters(void);
|
||||
std::function<void(const char*)> GetShaderParametersSaveFunction();
|
||||
};
|
||||
|
||||
|
||||
|
@ -117,7 +117,9 @@ INT_PTR CALLBACK CShaderParamDlg::WndProcContainerStatic(HWND hStatic, UINT msg,
|
||||
return dlg->oldStaticProc(hStatic, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
CShaderParamDlg::CShaderParamDlg(GLSLShader &glsl_shader): shader(glsl_shader)
|
||||
CShaderParamDlg::CShaderParamDlg(std::vector<GLSLParam>& parameters_, std::function<void (const char *)> save_function_)
|
||||
: parameters(parameters_),
|
||||
save_function(save_function_)
|
||||
{
|
||||
HDC hIC;
|
||||
TEXTMETRIC tm;
|
||||
@ -170,7 +172,7 @@ CShaderParamDlg::~CShaderParamDlg()
|
||||
|
||||
bool CShaderParamDlg::show()
|
||||
{
|
||||
saved_parameters = shader.param;
|
||||
saved_parameters = parameters;
|
||||
|
||||
if(DialogBoxParam(GUI.hInstance, MAKEINTRESOURCE(IDD_DIALOG_SHADER_PARAMS), GUI.hWnd, DlgShaderParams, (LPARAM)this) == IDOK)
|
||||
{
|
||||
@ -178,7 +180,7 @@ bool CShaderParamDlg::show()
|
||||
return true;
|
||||
}
|
||||
|
||||
shader.param = saved_parameters;
|
||||
parameters = saved_parameters;
|
||||
WinRefreshDisplay();
|
||||
return false;
|
||||
}
|
||||
@ -205,8 +207,8 @@ void CShaderParamDlg::createContent(HWND hDlg)
|
||||
unsigned int edit_width = clientRect.right - clientRect.left - edit_left - HORIZONTAL_MARGIN;
|
||||
unsigned int top = VERTICAL_MARGIN;
|
||||
|
||||
for(int i = 0; i < shader.param.size(); i++) {
|
||||
GLSLParam &p = shader.param[i];
|
||||
for(int i = 0; i < parameters.size(); i++) {
|
||||
GLSLParam &p = parameters[i];
|
||||
TCHAR desc[270];
|
||||
_stprintf(desc, TEXT("%s [%g-%g]"), (TCHAR*)_tFromChar(p.name.c_str()), p.min, p.max);
|
||||
HWND item = CreateWindow(TEXT("STATIC"), desc, SS_LEFTNOWORDWRAP | WS_VISIBLE | WS_CHILD, desc_left, (INT)(top + avgCharHeight * 0.3), desc_width, avgCharHeight, parent, (HMENU)(UINT_PTR)(IDC_PARAMS_START_STATIC + i), GUI.hInstance, NULL);
|
||||
@ -240,7 +242,7 @@ void CShaderParamDlg::handle_up_down(HWND hStatic, int id, int change)
|
||||
{
|
||||
int param_id = id - IDC_PARAMS_START_UPDOWN;
|
||||
HWND hEdit = GetDlgItem(hStatic, IDC_PARAMS_START_EDIT + param_id);
|
||||
GLSLParam &p = shader.param[param_id];
|
||||
GLSLParam &p = parameters[param_id];
|
||||
TCHAR val[100];
|
||||
GetWindowText(hEdit, val, 100);
|
||||
p.val = _ttof(val);
|
||||
@ -256,8 +258,8 @@ void CShaderParamDlg::handle_up_down(HWND hStatic, int id, int change)
|
||||
void CShaderParamDlg::get_changed_parameters(HWND hDlg)
|
||||
{
|
||||
HWND parent = GetDlgItem(hDlg, IDC_STATIC_CONTAINER);
|
||||
for(int i = 0; i < shader.param.size(); i++) {
|
||||
GLSLParam &p = shader.param[i];
|
||||
for(int i = 0; i < parameters.size(); i++) {
|
||||
GLSLParam &p = parameters[i];
|
||||
TCHAR val[100];
|
||||
HWND hEdit = GetDlgItem(parent, IDC_PARAMS_START_EDIT + i);
|
||||
GetWindowText(hEdit, val, 100);
|
||||
@ -281,7 +283,7 @@ void CShaderParamDlg::save_custom_shader()
|
||||
else {
|
||||
_stprintf(save_path, TEXT("%s\\custom_shader_params.slangp"), S9xGetDirectoryT(DEFAULT_DIR));
|
||||
}
|
||||
shader.save(_tToChar(save_path));
|
||||
save_function(_tToChar(save_path));
|
||||
lstrcpy(GUI.OGLshaderFileName, save_path);
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
#include "windows.h"
|
||||
#include "../shaders/glsl.h"
|
||||
#include <functional>
|
||||
|
||||
typedef void(*APPLYCALLBACK) ();
|
||||
|
||||
@ -21,17 +22,18 @@ private:
|
||||
void save_custom_shader();
|
||||
void apply_changes(HWND hDlg);
|
||||
|
||||
GLSLShader &shader;
|
||||
HFONT hFont;
|
||||
unsigned int avgCharWidth;
|
||||
unsigned int avgCharHeight;
|
||||
int scrollpos;
|
||||
std::vector<GLSLParam> saved_parameters;
|
||||
std::vector<GLSLParam>& parameters;
|
||||
std::vector<GLSLParam> saved_parameters;
|
||||
std::function<void (const char *)> save_function;
|
||||
|
||||
WNDPROC oldStaticProc;
|
||||
|
||||
public:
|
||||
CShaderParamDlg(GLSLShader &shade);
|
||||
CShaderParamDlg(std::vector<GLSLParam> ¶meters, std::function<void (const char *)> save_function);
|
||||
virtual ~CShaderParamDlg();
|
||||
|
||||
bool show();
|
||||
|
@ -25,10 +25,13 @@ bool CVulkan::Initialize(HWND hWnd)
|
||||
if (GUI.shaderEnabled && GUI.OGLshaderFileName)
|
||||
{
|
||||
shaderchain = std::make_unique<Vulkan::ShaderChain>(context.get());
|
||||
if (!shaderchain->load_shader_preset(std::string(_tToChar(GUI.OGLshaderFileName))))
|
||||
std::string shaderstring = _tToChar(GUI.OGLshaderFileName);
|
||||
if (!shaderchain->load_shader_preset(shaderstring))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
current_shadername = shaderstring;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -81,12 +84,21 @@ void CVulkan::DeInitialize()
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
current_shadername = "";
|
||||
context->wait_idle();
|
||||
shaderchain.reset();
|
||||
textures.clear();
|
||||
descriptors.clear();
|
||||
device.destroySampler(linear_sampler);
|
||||
device.destroySampler(nearest_sampler);
|
||||
if (linear_sampler)
|
||||
{
|
||||
device.destroySampler(linear_sampler);
|
||||
linear_sampler = nullptr;
|
||||
}
|
||||
if (nearest_sampler)
|
||||
{
|
||||
device.destroySampler(nearest_sampler);
|
||||
nearest_sampler = nullptr;
|
||||
}
|
||||
swapchain = nullptr;
|
||||
descriptor_set_layout.reset();
|
||||
pipeline_layout.reset();
|
||||
@ -105,7 +117,7 @@ void CVulkan::Render(SSurface Src)
|
||||
if (GUI.ReduceInputLag)
|
||||
device.waitIdle();
|
||||
|
||||
SSurface Dst;
|
||||
SSurface Dst{};
|
||||
|
||||
RECT dstRect = GetFilterOutputSize(Src);
|
||||
Dst.Width = dstRect.right - dstRect.left;
|
||||
@ -191,7 +203,34 @@ bool CVulkan::ChangeRenderSize(unsigned int newWidth, unsigned int newHeight)
|
||||
|
||||
bool CVulkan::ApplyDisplayChanges(void)
|
||||
{
|
||||
return false;
|
||||
if ((!GUI.shaderEnabled && shaderchain) || (GUI.shaderEnabled && !shaderchain))
|
||||
{
|
||||
DeInitialize();
|
||||
Initialize(hWnd);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string shadername = std::string(_tToChar(GUI.OGLshaderFileName));
|
||||
if (GUI.shaderEnabled && shaderchain && (shadername != current_shadername))
|
||||
{
|
||||
shaderchain.reset();
|
||||
shaderchain = std::make_unique<Vulkan::ShaderChain>(context.get());
|
||||
if (!shaderchain->load_shader_preset(shadername))
|
||||
{
|
||||
DeInitialize();
|
||||
GUI.shaderEnabled = false;
|
||||
Initialize(hWnd);
|
||||
return false;
|
||||
}
|
||||
current_shadername = shadername;
|
||||
}
|
||||
|
||||
if (swapchain->set_vsync(GUI.Vsync))
|
||||
{
|
||||
swapchain->recreate();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CVulkan::SetFullscreen(bool fullscreen)
|
||||
@ -242,6 +281,24 @@ void CVulkan::EnumModes(std::vector<dMode>* modeVector)
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<SlangShader::Parameter> *CVulkan::GetShaderParameters()
|
||||
{
|
||||
if (shaderchain)
|
||||
{
|
||||
return &shaderchain->preset->parameters;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::function<void(const char *)> CVulkan::GetShaderParametersSaveFunction()
|
||||
{
|
||||
return [&](const char *filename) {
|
||||
if (shaderchain)
|
||||
shaderchain->preset->save_to_file(filename);
|
||||
};
|
||||
}
|
||||
|
||||
static const char* vertex_shader = R"(
|
||||
#version 450
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "../vulkan/vulkan_context.hpp"
|
||||
#include "../vulkan/vulkan_texture.hpp"
|
||||
#include "../vulkan/vulkan_shader_chain.hpp"
|
||||
#include <functional>
|
||||
|
||||
class CVulkan : public IS9xDisplayOutput
|
||||
{
|
||||
@ -23,6 +24,7 @@ class CVulkan : public IS9xDisplayOutput
|
||||
std::vector<vk::UniqueDescriptorSet> descriptors;
|
||||
std::vector<uint16_t> filtered_image;
|
||||
std::unique_ptr<Vulkan::ShaderChain> shaderchain;
|
||||
std::string current_shadername;
|
||||
|
||||
int current_width;
|
||||
int current_height;
|
||||
@ -36,5 +38,7 @@ class CVulkan : public IS9xDisplayOutput
|
||||
bool SetFullscreen(bool fullscreen);
|
||||
void SetSnes9xColorFormat();
|
||||
void EnumModes(std::vector<dMode>* modeVector);
|
||||
std::vector<SlangShader::Parameter> *GetShaderParameters(void);
|
||||
std::function<void(const char *)> GetShaderParametersSaveFunction();
|
||||
};
|
||||
|
||||
|
@ -223,7 +223,7 @@ BEGIN
|
||||
LTEXT "Direct3D Shader File",IDC_STATIC,12,204,70,8
|
||||
EDITTEXT IDC_SHADER_GLSL_FILE,12,246,240,14,ES_AUTOHSCROLL | WS_DISABLED
|
||||
PUSHBUTTON "...",IDC_SHADER_GLSL_BROWSE,258,246,18,14,WS_DISABLED
|
||||
LTEXT "OpenGL Shader File",IDC_STATIC,12,234,68,8
|
||||
LTEXT "OpenGL/Vulkan Shader File",IDC_STATIC,12,234,68,8
|
||||
CONTROL "Blend Hi-Res Images",IDC_HIRESBLEND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,186,138,144,8
|
||||
CONTROL "VSync",IDC_VSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,107,37,10
|
||||
CONTROL "Reduce Input Lag",IDC_REDUCEINPUTLAG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,118,76,10
|
||||
|
@ -655,9 +655,23 @@ int WinGetAutomaticInputRate(void)
|
||||
return (int)newInputRate;
|
||||
}
|
||||
|
||||
GLSLShader *WinGetActiveGLSLShader()
|
||||
std::vector<GLSLParam> *WinGetShaderParameters()
|
||||
{
|
||||
return OpenGL.GetActiveShader();
|
||||
if (GUI.outputMethod == OPENGL)
|
||||
return OpenGL.GetShaderParameters();
|
||||
if (GUI.outputMethod == VULKAN)
|
||||
return (std::vector<GLSLParam> *)VulkanDriver.GetShaderParameters();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::function<void(const char*)> WinGetShaderSaveFunction()
|
||||
{
|
||||
if (GUI.outputMethod == OPENGL)
|
||||
return OpenGL.GetShaderParametersSaveFunction();
|
||||
else if (GUI.outputMethod == VULKAN)
|
||||
return VulkanDriver.GetShaderParametersSaveFunction();
|
||||
else
|
||||
return std::function<void(const char*)>();
|
||||
}
|
||||
|
||||
/* Depth conversion functions begin */
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "render.h"
|
||||
#include "../shaders/glsl.h"
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
#define IsHiRes(x) ((x.Height > SNES_HEIGHT_EXTENDED || x.Width == 512))
|
||||
#define CurrentScale (IsHiRes(Src) ? GUI.ScaleHiRes : GUI.Scale)
|
||||
@ -41,6 +42,7 @@ char *ReadShaderFileContents(const TCHAR *filename);
|
||||
void ReduceToPath(TCHAR *filename);
|
||||
double WinGetRefreshRate();
|
||||
int WinGetAutomaticInputRate();
|
||||
GLSLShader *WinGetActiveGLSLShader();
|
||||
std::vector<GLSLParam> *WinGetShaderParameters();
|
||||
std::function<void(const char*)> WinGetShaderSaveFunction();
|
||||
|
||||
#endif
|
||||
|
@ -7925,9 +7925,10 @@ INT_PTR CALLBACK DlgFunky(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
ShowWindow(hDlg, SW_HIDE);
|
||||
WinDisplayApplyChanges();
|
||||
WinRefreshDisplay();
|
||||
GLSLShader *shader = WinGetActiveGLSLShader();
|
||||
if (shader) {
|
||||
CShaderParamDlg dlg(*shader);
|
||||
auto shader_parameters = WinGetShaderParameters();
|
||||
if (shader_parameters) {
|
||||
auto save_function = WinGetShaderSaveFunction();
|
||||
CShaderParamDlg dlg(*shader_parameters, save_function);
|
||||
if (dlg.show()) {
|
||||
SetDlgItemText(hDlg, IDC_SHADER_GLSL_FILE, GUI.OGLshaderFileName);
|
||||
WinDisplayApplyChanges();
|
||||
|
Loading…
Reference in New Issue
Block a user