summaryrefslogtreecommitdiff
path: root/tools/gfx-unit-test/gfx-test-util.h
blob: 3be47bc8241fa1b792f36214de38a8eac594d22b (plain)
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
#pragma once

#include "slang-gfx.h"
#include "source/core/slang-basic.h"
#include "source/core/slang-render-api-util.h"
#include "tools/unit-test/slang-unit-test.h"

namespace gfx_test
{
        /// Helper function for print out diagnostic messages output by Slang compiler.
    void diagnoseIfNeeded(ISlangWriter* diagnosticWriter, slang::IBlob* diagnosticsBlob);

        /// Loads a compute shader module and produces a `gfx::IShaderProgram`.
    Slang::Result loadComputeProgram(
        gfx::IDevice* device,
        Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
        const char* shaderModuleName,
        const char* entryPointName,
        slang::ProgramLayout*& slangReflection);

    Slang::Result loadGraphicsProgram(
        gfx::IDevice* device,
        Slang::ComPtr<gfx::IShaderProgram>& outShaderProgram,
        const char* shaderModuleName,
        const char* vertexEntryPointName,
        const char* fragmentEntryPointName,
        slang::ProgramLayout*& slangReflection);

        /// Reads back the content of `buffer` and compares it against `expectedResult`.
    void compareComputeResult(
        gfx::IDevice* device,
        gfx::IBufferResource* buffer,
        size_t offset,
        const void* expectedResult,
        size_t expectedBufferSize);

    /// Reads back the content of `buffer` and compares it against `expectedResult`.
    void compareComputeResult(
        gfx::IDevice* device,
        gfx::ITextureResource* texture,
        gfx::ResourceState state,
        void* expectedResult,
        size_t expectedResultRowPitch,
        size_t rowCount);

    void compareComputeResultFuzzy(
        const float* result,
        float* expectedResult,
        size_t expectedBufferSize);

        /// Reads back the content of `buffer` and compares it against `expectedResult` with a set tolerance.
    void compareComputeResultFuzzy(
        gfx::IDevice* device,
        gfx::IBufferResource* buffer,
        float* expectedResult,
        size_t expectedBufferSize);

    template<typename T, Slang::Index count>
    void compareComputeResult(
        gfx::IDevice* device,
        gfx::IBufferResource* buffer,
        Slang::Array<T, count> expectedResult)
    {
        Slang::List<uint8_t> expectedBuffer;
        size_t bufferSize = sizeof(T) * count;
        expectedBuffer.setCount(bufferSize);
        memcpy(expectedBuffer.getBuffer(), expectedResult.begin(), bufferSize);
        if (std::is_same<T, float>::value) return compareComputeResultFuzzy(device, buffer, (float*)expectedBuffer.getBuffer(), bufferSize);
        return compareComputeResult(device, buffer, 0, expectedBuffer.getBuffer(), bufferSize);
    }
    
    Slang::ComPtr<gfx::IDevice> createTestingDevice(UnitTestContext* context, Slang::RenderApiFlag::Enum api);

    void initializeRenderDoc();
    void renderDocBeginFrame();
    void renderDocEndFrame();

    template<typename ImplFunc>
    void runTestImpl(const ImplFunc& f, UnitTestContext* context, Slang::RenderApiFlag::Enum api)
    {
        if ((api & context->enabledApis) == 0)
        {
            SLANG_IGNORE_TEST
        }
        auto device = createTestingDevice(context, api);
        if (!device)
        {
            SLANG_IGNORE_TEST
        }
        try
        {
            renderDocBeginFrame();
            f(device, context);
        }
        catch (AbortTestException& e)
        {
            renderDocEndFrame();
            throw e;
        }
        renderDocEndFrame();
    }

#define GFX_CHECK_CALL(x) SLANG_CHECK(!SLANG_FAILED(x))
#define GFX_CHECK_CALL_ABORT(x) SLANG_CHECK_ABORT(!SLANG_FAILED(x))

}