mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-24 16:39:43 +00:00
(D3D11) multi-pass shaders: add support for wrap modes and lut
mipmapping.
This commit is contained in:
parent
2a25e284af
commit
6fe3a31617
@ -2504,8 +2504,7 @@ typedef struct
|
|||||||
D3D11RenderTargetView renderTargetView;
|
D3D11RenderTargetView renderTargetView;
|
||||||
D3D11Buffer ubo;
|
D3D11Buffer ubo;
|
||||||
d3d11_uniform_t ubo_values;
|
d3d11_uniform_t ubo_values;
|
||||||
D3D11SamplerState sampler_nearest;
|
D3D11SamplerState samplers[RARCH_FILTER_MAX][RARCH_WRAP_MAX];
|
||||||
D3D11SamplerState sampler_linear;
|
|
||||||
D3D11BlendState blend_enable;
|
D3D11BlendState blend_enable;
|
||||||
D3D11BlendState blend_disable;
|
D3D11BlendState blend_disable;
|
||||||
D3D11BlendState blend_pipeline;
|
D3D11BlendState blend_pipeline;
|
||||||
|
@ -39,10 +39,13 @@ static void d3d11_set_filtering(void* data, unsigned index, bool smooth)
|
|||||||
{
|
{
|
||||||
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
|
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
|
||||||
|
|
||||||
if (smooth)
|
for (int i = 0; i < RARCH_WRAP_MAX; i++)
|
||||||
d3d11->frame.texture.sampler = d3d11->sampler_linear;
|
{
|
||||||
else
|
if (smooth)
|
||||||
d3d11->frame.texture.sampler = d3d11->sampler_nearest;
|
d3d11->samplers[RARCH_FILTER_UNSPEC][i] = d3d11->samplers[RARCH_FILTER_LINEAR][i];
|
||||||
|
else
|
||||||
|
d3d11->samplers[RARCH_FILTER_UNSPEC][i] = d3d11->samplers[RARCH_FILTER_NEAREST][i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void d3d11_gfx_set_rotation(void* data, unsigned rotation)
|
static void d3d11_gfx_set_rotation(void* data, unsigned rotation)
|
||||||
@ -218,43 +221,44 @@ static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const
|
|||||||
#else
|
#else
|
||||||
bool save_hlsl = false;
|
bool save_hlsl = false;
|
||||||
#endif
|
#endif
|
||||||
const char* vs_src = d3d11->shader_preset->pass[i].source.string.vertex;
|
static const char vs_ext[] = ".vs.hlsl";
|
||||||
const char* ps_src = d3d11->shader_preset->pass[i].source.string.fragment;
|
static const char ps_ext[] = ".ps.hlsl";
|
||||||
const char* vs_ext = ".vs.hlsl";
|
char vs_path[PATH_MAX_LENGTH];
|
||||||
const char* ps_ext = ".ps.hlsl";
|
char ps_path[PATH_MAX_LENGTH];
|
||||||
int base_len = strlen(d3d11->shader_preset->pass[i].source.path) - strlen(".slang");
|
const char* slang_path = d3d11->shader_preset->pass[i].source.path;
|
||||||
char* vs_filename = (char*)malloc(base_len + strlen(vs_ext) + 1);
|
const char* vs_src = d3d11->shader_preset->pass[i].source.string.vertex;
|
||||||
char* ps_filename = (char*)malloc(base_len + strlen(ps_ext) + 1);
|
const char* ps_src = d3d11->shader_preset->pass[i].source.string.fragment;
|
||||||
|
int base_len = strlen(slang_path) - strlen(".slang");
|
||||||
|
|
||||||
strncpy(vs_filename, d3d11->shader_preset->pass[i].source.path, base_len);
|
if(base_len <= 0)
|
||||||
strncpy(ps_filename, d3d11->shader_preset->pass[i].source.path, base_len);
|
base_len = strlen(slang_path);
|
||||||
strncpy(vs_filename + base_len, vs_ext, strlen(vs_ext) + 1);
|
|
||||||
strncpy(ps_filename + base_len, ps_ext, strlen(ps_ext) + 1);
|
strncpy(vs_path, slang_path, base_len);
|
||||||
|
strncpy(ps_path, slang_path, base_len);
|
||||||
|
strncpy(vs_path + base_len, vs_ext, sizeof(vs_ext));
|
||||||
|
strncpy(ps_path + base_len, ps_ext, sizeof(ps_ext));
|
||||||
|
|
||||||
if (!d3d11_init_shader(
|
if (!d3d11_init_shader(
|
||||||
d3d11->device, vs_src, 0, vs_filename, "main", NULL, NULL, desc, countof(desc),
|
d3d11->device, vs_src, 0, vs_path, "main", NULL, NULL, desc, countof(desc),
|
||||||
&d3d11->pass[i].shader))
|
&d3d11->pass[i].shader))
|
||||||
save_hlsl = true;
|
save_hlsl = true;
|
||||||
|
|
||||||
if (!d3d11_init_shader(
|
if (!d3d11_init_shader(
|
||||||
d3d11->device, ps_src, 0, ps_filename, NULL, "main", NULL, NULL, 0,
|
d3d11->device, ps_src, 0, ps_path, NULL, "main", NULL, NULL, 0,
|
||||||
&d3d11->pass[i].shader))
|
&d3d11->pass[i].shader))
|
||||||
save_hlsl = true;
|
save_hlsl = true;
|
||||||
|
|
||||||
if (save_hlsl)
|
if (save_hlsl)
|
||||||
{
|
{
|
||||||
FILE* fp = fopen(vs_filename, "w");
|
FILE* fp = fopen(vs_path, "w");
|
||||||
fwrite(vs_src, 1, strlen(vs_src), fp);
|
fwrite(vs_src, 1, strlen(vs_src), fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
fp = fopen(ps_filename, "w");
|
fp = fopen(ps_path, "w");
|
||||||
fwrite(ps_src, 1, strlen(ps_src), fp);
|
fwrite(ps_src, 1, strlen(ps_src), fp);
|
||||||
fclose(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.vertex);
|
||||||
free(d3d11->shader_preset->pass[i].source.string.fragment);
|
free(d3d11->shader_preset->pass[i].source.string.fragment);
|
||||||
|
|
||||||
@ -293,15 +297,20 @@ static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const
|
|||||||
d3d11->luts[i].desc.Width = image.width;
|
d3d11->luts[i].desc.Width = image.width;
|
||||||
d3d11->luts[i].desc.Height = image.height;
|
d3d11->luts[i].desc.Height = image.height;
|
||||||
d3d11->luts[i].desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
d3d11->luts[i].desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
|
||||||
|
if(d3d11->shader_preset->lut[i].mipmap)
|
||||||
|
d3d11->luts[i].desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;
|
||||||
|
|
||||||
d3d11_init_texture(d3d11->device, &d3d11->luts[i]);
|
d3d11_init_texture(d3d11->device, &d3d11->luts[i]);
|
||||||
|
|
||||||
d3d11_update_texture(
|
d3d11_update_texture(
|
||||||
d3d11->ctx, image.width, image.height, 0, DXGI_FORMAT_R8G8B8A8_UNORM, image.pixels,
|
d3d11->ctx, image.width, image.height, 0, DXGI_FORMAT_R8G8B8A8_UNORM, image.pixels,
|
||||||
&d3d11->luts[i]);
|
&d3d11->luts[i]);
|
||||||
|
|
||||||
image_texture_free(&image);
|
image_texture_free(&image);
|
||||||
|
|
||||||
d3d11->luts[i].sampler = d3d11->shader_preset->lut[i].filter == RARCH_FILTER_NEAREST
|
d3d11->luts[i].sampler =
|
||||||
? d3d11->sampler_nearest
|
d3d11->samplers[d3d11->shader_preset->lut[i].filter][d3d11->shader_preset->lut[i].wrap];
|
||||||
: d3d11->sampler_linear;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
video_shader_resolve_current_parameters(conf, d3d11->shader_preset);
|
video_shader_resolve_current_parameters(conf, d3d11->shader_preset);
|
||||||
@ -350,8 +359,11 @@ static void d3d11_gfx_free(void* data)
|
|||||||
Release(d3d11->blend_enable);
|
Release(d3d11->blend_enable);
|
||||||
Release(d3d11->blend_disable);
|
Release(d3d11->blend_disable);
|
||||||
|
|
||||||
Release(d3d11->sampler_nearest);
|
for (int i = 0; i < RARCH_WRAP_MAX; i++)
|
||||||
Release(d3d11->sampler_linear);
|
{
|
||||||
|
Release(d3d11->samplers[RARCH_FILTER_LINEAR][i]);
|
||||||
|
Release(d3d11->samplers[RARCH_FILTER_NEAREST][i]);
|
||||||
|
}
|
||||||
|
|
||||||
Release(d3d11->state);
|
Release(d3d11->state);
|
||||||
Release(d3d11->renderTargetView);
|
Release(d3d11->renderTargetView);
|
||||||
@ -478,19 +490,41 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
|
|||||||
|
|
||||||
{
|
{
|
||||||
D3D11_SAMPLER_DESC desc = {
|
D3D11_SAMPLER_DESC desc = {
|
||||||
.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT,
|
|
||||||
.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP,
|
|
||||||
.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP,
|
|
||||||
.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP,
|
|
||||||
.MaxAnisotropy = 1,
|
.MaxAnisotropy = 1,
|
||||||
.ComparisonFunc = D3D11_COMPARISON_NEVER,
|
.ComparisonFunc = D3D11_COMPARISON_NEVER,
|
||||||
.MinLOD = -D3D11_FLOAT32_MAX,
|
.MinLOD = -D3D11_FLOAT32_MAX,
|
||||||
.MaxLOD = D3D11_FLOAT32_MAX,
|
.MaxLOD = D3D11_FLOAT32_MAX,
|
||||||
};
|
};
|
||||||
D3D11CreateSamplerState(d3d11->device, &desc, &d3d11->sampler_nearest);
|
/* Initialize samplers */
|
||||||
|
for (int i = 0; i < RARCH_WRAP_MAX; i++)
|
||||||
|
{
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case RARCH_WRAP_BORDER:
|
||||||
|
desc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||||
|
break;
|
||||||
|
|
||||||
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
case RARCH_WRAP_EDGE:
|
||||||
D3D11CreateSamplerState(d3d11->device, &desc, &d3d11->sampler_linear);
|
desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RARCH_WRAP_REPEAT:
|
||||||
|
desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RARCH_WRAP_MIRRORED_REPEAT:
|
||||||
|
desc.AddressU = D3D11_TEXTURE_ADDRESS_MIRROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
desc.AddressV = desc.AddressU;
|
||||||
|
desc.AddressW = desc.AddressU;
|
||||||
|
|
||||||
|
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
||||||
|
D3D11CreateSamplerState(d3d11->device, &desc, &d3d11->samplers[RARCH_FILTER_LINEAR][i]);
|
||||||
|
|
||||||
|
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
|
||||||
|
D3D11CreateSamplerState(d3d11->device, &desc, &d3d11->samplers[RARCH_FILTER_NEAREST][i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d3d11_set_filtering(d3d11, 0, video->smooth);
|
d3d11_set_filtering(d3d11, 0, video->smooth);
|
||||||
@ -708,7 +742,7 @@ static bool d3d11_init_frame_textures(d3d11_video_t* d3d11, unsigned width, unsi
|
|||||||
{
|
{
|
||||||
struct video_shader_pass* pass = &d3d11->shader_preset->pass[i];
|
struct video_shader_pass* pass = &d3d11->shader_preset->pass[i];
|
||||||
|
|
||||||
if(pass->fbo.valid)
|
if (pass->fbo.valid)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch (pass->fbo.type_x)
|
switch (pass->fbo.type_x)
|
||||||
@ -755,11 +789,10 @@ static bool d3d11_init_frame_textures(d3d11_video_t* d3d11, unsigned width, unsi
|
|||||||
}
|
}
|
||||||
else if (i == (d3d11->shader_preset->passes - 1))
|
else if (i == (d3d11->shader_preset->passes - 1))
|
||||||
{
|
{
|
||||||
width = d3d11->vp.width;
|
width = d3d11->vp.width;
|
||||||
height = d3d11->vp.height;
|
height = d3d11->vp.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RARCH_LOG("[D3D11]: Updating framebuffer size %u x %u.\n", width, height);
|
RARCH_LOG("[D3D11]: Updating framebuffer size %u x %u.\n", width, height);
|
||||||
|
|
||||||
if ((i != (d3d11->shader_preset->passes - 1)) || (width != d3d11->vp.width) ||
|
if ((i != (d3d11->shader_preset->passes - 1)) || (width != d3d11->vp.width) ||
|
||||||
@ -782,8 +815,7 @@ static bool d3d11_init_frame_textures(d3d11_video_t* d3d11, unsigned width, unsi
|
|||||||
d3d11->pass[i].rt.size_data.w = 1.0f / height;
|
d3d11->pass[i].rt.size_data.w = 1.0f / height;
|
||||||
}
|
}
|
||||||
|
|
||||||
d3d11->pass[i].sampler = pass->filter == RARCH_FILTER_NEAREST ? d3d11->sampler_nearest
|
d3d11->pass[i].sampler = d3d11->samplers[pass->filter][pass->wrap];
|
||||||
: d3d11->sampler_linear;
|
|
||||||
|
|
||||||
for (int j = 0; j < d3d11->pass[i].semantics.texture_count; j++)
|
for (int j = 0; j < d3d11->pass[i].semantics.texture_count; j++)
|
||||||
{
|
{
|
||||||
@ -936,7 +968,8 @@ static bool d3d11_gfx_frame(
|
|||||||
{
|
{
|
||||||
d3d11_set_shader(d3d11->ctx, &d3d11->shaders[VIDEO_SHADER_STOCK_BLEND]);
|
d3d11_set_shader(d3d11->ctx, &d3d11->shaders[VIDEO_SHADER_STOCK_BLEND]);
|
||||||
D3D11SetPShaderResources(d3d11->ctx, 0, 1, &texture->view);
|
D3D11SetPShaderResources(d3d11->ctx, 0, 1, &texture->view);
|
||||||
D3D11SetPShaderSamplers(d3d11->ctx, 0, 1, &d3d11->frame.texture.sampler);
|
D3D11SetPShaderSamplers(
|
||||||
|
d3d11->ctx, 0, 1, &d3d11->samplers[RARCH_FILTER_UNSPEC][RARCH_WRAP_DEFAULT]);
|
||||||
D3D11SetVShaderConstantBuffers(d3d11->ctx, 0, 1, &d3d11->frame.ubo);
|
D3D11SetVShaderConstantBuffers(d3d11->ctx, 0, 1, &d3d11->frame.ubo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1063,9 +1096,10 @@ static void d3d11_set_menu_texture_frame(
|
|||||||
}
|
}
|
||||||
|
|
||||||
d3d11_update_texture(d3d11->ctx, width, height, 0, 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->menu.texture.sampler = d3d11->samplers
|
||||||
? d3d11->sampler_linear
|
[config_get_ptr()->bools.menu_linear_filter
|
||||||
: d3d11->sampler_nearest;
|
? RARCH_FILTER_LINEAR
|
||||||
|
: RARCH_FILTER_NEAREST][RARCH_WRAP_DEFAULT];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void d3d11_set_menu_texture_enable(void* data, bool state, bool full_screen)
|
static void d3d11_set_menu_texture_enable(void* data, bool state, bool full_screen)
|
||||||
@ -1129,13 +1163,13 @@ static uintptr_t d3d11_gfx_load_texture(
|
|||||||
texture->desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;
|
texture->desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case TEXTURE_FILTER_LINEAR:
|
case TEXTURE_FILTER_LINEAR:
|
||||||
texture->sampler = d3d11->sampler_linear;
|
texture->sampler = d3d11->samplers[RARCH_FILTER_LINEAR][RARCH_WRAP_DEFAULT];
|
||||||
break;
|
break;
|
||||||
case TEXTURE_FILTER_MIPMAP_NEAREST:
|
case TEXTURE_FILTER_MIPMAP_NEAREST:
|
||||||
texture->desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;
|
texture->desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case TEXTURE_FILTER_NEAREST:
|
case TEXTURE_FILTER_NEAREST:
|
||||||
texture->sampler = d3d11->sampler_nearest;
|
texture->sampler = d3d11->samplers[RARCH_FILTER_NEAREST][RARCH_WRAP_DEFAULT];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ d3d11_font_init_font(void* data, const char* font_path, float font_size, bool is
|
|||||||
}
|
}
|
||||||
|
|
||||||
font->atlas = font->font_driver->get_atlas(font->font_data);
|
font->atlas = font->font_driver->get_atlas(font->font_data);
|
||||||
font->texture.sampler = d3d11->sampler_linear;
|
font->texture.sampler = d3d11->samplers[RARCH_FILTER_LINEAR][RARCH_WRAP_BORDER];
|
||||||
font->texture.desc.Width = font->atlas->width;
|
font->texture.desc.Width = font->atlas->width;
|
||||||
font->texture.desc.Height = font->atlas->height;
|
font->texture.desc.Height = font->atlas->height;
|
||||||
font->texture.desc.Format = DXGI_FORMAT_A8_UNORM;
|
font->texture.desc.Format = DXGI_FORMAT_A8_UNORM;
|
||||||
|
@ -62,7 +62,8 @@ enum
|
|||||||
{
|
{
|
||||||
RARCH_FILTER_UNSPEC = 0,
|
RARCH_FILTER_UNSPEC = 0,
|
||||||
RARCH_FILTER_LINEAR,
|
RARCH_FILTER_LINEAR,
|
||||||
RARCH_FILTER_NEAREST
|
RARCH_FILTER_NEAREST,
|
||||||
|
RARCH_FILTER_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
enum gfx_wrap_type
|
enum gfx_wrap_type
|
||||||
|
Loading…
Reference in New Issue
Block a user