aboutsummaryrefslogtreecommitdiff
path: root/src/InputViewport.h
blob: 9bbdf2c98c1c654bb6c204f86731f35b51cae6a0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/* 
* Copyright (c) 2008-2018, NVIDIA CORPORATION. All rights reserved. 
* 
* NVIDIA CORPORATION and its licensors retain all intellectual property 
* and proprietary rights in and to this software, related documentation 
* and any modifications thereto. Any use, reproduction, disclosure or 
* distribution of this software and related documentation without an express 
* license agreement from NVIDIA CORPORATION is strictly prohibited. 
*/

#pragma once
#include "Common.h"
#include "UserTexture.h"

namespace GFSDK
{
namespace SSAO
{

#if !SUPPORT_D3D11
struct D3D11_VIEWPORT
{
    FLOAT TopLeftX;
    FLOAT TopLeftY;
    FLOAT Width;
    FLOAT Height;
    FLOAT MinDepth;
    FLOAT MaxDepth;
};
#endif

#if SUPPORT_D3D12
struct InputViewport : public D3D12_VIEWPORT
#else
struct InputViewport : public D3D11_VIEWPORT
#endif
{
    InputViewport()
    {
        ZERO_STRUCT(*this);
    }

    static bool HasValidDimensions(const GFSDK_SSAO_InputViewport& V)
    {
        return (V.Width != 0 && V.Height != 0);
    }

    static bool HasValidDepthRange(const GFSDK_SSAO_InputViewport& V)
    {
        // According to the DX11 spec:
        // Viewport MinDepth and MaxDepth must both be in the range [0.0f...1.0f], and MinDepth must be less-than or equal-to MaxDepth.
        // Viewport parameters are validated in the runtime such that values outside these ranges will never be passed to the DDI.
        return (V.MinDepth >= 0.f && V.MinDepth <= 1.f &&
                V.MaxDepth >= 0.f && V.MaxDepth <= 1.f &&
                V.MinDepth <= V.MaxDepth);
    }

    static bool CoversFullTexture(const GFSDK_SSAO_InputViewport& V, const SSAO::UserTextureDesc& Texture)
    {
        return (V.TopLeftX == 0.f &&
                V.TopLeftY == 0.f &&
                V.Width  == (FLOAT)Texture.Width &&
                V.Height == (FLOAT)Texture.Height);
    }

    GFSDK_SSAO_Status Init(const GFSDK_SSAO_InputViewport& Viewport, const SSAO::UserTextureDesc& Texture)
    {
        if (!Viewport.Enable)
        {
            return InitFromTexture(Texture);
        }

        return InitFromViewport(Viewport, Texture);
    }

    bool RectCoversFullInputTexture;

private:
    GFSDK_SSAO_Status InitFromTexture(const SSAO::UserTextureDesc& Texture)
    {
        TopLeftX   = 0.f;
        TopLeftY   = 0.f;
        Width      = FLOAT(Texture.Width);
        Height     = FLOAT(Texture.Height);
        MinDepth   = 0.f;
        MaxDepth   = 1.f;
        RectCoversFullInputTexture = true;

        return GFSDK_SSAO_OK;
    }

    GFSDK_SSAO_Status InitFromViewport(const GFSDK_SSAO_InputViewport& Viewport, const SSAO::UserTextureDesc& Texture)
    {
        if (!HasValidDimensions(Viewport))
        {
            return GFSDK_SSAO_INVALID_VIEWPORT_DIMENSIONS;
        }

        if (!HasValidDepthRange(Viewport))
        {
            return GFSDK_SSAO_INVALID_VIEWPORT_DEPTH_RANGE;
        }

        TopLeftX = (FLOAT)Viewport.TopLeftX;
        TopLeftY = (FLOAT)Viewport.TopLeftY;
        Width    = (FLOAT)Viewport.Width;
        Height   = (FLOAT)Viewport.Height;
        MinDepth = Viewport.MinDepth;
        MaxDepth = Viewport.MaxDepth;

        Width  = Min(Width,  FLOAT(Texture.Width)  - TopLeftX);
        Height = Min(Height, FLOAT(Texture.Height) - TopLeftY);

        RectCoversFullInputTexture = CoversFullTexture(Viewport, Texture);

        return GFSDK_SSAO_OK;
    }
};

} // namespace SSAO
} // namespace GFSDK