Skip to content
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)