yes
This commit is contained in:
@@ -0,0 +1,193 @@
|
||||
#!amber
|
||||
# Copyright 2022 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
SHADER vertex vert_shader PASSTHROUGH
|
||||
|
||||
SHADER fragment frag_shader GLSL TARGET_ENV spv1.6
|
||||
#version 460
|
||||
#extension GL_EXT_demote_to_helper_invocation : require
|
||||
#extension GL_KHR_shader_subgroup_quad : require
|
||||
|
||||
layout(binding = 0) readonly buffer Block0
|
||||
{
|
||||
float alpha[];
|
||||
};
|
||||
|
||||
layout(binding = 1) buffer Block1
|
||||
{
|
||||
uint atomics[];
|
||||
};
|
||||
|
||||
layout(location = 0) out vec4 color;
|
||||
|
||||
float build_alpha_shuffle(float v)
|
||||
{
|
||||
v = (gl_HelperInvocation ? 8.0 : roundEven(v));
|
||||
vec4 helpers;
|
||||
helpers.x = subgroupQuadBroadcast(v, 0u);
|
||||
helpers.y = subgroupQuadBroadcast(v, 1u);
|
||||
helpers.z = subgroupQuadBroadcast(v, 2u);
|
||||
helpers.w = subgroupQuadBroadcast(v, 3u);
|
||||
|
||||
return dot(helpers, vec4(1, 10, 100, 1000));
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 coord = ivec2(gl_FragCoord.xy);
|
||||
int linear_coord = coord.y * 2 + coord.x;
|
||||
|
||||
float alpha_value = alpha[linear_coord];
|
||||
float mask0 = build_alpha_shuffle(alpha_value);
|
||||
|
||||
// Lane 1 and 2 should be nuked by this.
|
||||
if (fract(alpha_value) < 0.5)
|
||||
{
|
||||
demote;
|
||||
}
|
||||
|
||||
float mask1 = build_alpha_shuffle(alpha_value);
|
||||
uint last_value = 0u;
|
||||
|
||||
last_value = atomicAdd(atomics[linear_coord], 101u);
|
||||
|
||||
if (linear_coord == 3 || last_value > 1000)
|
||||
{
|
||||
demote;
|
||||
}
|
||||
|
||||
float mask2 = build_alpha_shuffle(alpha_value);
|
||||
|
||||
color = vec4(1.0, mask0, mask1, mask2);
|
||||
}
|
||||
END
|
||||
|
||||
SHADER compute comp_shader GLSL
|
||||
#version 460
|
||||
layout(local_size_x=1,local_size_y=1) in;
|
||||
uniform layout(set=0, binding=0, rgba32f) image2D resultImage;
|
||||
|
||||
layout(set = 0, binding = 1) buffer block0
|
||||
{
|
||||
vec4 results[];
|
||||
};
|
||||
|
||||
layout(set = 0, binding = 2) readonly buffer Block1
|
||||
{
|
||||
uvec4 atomics;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 colorValues = imageLoad(resultImage, ivec2(0, 0));
|
||||
|
||||
results[0] = vec4(0.0, .0, 0.0, 0.0);
|
||||
results[1] = imageLoad(resultImage, ivec2(1, 0));
|
||||
results[2] = imageLoad(resultImage, ivec2(0, 1));
|
||||
results[3] = imageLoad(resultImage, ivec2(1, 1));
|
||||
|
||||
// We don't know if the invocations are helpers or not at the start
|
||||
// and therefore all the possible outcomes are allowed.
|
||||
for (int x = 0; x < 2; x++)
|
||||
{
|
||||
for (int y = 0; y < 2; y++)
|
||||
{
|
||||
for (int z = 0; z < 2; z++)
|
||||
{
|
||||
for (int w = 0; w < 2; w++)
|
||||
{
|
||||
vec4 testVec = vec4(x * 1.0, y * 2.0, z * 3.0, w * 4.0);
|
||||
uvec4 atomicVec = uvec4(0, 0, 0, 0);
|
||||
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
if (testVec[j] > 0.0)
|
||||
{
|
||||
testVec[j] = 8.0;
|
||||
atomicVec[j] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
testVec[j] = j + 1.0;
|
||||
atomicVec[j] = 101;
|
||||
}
|
||||
}
|
||||
|
||||
float mask0 = dot(testVec, vec4(1, 10, 100, 1000));
|
||||
float mask1 = dot(vec4(testVec.x, 8.0, 8.0, testVec.w), vec4(1, 10, 100, 1000));
|
||||
float mask2 = dot(vec4(testVec.x, 8.0, 8.0, 8.0), vec4(1, 10, 100, 1000));
|
||||
|
||||
atomicVec[1] = 0;
|
||||
atomicVec[2] = 0;
|
||||
|
||||
if (colorValues.x == 1.0 && atomics.x == atomicVec.x
|
||||
&& colorValues.y == mask0 && atomics.y == atomicVec.y
|
||||
&& colorValues.z == mask1 && atomics.z == atomicVec.z
|
||||
&& colorValues.w == mask2 && atomics.w == atomicVec.w)
|
||||
{
|
||||
results[0] = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
END
|
||||
|
||||
BUFFER alpha_keys DATA_TYPE float DATA
|
||||
0.75
|
||||
2.25
|
||||
3.25
|
||||
3.75
|
||||
END
|
||||
|
||||
BUFFER atomics DATA_TYPE uint32 DATA
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
END
|
||||
|
||||
BUFFER results DATA_TYPE float SIZE 16 FILL 0.0
|
||||
BUFFER ref_buffer DATA_TYPE float SIZE 16 FILL 1.0
|
||||
|
||||
BUFFER framebuffer FORMAT R32G32B32A32_SFLOAT
|
||||
|
||||
PIPELINE graphics myPipeline
|
||||
ATTACH vert_shader
|
||||
ATTACH frag_shader
|
||||
|
||||
FRAMEBUFFER_SIZE 2 2
|
||||
|
||||
BIND BUFFER framebuffer AS color LOCATION 0
|
||||
BIND BUFFER alpha_keys AS storage DESCRIPTOR_SET 0 BINDING 0
|
||||
BIND BUFFER atomics AS storage DESCRIPTOR_SET 0 BINDING 1
|
||||
END
|
||||
|
||||
PIPELINE compute verifyPipeline
|
||||
ATTACH comp_shader
|
||||
FRAMEBUFFER_SIZE 2 2
|
||||
BIND BUFFER framebuffer AS storage_image DESCRIPTOR_SET 0 BINDING 0
|
||||
BIND BUFFER results AS storage DESCRIPTOR_SET 0 BINDING 1
|
||||
BIND BUFFER atomics AS storage DESCRIPTOR_SET 0 BINDING 2
|
||||
END
|
||||
|
||||
CLEAR_COLOR myPipeline 255 255 255 255
|
||||
CLEAR myPipeline
|
||||
|
||||
RUN myPipeline DRAW_RECT POS 0 0 SIZE 2 2
|
||||
RUN verifyPipeline 1 1 1
|
||||
|
||||
EXPECT results EQ_BUFFER ref_buffer
|
||||
Reference in New Issue
Block a user