JamesCJ60 / Universal-x86-Tuning-Utility

Unlock the full potential of your Intel/AMD based device.
GNU General Public License v3.0
1.54k stars 38 forks source link

[FEATURE REQUEST] Interpolation frame for performance boost #73

Closed marcos32123 closed 1 year ago

marcos32123 commented 1 year ago

include

include

include

// Variáveis globais ID3D11Device g_pd3dDevice = nullptr; IDXGIOutputDuplication g_pDesktopDuplication = nullptr; IDXGIOutput1 g_pOutput = nullptr; ID3D11Texture2D g_pAcquiredDesktopImage = nullptr;

// Função para inicialização do DirectX e captura de tela bool InitializeDirectX() { // Criação do dispositivo DirectX 11 D3D_FEATURE_LEVEL featureLevel; HRESULT hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &g_pd3dDevice, &featureLevel, nullptr); if (FAILED(hr)) { std::cout << "Failed to create DirectX 11 device." << std::endl; return false; }

// Obtenção da saída primária
IDXGIFactory1* pFactory = nullptr;
hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory);
if (FAILED(hr))
{
    std::cout << "Failed to create DXGI factory." << std::endl;
    return false;
}

hr = pFactory->EnumAdapters1(0, &g_pOutput);
pFactory->Release();
if (FAILED(hr))
{
    std::cout << "Failed to get primary output." << std::endl;
    return false;
}

// Criação do objeto Desktop Duplication
IDXGIOutputDuplication* pDesktopDuplication = nullptr;
hr = g_pOutput->DuplicateOutput(g_pd3dDevice, &pDesktopDuplication);
if (FAILED(hr))
{
    std::cout << "Failed to create Desktop Duplication object." << std::endl;
    return false;
}

// QueryInterface para DXGIOutputDuplication 1.2
hr = pDesktopDuplication->QueryInterface(__uuidof(IDXGIOutputDuplication), (void**)&g_pDesktopDuplication);
pDesktopDuplication->Release();
if (FAILED(hr))
{
    std::cout << "Failed to get Desktop Duplication interface." << std::endl;
    return false;
}

return true;

}

// Função para capturar um quadro do jogo bool CaptureFrame(ID3D11Texture2D* pFrame) { DXGI_OUTDUPL_FRAME_INFO frameInfo; ID3D11Texture2D pAcquiredDesktopImage = nullptr;

// Captura do próximo quadro do jogo
HRESULT hr = g_pDesktopDuplication->AcquireNextFrame(500, &frameInfo, &pAcquiredDesktopImage);
if (hr == DXGI_ERROR_WAIT_TIMEOUT)
{
    // Não há alterações no quadro, continue com o quadro anterior
    return false;
}
else if (hr == DXGI_ERROR_ACCESS_LOST)
{
    // A captura foi perdida, reinicialize o dispositivo DirectX
    g_pDesktopDuplication->ReleaseFrame();
    g_pAcquiredDesktopImage->Release();
    g_pDesktopDuplication->Release();
    g_pOutput->Release();
    g_pd3dDevice->Release();
    InitializeDirectX();
    return false;
}
else if (FAILED(hr))
{
    std::cout << "Failed to acquire next frame." << std::endl;
    return false;
}

// Copia o quadro capturado para um novo objeto de textura
D3D11_TEXTURE2D_DESC desc;
pAcquiredDesktopImage->GetDesc(&desc);
hr = g_pd3dDevice->CreateTexture2D(&desc, nullptr, pFrame);
if (FAILED(hr))
{
    std::cout << "Failed to create texture for captured frame." << std::endl;
    return false;
}

ID3D11DeviceContext* pImmediateContext;
g_pd3dDevice->GetImmediateContext(&pImmediateContext);

pImmediateContext->CopyResource(*pFrame, pAcquiredDesktopImage);
g_pDesktopDuplication->ReleaseFrame();
pImmediateContext->Release();
pAcquiredDesktopImage->Release();

return true;

}

// Função para interpolar os quadros capturados void InterpolateFrames(ID3D11Texture2D pFrame1, ID3D11Texture2D pFrame2, ID3D11Texture2D** pInterpolatedFrame) { // Implemente a lógica de interpolação dos quadros capturados aqui // Você pode usar técnicas como interpolação bilinear ou bicúbica

// Exemplo de interpolação simples - média dos valores de pixel
ID3D11DeviceContext* pImmediateContext;
g_pd3dDevice->GetImmediateContext(&pImmediateContext);

pImmediateContext->CopyResource(*pInterpolatedFrame, pFrame1);
D3D11_MAPPED_SUBRESOURCE mappedResource1, mappedResource2, mappedResourceInterpolated;
pImmediateContext->Map(pFrame1, 0, D3D11_MAP_READ, 0, &mappedResource1);
pImmediateContext->Map(pFrame2, 0, D3D11_MAP_READ, 0, &mappedResource2);
pImmediateContext->Map(*pInterpolatedFrame, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResourceInterpolated);

// Itera sobre os pixels e realiza a interpolação
for (UINT y = 0; y < mappedResource1.RowPitch / 4; ++y)
{
    UINT* row1 = (UINT*)((BYTE*)mappedResource1.pData + y * mappedResource1.RowPitch);
    UINT* row2 = (UINT*)((BYTE*)mappedResource2.pData + y * mappedResource2.RowPitch);
    UINT* interpolatedRow = (UINT*)((BYTE*)mappedResourceInterpolated.pData + y * mappedResourceInterpolated.RowPitch);

    for (UINT x = 0; x < mappedResource1.RowPitch / 4; ++x)
    {
        UINT pixel1 = row1[x];
        UINT pixel2 = row2[x];

        // Interpolação simples - média dos valores de pixel
        UINT interpolatedPixel = (pixel1 + pixel2) / 2;

        interpolatedRow[x] = interpolatedPixel;
    }
}

pImmediateContext->Unmap(pFrame1, 0);
pImmediateContext->Unmap(pFrame2, 0);
pImmediateContext->Unmap(*pInterpolatedFrame, 0);
pImmediateContext->Release();

}

// Função para suavizar a exibição em tempo real void SmoothDisplay(ID3D11Texture2D* pInterpolatedFrame) { // Implemente a lógica de suavização da exibição em tempo real aqui // Você pode usar técnicas como filtro de média ou filtro gaussiano

// Exemplo de suavização simples - não faz nada
// Você pode substituir essa função pela implementação adequada

// Não faz nada

}

// Função principal int main() { if (!InitializeDirectX()) { std::cout << "Failed to initialize DirectX." << std::endl; return 1; }

ID3D11Texture2D* pFrame1 = nullptr;
ID3D11Texture2D* pFrame2 = nullptr;
ID3D11Texture2D* pInterpolatedFrame = nullptr;

while (true)
{
    if (CaptureFrame(&pFrame2))
    {
        if (pFrame1 != nullptr)
        {
            InterpolateFrames(pFrame1, pFrame2, &pInterpolatedFrame);
            SmoothDisplay(pInterpolatedFrame);
            // Exiba o quadro suavizado na tela

            pInterpolatedFrame->Release();
        }

        pFrame1 = pFrame2;
    }
}

// Libera recursos
pFrame1->Release();
g_pDesktopDuplication->Release();
g_pOutput->Release();
g_pd3dDevice->Release();

return 0;

}

JamesCJ60 commented 1 year ago

Hi, I have no intentions of adding frame generation to this application.