feat: gamma functionality on windows64
This commit is contained in:
@@ -99,6 +99,7 @@ Renderer::Context::Context(ID3D11Device* device, ID3D11DeviceContext* deviceCont
|
||||
, m_alphaTestBuffer(NULL)
|
||||
, m_clearColorBuffer(NULL)
|
||||
, m_forcedLODBuffer(NULL)
|
||||
, m_gammaRenderBuffer(NULL)
|
||||
, dynamicVertexBase(0)
|
||||
, dynamicVertexOffset(0)
|
||||
, dynamicVertexBuffer(NULL)
|
||||
@@ -226,6 +227,10 @@ Renderer::Context::Context(ID3D11Device* device, ID3D11DeviceContext* deviceCont
|
||||
device->CreateBuffer(&cbDesc, &cbData, &m_clearColorBuffer);
|
||||
device->CreateBuffer(&cbDesc, &cbData, &m_forcedLODBuffer);
|
||||
|
||||
cbDesc.ByteWidth = sizeof(zero4);
|
||||
cbData.pSysMem = zero4;
|
||||
device->CreateBuffer(&cbDesc, &cbData, &m_gammaRenderBuffer);
|
||||
|
||||
deviceContext->VSSetConstantBuffers(0, 10, &m_modelViewMatrix);
|
||||
deviceContext->PSSetConstantBuffers(0, 6, &m_tintColorBuffer);
|
||||
|
||||
@@ -411,7 +416,6 @@ void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut)
|
||||
|
||||
c.m_pDeviceContext->VSSetShader(screenSpaceVertexShader, NULL, 0);
|
||||
c.m_pDeviceContext->IASetInputLayout(NULL);
|
||||
c.m_pDeviceContext->PSSetShader(screenSpacePixelShader, NULL, 0);
|
||||
c.m_pDeviceContext->OMSetBlendState(blendState, NULL, -1);
|
||||
c.m_pDeviceContext->OMSetDepthStencilState(depthState, 0);
|
||||
c.m_pDeviceContext->RSSetState(rasterizerState);
|
||||
@@ -836,7 +840,26 @@ void Renderer::Initialise(ID3D11Device *pDevice, IDXGISwapChain *pSwapChain)
|
||||
m_pDevice->CreateBuffer(&fanIndexDesc, &fanIndexData, &fanIndexBuffer);
|
||||
delete[] fanIndices;
|
||||
|
||||
InitializeCriticalSection(&Renderer::totalAllocCS);
|
||||
D3D11_SAMPLER_DESC gammaSamplerDesc = {};
|
||||
gammaSamplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
gammaSamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
gammaSamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
gammaSamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
gammaSamplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
|
||||
m_pDevice->CreateSamplerState(&gammaSamplerDesc, &m_gammaSamplerState);
|
||||
|
||||
const float fullscreenBounds[4] = { 0.0f, 0.0f, 2.0f, 2.0f };
|
||||
D3D11_BUFFER_DESC boundsDesc = {};
|
||||
boundsDesc.ByteWidth = sizeof(fullscreenBounds);
|
||||
boundsDesc.Usage = D3D11_USAGE_IMMUTABLE;
|
||||
boundsDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||
D3D11_SUBRESOURCE_DATA boundsData = { fullscreenBounds };
|
||||
m_pDevice->CreateBuffer(&boundsDesc, &boundsData, &m_gammaFullscreenBoundsBuffer);
|
||||
|
||||
m_usPreviousGamma = 0xFFFF;
|
||||
m_usGamma = 1.0f;
|
||||
|
||||
InitializeCriticalSection(&Renderer::totalAllocCS);
|
||||
}
|
||||
|
||||
ID3D11DeviceContext *Renderer::InitialiseContext(bool fromPresent)
|
||||
@@ -877,6 +900,70 @@ bool Renderer::IsWidescreen()
|
||||
return (aspectRatio >= 1.56f);
|
||||
}
|
||||
|
||||
// PIEBOT: Inspired by CaptureThumbnail
|
||||
void Renderer::SetGamma(float gamma)
|
||||
{
|
||||
Renderer::Context &c = getContext();
|
||||
|
||||
// @Patoke fix: bind render target to a proper backbuffer texture
|
||||
ID3D11Resource *actualBackBuffer = NULL;
|
||||
mainRenderTargetView->GetResource(&actualBackBuffer);
|
||||
|
||||
// copy the backbuffer contents
|
||||
c.m_pDeviceContext->CopyResource(m_backBufferTexture, actualBackBuffer);
|
||||
actualBackBuffer->Release();
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mapped = {};
|
||||
if (SUCCEEDED(c.m_pDeviceContext->Map(c.m_gammaRenderBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped)))
|
||||
{
|
||||
*reinterpret_cast<DirectX::XMFLOAT4 *>(mapped.pData) = DirectX::XMFLOAT4(gamma, 0.0f, 0.0f, 0.0f);
|
||||
c.m_pDeviceContext->Unmap(c.m_gammaRenderBuffer, 0);
|
||||
}
|
||||
|
||||
ID3D11BlendState *blendState = NULL;
|
||||
ID3D11RasterizerState *rasterizerState = NULL;
|
||||
|
||||
D3D11_BLEND_DESC blendDesc = {};
|
||||
blendDesc.RenderTarget[0].BlendEnable = false;
|
||||
blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
|
||||
blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO;
|
||||
blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
|
||||
blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
|
||||
blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
|
||||
blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
||||
blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
|
||||
m_pDevice->CreateBlendState(&blendDesc, &blendState);
|
||||
|
||||
D3D11_RASTERIZER_DESC rasterDesc = {};
|
||||
rasterDesc.FillMode = D3D11_FILL_SOLID;
|
||||
rasterDesc.CullMode = D3D11_CULL_NONE;
|
||||
rasterDesc.DepthClipEnable = true;
|
||||
rasterDesc.MultisampleEnable = true;
|
||||
m_pDevice->CreateRasterizerState(&rasterDesc, &rasterizerState);
|
||||
|
||||
c.m_pDeviceContext->VSSetShader(screenSpaceVertexShader, NULL, 0);
|
||||
c.m_pDeviceContext->PSSetShader(screenGammaPixelShader, NULL, 0);
|
||||
c.m_pDeviceContext->IASetInputLayout(NULL);
|
||||
c.m_pDeviceContext->IASetVertexBuffers(0, 0, NULL, NULL, NULL);
|
||||
c.m_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
c.m_pDeviceContext->OMSetBlendState(blendState, NULL, 0xFFFFFFFF);
|
||||
c.m_pDeviceContext->RSSetState(rasterizerState);
|
||||
|
||||
blendState->Release();
|
||||
rasterizerState->Release();
|
||||
|
||||
D3D11_VIEWPORT viewport = { 0.0f, 0.0f, (float)backBufferWidth, (float)backBufferHeight, 0.0f, 1.0f };
|
||||
c.m_pDeviceContext->OMSetRenderTargets(1, &mainRenderTargetView, NULL);
|
||||
c.m_pDeviceContext->RSSetViewports(1, &viewport);
|
||||
|
||||
c.m_pDeviceContext->PSSetShaderResources(0, 1, &mainShaderResourceView);
|
||||
c.m_pDeviceContext->PSSetSamplers(0, 1, &m_gammaSamplerState);
|
||||
c.m_pDeviceContext->VSSetConstantBuffers(9, 1, &m_gammaFullscreenBoundsBuffer);
|
||||
c.m_pDeviceContext->PSSetConstantBuffers(6, 1, &c.m_gammaRenderBuffer);
|
||||
|
||||
c.m_pDeviceContext->Draw(4, 0);
|
||||
}
|
||||
|
||||
void Renderer::Present()
|
||||
{
|
||||
PROFILER_SCOPE("Renderer::Present", "Present", MP_MAGENTA);
|
||||
@@ -948,6 +1035,8 @@ void Renderer::Present()
|
||||
m_bShouldScreenGrabNextFrame = false;
|
||||
}
|
||||
|
||||
SetGamma(m_usGamma);
|
||||
|
||||
m_pSwapChain->Present(C4JRender::GetVSync(), 0);
|
||||
++presentCount;
|
||||
}
|
||||
@@ -993,6 +1082,7 @@ void Renderer::SetupShaders()
|
||||
m_pDevice->CreatePixelShader(g_main_PS_ForceLOD, sizeof(g_main_PS_ForceLOD), NULL, &pixelShaderTable[C4JRender::PIXEL_SHADER_TYPE_FORCELOD]);
|
||||
m_pDevice->CreatePixelShader(g_main_PS_ScreenSpace, sizeof(g_main_PS_ScreenSpace), NULL, &screenSpacePixelShader);
|
||||
m_pDevice->CreatePixelShader(g_main_PS_ScreenClear, sizeof(g_main_PS_ScreenClear), NULL, &screenClearPixelShader);
|
||||
m_pDevice->CreatePixelShader(g_main_PS_ScreenGamma, sizeof(g_main_PS_ScreenGamma), NULL, &screenGammaPixelShader);
|
||||
|
||||
m_pDevice->CreateInputLayout(g_vertex_PTN_Elements_PF3_TF2_CB4_NB4_XW1, 5, g_main_VS_PF3_TF2_CB4_NB4_XW1, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1), &inputLayoutTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1]);
|
||||
m_pDevice->CreateInputLayout(g_vertex_PTN_Elements_Compressed, 2, g_main_VS_Compressed, sizeof(g_main_VS_Compressed), &inputLayoutTable[C4JRender::VERTEX_TYPE_COMPRESSED]);
|
||||
@@ -1053,7 +1143,15 @@ bool Renderer::Suspended()
|
||||
return m_bSuspended;
|
||||
}
|
||||
|
||||
void Renderer::UpdateGamma(unsigned short) {}
|
||||
void Renderer::UpdateGamma(unsigned short usGamma)
|
||||
{
|
||||
if (usGamma != m_usPreviousGamma)
|
||||
{
|
||||
m_usPreviousGamma = usGamma;
|
||||
|
||||
m_usGamma = 1.0f / (0.5f + (usGamma / 32768.0f) * 1.5f);
|
||||
}
|
||||
}
|
||||
|
||||
Renderer::Context &Renderer::getContext()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user