fix(win/video): don't offload chroma subsampling math to texture sampler when downscaling (#3014)

* Don't use sampler math for chroma if downscaling

* Correct portrait rotation offsets
This commit is contained in:
ns6089
2024-09-03 03:02:05 +03:00
committed by Yukino Song
parent 4353599b74
commit 538a64a9cc
13 changed files with 177 additions and 93 deletions

View File

@@ -11,5 +11,5 @@ cbuffer rotate_texture_steps_cbuffer : register(b1) {
vertex_t main_vs(uint vertex_id : SV_VertexID)
{
return generate_fullscreen_triangle_vertex(vertex_id, subsample_offset.x, rotate_texture_steps);
return generate_fullscreen_triangle_vertex(vertex_id, subsample_offset, rotate_texture_steps);
}

View File

@@ -0,0 +1,5 @@
#include "include/convert_base.hlsl"
#define LEFT_SUBSAMPLING_SCALE
#include "include/convert_yuv420_packed_uv_ps_base.hlsl"

View File

@@ -0,0 +1,5 @@
#include "include/convert_linear_base.hlsl"
#define LEFT_SUBSAMPLING_SCALE
#include "include/convert_yuv420_packed_uv_ps_base.hlsl"

View File

@@ -0,0 +1,5 @@
#include "include/convert_perceptual_quantizer_base.hlsl"
#define LEFT_SUBSAMPLING_SCALE
#include "include/convert_yuv420_packed_uv_ps_base.hlsl"

View File

@@ -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_SCALE
#include "include/base_vs.hlsl"
vertex_t main_vs(uint vertex_id : SV_VertexID)
{
return generate_fullscreen_triangle_vertex(vertex_id, subsample_offset, rotate_texture_steps);
}

View File

@@ -6,5 +6,5 @@ cbuffer rotate_texture_steps_cbuffer : register(b1) {
vertex_t main_vs(uint vertex_id : SV_VertexID)
{
return generate_fullscreen_triangle_vertex(vertex_id, rotate_texture_steps);
return generate_fullscreen_triangle_vertex(vertex_id, float2(0, 0), rotate_texture_steps);
}

View File

@@ -6,5 +6,5 @@ cbuffer rotate_texture_steps_cbuffer : register(b1) {
vertex_t main_vs(uint vertex_id : SV_VertexID)
{
return generate_fullscreen_triangle_vertex(vertex_id, rotate_texture_steps);
return generate_fullscreen_triangle_vertex(vertex_id, float2(0, 0), rotate_texture_steps);
}

View File

@@ -15,7 +15,7 @@ cbuffer color_matrix_cbuffer : register(b3) {
vertex_t main_vs(uint vertex_id : SV_VertexID)
{
vertex_t output = generate_fullscreen_triangle_vertex(vertex_id % 3, rotate_texture_steps);
vertex_t output = generate_fullscreen_triangle_vertex(vertex_id % 3, float2(0, 0), rotate_texture_steps);
output.viewport = vertex_id / 3;

View File

@@ -6,5 +6,5 @@ cbuffer rotate_texture_steps_cbuffer : register(b2) {
vertex_t main_vs(uint vertex_id : SV_VertexID)
{
return generate_fullscreen_triangle_vertex(vertex_id, rotate_texture_steps);
return generate_fullscreen_triangle_vertex(vertex_id, float2(0, 0), rotate_texture_steps);
}

View File

@@ -1,12 +1,6 @@
#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;
@@ -30,11 +24,24 @@ vertex_t generate_fullscreen_triangle_vertex(uint vertex_id, int rotate_texture_
sin(rotation_radians), cos(rotation_radians) };
float2 rotation_center = { 0.5, 0.5 };
tex_coord = round(rotation_center + mul(rotation_matrix, tex_coord - rotation_center));
if (rotate_texture_steps % 2) {
subsample_offset.xy = subsample_offset.yx;
}
}
#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_center = float3(tex_coord.x, tex_coord.x - subsample_offset.x, tex_coord.y);
#elif defined(LEFT_SUBSAMPLING_SCALE)
float2 halfsample_offset = subsample_offset / 2;
float3 right_center_left = float3(tex_coord.x + halfsample_offset.x,
tex_coord.x - halfsample_offset.x,
tex_coord.x - 3 * halfsample_offset.x);
float2 top_bottom = float2(tex_coord.y - halfsample_offset.y,
tex_coord.y + halfsample_offset.y);
output.tex_right_center_left_top = float4(right_center_left, top_bottom.x);
output.tex_right_center_left_bottom = float4(right_center_left, top_bottom.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

View File

@@ -3,9 +3,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;
#elif defined(LEFT_SUBSAMPLING_SCALE)
float4 tex_right_center_left_top : TEXCOORD0;
float4 tex_right_center_left_bottom : TEXCOORD1;
#elif defined(TOPLEFT_SUBSAMPLING)
float3 tex_right_left_top : TEXCOORD0;
float3 tex_right_left_bottom : TEXCOORD1;
#else
float2 tex_coord : TEXCOORD;
#endif

View File

@@ -17,6 +17,15 @@ float2 main_ps(vertex_t input) : SV_Target
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(LEFT_SUBSAMPLING_SCALE)
float3 rgb = image.Sample(def_sampler, input.tex_right_center_left_top.yw).rgb; // top-center
rgb += image.Sample(def_sampler, input.tex_right_center_left_bottom.yw).rgb; // bottom-center
rgb *= 2;
rgb += image.Sample(def_sampler, input.tex_right_center_left_top.xw).rgb; // top-right
rgb += image.Sample(def_sampler, input.tex_right_center_left_top.zw).rgb; // top-left
rgb += image.Sample(def_sampler, input.tex_right_center_left_bottom.xw).rgb; // bottom-right
rgb += image.Sample(def_sampler, input.tex_right_center_left_bottom.zw).rgb; // bottom-left
rgb = CONVERT_FUNCTION(rgb * (1./8));
#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;