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

Support for linear space rendering in R4 renderer #1576

Open
wants to merge 10 commits into
base: dev
Choose a base branch
from
Binary file added res/gamedata/shaders/r3/yuv2rgb.ps
Binary file not shown.
Binary file modified res/gamedata/shaders/r5/yuv2rgb.ps
Binary file not shown.
14 changes: 13 additions & 1 deletion src/Layers/xrRender/dxRainRender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ const int max_particles = 1000;
const int particles_cache = 400;
const float particles_time = .3f;

namespace
{

float srgbToLinear(float c) { return std::pow(c, 2.2f); }

Fvector3 srgbToLinear(const Fvector3 c)
{
return Fvector3{srgbToLinear(c.x), srgbToLinear(c.y), srgbToLinear(c.z)};
}

} // namespace

dxRainRender::dxRainRender()
{
IReader* F = FS.r_open("$game_meshes$", "dm" DELIMITER "rain.dm");
Expand Down Expand Up @@ -84,7 +96,7 @@ void dxRainRender::Render(CEffect_Rain& owner)

// visual
const float factor_visual = factor / 2.f + .5f;
const Fvector3 f_rain_color = g_pGamePersistent->Environment().CurrentEnv.rain_color;
const Fvector3 f_rain_color = srgbToLinear(g_pGamePersistent->Environment().CurrentEnv.rain_color);
const u32 u_rain_color = color_rgba_f(f_rain_color.x, f_rain_color.y, f_rain_color.z, factor_visual);

const float b_radius_wrap_sqr = _sqr((source_radius + .5f));
Expand Down
5 changes: 5 additions & 0 deletions src/Layers/xrRender/xrRender_console.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ const xr_token qmsaa__atest_token[] = {
u32 ps_r3_minmax_sm = 3; // = 0;
const xr_token qminmax_sm_token[] = {{"off", 0}, {"on", 1}, {"auto", 2}, {"autodetect", 3}, {nullptr, 0}};

u32 ps_r3_rendering_space = 0; // = 0;
const xr_token rendering__space_token[] = {
{"gamma", 0}, {"linear", 1}, {nullptr, 0}};

// “Off”
// “DX10.0 style [Standard]”
// “DX10.1 style [Higher quality]”
Expand Down Expand Up @@ -1100,6 +1104,7 @@ void xrRender_initconsole()
//CMD3(CCC_Mask, "r3_msaa_alphatest", &ps_r2_ls_flags, (u32)R3FLAG_MSAA_ALPHATEST);
CMD3(CCC_Token, "r3_msaa_alphatest", &ps_r3_msaa_atest, qmsaa__atest_token);
CMD3(CCC_Token, "r3_minmax_sm", &ps_r3_minmax_sm, qminmax_sm_token);
CMD3(CCC_Token, "r3_rendering_space", &ps_r3_rendering_space, rendering__space_token);

// Allow real-time fog config reload
#if (RENDER == R_R3) || (RENDER == R_R4)
Expand Down
3 changes: 3 additions & 0 deletions src/Layers/xrRender/xrRender_console.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ extern ECORE_API const xr_token qmsaa__atest_token[];
extern ECORE_API u32 ps_r3_minmax_sm; // = 0;
extern ECORE_API const xr_token qminmax_sm_token[];

extern ECORE_API u32 ps_r3_rendering_space; // = 0;
extern ECORE_API const xr_token rendering__space_token[];

extern ENGINE_API int ps_r__Supersample;
extern ECORE_API int ps_r__LightSleepFrames;

Expand Down
43 changes: 28 additions & 15 deletions src/Layers/xrRenderDX11/dx11HW.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,15 +271,9 @@ bool CHW::CreateSwapChain(HWND hwnd)
sd.BufferDesc.Height = Device.dwHeight;

// TODO: DX11: implement dynamic format selection
constexpr DXGI_FORMAT formats[] =
{
//DXGI_FORMAT_R16G16B16A16_FLOAT, // Do we even need this?
//DXGI_FORMAT_R10G10B10A2_UNORM, // D3DX11SaveTextureToMemory fails on this format
DXGI_FORMAT_R8G8B8A8_UNORM,
};
sd.BufferDesc.Format = selectBackBufferFormat();

// Select back-buffer format
sd.BufferDesc.Format = SelectFormat(D3D_FORMAT_SUPPORT_DISPLAY, formats);
Caps.fTarget = dx11TextureUtils::ConvertTextureFormat(sd.BufferDesc.Format);

// Buffering
Expand Down Expand Up @@ -329,15 +323,8 @@ bool CHW::CreateSwapChain2(HWND hwnd)
desc.Width = Device.dwWidth;
desc.Height = Device.dwHeight;

constexpr DXGI_FORMAT formats[] =
{
//DXGI_FORMAT_R16G16B16A16_FLOAT,
//DXGI_FORMAT_R10G10B10A2_UNORM,
DXGI_FORMAT_R8G8B8A8_UNORM,
};
desc.Format = selectBackBufferFormat();

// Select back-buffer format
desc.Format = SelectFormat(D3D11_FORMAT_SUPPORT_DISPLAY, formats);
Caps.fTarget = dx11TextureUtils::ConvertTextureFormat(desc.Format);

// Buffering
Expand Down Expand Up @@ -388,6 +375,31 @@ bool CHW::CreateSwapChain2(HWND hwnd)
return false;
}

DXGI_FORMAT CHW::selectBackBufferFormat() const
{
if (ps_r3_rendering_space == 1)
{
constexpr DXGI_FORMAT formats[] = {
// DXGI_FORMAT_R16G16B16A16_FLOAT,
// DXGI_FORMAT_R10G10B10A2_UNORM,
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
// DXGI_FORMAT_R8G8B8A8_UNORM,
};

// Select back-buffer format
return SelectFormat(D3D11_FORMAT_SUPPORT_DISPLAY, formats);
} else {
constexpr DXGI_FORMAT formats[] = {
// DXGI_FORMAT_R16G16B16A16_FLOAT,
// DXGI_FORMAT_R10G10B10A2_UNORM,
DXGI_FORMAT_R8G8B8A8_UNORM,
};

// Select back-buffer format
return SelectFormat(D3D11_FORMAT_SUPPORT_DISPLAY, formats);
}
}

bool CHW::ThisInstanceIsGlobal() const
{
return this == &HW;
Expand Down Expand Up @@ -438,6 +450,7 @@ void CHW::Reset()
DXGI_MODE_DESC& desc = m_ChainDesc.BufferDesc;
desc.Width = Device.dwWidth;
desc.Height = Device.dwHeight;
desc.Format = selectBackBufferFormat();

CHK_DX(m_pSwapChain->ResizeTarget(&desc));
CHK_DX(m_pSwapChain->ResizeBuffers(
Expand Down
1 change: 1 addition & 0 deletions src/Layers/xrRenderDX11/dx11HW.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ class CHW
XRay::Module hD3DCompiler;
XRay::Module hDXGI;
XRay::Module hD3D;
DXGI_FORMAT selectBackBufferFormat() const;
};

extern ECORE_API CHW HW;
21 changes: 20 additions & 1 deletion src/Layers/xrRenderDX11/dx11Texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,21 @@ ID3DBaseTexture* CRender::texture_load(LPCSTR fRName, u32& ret_msize)
string_path fname;
xr_strcpy(fname, fRName); //. andy if (strext(fname)) *strext(fname)=0;
fix_texture_name(fname);

bool force_srgb =
o.linear_space_rendering
&& !strstr(fname, "_bump")
&& !strstr(fname, "_mask")
&& !strstr(fname, "_dudv")
&& !strstr(fname, "water_normal")
&& !strstr(fname, "internal_")

&& !strstr(fname, "_lm.") // terrain lightmaps (level/*/terrain/)
&& !strstr(fname, "level_lods_nm") // level lods normal map (level/*/)
&& !strstr(fname, "lmap#") // level light maps (level/*/)

&& !strstr(fname, "ui_magnifier2");

IReader* S = NULL;
if (!FS.exist(fn, "$game_textures$", fname, ".dds") && strstr(fname, "_bump"))
goto _BUMP_from_base;
Expand Down Expand Up @@ -346,9 +361,13 @@ ID3DBaseTexture* CRender::texture_load(LPCSTR fRName, u32& ret_msize)
}

R_CHK2(CreateTextureEx(HW.pDevice, texture.GetImages() + mip_lod, texture.GetImageCount(), IMG,
D3D_USAGE_IMMUTABLE, D3D_BIND_SHADER_RESOURCE, 0, IMG.miscFlags, DirectX::CREATETEX_DEFAULT,
D3D_USAGE_IMMUTABLE, D3D_BIND_SHADER_RESOURCE, 0, IMG.miscFlags, force_srgb ? DirectX::CREATETEX_FORCE_SRGB : DirectX::CREATETEX_DEFAULT,
&pTexture2D), fn
);
/*R_CHK2(DirectX::CreateDDSTextureFromMemoryEx(HW.pDevice, reinterpret_cast<uint8_t*>(S->pointer()), S->length(), 0, D3D_USAGE_IMMUTABLE, D3D_BIND_SHADER_RESOURCE, 0, 0,
force_srgb ? DirectX::DDS_LOADER_FORCE_SRGB : DirectX::DDS_LOADER_DEFAULT, &pTexture2D, nullptr),
fn);*/

FS.r_close(S);

// OK
Expand Down
1 change: 1 addition & 0 deletions src/Layers/xrRenderDX11/dx11TextureUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ TextureFormatPairs TextureFormatList[] = {
// D3DFMT_X4R4G4B4 Not available
{D3DFMT_A2B10G10R10, DXGI_FORMAT_R10G10B10A2_UNORM},
{D3DFMT_A8B8G8R8, DXGI_FORMAT_R8G8B8A8_UNORM}, // & DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
{D3DFMT_HACK_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB},
// D3DFMT_X8B8G8R8 Not available
{D3DFMT_G16R16, DXGI_FORMAT_R16G16_UNORM},
// D3DFMT_A2R10G10B10 Not available
Expand Down
11 changes: 11 additions & 0 deletions src/Layers/xrRenderPC_R4/r4_rendertarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,8 @@ class CRenderTarget : public IRender_Target

void DoAsyncScreenshot();



#ifdef DEBUG
void dbg_addline(const Fvector& P0, const Fvector& P1, u32 c)
{
Expand Down Expand Up @@ -407,4 +409,13 @@ class CRenderTarget : public IRender_Target
void dbg_addline(Fvector& /*P0*/, Fvector& /*P1*/, u32 /*c*/) {}
void dbg_addplane(Fplane& /*P0*/, u32 /*c*/) {}
#endif
private:
float toLinearSpace(float c) {
return RImplementation.o.linear_space_rendering ? std::pow(c, 2.2f) : c;
}

Fvector4 toLinearSpace(const Fvector4& c)
{
return Fvector4{toLinearSpace(c.x), toLinearSpace(c.y), toLinearSpace(c.z), c.w};
}
};
4 changes: 2 additions & 2 deletions src/Layers/xrRenderPC_R4/r4_rendertarget_phase_combine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,8 @@ void CRenderTarget::phase_combine()
RCache.set_c("Ldynamic_color", sunclr);
RCache.set_c("Ldynamic_dir", sundir);

RCache.set_c("env_color", envclr);
RCache.set_c("fog_color", fogclr);
RCache.set_c("env_color", toLinearSpace(envclr));
RCache.set_c("fog_color", toLinearSpace(fogclr));

RCache.set_c("ssao_noise_tile_factor", fSSAONoise);
RCache.set_c("ssao_kernel_size", fSSAOKernelSize);
Expand Down
4 changes: 4 additions & 0 deletions src/Layers/xrRenderPC_R4/r4_shaders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,10 @@ HRESULT CRender::shader_compile(pcstr name, IReader* fs, pcstr pFunctionName,
// Minmax SM
appendShaderOption(o.minmax_sm, "USE_MINMAX_SM", "1");

// Linear space rendering if 1, or gamma space if 0
appendShaderOption(o.linear_space_rendering, "LINEAR_SPACE_RENDERING", "1");


// Ascii's Screen Space Shaders - SSS preprocessor stuff
if (ps_ssfx_rain_1.w > 0)
{
Expand Down
1 change: 1 addition & 0 deletions src/Layers/xrRender_R2/r2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,7 @@ void CRender::create()
o.tessellation =
HW.FeatureLevel >= D3D_FEATURE_LEVEL_11_0 && ps_r2_ls_flags_ext.test(R2FLAGEXT_ENABLE_TESSELLATION);
o.support_rt_arrays = true;
o.linear_space_rendering = (ps_r3_rendering_space == 1);
#else
o.support_rt_arrays = false;
#endif
Expand Down
2 changes: 2 additions & 0 deletions src/Layers/xrRender_R2/r2.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,8 @@ class CRender final : public D3DXRenderBase

// Yohji - New shader support
u32 new_shader_support : 1;

u32 linear_space_rendering : 1;
} o;

struct RenderR2Statistics
Expand Down
16 changes: 9 additions & 7 deletions src/Layers/xrRender_R2/r2_rendertarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ CRenderTarget::CRenderTarget()
const u32 SampleCount = options.msaa ? options.msaa_samples : 1u;
const u32 BoundSamples = options.msaa_opt ? 1u : options.msaa_samples;

const D3DFORMAT mainColorFormat = options.linear_space_rendering ? D3DFMT_HACK_R8G8B8A8_UNORM_SRGB : D3DFMT_A8R8G8B8;

#ifdef DEBUG
Msg("MSAA samples = %d", SampleCount);
if (options.msaa_opt)
Expand Down Expand Up @@ -327,7 +329,7 @@ CRenderTarget::CRenderTarget()
if (options.mrtmixdepth)
{
// NV50
rt_Color.create(r2_RT_albedo, w, h, D3DFMT_A8R8G8B8, SampleCount);
rt_Color.create(r2_RT_albedo, w, h, mainColorFormat, SampleCount);
rt_Accumulator.create(r2_RT_accum, w, h, D3DFMT_A16B16G16R16F, SampleCount);
}
else
Expand Down Expand Up @@ -358,10 +360,10 @@ CRenderTarget::CRenderTarget()
}

// generic(LDR) RTs
rt_Generic_0.create(r2_RT_generic0, w, h, D3DFMT_A8R8G8B8, 1);
rt_Generic_1.create(r2_RT_generic1, w, h, D3DFMT_A8R8G8B8, 1);
rt_Generic_0.create(r2_RT_generic0, w, h, mainColorFormat, 1);
rt_Generic_1.create(r2_RT_generic1, w, h, mainColorFormat, 1);
#if defined(USE_DX11) || defined(USE_OGL)
rt_Generic.create(r2_RT_generic, w, h, D3DFMT_A8R8G8B8, 1);
rt_Generic.create(r2_RT_generic, w, h, mainColorFormat, 1);
#endif
if (!options.msaa)
{
Expand All @@ -370,8 +372,8 @@ CRenderTarget::CRenderTarget()
}
else
{
rt_Generic_0_r.create(r2_RT_generic0_r, w, h, D3DFMT_A8R8G8B8, SampleCount);
rt_Generic_1_r.create(r2_RT_generic1_r, w, h, D3DFMT_A8R8G8B8, SampleCount);
rt_Generic_0_r.create(r2_RT_generic0_r, w, h, mainColorFormat, SampleCount);
rt_Generic_1_r.create(r2_RT_generic1_r, w, h, mainColorFormat, SampleCount);
}
// Igor: for volumetric lights
// rt_Generic_2.create (r2_RT_generic2,w,h,D3DFMT_A8R8G8B8 );
Expand Down Expand Up @@ -631,7 +633,7 @@ CRenderTarget::CRenderTarget()

// BLOOM
{
D3DFORMAT fmt = D3DFMT_A8R8G8B8; // D3DFMT_X8R8G8B8;
D3DFORMAT fmt = mainColorFormat;
u32 w = BLOOM_size_X, h = BLOOM_size_Y;
constexpr u32 fvf_build = D3DFVF_XYZRHW | D3DFVF_TEX4 | D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEXCOORDSIZE2(1) |
D3DFVF_TEXCOORDSIZE2(2) | D3DFVF_TEXCOORDSIZE2(3);
Expand Down
2 changes: 2 additions & 0 deletions src/Layers/xrRender_R2/r2_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,5 @@ IC float u_diffuse2s(Fvector3& c)
{
return u_diffuse2s(c.x, c.y, c.z);
}

#define D3DFMT_HACK_R8G8B8A8_UNORM_SRGB ((D3DFORMAT)666)
Loading