Working Win32/Vulkan shader support.

This commit is contained in:
BearOso 2023-02-01 14:47:42 -06:00
parent 89bbf08c74
commit 2c7d5f7a4d
11 changed files with 127 additions and 30 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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> &parameters, std::function<void (const char *)> save_function);
virtual ~CShaderParamDlg();
bool show();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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