From 25142702d93c2674bc351d893664b61663c0d9f3 Mon Sep 17 00:00:00 2001 From: ns6089 <61738816+ns6089@users.noreply.github.com> Date: Sun, 10 Sep 2023 12:35:31 +0300 Subject: [PATCH 1/3] Support #include in dx shader compiler --- src/platform/windows/display_vram.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/windows/display_vram.cpp b/src/platform/windows/display_vram.cpp index bf8fb569160..5cd6efc14f1 100644 --- a/src/platform/windows/display_vram.cpp +++ b/src/platform/windows/display_vram.cpp @@ -345,7 +345,7 @@ namespace platf::dxgi { std::wstring_convert, wchar_t> converter; auto wFile = converter.from_bytes(file); - auto status = D3DCompileFromFile(wFile.c_str(), nullptr, nullptr, entrypoint, shader_model, flags, 0, &compiled_p, &msg_p); + auto status = D3DCompileFromFile(wFile.c_str(), nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE, entrypoint, shader_model, flags, 0, &compiled_p, &msg_p); if (msg_p) { BOOST_LOG(warning) << std::string_view { (const char *) msg_p->GetBufferPointer(), msg_p->GetBufferSize() - 1 }; From 0f24509f9e16ff54759369ed9d97a74683de4ffe Mon Sep 17 00:00:00 2001 From: ns6089 <61738816+ns6089@users.noreply.github.com> Date: Sun, 10 Sep 2023 12:36:08 +0300 Subject: [PATCH 2/3] Refactor shaders --- src/platform/windows/display_vram.cpp | 139 +++++++----------- .../assets/shaders/directx/ConvertUVPS.hlsl | 33 ----- .../shaders/directx/ConvertUVPS_Linear.hlsl | 36 ----- .../shaders/directx/ConvertUVPS_PQ.hlsl | 69 --------- .../assets/shaders/directx/ConvertUVVS.hlsl | 46 ------ .../assets/shaders/directx/ConvertYPS.hlsl | 25 ---- .../shaders/directx/ConvertYPS_Linear.hlsl | 31 ---- .../assets/shaders/directx/CursorVS.hlsl | 37 ----- .../assets/shaders/directx/ScenePS.hlsl | 14 -- .../assets/shaders/directx/ScenePS_NW.hlsl | 22 --- .../assets/shaders/directx/SceneVS.hlsl | 37 ----- .../convert_yuv420_packed_uv_type0_ps.hlsl | 5 + ...vert_yuv420_packed_uv_type0_ps_linear.hlsl | 5 + ...cked_uv_type0_ps_perceptual_quantizer.hlsl | 5 + .../convert_yuv420_packed_uv_type0_vs.hlsl | 15 ++ .../directx/convert_yuv420_planar_y_ps.hlsl | 3 + .../convert_yuv420_planar_y_ps_linear.hlsl | 3 + ...v420_planar_y_ps_perceptual_quantizer.hlsl | 3 + .../directx/convert_yuv420_planar_y_vs.hlsl | 10 ++ .../assets/shaders/directx/cursor_ps.hlsl | 9 ++ .../directx/cursor_ps_normalize_white.hlsl | 17 +++ .../assets/shaders/directx/cursor_vs.hlsl | 10 ++ .../shaders/directx/include/base_vs.hlsl | 45 ++++++ .../directx/include/base_vs_types.hlsl | 12 ++ .../common.hlsl} | 103 ++++++------- .../shaders/directx/include/convert_base.hlsl | 1 + .../directx/include/convert_linear_base.hlsl | 6 + .../convert_perceptual_quantizer_base.hlsl | 3 + .../convert_yuv420_packed_uv_ps_base.hlsl | 35 +++++ .../convert_yuv420_planar_y_ps_base.hlsl | 21 +++ 30 files changed, 302 insertions(+), 498 deletions(-) delete mode 100644 src_assets/windows/assets/shaders/directx/ConvertUVPS.hlsl delete mode 100644 src_assets/windows/assets/shaders/directx/ConvertUVPS_Linear.hlsl delete mode 100644 src_assets/windows/assets/shaders/directx/ConvertUVPS_PQ.hlsl delete mode 100644 src_assets/windows/assets/shaders/directx/ConvertUVVS.hlsl delete mode 100644 src_assets/windows/assets/shaders/directx/ConvertYPS.hlsl delete mode 100644 src_assets/windows/assets/shaders/directx/ConvertYPS_Linear.hlsl delete mode 100644 src_assets/windows/assets/shaders/directx/CursorVS.hlsl delete mode 100644 src_assets/windows/assets/shaders/directx/ScenePS.hlsl delete mode 100644 src_assets/windows/assets/shaders/directx/ScenePS_NW.hlsl delete mode 100644 src_assets/windows/assets/shaders/directx/SceneVS.hlsl create mode 100644 src_assets/windows/assets/shaders/directx/convert_yuv420_packed_uv_type0_ps.hlsl create mode 100644 src_assets/windows/assets/shaders/directx/convert_yuv420_packed_uv_type0_ps_linear.hlsl create mode 100644 src_assets/windows/assets/shaders/directx/convert_yuv420_packed_uv_type0_ps_perceptual_quantizer.hlsl create mode 100644 src_assets/windows/assets/shaders/directx/convert_yuv420_packed_uv_type0_vs.hlsl create mode 100644 src_assets/windows/assets/shaders/directx/convert_yuv420_planar_y_ps.hlsl create mode 100644 src_assets/windows/assets/shaders/directx/convert_yuv420_planar_y_ps_linear.hlsl create mode 100644 src_assets/windows/assets/shaders/directx/convert_yuv420_planar_y_ps_perceptual_quantizer.hlsl create mode 100644 src_assets/windows/assets/shaders/directx/convert_yuv420_planar_y_vs.hlsl create mode 100644 src_assets/windows/assets/shaders/directx/cursor_ps.hlsl create mode 100644 src_assets/windows/assets/shaders/directx/cursor_ps_normalize_white.hlsl create mode 100644 src_assets/windows/assets/shaders/directx/cursor_vs.hlsl create mode 100644 src_assets/windows/assets/shaders/directx/include/base_vs.hlsl create mode 100644 src_assets/windows/assets/shaders/directx/include/base_vs_types.hlsl rename src_assets/windows/assets/shaders/directx/{ConvertYPS_PQ.hlsl => include/common.hlsl} (65%) create mode 100644 src_assets/windows/assets/shaders/directx/include/convert_base.hlsl create mode 100644 src_assets/windows/assets/shaders/directx/include/convert_linear_base.hlsl create mode 100644 src_assets/windows/assets/shaders/directx/include/convert_perceptual_quantizer_base.hlsl create mode 100644 src_assets/windows/assets/shaders/directx/include/convert_yuv420_packed_uv_ps_base.hlsl create mode 100644 src_assets/windows/assets/shaders/directx/include/convert_yuv420_planar_y_ps_base.hlsl diff --git a/src/platform/windows/display_vram.cpp b/src/platform/windows/display_vram.cpp index 5cd6efc14f1..a0dd4dbc57e 100644 --- a/src/platform/windows/display_vram.cpp +++ b/src/platform/windows/display_vram.cpp @@ -102,17 +102,17 @@ namespace platf::dxgi { return blend; } - blob_t convert_UV_vs_hlsl; - blob_t convert_UV_ps_hlsl; - blob_t convert_UV_linear_ps_hlsl; - blob_t convert_UV_PQ_ps_hlsl; - blob_t scene_vs_hlsl; + blob_t convert_yuv420_packed_uv_type0_ps_hlsl; + blob_t convert_yuv420_packed_uv_type0_ps_linear_hlsl; + blob_t convert_yuv420_packed_uv_type0_ps_perceptual_quantizer_hlsl; + blob_t convert_yuv420_packed_uv_type0_vs_hlsl; + blob_t convert_yuv420_planar_y_ps_hlsl; + blob_t convert_yuv420_planar_y_ps_linear_hlsl; + blob_t convert_yuv420_planar_y_ps_perceptual_quantizer_hlsl; + blob_t convert_yuv420_planar_y_vs_hlsl; + blob_t cursor_ps_hlsl; + blob_t cursor_ps_normalize_white_hlsl; blob_t cursor_vs_hlsl; - blob_t convert_Y_ps_hlsl; - blob_t convert_Y_linear_ps_hlsl; - blob_t convert_Y_PQ_ps_hlsl; - blob_t scene_ps_hlsl; - blob_t scene_NW_ps_hlsl; struct img_d3d_t: public platf::img_t { // These objects are owned by the display_t's ID3D11Device @@ -464,14 +464,14 @@ namespace platf::dxgi { outY_view = D3D11_VIEWPORT { offsetX, offsetY, out_width_f, out_height_f, 0.0f, 1.0f }; outUV_view = D3D11_VIEWPORT { offsetX / 2, offsetY / 2, out_width_f / 2, out_height_f / 2, 0.0f, 1.0f }; - float info_in[16 / sizeof(float)] { 1.0f / (float) out_width_f }; // aligned to 16-byte - info_scene = make_buffer(device.get(), info_in); + float subsample_offset_in[16 / sizeof(float)] { 1.0f / (float) out_width_f, 1.0f / (float) out_height_f }; // aligned to 16-byte + subsample_offset = make_buffer(device.get(), subsample_offset_in); - if (!info_scene) { - BOOST_LOG(error) << "Failed to create info scene buffer"sv; + if (!subsample_offset) { + BOOST_LOG(error) << "Failed to create subsample offset vertex constant buffer"; return -1; } - device_ctx->VSSetConstantBuffers(0, 1, &info_scene); + device_ctx->VSSetConstantBuffers(0, 1, &subsample_offset); { int32_t rotation_modifier = display->display_rotation == DXGI_MODE_ROTATION_UNSPECIFIED ? 0 : display->display_rotation - 1; @@ -553,13 +553,13 @@ namespace platf::dxgi { } format = (pix_fmt == pix_fmt_e::nv12 ? DXGI_FORMAT_NV12 : DXGI_FORMAT_P010); - status = device->CreateVertexShader(scene_vs_hlsl->GetBufferPointer(), scene_vs_hlsl->GetBufferSize(), nullptr, &scene_vs); + status = device->CreateVertexShader(convert_yuv420_planar_y_vs_hlsl->GetBufferPointer(), convert_yuv420_planar_y_vs_hlsl->GetBufferSize(), nullptr, &scene_vs); if (status) { BOOST_LOG(error) << "Failed to create scene vertex shader [0x"sv << util::hex(status).to_string_view() << ']'; return -1; } - status = device->CreateVertexShader(convert_UV_vs_hlsl->GetBufferPointer(), convert_UV_vs_hlsl->GetBufferSize(), nullptr, &convert_UV_vs); + status = device->CreateVertexShader(convert_yuv420_packed_uv_type0_vs_hlsl->GetBufferPointer(), convert_yuv420_packed_uv_type0_vs_hlsl->GetBufferSize(), nullptr, &convert_UV_vs); if (status) { BOOST_LOG(error) << "Failed to create convertUV vertex shader [0x"sv << util::hex(status).to_string_view() << ']'; return -1; @@ -567,13 +567,13 @@ namespace platf::dxgi { // If the display is in HDR and we're streaming HDR, we'll be converting scRGB to SMPTE 2084 PQ. if (format == DXGI_FORMAT_P010 && display->is_hdr()) { - status = device->CreatePixelShader(convert_Y_PQ_ps_hlsl->GetBufferPointer(), convert_Y_PQ_ps_hlsl->GetBufferSize(), nullptr, &convert_Y_fp16_ps); + status = device->CreatePixelShader(convert_yuv420_planar_y_ps_perceptual_quantizer_hlsl->GetBufferPointer(), convert_yuv420_planar_y_ps_perceptual_quantizer_hlsl->GetBufferSize(), nullptr, &convert_Y_fp16_ps); if (status) { BOOST_LOG(error) << "Failed to create convertY pixel shader [0x"sv << util::hex(status).to_string_view() << ']'; return -1; } - status = device->CreatePixelShader(convert_UV_PQ_ps_hlsl->GetBufferPointer(), convert_UV_PQ_ps_hlsl->GetBufferSize(), nullptr, &convert_UV_fp16_ps); + status = device->CreatePixelShader(convert_yuv420_packed_uv_type0_ps_perceptual_quantizer_hlsl->GetBufferPointer(), convert_yuv420_packed_uv_type0_ps_perceptual_quantizer_hlsl->GetBufferSize(), nullptr, &convert_UV_fp16_ps); if (status) { BOOST_LOG(error) << "Failed to create convertUV pixel shader [0x"sv << util::hex(status).to_string_view() << ']'; return -1; @@ -582,13 +582,13 @@ namespace platf::dxgi { else { // If the display is in Advanced Color mode, the desktop format will be scRGB FP16. // scRGB uses linear gamma, so we must use our linear to sRGB conversion shaders. - status = device->CreatePixelShader(convert_Y_linear_ps_hlsl->GetBufferPointer(), convert_Y_linear_ps_hlsl->GetBufferSize(), nullptr, &convert_Y_fp16_ps); + status = device->CreatePixelShader(convert_yuv420_planar_y_ps_linear_hlsl->GetBufferPointer(), convert_yuv420_planar_y_ps_linear_hlsl->GetBufferSize(), nullptr, &convert_Y_fp16_ps); if (status) { BOOST_LOG(error) << "Failed to create convertY pixel shader [0x"sv << util::hex(status).to_string_view() << ']'; return -1; } - status = device->CreatePixelShader(convert_UV_linear_ps_hlsl->GetBufferPointer(), convert_UV_linear_ps_hlsl->GetBufferSize(), nullptr, &convert_UV_fp16_ps); + status = device->CreatePixelShader(convert_yuv420_packed_uv_type0_ps_linear_hlsl->GetBufferPointer(), convert_yuv420_packed_uv_type0_ps_linear_hlsl->GetBufferSize(), nullptr, &convert_UV_fp16_ps); if (status) { BOOST_LOG(error) << "Failed to create convertUV pixel shader [0x"sv << util::hex(status).to_string_view() << ']'; return -1; @@ -596,13 +596,13 @@ namespace platf::dxgi { } // These shaders consume standard 8-bit sRGB input - status = device->CreatePixelShader(convert_Y_ps_hlsl->GetBufferPointer(), convert_Y_ps_hlsl->GetBufferSize(), nullptr, &convert_Y_ps); + status = device->CreatePixelShader(convert_yuv420_planar_y_ps_hlsl->GetBufferPointer(), convert_yuv420_planar_y_ps_hlsl->GetBufferSize(), nullptr, &convert_Y_ps); if (status) { BOOST_LOG(error) << "Failed to create convertY pixel shader [0x"sv << util::hex(status).to_string_view() << ']'; return -1; } - status = device->CreatePixelShader(convert_UV_ps_hlsl->GetBufferPointer(), convert_UV_ps_hlsl->GetBufferSize(), nullptr, &convert_UV_ps); + status = device->CreatePixelShader(convert_yuv420_packed_uv_type0_ps_hlsl->GetBufferPointer(), convert_yuv420_packed_uv_type0_ps_hlsl->GetBufferSize(), nullptr, &convert_UV_ps); if (status) { BOOST_LOG(error) << "Failed to create convertUV pixel shader [0x"sv << util::hex(status).to_string_view() << ']'; return -1; @@ -627,7 +627,7 @@ namespace platf::dxgi { status = device->CreateInputLayout( &layout_desc, 1, - convert_UV_vs_hlsl->GetBufferPointer(), convert_UV_vs_hlsl->GetBufferSize(), + convert_yuv420_chroma_vs_type0_hlsl->GetBufferPointer(), convert_yuv420_chroma_vs_type0_hlsl->GetBufferSize(), &input_layout); this->display = std::dynamic_pointer_cast(display); @@ -734,7 +734,7 @@ namespace platf::dxgi { ::video::color_t *color_p; - buf_t info_scene; + buf_t subsample_offset; buf_t color_matrix; input_layout_t input_layout; @@ -1376,28 +1376,28 @@ namespace platf::dxgi { if (config.dynamicRange && is_hdr()) { // This shader will normalize scRGB white levels to a user-defined white level - status = device->CreatePixelShader(scene_NW_ps_hlsl->GetBufferPointer(), scene_NW_ps_hlsl->GetBufferSize(), nullptr, &cursor_ps); + status = device->CreatePixelShader(cursor_ps_normalize_white_hlsl->GetBufferPointer(), cursor_ps_normalize_white_hlsl->GetBufferSize(), nullptr, &cursor_ps); if (status) { - BOOST_LOG(error) << "Failed to create scene pixel shader [0x"sv << util::hex(status).to_string_view() << ']'; + BOOST_LOG(error) << "Failed to create cursor blending (normalized white) pixel shader [0x"sv << util::hex(status).to_string_view() << ']'; return -1; } // Use a 300 nit target for the mouse cursor. We should really get // the user's SDR white level in nits, but there is no API that // provides that information to Win32 apps. - float sdr_multiplier_data[16 / sizeof(float)] { 300.0f / 80.f }; // aligned to 16-byte - auto sdr_multiplier = make_buffer(device.get(), sdr_multiplier_data); - if (!sdr_multiplier) { - BOOST_LOG(warning) << "Failed to create SDR multiplier"sv; + float white_multiplier_data[16 / sizeof(float)] { 300.0f / 80.f }; // aligned to 16-byte + auto white_multiplier = make_buffer(device.get(), white_multiplier_data); + if (!white_multiplier) { + BOOST_LOG(warning) << "Failed to create cursor blending (normalized white) white multiplier constant buffer"; return -1; } - device_ctx->PSSetConstantBuffers(1, 1, &sdr_multiplier); + device_ctx->PSSetConstantBuffers(1, 1, &white_multiplier); } else { - status = device->CreatePixelShader(scene_ps_hlsl->GetBufferPointer(), scene_ps_hlsl->GetBufferSize(), nullptr, &cursor_ps); + status = device->CreatePixelShader(cursor_ps_hlsl->GetBufferPointer(), cursor_ps_hlsl->GetBufferSize(), nullptr, &cursor_ps); if (status) { - BOOST_LOG(error) << "Failed to create scene pixel shader [0x"sv << util::hex(status).to_string_view() << ']'; + BOOST_LOG(error) << "Failed to create cursor blending pixel shader [0x"sv << util::hex(status).to_string_view() << ']'; return -1; } } @@ -1670,62 +1670,29 @@ namespace platf::dxgi { int init() { BOOST_LOG(info) << "Compiling shaders..."sv; - scene_vs_hlsl = compile_vertex_shader(SUNSHINE_SHADERS_DIR "/SceneVS.hlsl"); - if (!scene_vs_hlsl) { - return -1; - } - - cursor_vs_hlsl = compile_vertex_shader(SUNSHINE_SHADERS_DIR "/CursorVS.hlsl"); - if (!cursor_vs_hlsl) { - return -1; - } - - convert_Y_ps_hlsl = compile_pixel_shader(SUNSHINE_SHADERS_DIR "/ConvertYPS.hlsl"); - if (!convert_Y_ps_hlsl) { - return -1; - } - convert_Y_PQ_ps_hlsl = compile_pixel_shader(SUNSHINE_SHADERS_DIR "/ConvertYPS_PQ.hlsl"); - if (!convert_Y_PQ_ps_hlsl) { - return -1; - } - - convert_Y_linear_ps_hlsl = compile_pixel_shader(SUNSHINE_SHADERS_DIR "/ConvertYPS_Linear.hlsl"); - if (!convert_Y_linear_ps_hlsl) { - return -1; - } - - convert_UV_ps_hlsl = compile_pixel_shader(SUNSHINE_SHADERS_DIR "/ConvertUVPS.hlsl"); - if (!convert_UV_ps_hlsl) { - return -1; - } +#define compile_vertex_shader_helper(x) \ + if (!(x##_hlsl = compile_vertex_shader(SUNSHINE_SHADERS_DIR "/" #x ".hlsl"))) return -1; +#define compile_pixel_shader_helper(x) \ + if (!(x##_hlsl = compile_pixel_shader(SUNSHINE_SHADERS_DIR "/" #x ".hlsl"))) return -1; + + compile_pixel_shader_helper(convert_yuv420_packed_uv_type0_ps); + compile_pixel_shader_helper(convert_yuv420_packed_uv_type0_ps_linear); + compile_pixel_shader_helper(convert_yuv420_packed_uv_type0_ps_perceptual_quantizer); + compile_vertex_shader_helper(convert_yuv420_packed_uv_type0_vs); + compile_pixel_shader_helper(convert_yuv420_planar_y_ps); + compile_pixel_shader_helper(convert_yuv420_planar_y_ps_linear); + compile_pixel_shader_helper(convert_yuv420_planar_y_ps_perceptual_quantizer); + compile_vertex_shader_helper(convert_yuv420_planar_y_vs); + compile_pixel_shader_helper(cursor_ps); + compile_pixel_shader_helper(cursor_ps_normalize_white); + compile_vertex_shader_helper(cursor_vs); - convert_UV_PQ_ps_hlsl = compile_pixel_shader(SUNSHINE_SHADERS_DIR "/ConvertUVPS_PQ.hlsl"); - if (!convert_UV_PQ_ps_hlsl) { - return -1; - } - - convert_UV_linear_ps_hlsl = compile_pixel_shader(SUNSHINE_SHADERS_DIR "/ConvertUVPS_Linear.hlsl"); - if (!convert_UV_linear_ps_hlsl) { - return -1; - } - - convert_UV_vs_hlsl = compile_vertex_shader(SUNSHINE_SHADERS_DIR "/ConvertUVVS.hlsl"); - if (!convert_UV_vs_hlsl) { - return -1; - } - - scene_ps_hlsl = compile_pixel_shader(SUNSHINE_SHADERS_DIR "/ScenePS.hlsl"); - if (!scene_ps_hlsl) { - return -1; - } - - scene_NW_ps_hlsl = compile_pixel_shader(SUNSHINE_SHADERS_DIR "/ScenePS_NW.hlsl"); - if (!scene_NW_ps_hlsl) { - return -1; - } BOOST_LOG(info) << "Compiled shaders"sv; +#undef compile_vertex_shader_helper +#undef compile_pixel_shader_helper + return 0; } } // namespace platf::dxgi diff --git a/src_assets/windows/assets/shaders/directx/ConvertUVPS.hlsl b/src_assets/windows/assets/shaders/directx/ConvertUVPS.hlsl deleted file mode 100644 index 2c4431889b9..00000000000 --- a/src_assets/windows/assets/shaders/directx/ConvertUVPS.hlsl +++ /dev/null @@ -1,33 +0,0 @@ -Texture2D image : register(t0); - -SamplerState def_sampler : register(s0); - -struct FragTexWide { - float3 uuv : TEXCOORD0; -}; - -cbuffer ColorMatrix : register(b0) { - float4 color_vec_y; - float4 color_vec_u; - float4 color_vec_v; - float2 range_y; - float2 range_uv; -}; - -//-------------------------------------------------------------------------------------- -// Pixel Shader -//-------------------------------------------------------------------------------------- -float2 main_ps(FragTexWide input) : SV_Target -{ - float3 rgb_left = saturate(image.Sample(def_sampler, input.uuv.xz)).rgb; - float3 rgb_right = saturate(image.Sample(def_sampler, input.uuv.yz)).rgb; - float3 rgb = (rgb_left + rgb_right) * 0.5; - - float u = dot(color_vec_u.xyz, rgb) + color_vec_u.w; - float v = dot(color_vec_v.xyz, rgb) + color_vec_v.w; - - u = u * range_uv.x + range_uv.y; - v = v * range_uv.x + range_uv.y; - - return float2(u, v); -} \ No newline at end of file diff --git a/src_assets/windows/assets/shaders/directx/ConvertUVPS_Linear.hlsl b/src_assets/windows/assets/shaders/directx/ConvertUVPS_Linear.hlsl deleted file mode 100644 index 209f3bf713c..00000000000 --- a/src_assets/windows/assets/shaders/directx/ConvertUVPS_Linear.hlsl +++ /dev/null @@ -1,36 +0,0 @@ -Texture2D image : register(t0); - -SamplerState def_sampler : register(s0); - -struct FragTexWide { - float3 uuv : TEXCOORD0; -}; - -cbuffer ColorMatrix : register(b0) { - float4 color_vec_y; - float4 color_vec_u; - float4 color_vec_v; - float2 range_y; - float2 range_uv; -}; - -// This is a fast sRGB approximation from Microsoft's ColorSpaceUtility.hlsli -float3 ApplySRGBCurve(float3 x) -{ - return x < 0.0031308 ? 12.92 * x : 1.13005 * sqrt(x - 0.00228) - 0.13448 * x + 0.005719; -} - -float2 main_ps(FragTexWide input) : SV_Target -{ - float3 rgb_left = ApplySRGBCurve(saturate(image.Sample(def_sampler, input.uuv.xz)).rgb); - float3 rgb_right = ApplySRGBCurve(saturate(image.Sample(def_sampler, input.uuv.yz)).rgb); - float3 rgb = (rgb_left + rgb_right) * 0.5; - - float u = dot(color_vec_u.xyz, rgb) + color_vec_u.w; - float v = dot(color_vec_v.xyz, rgb) + color_vec_v.w; - - u = u * range_uv.x + range_uv.y; - v = v * range_uv.x + range_uv.y; - - return float2(u, v); -} \ No newline at end of file diff --git a/src_assets/windows/assets/shaders/directx/ConvertUVPS_PQ.hlsl b/src_assets/windows/assets/shaders/directx/ConvertUVPS_PQ.hlsl deleted file mode 100644 index 3ae0fb1dd19..00000000000 --- a/src_assets/windows/assets/shaders/directx/ConvertUVPS_PQ.hlsl +++ /dev/null @@ -1,69 +0,0 @@ -Texture2D image : register(t0); - -SamplerState def_sampler : register(s0); - -struct FragTexWide { - float3 uuv : TEXCOORD0; -}; - -cbuffer ColorMatrix : register(b0) { - float4 color_vec_y; - float4 color_vec_u; - float4 color_vec_v; - float2 range_y; - float2 range_uv; -}; - -float3 NitsToPQ(float3 L) -{ - // Constants from SMPTE 2084 PQ - static const float m1 = 2610.0 / 4096.0 / 4; - static const float m2 = 2523.0 / 4096.0 * 128; - static const float c1 = 3424.0 / 4096.0; - static const float c2 = 2413.0 / 4096.0 * 32; - static const float c3 = 2392.0 / 4096.0 * 32; - - float3 Lp = pow(saturate(L / 10000.0), m1); - return pow((c1 + c2 * Lp) / (1 + c3 * Lp), m2); -} - -float3 Rec709toRec2020(float3 rec709) -{ - static const float3x3 ConvMat = - { - 0.627402, 0.329292, 0.043306, - 0.069095, 0.919544, 0.011360, - 0.016394, 0.088028, 0.895578 - }; - return mul(ConvMat, rec709); -} - -float3 scRGBTo2100PQ(float3 rgb) -{ - // Convert from Rec 709 primaries (used by scRGB) to Rec 2020 primaries (used by Rec 2100) - rgb = Rec709toRec2020(rgb); - - // 1.0f is defined as 80 nits in the scRGB colorspace - rgb *= 80; - - // Apply the PQ transfer function on the raw color values in nits - return NitsToPQ(rgb); -} - -//-------------------------------------------------------------------------------------- -// Pixel Shader -//-------------------------------------------------------------------------------------- -float2 main_ps(FragTexWide input) : SV_Target -{ - float3 rgb_left = scRGBTo2100PQ(image.Sample(def_sampler, input.uuv.xz).rgb); - float3 rgb_right = scRGBTo2100PQ(image.Sample(def_sampler, input.uuv.yz).rgb); - float3 rgb = (rgb_left + rgb_right) * 0.5; - - float u = dot(color_vec_u.xyz, rgb) + color_vec_u.w; - float v = dot(color_vec_v.xyz, rgb) + color_vec_v.w; - - u = u * range_uv.x + range_uv.y; - v = v * range_uv.x + range_uv.y; - - return float2(u, v); -} diff --git a/src_assets/windows/assets/shaders/directx/ConvertUVVS.hlsl b/src_assets/windows/assets/shaders/directx/ConvertUVVS.hlsl deleted file mode 100644 index f36128fefcd..00000000000 --- a/src_assets/windows/assets/shaders/directx/ConvertUVVS.hlsl +++ /dev/null @@ -1,46 +0,0 @@ -struct VertTexPosWide { - float3 uuv : TEXCOORD; - float4 pos : SV_POSITION; -}; - -cbuffer info : register(b0) { - float width_i; -}; - -cbuffer rotation_info : register(b1) { - int rotation; -}; - -//-------------------------------------------------------------------------------------- -// Vertex Shader -//-------------------------------------------------------------------------------------- -VertTexPosWide main_vs(uint vI : SV_VERTEXID) -{ - VertTexPosWide output; - float2 tex; - - if (vI == 0) { - output.pos = float4(-1, -1, 0, 1); - tex = float2(0, 1); - } - else if (vI == 1) { - output.pos = float4(-1, 3, 0, 1); - tex = float2(0, -1); - } - else if (vI == 2) { - output.pos = float4(3, -1, 0, 1); - tex = float2(2, 1); - } - - if (rotation != 0) { - float rotation_radians = radians(90 * rotation); - float2x2 rotation_matrix = { cos(rotation_radians), -sin(rotation_radians), - sin(rotation_radians), cos(rotation_radians) }; - float2 rotation_center = { 0.5, 0.5 }; - tex = round(rotation_center + mul(rotation_matrix, tex - rotation_center)); - } - - output.uuv = float3(tex.x, tex.x - width_i, tex.y); - - return output; -} diff --git a/src_assets/windows/assets/shaders/directx/ConvertYPS.hlsl b/src_assets/windows/assets/shaders/directx/ConvertYPS.hlsl deleted file mode 100644 index aad74f318b9..00000000000 --- a/src_assets/windows/assets/shaders/directx/ConvertYPS.hlsl +++ /dev/null @@ -1,25 +0,0 @@ -Texture2D image : register(t0); - -SamplerState def_sampler : register(s0); - -cbuffer ColorMatrix : register(b0) { - float4 color_vec_y; - float4 color_vec_u; - float4 color_vec_v; - float2 range_y; - float2 range_uv; -}; - -struct PS_INPUT -{ - float4 pos : SV_POSITION; - float2 tex : TEXCOORD; -}; - -float main_ps(PS_INPUT frag_in) : SV_Target -{ - float3 rgb = saturate(image.Sample(def_sampler, frag_in.tex, 0)).rgb; - float y = dot(color_vec_y.xyz, rgb) + color_vec_y.w; - - return y * range_y.x + range_y.y; -} \ No newline at end of file diff --git a/src_assets/windows/assets/shaders/directx/ConvertYPS_Linear.hlsl b/src_assets/windows/assets/shaders/directx/ConvertYPS_Linear.hlsl deleted file mode 100644 index a7e91dc16dd..00000000000 --- a/src_assets/windows/assets/shaders/directx/ConvertYPS_Linear.hlsl +++ /dev/null @@ -1,31 +0,0 @@ -Texture2D image : register(t0); - -SamplerState def_sampler : register(s0); - -cbuffer ColorMatrix : register(b0) { - float4 color_vec_y; - float4 color_vec_u; - float4 color_vec_v; - float2 range_y; - float2 range_uv; -}; - -struct PS_INPUT -{ - float4 pos : SV_POSITION; - float2 tex : TEXCOORD; -}; - -// This is a fast sRGB approximation from Microsoft's ColorSpaceUtility.hlsli -float3 ApplySRGBCurve(float3 x) -{ - return x < 0.0031308 ? 12.92 * x : 1.13005 * sqrt(x - 0.00228) - 0.13448 * x + 0.005719; -} - -float main_ps(PS_INPUT frag_in) : SV_Target -{ - float3 rgb = ApplySRGBCurve(saturate(image.Sample(def_sampler, frag_in.tex, 0)).rgb); - float y = dot(color_vec_y.xyz, rgb) + color_vec_y.w; - - return y * range_y.x + range_y.y; -} \ No newline at end of file diff --git a/src_assets/windows/assets/shaders/directx/CursorVS.hlsl b/src_assets/windows/assets/shaders/directx/CursorVS.hlsl deleted file mode 100644 index a93935d7496..00000000000 --- a/src_assets/windows/assets/shaders/directx/CursorVS.hlsl +++ /dev/null @@ -1,37 +0,0 @@ -struct PS_INPUT -{ - float4 pos : SV_POSITION; - float2 tex : TEXCOORD; -}; - -cbuffer rotation_info : register(b2) { - int rotation; -}; - -PS_INPUT main_vs(uint vI : SV_VERTEXID) -{ - PS_INPUT output; - - if (vI == 0) { - output.pos = float4(-1, -1, 0, 1); - output.tex = float2(0, 1); - } - else if (vI == 1) { - output.pos = float4(-1, 3, 0, 1); - output.tex = float2(0, -1); - } - else if (vI == 2) { - output.pos = float4(3, -1, 0, 1); - output.tex = float2(2, 1); - } - - if (rotation != 0) { - float rotation_radians = radians(90 * rotation); - float2x2 rotation_matrix = { cos(rotation_radians), -sin(rotation_radians), - sin(rotation_radians), cos(rotation_radians) }; - float2 rotation_center = { 0.5, 0.5 }; - output.tex = round(rotation_center + mul(rotation_matrix, output.tex - rotation_center)); - } - - return output; -} \ No newline at end of file diff --git a/src_assets/windows/assets/shaders/directx/ScenePS.hlsl b/src_assets/windows/assets/shaders/directx/ScenePS.hlsl deleted file mode 100644 index 53a9bc8dc2f..00000000000 --- a/src_assets/windows/assets/shaders/directx/ScenePS.hlsl +++ /dev/null @@ -1,14 +0,0 @@ -Texture2D image : register(t0); - -SamplerState def_sampler : register(s0); - -struct PS_INPUT -{ - float4 pos : SV_POSITION; - float2 tex : TEXCOORD; -}; - -float4 main_ps(PS_INPUT frag_in) : SV_Target -{ - return image.Sample(def_sampler, frag_in.tex, 0); -} \ No newline at end of file diff --git a/src_assets/windows/assets/shaders/directx/ScenePS_NW.hlsl b/src_assets/windows/assets/shaders/directx/ScenePS_NW.hlsl deleted file mode 100644 index 9553b698966..00000000000 --- a/src_assets/windows/assets/shaders/directx/ScenePS_NW.hlsl +++ /dev/null @@ -1,22 +0,0 @@ -Texture2D image : register(t0); - -SamplerState def_sampler : register(s0); - -struct PS_INPUT -{ - float4 pos : SV_POSITION; - float2 tex : TEXCOORD; -}; - -cbuffer SdrScaling : register(b1) { - float scale_factor; -}; - -float4 main_ps(PS_INPUT frag_in) : SV_Target -{ - float4 rgba = image.Sample(def_sampler, frag_in.tex, 0); - - rgba.rgb = rgba.rgb * scale_factor; - - return rgba; -} diff --git a/src_assets/windows/assets/shaders/directx/SceneVS.hlsl b/src_assets/windows/assets/shaders/directx/SceneVS.hlsl deleted file mode 100644 index 3e72aa0cd0d..00000000000 --- a/src_assets/windows/assets/shaders/directx/SceneVS.hlsl +++ /dev/null @@ -1,37 +0,0 @@ -struct PS_INPUT -{ - float4 pos : SV_POSITION; - float2 tex : TEXCOORD; -}; - -cbuffer rotation_info : register(b1) { - int rotation; -}; - -PS_INPUT main_vs(uint vI : SV_VERTEXID) -{ - PS_INPUT output; - - if (vI == 0) { - output.pos = float4(-1, -1, 0, 1); - output.tex = float2(0, 1); - } - else if (vI == 1) { - output.pos = float4(-1, 3, 0, 1); - output.tex = float2(0, -1); - } - else if (vI == 2) { - output.pos = float4(3, -1, 0, 1); - output.tex = float2(2, 1); - } - - if (rotation != 0) { - float rotation_radians = radians(90 * rotation); - float2x2 rotation_matrix = { cos(rotation_radians), -sin(rotation_radians), - sin(rotation_radians), cos(rotation_radians) }; - float2 rotation_center = { 0.5, 0.5 }; - output.tex = round(rotation_center + mul(rotation_matrix, output.tex - rotation_center)); - } - - return output; -} \ No newline at end of file diff --git a/src_assets/windows/assets/shaders/directx/convert_yuv420_packed_uv_type0_ps.hlsl b/src_assets/windows/assets/shaders/directx/convert_yuv420_packed_uv_type0_ps.hlsl new file mode 100644 index 00000000000..2e67d258fd3 --- /dev/null +++ b/src_assets/windows/assets/shaders/directx/convert_yuv420_packed_uv_type0_ps.hlsl @@ -0,0 +1,5 @@ +#include "include/convert_base.hlsl" + +#define LEFT_SUBSAMPLING + +#include "include/convert_yuv420_packed_uv_ps_base.hlsl" diff --git a/src_assets/windows/assets/shaders/directx/convert_yuv420_packed_uv_type0_ps_linear.hlsl b/src_assets/windows/assets/shaders/directx/convert_yuv420_packed_uv_type0_ps_linear.hlsl new file mode 100644 index 00000000000..17957b09f6e --- /dev/null +++ b/src_assets/windows/assets/shaders/directx/convert_yuv420_packed_uv_type0_ps_linear.hlsl @@ -0,0 +1,5 @@ +#include "include/convert_linear_base.hlsl" + +#define LEFT_SUBSAMPLING + +#include "include/convert_yuv420_packed_uv_ps_base.hlsl" diff --git a/src_assets/windows/assets/shaders/directx/convert_yuv420_packed_uv_type0_ps_perceptual_quantizer.hlsl b/src_assets/windows/assets/shaders/directx/convert_yuv420_packed_uv_type0_ps_perceptual_quantizer.hlsl new file mode 100644 index 00000000000..66ffb7464ca --- /dev/null +++ b/src_assets/windows/assets/shaders/directx/convert_yuv420_packed_uv_type0_ps_perceptual_quantizer.hlsl @@ -0,0 +1,5 @@ +#include "include/convert_perceptual_quantizer_base.hlsl" + +#define LEFT_SUBSAMPLING + +#include "include/convert_yuv420_packed_uv_ps_base.hlsl" diff --git a/src_assets/windows/assets/shaders/directx/convert_yuv420_packed_uv_type0_vs.hlsl b/src_assets/windows/assets/shaders/directx/convert_yuv420_packed_uv_type0_vs.hlsl new file mode 100644 index 00000000000..eb9068b4187 --- /dev/null +++ b/src_assets/windows/assets/shaders/directx/convert_yuv420_packed_uv_type0_vs.hlsl @@ -0,0 +1,15 @@ +cbuffer subsample_offset_cbuffer : register(b0) { + float2 subsample_offset; +}; + +cbuffer rotate_texture_steps_cbuffer : register(b1) { + int rotate_texture_steps; +}; + +#define LEFT_SUBSAMPLING +#include "include/base_vs.hlsl" + +vertex_t main_vs(uint vertex_id : SV_VertexID) +{ + return generate_fullscreen_triangle_vertex(vertex_id, subsample_offset.x, rotate_texture_steps); +} diff --git a/src_assets/windows/assets/shaders/directx/convert_yuv420_planar_y_ps.hlsl b/src_assets/windows/assets/shaders/directx/convert_yuv420_planar_y_ps.hlsl new file mode 100644 index 00000000000..7576fb64540 --- /dev/null +++ b/src_assets/windows/assets/shaders/directx/convert_yuv420_planar_y_ps.hlsl @@ -0,0 +1,3 @@ +#include "include/convert_base.hlsl" + +#include "include/convert_yuv420_planar_y_ps_base.hlsl" diff --git a/src_assets/windows/assets/shaders/directx/convert_yuv420_planar_y_ps_linear.hlsl b/src_assets/windows/assets/shaders/directx/convert_yuv420_planar_y_ps_linear.hlsl new file mode 100644 index 00000000000..7c22cc42250 --- /dev/null +++ b/src_assets/windows/assets/shaders/directx/convert_yuv420_planar_y_ps_linear.hlsl @@ -0,0 +1,3 @@ +#include "include/convert_linear_base.hlsl" + +#include "include/convert_yuv420_planar_y_ps_base.hlsl" diff --git a/src_assets/windows/assets/shaders/directx/convert_yuv420_planar_y_ps_perceptual_quantizer.hlsl b/src_assets/windows/assets/shaders/directx/convert_yuv420_planar_y_ps_perceptual_quantizer.hlsl new file mode 100644 index 00000000000..2b42c8ad318 --- /dev/null +++ b/src_assets/windows/assets/shaders/directx/convert_yuv420_planar_y_ps_perceptual_quantizer.hlsl @@ -0,0 +1,3 @@ +#include "include/convert_perceptual_quantizer_base.hlsl" + +#include "include/convert_yuv420_planar_y_ps_base.hlsl" diff --git a/src_assets/windows/assets/shaders/directx/convert_yuv420_planar_y_vs.hlsl b/src_assets/windows/assets/shaders/directx/convert_yuv420_planar_y_vs.hlsl new file mode 100644 index 00000000000..33e481453ed --- /dev/null +++ b/src_assets/windows/assets/shaders/directx/convert_yuv420_planar_y_vs.hlsl @@ -0,0 +1,10 @@ +cbuffer rotate_texture_steps_cbuffer : register(b1) { + int rotate_texture_steps; +}; + +#include "include/base_vs.hlsl" + +vertex_t main_vs(uint vertex_id : SV_VertexID) +{ + return generate_fullscreen_triangle_vertex(vertex_id, rotate_texture_steps); +} diff --git a/src_assets/windows/assets/shaders/directx/cursor_ps.hlsl b/src_assets/windows/assets/shaders/directx/cursor_ps.hlsl new file mode 100644 index 00000000000..682e13c2538 --- /dev/null +++ b/src_assets/windows/assets/shaders/directx/cursor_ps.hlsl @@ -0,0 +1,9 @@ +Texture2D cursor : register(t0); +SamplerState def_sampler : register(s0); + +#include "include/base_vs_types.hlsl" + +float4 main_ps(vertex_t input) : SV_Target +{ + return cursor.Sample(def_sampler, input.tex_coord, 0); +} diff --git a/src_assets/windows/assets/shaders/directx/cursor_ps_normalize_white.hlsl b/src_assets/windows/assets/shaders/directx/cursor_ps_normalize_white.hlsl new file mode 100644 index 00000000000..fdc7ff17091 --- /dev/null +++ b/src_assets/windows/assets/shaders/directx/cursor_ps_normalize_white.hlsl @@ -0,0 +1,17 @@ +Texture2D cursor : register(t0); +SamplerState def_sampler : register(s0); + +cbuffer normalize_white_cbuffer : register(b1) { + float white_multiplier; +}; + +#include "include/base_vs_types.hlsl" + +float4 main_ps(vertex_t input) : SV_Target +{ + float4 output = cursor.Sample(def_sampler, input.tex_coord, 0); + + output.rgb = output.rgb * white_multiplier; + + return output; +} diff --git a/src_assets/windows/assets/shaders/directx/cursor_vs.hlsl b/src_assets/windows/assets/shaders/directx/cursor_vs.hlsl new file mode 100644 index 00000000000..cf737ede7e4 --- /dev/null +++ b/src_assets/windows/assets/shaders/directx/cursor_vs.hlsl @@ -0,0 +1,10 @@ +cbuffer rotate_texture_steps_cbuffer : register(b2) { + int rotate_texture_steps; +}; + +#include "include/base_vs.hlsl" + +vertex_t main_vs(uint vertex_id : SV_VertexID) +{ + return generate_fullscreen_triangle_vertex(vertex_id, rotate_texture_steps); +} diff --git a/src_assets/windows/assets/shaders/directx/include/base_vs.hlsl b/src_assets/windows/assets/shaders/directx/include/base_vs.hlsl new file mode 100644 index 00000000000..5fc9226bd4f --- /dev/null +++ b/src_assets/windows/assets/shaders/directx/include/base_vs.hlsl @@ -0,0 +1,45 @@ +#include "include/base_vs_types.hlsl" + +#if defined(LEFT_SUBSAMPLING) +vertex_t generate_fullscreen_triangle_vertex(uint vertex_id, float subsample_offset, int rotate_texture_steps) +#elif defined (TOPLEFT_SUBSAMPLING) +vertex_t generate_fullscreen_triangle_vertex(uint vertex_id, float2 subsample_offset, int rotate_texture_steps) +#else +vertex_t generate_fullscreen_triangle_vertex(uint vertex_id, int rotate_texture_steps) +#endif +{ + vertex_t output; + float2 tex_coord; + + if (vertex_id == 0) { + output.viewpoint_pos = float4(-1, -1, 0, 1); + tex_coord = float2(0, 1); + } + else if (vertex_id == 1) { + output.viewpoint_pos = float4(-1, 3, 0, 1); + tex_coord = float2(0, -1); + } + else if (vertex_id == 2) { + output.viewpoint_pos = float4(3, -1, 0, 1); + tex_coord = float2(2, 1); + } + + if (rotate_texture_steps != 0) { + float rotation_radians = radians(90 * rotate_texture_steps); + float2x2 rotation_matrix = { cos(rotation_radians), -sin(rotation_radians), + sin(rotation_radians), cos(rotation_radians) }; + float2 rotation_center = { 0.5, 0.5 }; + tex_coord = round(tex_coord + mul(rotation_matrix, tex_coord - rotation_center)); + } + +#if defined(LEFT_SUBSAMPLING) + output.tex_right_left_center = float3(tex_coord.x, tex_coord.x - subsample_offset, tex_coord.y); +#elif defined (TOPLEFT_SUBSAMPLING) + output.tex_right_left_top = float3(tex_coord.x, tex_coord.x - subsample_offset.x, tex_coord.y - subsample_offset.y); + output.tex_right_left_bottom = float3(tex_coord.x, tex_coord.x - subsample_offset.x, tex_coord.y); +#else + output.tex_coord = tex_coord; +#endif + + return output; +} diff --git a/src_assets/windows/assets/shaders/directx/include/base_vs_types.hlsl b/src_assets/windows/assets/shaders/directx/include/base_vs_types.hlsl new file mode 100644 index 00000000000..9e4b28f18fb --- /dev/null +++ b/src_assets/windows/assets/shaders/directx/include/base_vs_types.hlsl @@ -0,0 +1,12 @@ +struct vertex_t +{ + float4 viewpoint_pos : SV_Position; +#if defined(LEFT_SUBSAMPLING) + float3 tex_right_left_center : TEXCOORD; +#elif defined (TOPLEFT_SUBSAMPLING) + float3 tex_right_left_top : TEXCOORD; + float3 tex_right_left_bottom : TEXCOORD; +#else + float2 tex_coord : TEXCOORD; +#endif +}; diff --git a/src_assets/windows/assets/shaders/directx/ConvertYPS_PQ.hlsl b/src_assets/windows/assets/shaders/directx/include/common.hlsl similarity index 65% rename from src_assets/windows/assets/shaders/directx/ConvertYPS_PQ.hlsl rename to src_assets/windows/assets/shaders/directx/include/common.hlsl index cc3054e8350..8398c7000a1 100644 --- a/src_assets/windows/assets/shaders/directx/ConvertYPS_PQ.hlsl +++ b/src_assets/windows/assets/shaders/directx/include/common.hlsl @@ -1,62 +1,41 @@ -Texture2D image : register(t0); - -SamplerState def_sampler : register(s0); - -cbuffer ColorMatrix : register(b0) { - float4 color_vec_y; - float4 color_vec_u; - float4 color_vec_v; - float2 range_y; - float2 range_uv; -}; - -struct PS_INPUT -{ - float4 pos : SV_POSITION; - float2 tex : TEXCOORD; -}; - -float3 NitsToPQ(float3 L) -{ - // Constants from SMPTE 2084 PQ - static const float m1 = 2610.0 / 4096.0 / 4; - static const float m2 = 2523.0 / 4096.0 * 128; - static const float c1 = 3424.0 / 4096.0; - static const float c2 = 2413.0 / 4096.0 * 32; - static const float c3 = 2392.0 / 4096.0 * 32; - - float3 Lp = pow(saturate(L / 10000.0), m1); - return pow((c1 + c2 * Lp) / (1 + c3 * Lp), m2); -} - -float3 Rec709toRec2020(float3 rec709) -{ - static const float3x3 ConvMat = - { - 0.627402, 0.329292, 0.043306, - 0.069095, 0.919544, 0.011360, - 0.016394, 0.088028, 0.895578 - }; - return mul(ConvMat, rec709); -} - -float3 scRGBTo2100PQ(float3 rgb) -{ - // Convert from Rec 709 primaries (used by scRGB) to Rec 2020 primaries (used by Rec 2100) - rgb = Rec709toRec2020(rgb); - - // 1.0f is defined as 80 nits in the scRGB colorspace - rgb *= 80; - - // Apply the PQ transfer function on the raw color values in nits - return NitsToPQ(rgb); -} - -float main_ps(PS_INPUT frag_in) : SV_Target -{ - float3 rgb = scRGBTo2100PQ(image.Sample(def_sampler, frag_in.tex, 0).rgb); - - float y = dot(color_vec_y.xyz, rgb) + color_vec_y.w; - - return y * range_y.x + range_y.y; -} +// This is a fast sRGB approximation from Microsoft's ColorSpaceUtility.hlsli +float3 ApplySRGBCurve(float3 x) +{ + return x < 0.0031308 ? 12.92 * x : 1.13005 * sqrt(x - 0.00228) - 0.13448 * x + 0.005719; +} + +float3 NitsToPQ(float3 L) +{ + // Constants from SMPTE 2084 PQ + static const float m1 = 2610.0 / 4096.0 / 4; + static const float m2 = 2523.0 / 4096.0 * 128; + static const float c1 = 3424.0 / 4096.0; + static const float c2 = 2413.0 / 4096.0 * 32; + static const float c3 = 2392.0 / 4096.0 * 32; + + float3 Lp = pow(saturate(L / 10000.0), m1); + return pow((c1 + c2 * Lp) / (1 + c3 * Lp), m2); +} + +float3 Rec709toRec2020(float3 rec709) +{ + static const float3x3 ConvMat = + { + 0.627402, 0.329292, 0.043306, + 0.069095, 0.919544, 0.011360, + 0.016394, 0.088028, 0.895578 + }; + return mul(ConvMat, rec709); +} + +float3 scRGBTo2100PQ(float3 rgb) +{ + // Convert from Rec 709 primaries (used by scRGB) to Rec 2020 primaries (used by Rec 2100) + rgb = Rec709toRec2020(rgb); + + // 1.0f is defined as 80 nits in the scRGB colorspace + rgb *= 80; + + // Apply the PQ transfer function on the raw color values in nits + return NitsToPQ(rgb); +} diff --git a/src_assets/windows/assets/shaders/directx/include/convert_base.hlsl b/src_assets/windows/assets/shaders/directx/include/convert_base.hlsl new file mode 100644 index 00000000000..6d0c1e5943e --- /dev/null +++ b/src_assets/windows/assets/shaders/directx/include/convert_base.hlsl @@ -0,0 +1 @@ +#define CONVERT_FUNCTION saturate diff --git a/src_assets/windows/assets/shaders/directx/include/convert_linear_base.hlsl b/src_assets/windows/assets/shaders/directx/include/convert_linear_base.hlsl new file mode 100644 index 00000000000..8599318cc52 --- /dev/null +++ b/src_assets/windows/assets/shaders/directx/include/convert_linear_base.hlsl @@ -0,0 +1,6 @@ +#include "include/common.hlsl" + +float3 CONVERT_FUNCTION(float3 input) +{ + return ApplySRGBCurve(saturate(input)); +} diff --git a/src_assets/windows/assets/shaders/directx/include/convert_perceptual_quantizer_base.hlsl b/src_assets/windows/assets/shaders/directx/include/convert_perceptual_quantizer_base.hlsl new file mode 100644 index 00000000000..7a0df8ad9e8 --- /dev/null +++ b/src_assets/windows/assets/shaders/directx/include/convert_perceptual_quantizer_base.hlsl @@ -0,0 +1,3 @@ +#include "include/common.hlsl" + +#define CONVERT_FUNCTION scRGBTo2100PQ diff --git a/src_assets/windows/assets/shaders/directx/include/convert_yuv420_packed_uv_ps_base.hlsl b/src_assets/windows/assets/shaders/directx/include/convert_yuv420_packed_uv_ps_base.hlsl new file mode 100644 index 00000000000..c21dccd7ed2 --- /dev/null +++ b/src_assets/windows/assets/shaders/directx/include/convert_yuv420_packed_uv_ps_base.hlsl @@ -0,0 +1,35 @@ +Texture2D image : register(t0); +SamplerState def_sampler : register(s0); + +cbuffer color_matrix_cbuffer : register(b0) { + float4 color_vec_y; + float4 color_vec_u; + float4 color_vec_v; + float2 range_y; + float2 range_uv; +}; + +#include "include/base_vs_types.hlsl" + +float2 main_ps(vertex_t input) : SV_Target +{ +#if defined(LEFT_SUBSAMPLING) + float3 rgb_left = image.Sample(def_sampler, input.tex_right_left_center.xz).rgb; + float3 rgb_right = image.Sample(def_sampler, input.tex_right_left_center.yz).rgb; + float3 rgb = CONVERT_FUNCTION((rgb_left + rgb_right) * 0.5); +#elif defined(TOPLEFT_SUBSAMPLING) + float3 rgb_top_left = image.Sample(def_sampler, input.tex_right_left_top.xz).rgb; + float3 rgb_top_right = image.Sample(def_sampler, input.tex_right_left_top.yz).rgb; + float3 rgb_bottom_left = image.Sample(def_sampler, input.tex_right_left_bottom.xz).rgb; + float3 rgb_bottom_right = image.Sample(def_sampler, input.tex_right_left_bottom.yz).rgb; + float3 rgb = CONVERT_FUNCTION((rgb_top_left + rgb_top_right + rgb_bottom_left + rgb_bottom_right) * 0.25); +#endif + + float u = dot(color_vec_u.xyz, rgb) + color_vec_u.w; + float v = dot(color_vec_v.xyz, rgb) + color_vec_v.w; + + u = u * range_uv.x + range_uv.y; + v = v * range_uv.x + range_uv.y; + + return float2(u, v); +} diff --git a/src_assets/windows/assets/shaders/directx/include/convert_yuv420_planar_y_ps_base.hlsl b/src_assets/windows/assets/shaders/directx/include/convert_yuv420_planar_y_ps_base.hlsl new file mode 100644 index 00000000000..7742e61c2c5 --- /dev/null +++ b/src_assets/windows/assets/shaders/directx/include/convert_yuv420_planar_y_ps_base.hlsl @@ -0,0 +1,21 @@ +Texture2D image : register(t0); +SamplerState def_sampler : register(s0); + +cbuffer color_matrix_cbuffer : register(b0) { + float4 color_vec_y; + float4 color_vec_u; + float4 color_vec_v; + float2 range_y; + float2 range_uv; +}; + +#include "include/base_vs_types.hlsl" + +float main_ps(vertex_t input) : SV_Target +{ + float3 rgb = CONVERT_FUNCTION(image.Sample(def_sampler, input.tex_coord, 0).rgb); + + float y = dot(color_vec_y.xyz, rgb) + color_vec_y.w; + + return y * range_y.x + range_y.y; +} From c01df85ad1bfcdcb950e4d03cd5ccd2ccfebc632 Mon Sep 17 00:00:00 2001 From: ns6089 <61738816+ns6089@users.noreply.github.com> Date: Mon, 11 Sep 2023 16:00:29 +0300 Subject: [PATCH 3/3] Remove unused shader input layout We don't use SV_Position in our vertex shaders. --- src/platform/windows/display_vram.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/platform/windows/display_vram.cpp b/src/platform/windows/display_vram.cpp index a0dd4dbc57e..71310c90c16 100644 --- a/src/platform/windows/display_vram.cpp +++ b/src/platform/windows/display_vram.cpp @@ -621,15 +621,6 @@ namespace platf::dxgi { } device_ctx->PSSetConstantBuffers(0, 1, &color_matrix); - D3D11_INPUT_ELEMENT_DESC layout_desc { - "SV_Position", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 - }; - - status = device->CreateInputLayout( - &layout_desc, 1, - convert_yuv420_chroma_vs_type0_hlsl->GetBufferPointer(), convert_yuv420_chroma_vs_type0_hlsl->GetBufferSize(), - &input_layout); - this->display = std::dynamic_pointer_cast(display); if (!this->display) { return -1; @@ -656,8 +647,6 @@ namespace platf::dxgi { return -1; } - device_ctx->IASetInputLayout(input_layout.get()); - device_ctx->OMSetBlendState(blend_disable.get(), nullptr, 0xFFFFFFFFu); device_ctx->PSSetSamplers(0, 1, &sampler_linear); device_ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); @@ -737,8 +726,6 @@ namespace platf::dxgi { buf_t subsample_offset; buf_t color_matrix; - input_layout_t input_layout; - blend_t blend_disable; sampler_state_t sampler_linear;