Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor dx shaders #1621

Merged
merged 3 commits into from
Oct 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 53 additions & 99 deletions src/platform/windows/display_vram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -345,7 +345,7 @@ namespace platf::dxgi {
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, 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 };
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -553,27 +553,27 @@ 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;
}

// 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;
Expand All @@ -582,27 +582,27 @@ 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;
}
}

// 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;
Expand All @@ -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_UV_vs_hlsl->GetBufferPointer(), convert_UV_vs_hlsl->GetBufferSize(),
&input_layout);

this->display = std::dynamic_pointer_cast<display_base_t>(display);
if (!this->display) {
return -1;
Expand All @@ -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);
Expand Down Expand Up @@ -734,11 +723,9 @@ 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;

blend_t blend_disable;
sampler_state_t sampler_linear;

Expand Down Expand Up @@ -1376,28 +1363,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;
}
}
Expand Down Expand Up @@ -1670,62 +1657,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;
}

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

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
33 changes: 0 additions & 33 deletions src_assets/windows/assets/shaders/directx/ConvertUVPS.hlsl

This file was deleted.

36 changes: 0 additions & 36 deletions src_assets/windows/assets/shaders/directx/ConvertUVPS_Linear.hlsl

This file was deleted.

Loading