summaryrefslogtreecommitdiff
path: root/appendices/VK_QCOM_image_processing2.adoc
blob: e23beaf4e7d643b83c036ff3c96021e2624db67d (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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright (c) 2023 Qualcomm Technologies, Inc.
//
// SPDX-License-Identifier: CC-BY-4.0

include::{generated}/meta/{refprefix}VK_QCOM_image_processing2.adoc[]

=== Other Extension Metadata

*Last Modified Date*::
    2023-03-10
*Interactions and External Dependencies*::
  - This extension requires
    {spirv}/QCOM/SPV_QCOM_image_processing2.html[`SPV_QCOM_image_processing2`]
  - This extension provides API support for
    {GLSLregistry}/qcom/GLSL_QCOM_image_processing2.txt[`GL_QCOM_image_processing2`]

*Contributors*::
  - Jeff Leger, Qualcomm Technologies, Inc.

=== Description

This extension enables support for the SPIR-V code:TextureBlockMatch2QCOM
capability.
It builds on the functionality of QCOM_image_processing with the addition of
4 new image processing operations.

  * The code:opImageBlockMatchWindowSADQCOM` SPIR-V instruction builds upon
    the functionality of code:opImageBlockMatchSADQCOM` by repeatedly
    performing block match operations across a 2D window.
    The "`2D windowExtent`" and "`compareMode`" are are specified by
    slink:VkSamplerBlockMatchWindowCreateInfoQCOM in the sampler used to
    create the _target image_.
    Like code:OpImageBlockMatchSADQCOM, code:opImageBlockMatchWindowSADQCOM
    computes an error metric, that describes whether a block of texels in
    the _target image_ matches a corresponding block of texels in the
    _reference image_.
    Unlike code:OpImageBlockMatchSADQCOM, this instruction computes an error
    metric at each (X,Y) location within the 2D window and returns either
    the minimum or maximum error.
    The instruction only supports single-component formats.
    Refer to the pseudocode below for details.
  * The code:opImageBlockMatchWindowSSDQCOM follows the same pattern,
    computing the SSD error metric at each location within the 2D window.
  * The code:opImageBlockMatchGatherSADQCOM builds upon
    code:OpImageBlockMatchSADQCOM.
    This instruction computes an error metric, that describes whether a
    block of texels in the _target image_ matches a corresponding block of
    texels in the _reference image_.
    The instruction computes the SAD error metric at 4 texel offsets and
    returns the error metric for each offset in the X,Y,Z,and W components.
    The instruction only supports single-component texture formats.
    Refer to the pseudocode below for details.
  * The code:opImageBlockMatchGatherSSDQCOM follows the same pattern,
    computing the SSD error metric for 4 offsets.

Each of the above 4 image processing instructions are limited to
single-component formats.

Below is the pseudocode for GLSL built-in function
code:textureWindowBlockMatchSADQCOM.
The pseudocode for code:textureWindowBlockMatchSSD is identical other than
replacing all instances of `"SAD"` with `"SSD"`.

[source,c]
----
vec4 textureBlockMatchWindowSAD( sampler2D target,
                                 uvec2 targetCoord,
                                 samler2D reference,
                                 uvec2 refCoord,
                                 uvec2 blocksize) {
    // compareMode (MIN or MAX) comes from the vkSampler associated with `target`
    // uvec2 window  comes from the vkSampler associated with `target`
    minSAD = INF;
    maxSAD = -INF;
    uvec2 minCoord;
    uvec2 maxCoord;

    for (uint x=0, x < window.width; x++) {
        for (uint y=0; y < window.height; y++) {
            float SAD = textureBlockMatchSAD(target,
                                            targetCoord + uvec2(x, y),
                                            reference,
                                            refCoord,
                                            blocksize).x;
            // Note: the below comparison operator will produce undefined results
            // if SAD is a denorm value.
            if (SAD < minSAD) {
                minSAD = SAD;
                minCoord = uvec2(x,y);
            }
            if (SAD > maxSAD) {
                maxSAD = SAD;
                maxCoord = uvec2(x,y);
            }
        }
    }
    if (compareMode=MIN) {
        return vec4(minSAD, minCoord.x, minCoord.y, 0.0);
    } else {
        return vec4(maxSAD, maxCoord.x, maxCoord.y, 0.0);
    }
}
----

Below is the pseudocode for code:textureBlockMatchGatherSADQCOM.
The pseudocode for code:textureBlockMatchGatherSSD follows an identical
pattern.

[source,c]
----
vec4 textureBlockMatchGatherSAD( sampler2D target,
                                 uvec2 targetCoord,
                                 samler2D reference,
                                 uvec2 refCoord,
                                 uvec2 blocksize) {
    vec4 out;
    for (uint x=0, x<4; x++) {
            float SAD = textureBlockMatchSAD(target,
                                            targetCoord + uvec2(x, 0),
                                            reference,
                                            refCoord,
                                            blocksize).x;
            out[x] = SAD;
    }
    return out;
}
----

include::{generated}/interfaces/VK_QCOM_image_processing2.adoc[]

=== Issues

1) What is the precision of the min/max comparison checks?

*RESOLVED*: Intermediate computations for the new operations are performed
at 16-bit floating point precision.
If the value of `"float SAD"` in the above code sample is a 16-bit denorm
value, then behavior of the MIN/MAX comparison is undefined.

=== Version History

  * Revision 1, 2023-03-10 (Jeff Leger)