1// Copyright (c) 2023 Qualcomm Technologies, Inc.
2//
3// SPDX-License-Identifier: CC-BY-4.0
4
5include::{generated}/meta/{refprefix}VK_QCOM_image_processing2.adoc[]
6
7=== Other Extension Metadata
8
9*Last Modified Date*::
10    2023-03-10
11*Interactions and External Dependencies*::
12  - This extension requires
13    {spirv}/QCOM/SPV_QCOM_image_processing2.html[`SPV_QCOM_image_processing2`]
14  - This extension provides API support for
15    {GLSLregistry}/qcom/GLSL_QCOM_image_processing2.txt[`GL_QCOM_image_processing2`]
16
17*Contributors*::
18  - Jeff Leger, Qualcomm Technologies, Inc.
19
20=== Description
21
22This extension enables support for the SPIR-V code:TextureBlockMatch2QCOM
23capability.
24It builds on the functionality of QCOM_image_processing with the addition of
254 new image processing operations.
26
27  * The code:opImageBlockMatchWindowSADQCOM` SPIR-V instruction builds upon
28    the functionality of code:opImageBlockMatchSADQCOM` by repeatedly
29    performing block match operations across a 2D window.
30    The "`2D windowExtent`" and "`compareMode`" are are specified by
31    slink:VkSamplerBlockMatchWindowCreateInfoQCOM in the sampler used to
32    create the _target image_.
33    Like code:OpImageBlockMatchSADQCOM, code:opImageBlockMatchWindowSADQCOM
34    computes an error metric, that describes whether a block of texels in
35    the _target image_ matches a corresponding block of texels in the
36    _reference image_.
37    Unlike code:OpImageBlockMatchSADQCOM, this instruction computes an error
38    metric at each (X,Y) location within the 2D window and returns either
39    the minimum or maximum error.
40    The instruction only supports single-component formats.
41    Refer to the pseudocode below for details.
42  * The code:opImageBlockMatchWindowSSDQCOM follows the same pattern,
43    computing the SSD error metric at each location within the 2D window.
44  * The code:opImageBlockMatchGatherSADQCOM builds upon
45    code:OpImageBlockMatchSADQCOM.
46    This instruction computes an error metric, that describes whether a
47    block of texels in the _target image_ matches a corresponding block of
48    texels in the _reference image_.
49    The instruction computes the SAD error metric at 4 texel offsets and
50    returns the error metric for each offset in the X,Y,Z,and W components.
51    The instruction only supports single-component texture formats.
52    Refer to the pseudocode below for details.
53  * The code:opImageBlockMatchGatherSSDQCOM follows the same pattern,
54    computing the SSD error metric for 4 offsets.
55
56Each of the above 4 image processing instructions are limited to
57single-component formats.
58
59Below is the pseudocode for GLSL built-in function
60code:textureWindowBlockMatchSADQCOM.
61The pseudocode for code:textureWindowBlockMatchSSD is identical other than
62replacing all instances of `"SAD"` with `"SSD"`.
63
64[source,c]
65----
66vec4 textureBlockMatchWindowSAD( sampler2D target,
67                                 uvec2 targetCoord,
68                                 samler2D reference,
69                                 uvec2 refCoord,
70                                 uvec2 blocksize) {
71    // compareMode (MIN or MAX) comes from the vkSampler associated with `target`
72    // uvec2 window  comes from the vkSampler associated with `target`
73    minSAD = INF;
74    maxSAD = -INF;
75    uvec2 minCoord;
76    uvec2 maxCoord;
77
78    for (uint x=0, x < window.width; x++) {
79        for (uint y=0; y < window.height; y++) {
80            float SAD = textureBlockMatchSAD(target,
81                                            targetCoord + uvec2(x, y),
82                                            reference,
83                                            refCoord,
84                                            blocksize).x;
85            // Note: the below comparison operator will produce undefined results
86            // if SAD is a denorm value.
87            if (SAD < minSAD) {
88                minSAD = SAD;
89                minCoord = uvec2(x,y);
90            }
91            if (SAD > maxSAD) {
92                maxSAD = SAD;
93                maxCoord = uvec2(x,y);
94            }
95        }
96    }
97    if (compareMode=MIN) {
98        return vec4(minSAD, minCoord.x, minCoord.y, 0.0);
99    } else {
100        return vec4(maxSAD, maxCoord.x, maxCoord.y, 0.0);
101    }
102}
103----
104
105Below is the pseudocode for code:textureBlockMatchGatherSADQCOM.
106The pseudocode for code:textureBlockMatchGatherSSD follows an identical
107pattern.
108
109[source,c]
110----
111vec4 textureBlockMatchGatherSAD( sampler2D target,
112                                 uvec2 targetCoord,
113                                 samler2D reference,
114                                 uvec2 refCoord,
115                                 uvec2 blocksize) {
116    vec4 out;
117    for (uint x=0, x<4; x++) {
118            float SAD = textureBlockMatchSAD(target,
119                                            targetCoord + uvec2(x, 0),
120                                            reference,
121                                            refCoord,
122                                            blocksize).x;
123            out[x] = SAD;
124    }
125    return out;
126}
127----
128
129include::{generated}/interfaces/VK_QCOM_image_processing2.adoc[]
130
131=== Issues
132
1331) What is the precision of the min/max comparison checks?
134
135*RESOLVED*: Intermediate computations for the new operations are performed
136at 16-bit floating point precision.
137If the value of `"float SAD"` in the above code sample is a 16-bit denorm
138value, then behavior of the MIN/MAX comparison is undefined.
139
140=== Version History
141
142  * Revision 1, 2023-03-10 (Jeff Leger)
143