mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-06 05:45:52 +00:00
5185 lines
187 KiB
C++
5185 lines
187 KiB
C++
/******************************************************************************
|
|
* The MIT License (MIT)
|
|
*
|
|
* Copyright (c) 2019-2025 Baldur Karlsson
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
* THE SOFTWARE.
|
|
******************************************************************************/
|
|
|
|
#include <limits>
|
|
#include "3rdparty/fmt/core.h"
|
|
#include "vk_test.h"
|
|
|
|
RD_TEST(VK_Shader_Debug_Zoo, VulkanGraphicsTest)
|
|
{
|
|
static constexpr const char *Description = "Tests shader debugging on SPIR-V opcodes.";
|
|
|
|
struct ConstsA2V
|
|
{
|
|
Vec4f pos;
|
|
float zero;
|
|
float one;
|
|
float negone;
|
|
Vec2f uv;
|
|
};
|
|
|
|
struct PushData
|
|
{
|
|
Vec4i push;
|
|
Vec2u bda_uvec2;
|
|
uint32_t bda_hi;
|
|
uint32_t bda_lo;
|
|
uint64_t bda_u64;
|
|
};
|
|
|
|
struct BDA_Data
|
|
{
|
|
float f32[8];
|
|
};
|
|
|
|
std::string v2f =
|
|
R"EOSHADER(
|
|
|
|
struct flatv2f
|
|
{
|
|
uint test;
|
|
uint intval;
|
|
};
|
|
|
|
struct v2f
|
|
{
|
|
vec2 zeroVal;
|
|
vec2 inpos;
|
|
vec2 inposIncreased;
|
|
float tinyVal;
|
|
float oneVal;
|
|
float negoneVal;
|
|
};
|
|
|
|
layout(location = 1) inout_type flat flatv2f flatData;
|
|
layout(location = 3) inout_type v2f linearData;
|
|
|
|
)EOSHADER";
|
|
|
|
std::string vertex = R"EOSHADER(
|
|
#version 430 core
|
|
|
|
#define inout_type out
|
|
|
|
)EOSHADER" + v2f + R"EOSHADER(
|
|
|
|
layout(location = 0) in vec4 pos;
|
|
layout(location = 1) in float zero;
|
|
layout(location = 2) in float one;
|
|
layout(location = 3) in float negone;
|
|
|
|
void main()
|
|
{
|
|
int test = gl_InstanceIndex;
|
|
|
|
gl_Position = vec4(pos.x + pos.z * float(test % 256), pos.y + pos.w * float(test / 256), 0.0, 1.0);
|
|
|
|
const vec4 verts[4] = vec4[4](vec4(-1.0, -1.0, 0.5, 1.0), vec4(1.0, -1.0, 0.5, 1.0),
|
|
vec4(-1.0, 1.0, 0.5, 1.0), vec4(1.0, 1.0, 0.5, 1.0));
|
|
|
|
const vec2 data[3] = vec2[3](vec2(10.0f, 10.0f), vec2(20.0f, 10.0f), vec2(10.0f, 20.0f));
|
|
|
|
linearData.zeroVal = zero.xx;
|
|
linearData.oneVal = one;
|
|
linearData.negoneVal = negone;
|
|
linearData.tinyVal = one * 1.0e-30;
|
|
linearData.inpos = data[gl_VertexIndex];
|
|
linearData.inposIncreased = data[gl_VertexIndex] * 2.75f;
|
|
flatData.test = test;
|
|
flatData.intval = test + 7;
|
|
}
|
|
|
|
)EOSHADER";
|
|
|
|
std::string pixel_glsl_header = R"EOSHADER(
|
|
#version 460 core
|
|
|
|
#extension GL_EXT_samplerless_texture_functions : require
|
|
#extension GL_EXT_nonuniform_qualifier : require
|
|
|
|
#define TEST_DESC_INDEXING
|
|
|
|
layout(set = 0, binding = 10, std140) uniform constsbuf
|
|
{
|
|
vec4 first;
|
|
uint uniformIndex;
|
|
vec4 second;
|
|
vec4 nan;
|
|
vec4 third;
|
|
vec4 pad3;
|
|
vec4 fourth;
|
|
vec4 unorm2PackSource;
|
|
vec4 snorm2PackSource;
|
|
vec4 unorm4PackSource;
|
|
vec4 snorm4PackSource;
|
|
vec4 halfPackSource;
|
|
uint unormUnpackSource;
|
|
uint snormUnpackSource;
|
|
uint halfUnpackSource;
|
|
uint pad;
|
|
} cbuf;
|
|
|
|
layout(set = 0, binding = 11) uniform sampler pointSampler;
|
|
layout(set = 0, binding = 12) uniform sampler linearSampler;
|
|
|
|
layout(set = 0, binding = 13) uniform texture2D sampledImage;
|
|
|
|
layout(set = 0, binding = 14) uniform sampler2D linearSampledImage;
|
|
|
|
struct dummy
|
|
{
|
|
uvec4 val;
|
|
uvec4 val2;
|
|
};
|
|
|
|
layout(set = 0, binding = 15, std430) buffer storebuftype
|
|
{
|
|
layout(row_major) mat4 a;
|
|
layout(column_major) mat4 b;
|
|
vec4 x;
|
|
dummy y;
|
|
vec4 arr[];
|
|
} storebuf;
|
|
|
|
layout(set = 0, binding = 16, rgba32f) uniform coherent image2D storeImage;
|
|
|
|
layout(set = 0, binding = 17) uniform samplerBuffer texBuffer;
|
|
layout(set = 0, binding = 18, rgba32f) uniform coherent imageBuffer storeTexBuffer;
|
|
|
|
layout(set = 0, binding = 19) uniform sampler shadowSampler;
|
|
|
|
layout(set = 0, binding = 20) uniform samplerCube cubeSampler;
|
|
|
|
layout(set = 0, binding = 21, std430) buffer atomicbuftype
|
|
{
|
|
uvec4 data[];
|
|
} atomicbuf;
|
|
|
|
layout(set = 0, r32ui, binding = 22) uniform uimage2D atomicimg;
|
|
|
|
layout(set = 0, binding = 30) uniform sampler2DArray queryTest;
|
|
layout(set = 0, binding = 31) uniform sampler2DMSArray queryTestMS;
|
|
|
|
layout(set = 0, binding = 32) uniform texture2D depthImage;
|
|
|
|
layout(set = 0, binding = 33) uniform samplerBuffer texBuffer1010102unorm;
|
|
layout(set = 0, binding = 34, rgb10_a2) uniform imageBuffer storeTexBuffer1010102unorm;
|
|
layout(set = 0, binding = 35) uniform usamplerBuffer texBuffer1010102uint;
|
|
layout(set = 0, binding = 36, rgb10_a2ui) uniform uimageBuffer storeTexBuffer1010102uint;
|
|
|
|
#if TEST_DESC_INDEXING
|
|
|
|
layout(set = 1, binding = 1) uniform sampler pointSamplers[14];
|
|
layout(set = 1, binding = 2) uniform sampler linearSamplers[14];
|
|
|
|
layout(set = 1, binding = 3) uniform texture2D sampledImages[14];
|
|
|
|
layout(set = 1, binding = 4) uniform sampler2D linearSampledImages[14];
|
|
|
|
layout(set = 1, binding = 5, std430) buffer storebufstype
|
|
{
|
|
vec4 x;
|
|
dummy y;
|
|
vec4 arr[];
|
|
} storebufs[14];
|
|
|
|
layout(set = 1, binding = 6, rgba32f) uniform coherent image2D storeImages[14];
|
|
|
|
layout(set = 1, binding = 7) uniform samplerBuffer texBuffers[14];
|
|
layout(set = 1, binding = 8, rgba32f) uniform coherent imageBuffer storeTexBuffers[14];
|
|
|
|
layout(set = 1, binding = 9) uniform sampler shadowSamplers[14];
|
|
|
|
layout(set = 1, binding = 20) uniform sampler2DArray queryTests[14];
|
|
layout(set = 1, binding = 21) uniform sampler2DMSArray queryTestsMS[14];
|
|
|
|
layout(set = 2, binding = 0) uniform sampler1D zoo_1D;
|
|
layout(set = 2, binding = 1) uniform sampler2D zoo_2D;
|
|
layout(set = 2, binding = 2) uniform sampler3D zoo_3D;
|
|
layout(set = 2, binding = 3) uniform samplerCube zoo_Cube;
|
|
layout(set = 2, binding = 4) uniform sampler1DArray zoo_1DArray;
|
|
layout(set = 2, binding = 5) uniform sampler2DArray zoo_2DArray;
|
|
layout(set = 2, binding = 6) uniform samplerCubeArray zoo_CubeArray;
|
|
layout(set = 2, binding = 7) uniform sampler2DMS zoo_2DMS;
|
|
layout(set = 2, binding = 8) uniform sampler2DMSArray zoo_2DMSArray;
|
|
layout(set = 2, binding = 9) uniform samplerBuffer zoo_Buffer;
|
|
|
|
layout(set = 2, binding = 10) uniform usampler1D zoo_u1D;
|
|
layout(set = 2, binding = 11) uniform usampler2D zoo_u2D;
|
|
layout(set = 2, binding = 12) uniform usampler3D zoo_u3D;
|
|
layout(set = 2, binding = 13) uniform usamplerCube zoo_uCube;
|
|
layout(set = 2, binding = 14) uniform usampler1DArray zoo_u1DArray;
|
|
layout(set = 2, binding = 15) uniform usampler2DArray zoo_u2DArray;
|
|
layout(set = 2, binding = 16) uniform usamplerCubeArray zoo_uCubeArray;
|
|
layout(set = 2, binding = 17) uniform usampler2DMS zoo_u2DMS;
|
|
layout(set = 2, binding = 18) uniform usampler2DMSArray zoo_u2DMSArray;
|
|
layout(set = 2, binding = 19) uniform usamplerBuffer zoo_uBuffer;
|
|
|
|
layout(set = 2, binding = 20) uniform isampler1D zoo_i1D;
|
|
layout(set = 2, binding = 21) uniform isampler2D zoo_i2D;
|
|
layout(set = 2, binding = 22) uniform isampler3D zoo_i3D;
|
|
layout(set = 2, binding = 23) uniform isamplerCube zoo_iCube;
|
|
layout(set = 2, binding = 24) uniform isampler1DArray zoo_i1DArray;
|
|
layout(set = 2, binding = 25) uniform isampler2DArray zoo_i2DArray;
|
|
layout(set = 2, binding = 26) uniform isamplerCubeArray zoo_iCubeArray;
|
|
layout(set = 2, binding = 27) uniform isampler2DMS zoo_i2DMS;
|
|
layout(set = 2, binding = 28) uniform isampler2DMSArray zoo_i2DMSArray;
|
|
layout(set = 2, binding = 29) uniform isamplerBuffer zoo_iBuffer;
|
|
|
|
layout(set = 2, rgba32f, binding = 30) uniform image1D storezoo_1D;
|
|
layout(set = 2, rgba32f, binding = 31) uniform image2D storezoo_2D;
|
|
layout(set = 2, rgba32f, binding = 32) uniform image3D storezoo_3D;
|
|
layout(set = 2, rgba32f, binding = 33) uniform imageCube storezoo_Cube;
|
|
layout(set = 2, rgba32f, binding = 34) uniform image1DArray storezoo_1DArray;
|
|
layout(set = 2, rgba32f, binding = 35) uniform image2DArray storezoo_2DArray;
|
|
layout(set = 2, rgba32f, binding = 36) uniform imageCubeArray storezoo_CubeArray;
|
|
//layout(set = 2, rgba32f, binding = 37) uniform image2DMS storezoo_2DMS;
|
|
//layout(set = 2, rgba32f, binding = 38) uniform image2DMSArray storezoo_2DMSArray;
|
|
layout(set = 2, rgba32f, binding = 39) uniform imageBuffer storezoo_Buffer;
|
|
|
|
layout(set = 2, rgba32ui, binding = 40) uniform uimage1D storezoo_u1D;
|
|
layout(set = 2, rgba32ui, binding = 41) uniform uimage2D storezoo_u2D;
|
|
layout(set = 2, rgba32ui, binding = 42) uniform uimage3D storezoo_u3D;
|
|
layout(set = 2, rgba32ui, binding = 43) uniform uimageCube storezoo_uCube;
|
|
layout(set = 2, rgba32ui, binding = 44) uniform uimage1DArray storezoo_u1DArray;
|
|
layout(set = 2, rgba32ui, binding = 45) uniform uimage2DArray storezoo_u2DArray;
|
|
layout(set = 2, rgba32ui, binding = 46) uniform uimageCubeArray storezoo_uCubeArray;
|
|
//layout(set = 2, rgba32ui, binding = 47) uniform uimage2DMS storezoo_u2DMS;
|
|
//layout(set = 2, rgba32ui, binding = 48) uniform uimage2DMSArray storezoo_u2DMSArray;
|
|
layout(set = 2, rgba32ui, binding = 49) uniform uimageBuffer storezoo_uBuffer;
|
|
|
|
layout(set = 2, rgba32i, binding = 50) uniform iimage1D storezoo_i1D;
|
|
layout(set = 2, rgba32i, binding = 51) uniform iimage2D storezoo_i2D;
|
|
layout(set = 2, rgba32i, binding = 52) uniform iimage3D storezoo_i3D;
|
|
layout(set = 2, rgba32i, binding = 53) uniform iimageCube storezoo_iCube;
|
|
layout(set = 2, rgba32i, binding = 54) uniform iimage1DArray storezoo_i1DArray;
|
|
layout(set = 2, rgba32i, binding = 55) uniform iimage2DArray storezoo_i2DArray;
|
|
layout(set = 2, rgba32i, binding = 56) uniform iimageCubeArray storezoo_iCubeArray;
|
|
//layout(set = 2, rgba32i, binding = 57) uniform iimage2DMS storezoo_i2DMS;
|
|
//layout(set = 2, rgba32i, binding = 58) uniform iimage2DMSArray storezoo_i2DMSArray;
|
|
layout(set = 2, rgba32i, binding = 59) uniform iimageBuffer storezoo_iBuffer;
|
|
|
|
#endif
|
|
|
|
layout(push_constant) uniform PushData {
|
|
layout(offset = 16) ivec4 data;
|
|
} push;
|
|
)EOSHADER";
|
|
|
|
std::string pixel_glsl1 = pixel_glsl_header + R"EOSHADER(
|
|
|
|
layout(location = 0, index = 0) out vec4 Color;
|
|
|
|
#define inout_type in
|
|
|
|
)EOSHADER" + v2f +
|
|
R"EOSHADER(
|
|
|
|
vec4 varscope_test(int coord, vec2 inpos_param, vec2 inpos_incr_param)
|
|
{
|
|
float never_in_scope;
|
|
|
|
if(coord < 0)
|
|
{
|
|
never_in_scope = inpos_param.x;
|
|
never_in_scope *= 2.0f;
|
|
}
|
|
|
|
vec4 ret;
|
|
|
|
// for the first pixel ret comes into scope early
|
|
if(coord == 0)
|
|
{
|
|
ret = vec4(0.5, 0.5, 0.5, 0.0);
|
|
}
|
|
|
|
float long_scope;
|
|
|
|
{
|
|
float short_scope;
|
|
short_scope = inpos_param.y;
|
|
short_scope = sin(short_scope);
|
|
long_scope = short_scope * inpos_incr_param.x;
|
|
}
|
|
|
|
if(coord != 0)
|
|
{
|
|
ret = vec4(1.0, 1.0, 1.0, 0.0);
|
|
}
|
|
|
|
ret.w += long_scope;
|
|
|
|
ret *= 1.5f;
|
|
|
|
return ret;
|
|
}
|
|
|
|
void main()
|
|
{
|
|
float posinf = linearData.oneVal/linearData.zeroVal.x;
|
|
float neginf = linearData.negoneVal/linearData.zeroVal.x;
|
|
float nan = linearData.zeroVal.x/linearData.zeroVal.y;
|
|
nan *= cbuf.nan.x;
|
|
|
|
float negone = linearData.negoneVal;
|
|
float posone = linearData.oneVal;
|
|
float zerof = linearData.zeroVal.x;
|
|
float tiny = linearData.tinyVal;
|
|
|
|
int intval = int(flatData.intval);
|
|
uint zerou = flatData.intval - flatData.test - 7u;
|
|
int zeroi = int(zerou);
|
|
|
|
uint test = flatData.test;
|
|
|
|
vec2 inpos = linearData.inpos;
|
|
vec2 inposIncreased = linearData.inposIncreased;
|
|
|
|
ivec2 localCoord = ivec2(gl_FragCoord) % ivec2(4, 4);
|
|
int flatLocalCoord = localCoord.x + localCoord.y * 4;
|
|
|
|
int flatGlobalCoord = int(gl_FragCoord.x) + int(gl_FragCoord.y) * 1024;
|
|
|
|
Color = vec4(0,0,0,0);
|
|
switch(test)
|
|
{
|
|
case 0:
|
|
{
|
|
Color = gl_FragCoord;
|
|
break;
|
|
}
|
|
case 1:
|
|
{
|
|
Color = dFdx(gl_FragCoord);
|
|
break;
|
|
}
|
|
case 2:
|
|
{
|
|
Color = dFdy(gl_FragCoord);
|
|
break;
|
|
}
|
|
case 3:
|
|
{
|
|
Color = dFdxCoarse(gl_FragCoord);
|
|
break;
|
|
}
|
|
case 4:
|
|
{
|
|
Color = dFdyCoarse(gl_FragCoord);
|
|
break;
|
|
}
|
|
case 5:
|
|
{
|
|
Color = dFdxFine(gl_FragCoord);
|
|
break;
|
|
}
|
|
case 6:
|
|
{
|
|
Color = dFdyFine(gl_FragCoord);
|
|
break;
|
|
}
|
|
case 7:
|
|
{
|
|
Color = dFdx(vec4(inpos, inposIncreased));
|
|
break;
|
|
}
|
|
case 8:
|
|
{
|
|
Color = dFdy(vec4(inpos, inposIncreased));
|
|
break;
|
|
}
|
|
case 9:
|
|
{
|
|
Color = dFdxCoarse(vec4(inpos, inposIncreased));
|
|
break;
|
|
}
|
|
case 10:
|
|
{
|
|
Color = dFdyCoarse(vec4(inpos, inposIncreased));
|
|
break;
|
|
}
|
|
case 11:
|
|
{
|
|
Color = dFdxFine(vec4(inpos, inposIncreased));
|
|
break;
|
|
}
|
|
case 12:
|
|
{
|
|
Color = dFdyFine(vec4(inpos, inposIncreased));
|
|
break;
|
|
}
|
|
case 13:
|
|
{
|
|
Color = vec4(abs(posone*2.5f), abs(negone*2.5f), abs(zerof*2.5f), 1.0f);
|
|
break;
|
|
}
|
|
case 14:
|
|
{
|
|
Color = vec4(pow(posone*2.5f, posone*1.3f), pow(posone*2.5f, posone*0.45f),
|
|
pow(vec2(posone*2.5f, posone*1.3f), vec2(posone*0.9f, posone*8.5f)));
|
|
break;
|
|
}
|
|
case 15:
|
|
{
|
|
Color = vec4(normalize(posone*2.5f), normalize(posone), normalize(negone), 1.0f);
|
|
break;
|
|
}
|
|
case 16:
|
|
{
|
|
Color = vec4(normalize(vec2(posone*2.5f, negone*1.8f)), normalize(vec2(posone*8.5f, negone*7.1f)));
|
|
break;
|
|
}
|
|
case 17:
|
|
{
|
|
Color = vec4(normalize(vec3(posone*2.5f, negone*1.8f, posone*8.5f)), 1.0f);
|
|
break;
|
|
}
|
|
case 18:
|
|
{
|
|
Color = normalize(vec4(posone*2.5f, negone*1.8f, posone*8.5f, negone*5.2f));
|
|
break;
|
|
}
|
|
case 19:
|
|
{
|
|
Color = vec4(floor(posone*2.5f), floor(posone*2.4f), floor(posone*2.6f), floor(zerof));
|
|
break;
|
|
}
|
|
case 20:
|
|
{
|
|
Color = vec4(floor(negone*2.5f), floor(negone*2.4f), floor(negone*2.6f), 1.0f);
|
|
break;
|
|
}
|
|
case 21:
|
|
{
|
|
Color = vec4(mix(posone*1.1f, posone*3.3f, 0.5f),
|
|
mix(posone*1.1f, posone*3.3f, 0.2f),
|
|
mix(posone*1.1f, posone*3.3f, 0.8f),
|
|
1.0f);
|
|
break;
|
|
}
|
|
case 22:
|
|
{
|
|
Color = vec4(mix(posone*1.1f, posone*3.3f, 1.5f),
|
|
mix(posone*1.1f, posone*3.3f, -0.3f),
|
|
0.0f,
|
|
1.0f);
|
|
break;
|
|
}
|
|
case 23:
|
|
{
|
|
Color = vec4(mix(posone*3.3f, posone*1.1f, 0.5f),
|
|
mix(posone*3.3f, posone*1.1f, 0.2f),
|
|
mix(posone*3.3f, posone*1.1f, 0.8f),
|
|
1.0f);
|
|
break;
|
|
}
|
|
case 24:
|
|
{
|
|
vec3 a = vec3(posone*2.5f, negone*1.8f, posone*8.5f);
|
|
vec3 b = vec3(negone*6.3f, posone*3.2f, negone*0.4f);
|
|
Color = vec4(cross(a, b), 1.0f);
|
|
break;
|
|
}
|
|
case 25:
|
|
{
|
|
vec4 a = vec4(posone*2.5f, negone*1.8f, posone*8.5f, posone*3.9f);
|
|
vec4 b = vec4(negone*6.3f, posone*3.2f, negone*0.4f, zerof);
|
|
Color = vec4(dot(a.xyz, b.xyz), dot(a.w, b.w), dot(a, b), dot(a.wz, b.ww));
|
|
break;
|
|
}
|
|
case 26:
|
|
{
|
|
Color = cbuf.first;
|
|
break;
|
|
}
|
|
case 27:
|
|
{
|
|
Color = cbuf.second;
|
|
break;
|
|
}
|
|
case 28:
|
|
{
|
|
Color = cbuf.third;
|
|
break;
|
|
}
|
|
case 29:
|
|
{
|
|
Color = cbuf.fourth;
|
|
break;
|
|
}
|
|
case 30:
|
|
{
|
|
Color = cbuf.first + cbuf.second + cbuf.third + cbuf.fourth +
|
|
cbuf.pad3;
|
|
break;
|
|
}
|
|
case 31:
|
|
{
|
|
ivec2 coord = ivec2(zeroi + 20, zeroi + 20);
|
|
|
|
Color = texelFetch(sampledImage, coord, 0);
|
|
break;
|
|
}
|
|
case 32:
|
|
{
|
|
vec2 coord = vec2(zerof + 0.5, zerof + 0.145);
|
|
|
|
Color = textureLod(sampler2D(sampledImage, pointSampler), coord, 0.0);
|
|
break;
|
|
}
|
|
case 33:
|
|
{
|
|
vec2 coord = vec2(zerof + 0.5, zerof + 0.145);
|
|
|
|
Color = textureLod(sampler2D(sampledImage, linearSampler), coord, 0.0);
|
|
break;
|
|
}
|
|
case 34:
|
|
{
|
|
Color = texture(linearSampledImage, inpos);
|
|
break;
|
|
}
|
|
case 35:
|
|
{
|
|
Color = vec4(max(posone*3.3f, posone*4.4f),
|
|
max(posone*4.4f, posone*3.3f),
|
|
max(posone, posinf),
|
|
max(posone, neginf));
|
|
break;
|
|
}
|
|
case 36:
|
|
{
|
|
Color = vec4(max(negone*3.3f, negone*4.4f),
|
|
max(negone*4.4f, negone*3.3f),
|
|
max(negone, posinf),
|
|
max(negone, neginf));
|
|
break;
|
|
}
|
|
case 37:
|
|
{
|
|
Color = vec4(min(posone*3.3f, posone*4.4f),
|
|
min(posone*4.4f, posone*3.3f),
|
|
min(posone, posinf),
|
|
min(posone, neginf));
|
|
break;
|
|
}
|
|
case 38:
|
|
{
|
|
Color = vec4(min(negone*3.3f, negone*4.4f),
|
|
min(negone*4.4f, negone*3.3f),
|
|
min(negone, posinf),
|
|
min(negone, neginf));
|
|
break;
|
|
}
|
|
case 39:
|
|
{
|
|
Color = vec4(float(max(zeroi+5, zeroi+8)),
|
|
float(max(zeroi+8, zeroi+5)),
|
|
float(max(zeroi-8, zeroi-5)),
|
|
float(max(zeroi-5, zeroi-8)));
|
|
break;
|
|
}
|
|
case 40:
|
|
{
|
|
Color = vec4(float(min(zeroi+5, zeroi+8)),
|
|
float(min(zeroi+8, zeroi+5)),
|
|
float(min(zeroi-8, zeroi-5)),
|
|
float(min(zeroi-5, zeroi-8)));
|
|
break;
|
|
}
|
|
case 41:
|
|
{
|
|
Color = vec4(float(max(zerou+5, zerou+8)),
|
|
float(max(zerou+8, zerou+5)),
|
|
float(min(zerou+8, zerou+5)),
|
|
float(min(zerou+5, zerou+8)));
|
|
break;
|
|
}
|
|
case 42:
|
|
{
|
|
Color = vec4(clamp(posone*3.3f, posone, posone*5.0f),
|
|
clamp(posone*0.3f, posone, posone*5.0f),
|
|
clamp(posone*8.3f, posone, posone*5.0f),
|
|
1.0f);
|
|
break;
|
|
}
|
|
case 43:
|
|
{
|
|
uint x = uint(posone);
|
|
Color = vec4(float(clamp(x*4, zerou+2, zerou+50)),
|
|
float(clamp(x, zerou+2, zerou+50)),
|
|
float(clamp(x*400, zerou+2, zerou+50)),
|
|
1.0f);
|
|
break;
|
|
}
|
|
case 44:
|
|
{
|
|
int x = int(posone);
|
|
Color = vec4(float(clamp(x*4, zeroi+2, zeroi+50)),
|
|
float(clamp(x, zeroi+2, zeroi+50)),
|
|
float(clamp(x*400, zeroi+2, zeroi+50)),
|
|
1.0f);
|
|
break;
|
|
}
|
|
case 45:
|
|
{
|
|
Color = vec4(float(abs(zeroi+2)),
|
|
float(abs(zeroi)),
|
|
float(abs(zeroi-5)),
|
|
1.0f);
|
|
break;
|
|
}
|
|
case 46:
|
|
{
|
|
Color = fwidth(gl_FragCoord);
|
|
break;
|
|
}
|
|
case 47:
|
|
{
|
|
Color = fwidthCoarse(gl_FragCoord);
|
|
break;
|
|
}
|
|
case 48:
|
|
{
|
|
Color = fwidthFine(gl_FragCoord);
|
|
break;
|
|
}
|
|
case 49:
|
|
{
|
|
Color = fwidth(vec4(inpos, inposIncreased));
|
|
break;
|
|
}
|
|
case 50:
|
|
{
|
|
Color = fwidthCoarse(vec4(inpos, inposIncreased));
|
|
break;
|
|
}
|
|
)EOSHADER"
|
|
R"EOSHADER(
|
|
case 51:
|
|
{
|
|
Color = fwidthFine(vec4(inpos, inposIncreased));
|
|
break;
|
|
}
|
|
case 52:
|
|
{
|
|
Color = vec4(isinf(posone) ? 1.0f : 0.0f, isinf(zerof) ? 1.0f : 0.0f, isinf(negone) ? 1.0f : 0.0f, 1.0f);
|
|
break;
|
|
}
|
|
case 53:
|
|
{
|
|
Color = vec4(isnan(posone) ? 1.0f : 0.0f, isnan(zerof) ? 1.0f : 0.0f, isnan(negone) ? 1.0f : 0.0f, 1.0f);
|
|
break;
|
|
}
|
|
case 54:
|
|
{
|
|
Color = vec4(isinf(posinf) ? 1.0f : 0.0f, isinf(neginf) ? 1.0f : 0.0f, isinf(nan) ? 1.0f : 0.0f, 1.0f);
|
|
break;
|
|
}
|
|
case 55:
|
|
{
|
|
Color = vec4(isnan(posinf) ? 1.0f : 0.0f, isnan(neginf) ? 1.0f : 0.0f, isnan(nan) ? 1.0f : 0.0f, 1.0f);
|
|
break;
|
|
}
|
|
case 56:
|
|
{
|
|
Color = vec4(push.data);
|
|
break;
|
|
}
|
|
case 57:
|
|
{
|
|
Color = vec4(roundEven(posone*2.5f), roundEven(posone*3.5f), roundEven(posone*4.5f), roundEven(posone*5.1f));
|
|
break;
|
|
}
|
|
case 58:
|
|
{
|
|
Color = vec4(roundEven(negone*2.5f), roundEven(negone*3.5f), roundEven(negone*4.5f), roundEven(negone*5.1f));
|
|
break;
|
|
}
|
|
case 59:
|
|
{
|
|
// avoid implementation-defined behaviour at half-way points
|
|
Color = vec4(round(posone*2.4f), round(posone*3.6f), round(posone*4.6f), round(posone*5.1f));
|
|
break;
|
|
}
|
|
case 60:
|
|
{
|
|
Color = vec4(round(negone*2.6f), round(negone*3.6f), round(negone*4.6f), round(posone*5.1f));
|
|
break;
|
|
}
|
|
case 61:
|
|
{
|
|
Color = vec4(trunc(posone*2.4f), trunc(posone*2.5f), trunc(posone*2.6f), trunc(posone*5.1f));
|
|
break;
|
|
}
|
|
case 62:
|
|
{
|
|
Color = vec4(trunc(negone*2.4f), trunc(negone*2.5f), trunc(negone*2.6f), trunc(negone*3.1f));
|
|
break;
|
|
}
|
|
case 63:
|
|
{
|
|
Color = vec4(fract(posone*2.4f), fract(posone*2.5f), fract(posone*2.6f), fract(posone*3.1f));
|
|
break;
|
|
}
|
|
case 64:
|
|
{
|
|
Color = vec4(fract(negone*2.4f), fract(negone*2.5f), fract(negone*2.6f), fract(negone*3.1f));
|
|
break;
|
|
}
|
|
case 65:
|
|
{
|
|
Color = vec4(ceil(posone*2.4f), ceil(posone*2.5f), ceil(posone*2.6f), ceil(posone*3.1f));
|
|
break;
|
|
}
|
|
case 66:
|
|
{
|
|
Color = vec4(ceil(negone*2.4f), ceil(negone*2.5f), ceil(negone*2.6f), ceil(negone*3.1f));
|
|
break;
|
|
}
|
|
case 67:
|
|
{
|
|
Color = vec4(sign(negone*2.4f), sign(posone*2.4f), sign(posinf), sign(neginf));
|
|
break;
|
|
}
|
|
case 68:
|
|
{
|
|
int onei = zeroi+1;
|
|
int negi = zeroi-1;
|
|
Color = vec4(float(sign(onei*2)), float(sign(negi*2)), float(sign(0)), 1.0f);
|
|
break;
|
|
}
|
|
case 69:
|
|
{
|
|
Color = vec4(degrees(negone*2.4f), degrees(posone*2.4f), degrees(zerof), degrees(posone*34.56f));
|
|
break;
|
|
}
|
|
case 70:
|
|
{
|
|
Color = vec4(radians(negone*164.2f), radians(posone*164.2f), radians(zerof), radians(posone*3456.78f));
|
|
break;
|
|
}
|
|
case 71:
|
|
{
|
|
vec4 a = vec4(posone*2.4f, posone*2.5f, posone*2.6f, posone*2.7f);
|
|
vec4 b = vec4(zerof+2.5f, zerof+2.5f, zerof+2.5f, zerof+2.5f);
|
|
Color = vec4(float(a.x < b.x), float(a.x <= b.x), float(a.x > b.x), float(a.x >= b.x));
|
|
break;
|
|
}
|
|
case 72:
|
|
{
|
|
vec4 a = vec4(posone*2.4f, posone*2.5f, posone*2.6f, posone*2.7f);
|
|
vec4 b = vec4(zerof+2.5f, zerof+2.5f, zerof+2.5f, zerof+2.5f);
|
|
bvec4 c = lessThanEqual(a, b);
|
|
Color = vec4(float(a.x == b.x), float(a.x != b.x), 0.0f, 1.0f);
|
|
break;
|
|
}
|
|
case 73:
|
|
{
|
|
ivec4 a = ivec4(zeroi+2, zeroi+3, zeroi+4, zeroi+5);
|
|
ivec4 b = ivec4(zeroi+4, zeroi+4, zeroi+4, zeroi+4);
|
|
Color = vec4(float(a.x < b.x), float(a.x <= b.x), float(a.x > b.x), float(a.x >= b.x));
|
|
break;
|
|
}
|
|
case 74:
|
|
{
|
|
ivec4 a = ivec4(zeroi+2, zeroi+3, zeroi+4, zeroi+5);
|
|
ivec4 b = ivec4(zeroi+4, zeroi+4, zeroi+4, zeroi+4);
|
|
Color = vec4(float(a.x == b.x), float(a.x != b.x), 0.0f, 1.0f);
|
|
break;
|
|
}
|
|
case 75:
|
|
{
|
|
uvec4 a = uvec4(zerou+2, zerou+3, zerou+4, zerou+5);
|
|
uvec4 b = uvec4(zerou+4, zerou+4, zerou+4, zerou+4);
|
|
Color = vec4(float(a.x < b.x), float(a.x <= b.x), float(a.x > b.x), float(a.x >= b.x));
|
|
break;
|
|
}
|
|
case 76:
|
|
{
|
|
uvec4 a = uvec4(zerou+2, zerou+3, zerou+4, zerou+5);
|
|
uvec4 b = uvec4(zerou+4, zerou+4, zerou+4, zerou+4);
|
|
Color = vec4(float(a.x == b.x), float(a.x != b.x), 0.0f, 1.0f);
|
|
break;
|
|
}
|
|
case 77:
|
|
{
|
|
vec4 a = vec4(posone*2.4f, posone*2.5f, posone*2.6f, posone*2.7f);
|
|
vec4 b = vec4(zerof+2.5f, zerof+2.5f, zerof+2.5f, zerof+2.5f);
|
|
bvec4 c = lessThanEqual(a, b);
|
|
Color = vec4(float(any(c)), float(all(c)), float(c.x == c.z), float(c.x != c.w));
|
|
break;
|
|
}
|
|
case 78:
|
|
{
|
|
vec4 a = vec4(posone*2.4f, posone*2.5f, posone*2.6f, posone*2.7f);
|
|
vec4 b = vec4(zerof+2.5f, zerof+2.5f, zerof+2.5f, zerof+2.5f);
|
|
bvec4 c = lessThanEqual(a, b);
|
|
Color = vec4(float(c.x || c.y), float(c.x && c.y), float(!c.x), 1.0f);
|
|
break;
|
|
}
|
|
case 79:
|
|
{
|
|
vec4 a = vec4(posone*2.4f, posone*2.5f, posone*2.6f, posone*2.7f);
|
|
vec4 b = vec4(zerof+2.5f, zerof+2.5f, zerof+2.5f, zerof+2.5f);
|
|
bvec4 c = lessThanEqual(a, b);
|
|
Color = mix(vec4(posone*9.0f, posone*8.0f, posone*7.0f, posone*6.0f),
|
|
vec4(posone*1.0f, posone*2.0f, posone*3.0f, posone*4.0f), c);
|
|
break;
|
|
}
|
|
case 80:
|
|
{
|
|
discard;
|
|
}
|
|
case 81:
|
|
{
|
|
Color = vec4(sin(posone*2.4f), cos(posone*2.4f), asin(posone*2.4f), acos(posone*2.4f));
|
|
break;
|
|
}
|
|
case 82:
|
|
{
|
|
Color = vec4(sinh(posone*2.4f), cosh(posone*2.4f), asinh(posone*2.4f), acosh(posone*2.4f));
|
|
break;
|
|
}
|
|
case 83:
|
|
{
|
|
Color = vec4(tan(posone*2.4f), tanh(posone*2.4f), atan(posone*2.4f), atanh(posone*2.4f));
|
|
break;
|
|
}
|
|
case 84:
|
|
{
|
|
Color = vec4(atan(posone*2.4f, posone*5.7f), sqrt(posone*2.4f), inversesqrt(posone*2.4f), 1.0f);
|
|
break;
|
|
}
|
|
case 85:
|
|
{
|
|
Color = vec4(log(posone*2.4f), log2(posone*2.4f), exp(posone*2.4f), exp2(posone*2.4f));
|
|
break;
|
|
}
|
|
case 86:
|
|
{
|
|
vec4 a = vec4(posone*2.4f, posone*2.5f, posone*2.6f, posone*2.7f);
|
|
vec4 b = vec4(zerof+2.5f, zerof+2.5f, zerof+2.5f, zerof+2.5f);
|
|
Color = vec4(length(a), length(b), distance(a, b), 1.0f);
|
|
break;
|
|
}
|
|
case 87:
|
|
{
|
|
vec4 a = vec4(posone*2.4f, posone*2.5f, posone*2.6f, posone*2.7f);
|
|
Color = normalize(a);
|
|
break;
|
|
}
|
|
case 88:
|
|
{
|
|
vec4 a = vec4(posone*2.4f, posone*2.5f, posone*2.6f, posone*2.7f);
|
|
vec4 b = vec4(zerof+2.5f, zerof+2.5f, zerof+2.5f, zerof+2.5f);
|
|
Color = refract(a, b, zerof+3.1f);
|
|
break;
|
|
}
|
|
case 89:
|
|
{
|
|
Color = vec4(fma(zerof+2.4f, posone*0.1f, posone*8.3f),
|
|
fma(zerof+2.4f, posone*0.0f, posone*8.3f),
|
|
fma(zerof+3.675f, posone*9.703f, posone*1.45f),
|
|
((zerof+3.675f) * (posone*9.703f)) + posone*1.45f);
|
|
break;
|
|
}
|
|
case 90:
|
|
{
|
|
Color = vec4(step(posone*2.6f, zerof+2.4f),
|
|
step(posone*2.6f, zerof+2.5f),
|
|
step(posone*2.6f, zerof+2.6f),
|
|
step(posone*2.6f, zerof+2.7f));
|
|
break;
|
|
}
|
|
case 91:
|
|
{
|
|
Color = vec4(smoothstep(posone*2.0f, posone*2.6f, zerof+1.9f),
|
|
smoothstep(posone*2.0f, posone*2.6f, zerof+2.0f),
|
|
smoothstep(posone*2.0f, posone*2.6f, zerof+2.1f),
|
|
smoothstep(posone*2.0f, posone*2.6f, zerof+2.3f));
|
|
break;
|
|
}
|
|
case 92:
|
|
{
|
|
Color = vec4(smoothstep(posone*2.0f, posone*2.6f, zerof+2.4f),
|
|
smoothstep(posone*2.0f, posone*2.6f, zerof+2.5f),
|
|
smoothstep(posone*2.0f, posone*2.6f, zerof+2.6f),
|
|
smoothstep(posone*2.0f, posone*2.6f, zerof+2.8f));
|
|
break;
|
|
}
|
|
case 93:
|
|
{
|
|
vec4 N = vec4(posone*1.4f, posone*2.8f, posone*5.6f, posone*4.4f);
|
|
vec4 I = vec4(posone*3.7f, posone*2.2f, posone*6.1f, posone*9.5f);
|
|
vec4 Nref = vec4(posone*6.4f, posone*7.5f, posone*8.3f, posone*0.9f);
|
|
Color = faceforward(N, I, Nref);
|
|
break;
|
|
}
|
|
case 94:
|
|
{
|
|
vec4 N = vec4(posone*1.4f, posone*2.8f, posone*5.6f, posone*4.4f);
|
|
vec4 I = vec4(posone*3.7f, posone*2.2f, posone*6.1f, posone*9.5f);
|
|
Color = reflect(N, I);
|
|
break;
|
|
}
|
|
case 95:
|
|
{
|
|
Color = vec4(ldexp(posone*1.4f, zeroi-3),
|
|
ldexp(posone*2.8f, zeroi+0),
|
|
ldexp(posone*5.6f, zeroi+3),
|
|
ldexp(posone*4.4f, zeroi+7));
|
|
break;
|
|
}
|
|
case 96:
|
|
{
|
|
uint a = zerou + 0xb0b0b0b0;
|
|
uint b = zerou + 0x12345678;
|
|
|
|
// add and sub with no carry/borrow
|
|
uint y;
|
|
uint x = uaddCarry(a, b, y);
|
|
uint w;
|
|
uint z = usubBorrow(a, b, w);
|
|
|
|
Color = vec4(float(x), float(y), float(z), float(w));
|
|
break;
|
|
}
|
|
case 97:
|
|
{
|
|
uint a = zerou + 0xb0b0b0b0;
|
|
uint b = zerou + 0xdeadbeef;
|
|
|
|
// add and sub with carry/borrow
|
|
uint y;
|
|
uint x = uaddCarry(a, b, y);
|
|
uint w;
|
|
uint z = usubBorrow(a, b, w);
|
|
|
|
Color = vec4(float(x), float(y), float(z), float(w));
|
|
break;
|
|
}
|
|
case 98:
|
|
{
|
|
uint a = zerou + 0xb0b0b0b0;
|
|
uint b = zerou + 0xdeadbeef;
|
|
|
|
// add and sub with carry/borrow
|
|
uint y;
|
|
uint x = uaddCarry(a, b, y);
|
|
uint w;
|
|
uint z = usubBorrow(a, b, w);
|
|
|
|
Color = vec4(float(x), float(y), float(z), float(w));
|
|
break;
|
|
}
|
|
case 99:
|
|
{
|
|
uint a = zerou + 0x1234;
|
|
uint b = zerou + 0x5678;
|
|
int c = zeroi + 0x1234;
|
|
int d = zeroi + 0x5678;
|
|
|
|
// positive mul with no overflow
|
|
uint x, y;
|
|
umulExtended(a, b, y, x);
|
|
int z, w;
|
|
imulExtended(c, d, w, z);
|
|
|
|
Color = vec4(float(x), float(y), float(z), float(w));
|
|
break;
|
|
}
|
|
case 100:
|
|
{
|
|
uint a = zerou + 0x123456;
|
|
uint b = zerou + 0x78abcd;
|
|
int c = zeroi + 0x123456;
|
|
int d = zeroi + 0x78abcd;
|
|
|
|
// positive mul with overflow
|
|
uint x, y;
|
|
umulExtended(a, b, y, x);
|
|
int z, w;
|
|
imulExtended(c, d, w, z);
|
|
|
|
Color = vec4(float(x), float(y), float(z), float(w));
|
|
break;
|
|
}
|
|
case 101:
|
|
{
|
|
int a = zeroi - 0x1234;
|
|
int b = zeroi - 0x5678;
|
|
int c = zeroi - 0x123456;
|
|
int d = zeroi - 0x78abcd;
|
|
|
|
// negative mul with and without overflow
|
|
int x, y;
|
|
imulExtended(a, b, y, x);
|
|
int z, w;
|
|
imulExtended(c, d, w, z);
|
|
|
|
Color = vec4(float(x), float(y), float(z), float(w));
|
|
break;
|
|
}
|
|
)EOSHADER"
|
|
R"EOSHADER(
|
|
case 102:
|
|
{
|
|
uint a = zerou + 0x0dadbeef;
|
|
int b = zeroi + 0x0dadbeef;
|
|
|
|
Color = vec4(float(findLSB(a)), float(findLSB(b)), float(findMSB(a)), float(findMSB(b)));
|
|
break;
|
|
}
|
|
case 103:
|
|
{
|
|
int a = zeroi - 0x0dadbeef;
|
|
|
|
Color = vec4(float(findLSB(a)), float(findLSB(zeroi)), float(findMSB(a)), float(findMSB(zeroi)));
|
|
break;
|
|
}
|
|
case 104:
|
|
{
|
|
uint a = zerou + 0x44b82a24;
|
|
int b = zeroi + 0x44b82a24;
|
|
|
|
Color = vec4(float(bitCount(a)), float(bitCount(b)), uintBitsToFloat(bitfieldReverse(a)), intBitsToFloat(bitfieldReverse(b)));
|
|
break;
|
|
}
|
|
case 105:
|
|
{
|
|
uint a = zerou + 0x44b82a24;
|
|
int b = zeroi + 0x44b82a24;
|
|
uint af = zerou+0xffffffff;
|
|
int bf = zeroi-1;
|
|
|
|
Color = vec4(float(bitfieldExtract(a, 4, 5)), float(bitfieldExtract(b, 4, 5)),
|
|
uintBitsToFloat(bitfieldInsert(a, af, 4, 5)), intBitsToFloat(bitfieldInsert(b, bf, 4, 5)));
|
|
break;
|
|
}
|
|
case 106:
|
|
{
|
|
Color = vec4(float(textureQueryLevels(queryTest)), float(textureSamples(queryTestMS)), 0.0f, 1.0f);
|
|
break;
|
|
}
|
|
case 107:
|
|
{
|
|
Color = vec4(vec3(textureSize(queryTest, 0)), 1.0f);
|
|
break;
|
|
}
|
|
case 108:
|
|
{
|
|
Color = vec4(vec3(textureSize(queryTest, 1)), 1.0f);
|
|
break;
|
|
}
|
|
case 109:
|
|
{
|
|
Color = vec4(vec3(textureSize(queryTestMS)), 1.0f);
|
|
break;
|
|
}
|
|
case 110:
|
|
{
|
|
Color = vec4(vec3(textureSize(queryTestMS)), 1.0f);
|
|
break;
|
|
}
|
|
case 111:
|
|
{
|
|
Color = texelFetch(texBuffer, int(zeroi+2));
|
|
break;
|
|
}
|
|
case 112:
|
|
{
|
|
float x = texture(sampler2DShadow(depthImage, shadowSampler), vec3(inpos, 0.1f));
|
|
float y = texture(sampler2DShadow(depthImage, shadowSampler), vec3(inpos, 0.3f));
|
|
float z = texture(sampler2DShadow(depthImage, shadowSampler), vec3(inpos, 0.7f));
|
|
float w = texture(sampler2DShadow(depthImage, shadowSampler), vec3(inpos, 0.9f));
|
|
Color = vec4(x, y, z, w);
|
|
break;
|
|
}
|
|
case 113:
|
|
{
|
|
vec2 coord = vec2(zerof + 0.6, zerof + 0.43);
|
|
|
|
Color = textureGather(linearSampledImage, coord, 0);
|
|
break;
|
|
}
|
|
case 114:
|
|
{
|
|
vec2 coord = vec2(zerof + 0.6, zerof + 0.43);
|
|
|
|
Color = textureGather(linearSampledImage, coord, 1);
|
|
break;
|
|
}
|
|
case 115:
|
|
{
|
|
vec2 coord = vec2(zerof + 0.6, zerof + 0.43);
|
|
|
|
Color = textureGather(linearSampledImage, coord, 2);
|
|
break;
|
|
}
|
|
case 116:
|
|
{
|
|
vec2 coord = vec2(zerof + 0.6, zerof + 0.43);
|
|
|
|
Color = textureGather(sampler2DShadow(depthImage, shadowSampler), coord, 0.8f);
|
|
break;
|
|
}
|
|
case 117:
|
|
{
|
|
uint packed = packHalf2x16(cbuf.halfPackSource.xy);
|
|
|
|
Color = vec4(float((packed & 0xff000000) >> 24),
|
|
float((packed & 0x00ff0000) >> 16),
|
|
float((packed & 0x0000ff00) >> 8),
|
|
float((packed & 0x000000ff) >> 0));
|
|
break;
|
|
}
|
|
case 118:
|
|
{
|
|
vec2 unpacked = unpackHalf2x16(cbuf.halfUnpackSource);
|
|
|
|
Color = unpacked.xyxy;
|
|
break;
|
|
}
|
|
case 119:
|
|
{
|
|
uint packed = packUnorm2x16(cbuf.unorm2PackSource.xy);
|
|
|
|
Color = vec4(float((packed & 0xff000000) >> 24),
|
|
float((packed & 0x00ff0000) >> 16),
|
|
float((packed & 0x0000ff00) >> 8),
|
|
float((packed & 0x000000ff) >> 0));
|
|
break;
|
|
}
|
|
case 120:
|
|
{
|
|
uint packed = packUnorm4x8(cbuf.unorm4PackSource);
|
|
|
|
Color = vec4(float((packed & 0xff000000) >> 24),
|
|
float((packed & 0x00ff0000) >> 16),
|
|
float((packed & 0x0000ff00) >> 8),
|
|
float((packed & 0x000000ff) >> 0));
|
|
break;
|
|
}
|
|
case 121:
|
|
{
|
|
uint packed = packSnorm2x16(cbuf.snorm2PackSource.xy);
|
|
|
|
Color = vec4(float((packed & 0xff000000) >> 24),
|
|
float((packed & 0x00ff0000) >> 16),
|
|
float((packed & 0x0000ff00) >> 8),
|
|
float((packed & 0x000000ff) >> 0));
|
|
break;
|
|
}
|
|
case 122:
|
|
{
|
|
uint packed = packSnorm4x8(cbuf.snorm4PackSource);
|
|
|
|
Color = vec4(float((packed & 0xff000000) >> 24),
|
|
float((packed & 0x00ff0000) >> 16),
|
|
float((packed & 0x0000ff00) >> 8),
|
|
float((packed & 0x000000ff) >> 0));
|
|
break;
|
|
}
|
|
case 123:
|
|
{
|
|
vec2 unpacked = unpackUnorm2x16(cbuf.unormUnpackSource);
|
|
|
|
Color = unpacked.xyxy;
|
|
break;
|
|
}
|
|
case 124:
|
|
{
|
|
vec4 unpacked = unpackUnorm4x8(cbuf.unormUnpackSource);
|
|
|
|
Color = unpacked;
|
|
break;
|
|
}
|
|
case 125:
|
|
{
|
|
vec2 unpacked = unpackSnorm2x16(cbuf.snormUnpackSource);
|
|
|
|
Color = unpacked.xyxy;
|
|
break;
|
|
}
|
|
case 126:
|
|
{
|
|
vec4 unpacked = unpackSnorm4x8(cbuf.snormUnpackSource);
|
|
|
|
Color = unpacked;
|
|
break;
|
|
}
|
|
case 127:
|
|
{
|
|
uint len = storebuf.arr.length();
|
|
Color = vec4(float(len), float(len), float(len), float(len));
|
|
break;
|
|
}
|
|
case 128:
|
|
{
|
|
// test storage buffer write here, we'll read from it in GLSL test 2
|
|
storebuf.x = vec4(3.1f, 4.1f, 5.9f, 2.6f);
|
|
storebuf.y.val = uvec4(31, 41, 59, 26);
|
|
storebuf.arr[flatData.intval - flatData.test] = vec4(inpos, inposIncreased);
|
|
|
|
Color = storebuf.x;
|
|
break;
|
|
}
|
|
case 129:
|
|
{
|
|
Color = textureProj(linearSampledImage, vec3(inpos, 0.5f));
|
|
break;
|
|
}
|
|
case 130:
|
|
{
|
|
Color.xy = textureQueryLod(linearSampledImage, inpos);
|
|
Color.zw = textureQueryLod(linearSampledImage, vec2(1.0f, 1.0f)/inpos);
|
|
break;
|
|
}
|
|
case 131:
|
|
{
|
|
Color = vec4(vec2(imageSize(storeImage)), 0.0f, 1.0f);
|
|
break;
|
|
}
|
|
case 132:
|
|
{
|
|
Color = vec4(float(imageSize(storeTexBuffer)), 0.0f, 0.0f, 1.0f);
|
|
break;
|
|
}
|
|
case 133:
|
|
{
|
|
imageStore(storeImage, ivec2(zeroi+1,zeroi+3), vec4(3.1f, 4.1f, 5.9f, 2.6f));
|
|
Color = imageLoad(storeImage, ivec2(zeroi+1,zeroi+3));
|
|
break;
|
|
}
|
|
#if TEST_DESC_INDEXING
|
|
case 134:
|
|
{
|
|
ivec2 coord = ivec2(zeroi + 20, zeroi + 20);
|
|
|
|
Color = texelFetch(sampledImages[1], coord, 0);
|
|
break;
|
|
}
|
|
case 135:
|
|
{
|
|
vec2 coord = vec2(zerof + 0.5, zerof + 0.145);
|
|
|
|
Color = textureLod(sampler2D(sampledImages[2], pointSamplers[3]), coord, 0.0);
|
|
break;
|
|
}
|
|
case 136:
|
|
{
|
|
vec2 coord = vec2(zerof + 0.5, zerof + 0.145);
|
|
|
|
Color = textureLod(sampler2D(sampledImages[2], linearSamplers[3]), coord, 0.0);
|
|
break;
|
|
}
|
|
case 137:
|
|
{
|
|
Color = texture(linearSampledImages[4], inpos.xy);
|
|
break;
|
|
}
|
|
case 138:
|
|
{
|
|
ivec2 coord = ivec2(zeroi + 20, zeroi + 20);
|
|
|
|
Color = texelFetch(sampledImages[cbuf.uniformIndex+1], coord, 0);
|
|
break;
|
|
}
|
|
case 139:
|
|
{
|
|
vec2 coord = vec2(zerof + 0.5, zerof + 0.145);
|
|
|
|
Color = textureLod(sampler2D(sampledImages[cbuf.uniformIndex+2], pointSamplers[cbuf.uniformIndex+3]), coord, 0.0);
|
|
break;
|
|
}
|
|
case 140:
|
|
{
|
|
vec2 coord = vec2(zerof + 0.5, zerof + 0.145);
|
|
|
|
Color = textureLod(sampler2D(sampledImages[cbuf.uniformIndex+2], linearSamplers[cbuf.uniformIndex+3]), coord, 0.0);
|
|
break;
|
|
}
|
|
case 141:
|
|
{
|
|
Color = texture(linearSampledImages[cbuf.uniformIndex+4], inpos.xy);
|
|
break;
|
|
}
|
|
case 142:
|
|
{
|
|
ivec2 coord = ivec2(zeroi + 20, zeroi + 20);
|
|
|
|
Color = texelFetch(sampledImages[nonuniformEXT(zeroi)+9], coord, 0);
|
|
break;
|
|
}
|
|
case 143:
|
|
{
|
|
vec2 coord = vec2(zerof + 0.5, zerof + 0.145);
|
|
|
|
Color = textureLod(sampler2D(sampledImages[nonuniformEXT(zeroi)+10], pointSamplers[nonuniformEXT(zeroi)+11]), coord, 0.0);
|
|
break;
|
|
}
|
|
case 144:
|
|
{
|
|
vec2 coord = vec2(zerof + 0.5, zerof + 0.145);
|
|
|
|
Color = textureLod(sampler2D(sampledImages[nonuniformEXT(zeroi)+10], linearSamplers[nonuniformEXT(zeroi)+11]), coord, 0.0);
|
|
break;
|
|
}
|
|
case 145:
|
|
{
|
|
Color = texture(linearSampledImages[nonuniformEXT(zeroi)+12], inpos.xy);
|
|
break;
|
|
}
|
|
case 146:
|
|
{
|
|
Color = vec4(float(textureQueryLevels(queryTests[0])), float(textureSamples(queryTestsMS[0])), 0.0f, 1.0f);
|
|
break;
|
|
}
|
|
case 147:
|
|
{
|
|
Color = vec4(float(textureQueryLevels(queryTests[zeroi+3])), float(textureSamples(queryTestsMS[zeroi+3])), 0.0f, 1.0f);
|
|
break;
|
|
}
|
|
case 148:
|
|
{
|
|
Color = vec4(float(textureQueryLevels(queryTests[nonuniformEXT(zeroi)+5])), float(textureSamples(queryTestsMS[nonuniformEXT(zeroi)+5])), 0.0f, 1.0f);
|
|
break;
|
|
}
|
|
case 149:
|
|
{
|
|
uint len = storebufs[zeroi+7].arr.length();
|
|
Color = vec4(float(len), float(len), float(len), float(len));
|
|
break;
|
|
}
|
|
case 150:
|
|
{
|
|
// test storage buffer write here, we'll read from it in GLSL test 2
|
|
storebufs[zeroi+7].x = vec4(3.1f, 4.1f, 5.9f, 2.6f);
|
|
storebufs[zeroi+7].y.val = uvec4(31, 41, 59, 26);
|
|
storebufs[zeroi+7].arr[flatData.intval - flatData.test] = vec4(inpos, inposIncreased);
|
|
|
|
Color = storebufs[zeroi+7].x;
|
|
break;
|
|
}
|
|
case 151:
|
|
{
|
|
imageStore(storeImages[zeroi+7], ivec2(zeroi+1,zeroi+3), vec4(3.1f, 4.1f, 5.9f, 2.6f));
|
|
Color = imageLoad(storeImages[zeroi+7], ivec2(zeroi+1,zeroi+3));
|
|
break;
|
|
}
|
|
case 152:
|
|
{
|
|
float x = texture(sampler2DShadow(sampledImages[zeroi+5], shadowSamplers[zeroi+8]), vec3(inpos, 0.1f));
|
|
float y = texture(sampler2DShadow(sampledImages[zeroi+5], shadowSamplers[zeroi+8]), vec3(inpos, 0.3f));
|
|
float z = texture(sampler2DShadow(sampledImages[zeroi+5], shadowSamplers[zeroi+8]), vec3(inpos, 0.7f));
|
|
float w = texture(sampler2DShadow(sampledImages[zeroi+5], shadowSamplers[zeroi+8]), vec3(inpos, 0.9f));
|
|
Color = vec4(x, y, z, w);
|
|
break;
|
|
}
|
|
#endif
|
|
)EOSHADER"
|
|
R"EOSHADER(
|
|
case 153:
|
|
{
|
|
vec3 cubeCoord = vec3(1.0f, -0.3f, 0.9f);
|
|
Color = textureLod(cubeSampler, cubeCoord, 0.0f);
|
|
break;
|
|
}
|
|
case 154:
|
|
{
|
|
vec3 cubeCoord = vec3(-1.0f, -0.3f, 0.9f);
|
|
Color = textureLod(cubeSampler, cubeCoord, 0.0f);
|
|
break;
|
|
}
|
|
case 155:
|
|
{
|
|
vec3 cubeCoord = vec3(-1.0f, 0.3f, 0.9f);
|
|
Color = textureLod(cubeSampler, cubeCoord, 0.0f);
|
|
break;
|
|
}
|
|
case 156:
|
|
{
|
|
vec3 cubeCoord = vec3(-1.0f, 0.3f, -0.9f);
|
|
Color = textureLod(cubeSampler, cubeCoord, 0.0f);
|
|
break;
|
|
}
|
|
case 157:
|
|
{
|
|
uint old = atomicAdd(atomicbuf.data[flatGlobalCoord].x, flatGlobalCoord);
|
|
Color = vec4(float(old & 0xfffff), float(atomicbuf.data[flatGlobalCoord].x & 0xfffff), 0.0f, 0.0f);
|
|
break;
|
|
}
|
|
case 158:
|
|
{
|
|
uint old = atomicOr(atomicbuf.data[flatGlobalCoord].x, 0x55555555U);
|
|
Color = vec4(float(old & 0xfffff), float(atomicbuf.data[flatGlobalCoord].x & 0xfffff), 0.0f, 0.0f);
|
|
break;
|
|
}
|
|
case 159:
|
|
{
|
|
uint old = atomicXor(atomicbuf.data[flatGlobalCoord].x, 0x55555555U);
|
|
Color = vec4(float(old & 0xfffff), float(atomicbuf.data[flatGlobalCoord].x & 0xfffff), 0.0f, 0.0f);
|
|
break;
|
|
}
|
|
case 160:
|
|
{
|
|
uint old = atomicMax(atomicbuf.data[flatGlobalCoord].x, 0x55555555U);
|
|
uint old2 = atomicMax(atomicbuf.data[flatGlobalCoord].y, 0x38383838U);
|
|
Color = vec4(float(old & 0xfffff), float(atomicbuf.data[flatGlobalCoord].x & 0xfffff),
|
|
float(old2 & 0xfffff), float(atomicbuf.data[flatGlobalCoord].y & 0xfffff));
|
|
break;
|
|
}
|
|
case 161:
|
|
{
|
|
uint old = atomicMin(atomicbuf.data[flatGlobalCoord].x, 0x55555555U);
|
|
uint old2 = atomicMin(atomicbuf.data[flatGlobalCoord].y, 0x38383838U);
|
|
Color = vec4(float(old & 0xfffff), float(atomicbuf.data[flatGlobalCoord].x & 0xfffff),
|
|
float(old2 & 0xfffff), float(atomicbuf.data[flatGlobalCoord].y & 0xfffff));
|
|
break;
|
|
}
|
|
case 162:
|
|
{
|
|
uint old = atomicExchange(atomicbuf.data[flatGlobalCoord].x, 0x12345678U);
|
|
Color = vec4(float(old & 0xfffff), float(atomicbuf.data[flatGlobalCoord].x & 0xfffff), 0.0f, 0.0f);
|
|
break;
|
|
}
|
|
case 163:
|
|
{
|
|
uint old = atomicCompSwap(atomicbuf.data[flatGlobalCoord].x, 0x55555555U, 0x12345678U);
|
|
uint old2 = atomicCompSwap(atomicbuf.data[flatGlobalCoord].y, 0x42424242U, 0x12345678U);
|
|
Color = vec4(float(old & 0xfffff), float(atomicbuf.data[flatGlobalCoord].x & 0xfffff),
|
|
float(old2 & 0xfffff), float(atomicbuf.data[flatGlobalCoord].y & 0xfffff));
|
|
break;
|
|
}
|
|
case 164:
|
|
{
|
|
uint old = imageAtomicAdd(atomicimg, ivec2(gl_FragCoord), flatGlobalCoord);
|
|
Color = vec4(float(old & 0xfffff), float(imageLoad(atomicimg, ivec2(gl_FragCoord)).x & 0xfffff), 0.0f, 0.0f);
|
|
break;
|
|
}
|
|
case 165:
|
|
{
|
|
uint old = imageAtomicOr(atomicimg, ivec2(gl_FragCoord), 0x55555555U);
|
|
Color = vec4(float(old & 0xfffff), float(imageLoad(atomicimg, ivec2(gl_FragCoord)).x & 0xfffff), 0.0f, 0.0f);
|
|
break;
|
|
}
|
|
case 166:
|
|
{
|
|
uint old = imageAtomicXor(atomicimg, ivec2(gl_FragCoord), 0x55555555U);
|
|
Color = vec4(float(old & 0xfffff), float(imageLoad(atomicimg, ivec2(gl_FragCoord)).x & 0xfffff), 0.0f, 0.0f);
|
|
break;
|
|
}
|
|
case 167:
|
|
{
|
|
uint old = imageAtomicMax(atomicimg, ivec2(gl_FragCoord), 0x55555555U);
|
|
Color = vec4(float(old & 0xfffff), float(imageLoad(atomicimg, ivec2(gl_FragCoord)).x & 0xfffff), 0.0f, 0.0f);
|
|
break;
|
|
}
|
|
case 168:
|
|
{
|
|
uint old = imageAtomicMin(atomicimg, ivec2(gl_FragCoord), 0x55555555U);
|
|
Color = vec4(float(old & 0xfffff), float(imageLoad(atomicimg, ivec2(gl_FragCoord)).x & 0xfffff), 0.0f, 0.0f);
|
|
break;
|
|
}
|
|
case 169:
|
|
{
|
|
uint old = imageAtomicExchange(atomicimg, ivec2(gl_FragCoord), 0x12345678U);
|
|
Color = vec4(float(old & 0xfffff), float(imageLoad(atomicimg, ivec2(gl_FragCoord)).x & 0xfffff), 0.0f, 0.0f);
|
|
break;
|
|
}
|
|
case 170:
|
|
{
|
|
uint old = imageAtomicCompSwap(atomicimg, ivec2(gl_FragCoord), 0x55555555U, 0x12345678U);
|
|
Color = vec4(float(old & 0xfffff), float(imageLoad(atomicimg, ivec2(gl_FragCoord)).x & 0xfffff), 0.0f, 0.0f);
|
|
break;
|
|
}
|
|
case 171:
|
|
{
|
|
vec4 ret = vec4(0,0,0,0);
|
|
// test loop continues
|
|
for(int i=0; i < flatLocalCoord + 5; i++)
|
|
{
|
|
ret.x += 0.1f;
|
|
if(i == 2)
|
|
{
|
|
ret.y += 0.2f;
|
|
continue;
|
|
}
|
|
ret.z += 0.1f;
|
|
if(i == 4)
|
|
{
|
|
continue;
|
|
}
|
|
ret.w += 0.1f;
|
|
}
|
|
Color = ret;
|
|
break;
|
|
}
|
|
case 172:
|
|
{
|
|
vec4 ret = vec4(0,0,0,0);
|
|
// test loop breaks
|
|
for(int i=0; i < flatLocalCoord + 5; i++)
|
|
{
|
|
ret.x += 0.1f;
|
|
if(i == 2)
|
|
{
|
|
break;
|
|
}
|
|
ret.y += 0.2f;
|
|
}
|
|
Color = ret;
|
|
break;
|
|
}
|
|
// test fall through
|
|
case 173:
|
|
Color += vec4(0.5, 0.5, 0.5, 0.5);
|
|
case 174:
|
|
{
|
|
Color += vec4(1.0, 1.0, 1.0, 1.0);
|
|
break;
|
|
}
|
|
case 175:
|
|
{
|
|
// this isn't really intended as a true test but more a convenience for manual testing.
|
|
Color = varscope_test(flatLocalCoord, inpos, inposIncreased);
|
|
break;
|
|
}
|
|
case 176:
|
|
{
|
|
ivec2 coord = ivec2(zeroi + 20, zeroi + 20);
|
|
Color = texelFetch(sampledImages[cbuf.uniformIndex+1], coord, 0);
|
|
mat4 mat;
|
|
// force out of bounds matrix lookup to make sure it doesn't crash
|
|
float temp = mat[int(Color.r)+70][int(Color.g)+80];
|
|
if (int(temp/(temp+10000.0)) == 1)
|
|
{
|
|
Color.r = Color.r;
|
|
}
|
|
Color += vec4(1.0, 1.0, 1.0, 1.0);
|
|
break;
|
|
}
|
|
case 177:
|
|
{
|
|
Color = imageLoad(storeTexBuffer, 1) + imageLoad(storeTexBuffer, 4);
|
|
break;
|
|
}
|
|
case 178:
|
|
{
|
|
imageStore(storeTexBuffer, 5, vec4(3.1f, 4.1f, 5.9f, 2.6f));
|
|
Color = imageLoad(storeTexBuffer, 5);
|
|
break;
|
|
}
|
|
case 179:
|
|
{
|
|
Color = texelFetch(texBuffer1010102unorm, int(1));
|
|
break;
|
|
}
|
|
case 180:
|
|
{
|
|
Color = vec4(texelFetch(texBuffer1010102uint, int(1)));
|
|
break;
|
|
}
|
|
case 181:
|
|
{
|
|
Color = imageLoad(storeTexBuffer1010102unorm, int(1)) + imageLoad(storeTexBuffer1010102unorm, int(4));
|
|
break;
|
|
}
|
|
case 182:
|
|
{
|
|
Color = vec4(imageLoad(storeTexBuffer1010102uint, int(1))) + vec4(imageLoad(storeTexBuffer1010102uint, int(4)));
|
|
break;
|
|
}
|
|
case 183:
|
|
{
|
|
imageStore(storeTexBuffer1010102unorm, 5, vec4(200.1f/1023.0f, 400.1f/1023.0f, 800.1f/1023.0f, 1.0f));
|
|
Color = imageLoad(storeTexBuffer1010102unorm, int(1)) + imageLoad(storeTexBuffer1010102unorm, int(5));
|
|
break;
|
|
}
|
|
case 184:
|
|
{
|
|
imageStore(storeTexBuffer1010102uint, 5, uvec4(20, 40, 80, 1));
|
|
Color = vec4(imageLoad(storeTexBuffer1010102uint, int(1))) + vec4(imageLoad(storeTexBuffer1010102uint, int(5)));
|
|
break;
|
|
}
|
|
case 185:
|
|
{
|
|
// this is intended to test triggering a mixture of GPU math and GPU sample ops
|
|
vec2 coord = vec2(zerof + 0.5, zerof + 0.15);
|
|
if (localCoord.x % 2 == 0)
|
|
{
|
|
Color = textureLod(sampler2D(sampledImage, pointSampler), coord, 0.0);
|
|
for (int i = 0; i < 100; i++)
|
|
{
|
|
Color += textureLod(sampler2D(sampledImage, pointSampler), coord, float(i));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Color = vec4(pow(posone*2.5f, posone*1.3f), pow(posone*2.5f, posone*0.45f),
|
|
pow(vec2(posone*2.5f, posone*1.3f), vec2(posone*0.9f, posone*8.5f)));
|
|
for (int i = 0; i < 100; i++)
|
|
{
|
|
vec4 value = vec4(pow(posone*2.5f+float(i), posone*1.3f), pow(posone*2.5f, posone*0.45f),
|
|
pow(vec2(posone*2.5f, posone*1.3f), vec2(posone*0.9f, posone*8.5f)));
|
|
Color += value / 100.0;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
)EOSHADER";
|
|
|
|
std::string vertex2 = R"EOSHADER(
|
|
#version 460 core
|
|
|
|
layout(location = 0) in vec4 pos;
|
|
layout(location = 1) in float zero;
|
|
layout(location = 2) in float one;
|
|
layout(location = 3) in float negone;
|
|
layout(location = 4) in vec2 texcoord;
|
|
|
|
layout(location = 0, component = 0) flat out uint test;
|
|
layout(location = 0, component = 1) flat out int zeroi;
|
|
layout(location = 0, component = 2) flat out uint intval;
|
|
|
|
layout(location = 1, component = 1) out vec3 uv;
|
|
|
|
struct nested
|
|
{
|
|
float c; // location 4
|
|
vec2 d; // location 5
|
|
};
|
|
|
|
struct iostruct
|
|
{
|
|
float a; // location 2
|
|
float b; // location 3
|
|
nested n;
|
|
};
|
|
|
|
layout(location = 2) out iostruct str;
|
|
|
|
layout(location = 6) out mat3 matrix;
|
|
|
|
layout(location = 9) out vec3 arr[3];
|
|
|
|
void main()
|
|
{
|
|
test = gl_InstanceIndex;
|
|
|
|
gl_Position = vec4(pos.x + pos.z * float(test % 256), pos.y + pos.w * float(test / 256), 0.0, 1.0);
|
|
|
|
zeroi = 0;
|
|
intval = test + 7u;
|
|
|
|
uv = vec3(texcoord.xy, pos.x);
|
|
|
|
vec4 test = vec4(uv.x + 1.0f, uv.y + 2.0f, uv.x + 3.0f, uv.y + 4.0f);
|
|
|
|
str.a = test.x;
|
|
str.b = test.y;
|
|
str.n.c = test.z;
|
|
str.n.d = vec2(test.w, 3.141592f);
|
|
|
|
test *= 1.5f;
|
|
|
|
matrix = mat3((test * 2.0f).xyz, (test * 3.0f).xyz, (test * 4.0f).xyz);
|
|
|
|
arr[0] = (test * 5.0f).yzw;
|
|
arr[1] = (test * 6.0f).yzw;
|
|
arr[2] = (test * 7.0f).yzw;
|
|
}
|
|
|
|
)EOSHADER";
|
|
|
|
std::string pixel_glsl2 = pixel_glsl_header + R"EOSHADER(
|
|
|
|
layout(location = 0, component = 0) flat in uint test;
|
|
layout(location = 0, component = 1) flat in int zeroi;
|
|
layout(location = 0, component = 2) flat in uint intval;
|
|
|
|
layout(location = 1, component = 1) in vec3 uv;
|
|
|
|
struct nested
|
|
{
|
|
float c; // location 4
|
|
vec2 d; // location 5
|
|
};
|
|
|
|
struct iostruct
|
|
{
|
|
float a; // location 2
|
|
float b; // location 3
|
|
nested n;
|
|
};
|
|
|
|
layout(location = 2) in iostruct str;
|
|
|
|
layout(location = 6) in mat3 matrix;
|
|
|
|
layout(location = 9) in vec3 arr[3];
|
|
|
|
layout(location = 0) out vec4 Color;
|
|
|
|
void main()
|
|
{
|
|
float zerof = float(zeroi);
|
|
Color = vec4(0,0,0,0);
|
|
switch(test)
|
|
{
|
|
case 0:
|
|
{
|
|
// test loading from the storage buffer (after a nice big barrier)
|
|
Color = storebuf.x;
|
|
break;
|
|
}
|
|
case 1:
|
|
{
|
|
// test loading from the storage buffer (after a nice big barrier)
|
|
Color = vec4(storebuf.y.val);
|
|
break;
|
|
}
|
|
case 2:
|
|
{
|
|
// test loading from the storage buffer (after a nice big barrier)
|
|
Color = storebuf.arr[intval - test];
|
|
break;
|
|
}
|
|
case 3:
|
|
{
|
|
Color = imageLoad(storeImage, ivec2(zeroi+1,zeroi+3));
|
|
break;
|
|
}
|
|
case 4:
|
|
{
|
|
Color = vec4(test, zeroi, intval, 1.0f);
|
|
break;
|
|
}
|
|
case 5:
|
|
{
|
|
Color = vec4(uv.xyz, 1.0f);
|
|
break;
|
|
}
|
|
case 6:
|
|
{
|
|
Color = vec4(str.a, str.b, str.n.c, length(str.n.d));
|
|
break;
|
|
}
|
|
case 7:
|
|
{
|
|
Color = matrix[0].xyzx;
|
|
break;
|
|
}
|
|
case 8:
|
|
{
|
|
Color = matrix[1].xyzx;
|
|
break;
|
|
}
|
|
case 9:
|
|
{
|
|
Color = matrix[2].xyzx;
|
|
break;
|
|
}
|
|
case 10:
|
|
{
|
|
Color = arr[0].xyzx;
|
|
break;
|
|
}
|
|
case 11:
|
|
{
|
|
Color = arr[1].xyzx;
|
|
break;
|
|
}
|
|
case 12:
|
|
{
|
|
Color = arr[2].xyzx;
|
|
break;
|
|
}
|
|
case 13:
|
|
{
|
|
Color = vec4(0,0,0,0);
|
|
uint loopCount = uint(intval - test);
|
|
loopCount -= (uint(gl_FragCoord.x) % 2u);
|
|
loopCount -= (uint(gl_FragCoord.y) % 2u) * 2u;
|
|
vec2 val = uv.xy;
|
|
for(uint i=0; i < loopCount; i++)
|
|
{
|
|
val += vec2(0.01f, 0.01f);
|
|
}
|
|
Color = dFdxFine(val).xyxy;
|
|
break;
|
|
}
|
|
case 14:
|
|
{
|
|
Color = vec4(0,0,0,0);
|
|
uint loopCount = uint(intval - test);
|
|
loopCount += (uint(gl_FragCoord.x) % 2u);
|
|
loopCount += (uint(gl_FragCoord.y) % 2u) * 2u;
|
|
vec2 val = uv.xy;
|
|
for(uint i=0; i < loopCount; i++)
|
|
{
|
|
val += vec2(0.01f, 0.01f);
|
|
}
|
|
Color = dFdxFine(val).xyxy;
|
|
break;
|
|
}
|
|
#if TEST_DESC_INDEXING
|
|
case 15:
|
|
{
|
|
// test loading from the storage buffer (after a nice big barrier)
|
|
Color = storebufs[zeroi+7].x;
|
|
break;
|
|
}
|
|
case 16:
|
|
{
|
|
// test loading from the storage buffer (after a nice big barrier)
|
|
Color = vec4(storebufs[zeroi+7].y.val);
|
|
break;
|
|
}
|
|
case 17:
|
|
{
|
|
// test loading from the storage buffer (after a nice big barrier)
|
|
Color = storebufs[zeroi+7].arr[intval - test];
|
|
break;
|
|
}
|
|
case 18:
|
|
{
|
|
Color = imageLoad(storeImages[zeroi+7], ivec2(zeroi+1,zeroi+3));
|
|
break;
|
|
}
|
|
#endif
|
|
case 19:
|
|
{
|
|
Color = gl_FrontFacing ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
|
|
break;
|
|
}
|
|
case 20:
|
|
{
|
|
Color = imageLoad(storeTexBuffer, 1)+imageLoad(storeTexBuffer, 5);
|
|
break;
|
|
}
|
|
case 21:
|
|
{
|
|
Color = imageLoad(storeTexBuffer1010102unorm, int(1)) + imageLoad(storeTexBuffer1010102unorm, int(5));
|
|
}
|
|
case 22:
|
|
{
|
|
Color = vec4(imageLoad(storeTexBuffer1010102uint, int(1))) + vec4(imageLoad(storeTexBuffer1010102uint, int(5)));
|
|
}
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
)EOSHADER";
|
|
|
|
std::string capabilities = "OpCapability Shader\n";
|
|
std::string spv_extensions;
|
|
std::string extinstimport =
|
|
R"EOSHADER(
|
|
%glsl450 = OpExtInstImport "GLSL.std.450"
|
|
)EOSHADER";
|
|
std::string executionmodes =
|
|
R"EOSHADER(
|
|
OpExecutionMode %main OriginUpperLeft
|
|
)EOSHADER";
|
|
std::string spv_debug =
|
|
R"EOSHADER(
|
|
%filename = OpString "file.foo"
|
|
)EOSHADER";
|
|
std::string decorations = R"EOSHADER(
|
|
OpDecorate %flatData Flat
|
|
OpDecorate %flatData Location 1
|
|
OpDecorate %linearData Location 3
|
|
OpDecorate %Color Index 0
|
|
OpDecorate %Color Location 0
|
|
OpDecorate %gl_FragCoord BuiltIn FragCoord
|
|
|
|
OpDecorate %rtarray_float4 ArrayStride 16
|
|
OpMemberDecorate %dummy 0 Offset 0
|
|
OpMemberDecorate %dummy 1 Offset 16
|
|
OpMemberDecorate %buftype 0 Offset 0
|
|
OpMemberDecorate %buftype 1 Offset 64
|
|
OpMemberDecorate %buftype 2 Offset 128
|
|
OpMemberDecorate %buftype 3 Offset 144
|
|
OpMemberDecorate %buftype 4 Offset 176
|
|
|
|
OpMemberDecorate %buftype 0 MatrixStride 16
|
|
OpMemberDecorate %buftype 0 RowMajor
|
|
|
|
OpMemberDecorate %buftype 1 MatrixStride 16
|
|
OpMemberDecorate %buftype 1 ColMajor
|
|
|
|
OpDecorate %buftype BufferBlock
|
|
OpDecorate %buffer DescriptorSet 0
|
|
OpDecorate %buffer Binding 15
|
|
)EOSHADER";
|
|
std::string typesConstants = R"EOSHADER(
|
|
%void = OpTypeVoid
|
|
%bool = OpTypeBool
|
|
%float = OpTypeFloat 32
|
|
%uint = OpTypeInt 32 0
|
|
%int = OpTypeInt 32 1
|
|
|
|
%float2 = OpTypeVector %float 2
|
|
%float3 = OpTypeVector %float 3
|
|
%float4 = OpTypeVector %float 4
|
|
|
|
%int2 = OpTypeVector %int 2
|
|
%int3 = OpTypeVector %int 3
|
|
%int4 = OpTypeVector %int 4
|
|
|
|
%uint2 = OpTypeVector %uint 2
|
|
%uint3 = OpTypeVector %uint 3
|
|
%uint4 = OpTypeVector %uint 4
|
|
|
|
%float2x2 = OpTypeMatrix %float2 2
|
|
%float3x3 = OpTypeMatrix %float3 3
|
|
%float2x4 = OpTypeMatrix %float2 4
|
|
%float4x2 = OpTypeMatrix %float4 2
|
|
%float4x4 = OpTypeMatrix %float4 4
|
|
|
|
%mainfunc = OpTypeFunction %void
|
|
%doublerfunc = OpTypeFunction %float %float
|
|
|
|
%rtarray_float4 = OpTypeRuntimeArray %float4
|
|
|
|
%v2f = OpTypeStruct %float2 %float2 %float2 %float %float %float
|
|
%flatv2f = OpTypeStruct %uint %uint
|
|
|
|
%child = OpTypeStruct %float4 %float3 %float
|
|
%parent = OpTypeStruct %float4 %child %float4x4
|
|
|
|
%f32f32 = OpTypeStruct %float %float
|
|
%f32i32 = OpTypeStruct %float %int
|
|
|
|
%dummy = OpTypeStruct %uint4 %uint4
|
|
%buftype = OpTypeStruct %float4x4 %float4x4 %float4 %dummy %rtarray_float4
|
|
|
|
%ptr_Input_v2f = OpTypePointer Input %v2f
|
|
%ptr_Input_flatv2f = OpTypePointer Input %flatv2f
|
|
%ptr_Input_uint = OpTypePointer Input %uint
|
|
%ptr_Input_int = OpTypePointer Input %int
|
|
%ptr_Input_float = OpTypePointer Input %float
|
|
%ptr_Input_float2 = OpTypePointer Input %float2
|
|
%ptr_Input_float4 = OpTypePointer Input %float4
|
|
%ptr_Output_float4 = OpTypePointer Output %float4
|
|
%ptr_Private_int = OpTypePointer Private %int
|
|
%ptr_Private_float = OpTypePointer Private %float
|
|
%ptr_Private_float4 = OpTypePointer Private %float4
|
|
%ptr_Private_float4x4 = OpTypePointer Private %float4x4
|
|
|
|
%ptr_Function_float = OpTypePointer Function %float
|
|
|
|
%ptr_Uniform_float = OpTypePointer Uniform %float
|
|
%ptr_Uniform_float2 = OpTypePointer Uniform %float2
|
|
%ptr_Uniform_float3 = OpTypePointer Uniform %float3
|
|
%ptr_Uniform_float4 = OpTypePointer Uniform %float4
|
|
|
|
%ptr_Uniform_uint = OpTypePointer Uniform %uint
|
|
%ptr_Uniform_uint2 = OpTypePointer Uniform %uint2
|
|
%ptr_Uniform_uint3 = OpTypePointer Uniform %uint3
|
|
%ptr_Uniform_uint4 = OpTypePointer Uniform %uint4
|
|
|
|
%ptr_Uniform_int = OpTypePointer Uniform %int
|
|
%ptr_Uniform_int2 = OpTypePointer Uniform %int2
|
|
%ptr_Uniform_int3 = OpTypePointer Uniform %int3
|
|
%ptr_Uniform_int4 = OpTypePointer Uniform %int4
|
|
|
|
%ptr_Uniform_float4x4 = OpTypePointer Uniform %float4x4
|
|
|
|
%ptr_Uniform_dummy = OpTypePointer Uniform %dummy
|
|
%ptr_Uniform_buftype = OpTypePointer Uniform %buftype
|
|
|
|
%linearData = OpVariable %ptr_Input_v2f Input
|
|
%flatData = OpVariable %ptr_Input_flatv2f Input
|
|
%gl_FragCoord = OpVariable %ptr_Input_float4 Input
|
|
%Color = OpVariable %ptr_Output_float4 Output
|
|
|
|
%priv_int = OpVariable %ptr_Private_int Private
|
|
%priv_float = OpVariable %ptr_Private_float Private
|
|
%priv_float4 = OpVariable %ptr_Private_float4 Private
|
|
%priv_float4x4 = OpVariable %ptr_Private_float4x4 Private
|
|
|
|
%buffer = OpVariable %ptr_Uniform_buftype Uniform
|
|
|
|
%flatv2f_test_idx = OpConstant %int 0
|
|
%flatv2f_intval_idx = OpConstant %int 1
|
|
|
|
%v2f_zeroVal_idx = OpConstant %int 0
|
|
%v2f_inpos_idx = OpConstant %int 1
|
|
%v2f_inposIncreased_idx = OpConstant %int 2
|
|
%v2f_tinyVal_idx = OpConstant %int 3
|
|
%v2f_oneVal_idx = OpConstant %int 4
|
|
%v2f_negoneVal_idx = OpConstant %int 5
|
|
|
|
)EOSHADER";
|
|
std::string functions = R"EOSHADER(
|
|
|
|
%doubler = OpFunction %float None %doublerfunc
|
|
OpLine %filename 123 456
|
|
OpNoLine
|
|
OpLine %filename 111 222
|
|
%doubler_in = OpFunctionParameter %float
|
|
OpNoLine
|
|
OpLine %filename 99 55
|
|
OpLine %filename 199 155
|
|
%doubler_begin = OpLabel
|
|
OpLine %filename 299 255
|
|
%doubler_tmp = OpVariable %ptr_Function_float Function
|
|
OpLine %filename 399 355
|
|
%doubler_ret = OpFMul %float %float_2_0 %doubler_in
|
|
OpLine %filename 499 455
|
|
OpStore %doubler_tmp %doubler_ret
|
|
OpLine %filename 599 555
|
|
%doubler_ret2 = OpLoad %float %doubler_tmp
|
|
OpLine %filename 699 655
|
|
OpReturnValue %doubler_ret2
|
|
OpLine %filename 799 755
|
|
OpFunctionEnd
|
|
)EOSHADER";
|
|
std::vector<std::string> asm_tests;
|
|
|
|
void append_tests(const std::initializer_list<std::string> &tests)
|
|
{
|
|
asm_tests.insert(asm_tests.end(), tests.begin(), tests.end());
|
|
}
|
|
|
|
void make_asm_tests()
|
|
{
|
|
std::vector<std::string> ret;
|
|
|
|
// test binary float maths operations
|
|
for(const std::string &op : {"OpFAdd", "OpFSub", "OpFMul", "OpFDiv", "OpFMod", "OpFRem"})
|
|
{
|
|
bool div = (op == "OpFDiv" || op == "OpFMod" || op == "OpFRem");
|
|
bool mod = (op == "OpFMod" || op == "OpFRem");
|
|
for(const std::string &a : {"15_75", "4_5"})
|
|
{
|
|
for(const std::string &b : {"15_75", "4_5"})
|
|
{
|
|
// don't test A mod A
|
|
if(mod && a == b)
|
|
continue;
|
|
|
|
// test A op B and B op A, with neg/pos and dyn/const
|
|
append_tests({
|
|
fmt::format("%_x = {0} %float %float_{1} %float_{2}\n"
|
|
"%_y = {0} %float %float_neg{1} %float_{2}\n"
|
|
"%_z = {0} %float %float_{2} %float_{1}\n"
|
|
"%_w = {0} %float %float_neg{2} %float_{1}\n"
|
|
"%_out_float4 = OpCompositeConstruct %float4 %_x %_y %_z %_w\n",
|
|
op, a, b),
|
|
fmt::format("%_x = {0} %float %float_dyn_{1} %float_dyn_{2}\n"
|
|
"%_y = {0} %float %float_dyn_neg{1} %float_dyn_{2}\n"
|
|
"%_z = {0} %float %float_dyn_{2} %float_dyn_{1}\n"
|
|
"%_w = {0} %float %float_dyn_neg{2} %float_dyn_{1}\n"
|
|
"%_out_float4 = OpCompositeConstruct %float4 %_x %_y %_z %_w\n",
|
|
op, a, b),
|
|
});
|
|
|
|
if(features.shaderFloat64)
|
|
{
|
|
append_tests({
|
|
fmt::format("%_x = {0} %double %double_{1} %double_{2}\n"
|
|
"%_y = {0} %double %double_neg{1} %double_{2}\n"
|
|
"%_z = {0} %double %double_{2} %double_{1}\n"
|
|
"%_w = {0} %double %double_neg{2} %double_{1}\n"
|
|
"%_out_double4 = OpCompositeConstruct %double4 %_x %_y %_z %_w\n",
|
|
op, a, b),
|
|
fmt::format("%_x = {0} %double %double_dyn_{1} %double_dyn_{2}\n"
|
|
"%_y = {0} %double %double_dyn_neg{1} %double_dyn_{2}\n"
|
|
"%_z = {0} %double %double_dyn_{2} %double_dyn_{1}\n"
|
|
"%_w = {0} %double %double_dyn_neg{2} %double_dyn_{1}\n"
|
|
"%_out_double4 = OpCompositeConstruct %double4 %_x %_y %_z %_w\n",
|
|
op, a, b),
|
|
});
|
|
}
|
|
|
|
// also test 0 op A/B
|
|
|
|
append_tests({
|
|
fmt::format("%_x = {0} %float %float_0_0 %float_{1}\n"
|
|
"%_y = {0} %float %float_0_0 %float_{2}\n"
|
|
"%_z = {0} %float %float_0_0 %float_{3}{1}\n"
|
|
"%_w = {0} %float %float_0_0 %float_{3}{2}\n"
|
|
"%_out_float4 = OpCompositeConstruct %float4 %_x %_y %_z %_w\n",
|
|
op, a, b, mod ? "" : "neg"),
|
|
fmt::format("%_x = {0} %float %float_dyn_0_0 %float_dyn_{1}\n"
|
|
"%_y = {0} %float %float_dyn_0_0 %float_dyn_{2}\n"
|
|
"%_z = {0} %float %float_dyn_0_0 %float_dyn_{3}{1}\n"
|
|
"%_w = {0} %float %float_dyn_0_0 %float_dyn_{3}{2}\n"
|
|
"%_out_float4 = OpCompositeConstruct %float4 %_x %_y %_z %_w\n",
|
|
op, a, b, mod ? "" : "neg"),
|
|
});
|
|
|
|
// if this isn't a divide, test A/B op 0
|
|
if(!div)
|
|
{
|
|
append_tests({
|
|
fmt::format("%_x = {0} %float %float_{1} %float_0_0\n"
|
|
"%_y = {0} %float %float_neg{1} %float_0_0\n"
|
|
"%_z = {0} %float %float_{2} %float_0_0\n"
|
|
"%_w = {0} %float %float_neg{2} %float_0_0\n"
|
|
"%_out_float4 = OpCompositeConstruct %float4 %_x %_y %_z %_w\n",
|
|
op, a, b),
|
|
fmt::format("%_x = {0} %float %float_dyn_{1} %float_dyn_0_0\n"
|
|
"%_y = {0} %float %float_dyn_neg{1} %float_dyn_0_0\n"
|
|
"%_z = {0} %float %float_dyn_{2} %float_dyn_0_0\n"
|
|
"%_w = {0} %float %float_dyn_neg{2} %float_dyn_0_0\n"
|
|
"%_out_float4 = OpCompositeConstruct %float4 %_x %_y %_z %_w\n",
|
|
op, a, b),
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// test binary int maths operations
|
|
for(const std::string &op :
|
|
{"OpIAdd", "OpISub", "OpIMul", "OpSDiv", "OpSMod", "OpSRem", "OpUDiv", "OpUMod"})
|
|
{
|
|
bool div =
|
|
(op == "OpSDiv" || op == "OpSMod" || op == "OpSRem" || op == "OpUDiv" || op == "OpUMod");
|
|
bool mod = (op == "OpSMod" || op == "OpSRem" || op == "OpUMod");
|
|
bool sign = op.find('U') == std::string::npos;
|
|
for(uint32_t a : {15, 4})
|
|
{
|
|
for(uint32_t b : {15, 4})
|
|
{
|
|
// don't test A mod A
|
|
if(mod && a == b)
|
|
continue;
|
|
|
|
// test A op B for uint and int (positive)
|
|
append_tests({
|
|
fmt::format("%_x = {0} %uint %uint_{1} %uint_{2}\n"
|
|
"%_y = {0} %uint %uint_dyn_{1} %uint_{2}\n"
|
|
"%_z = {0} %uint %uint_{2} %uint_{1}\n"
|
|
"%_w = {0} %uint %uint_dyn_{2} %uint_{1}\n"
|
|
"%_out_uint4 = OpCompositeConstruct %uint4 %_x %_y %_z %_w\n",
|
|
op, a, b),
|
|
fmt::format("%_x = {0} %uint %uint_0 %uint_{1}\n"
|
|
"%_y = {0} %uint %uint_0 %uint_dyn_{1}\n"
|
|
"%_z = {0} %uint %uint_0 %uint_{2}\n"
|
|
"%_w = {0} %uint %uint_0 %uint_dyn_{2}\n"
|
|
"%_out_uint4 = OpCompositeConstruct %uint4 %_x %_y %_z %_w\n",
|
|
op, a, b),
|
|
});
|
|
|
|
// if this is a signed op, test negative values too
|
|
if(sign && !mod)
|
|
{
|
|
append_tests({
|
|
fmt::format("%_x = {0} %int %int_{1} %int_{2}\n"
|
|
"%_y = {0} %int %int_dyn_{1} %int_{2}\n"
|
|
"%_z = {0} %int %int_{2} %int_{1}\n"
|
|
"%_w = {0} %int %int_dyn_{2} %int_{1}\n"
|
|
"%_out_int4 = OpCompositeConstruct %int4 %_x %_y %_z %_w\n",
|
|
op, a, b),
|
|
fmt::format("%_x = {0} %int %int_0 %int_{1}\n"
|
|
"%_y = {0} %int %int_0 %int_dyn_{1}\n"
|
|
"%_z = {0} %int %int_0 %int_{2}\n"
|
|
"%_w = {0} %int %int_0 %int_dyn_{2}\n"
|
|
"%_out_int4 = OpCompositeConstruct %int4 %_x %_y %_z %_w\n",
|
|
op, a, b),
|
|
fmt::format("%_x = {0} %int %int_neg{1} %int_{2}\n"
|
|
"%_y = {0} %int %int_dyn_neg{1} %int_{2}\n"
|
|
"%_z = {0} %int %int_neg{2} %int_{1}\n"
|
|
"%_w = {0} %int %int_dyn_neg{2} %int_{1}\n"
|
|
"%_out_int4 = OpCompositeConstruct %int4 %_x %_y %_z %_w\n",
|
|
op, a, b),
|
|
fmt::format("%_x = {0} %int %int_0 %int_neg{1}\n"
|
|
"%_y = {0} %int %int_0 %int_dyn_neg{1}\n"
|
|
"%_z = {0} %int %int_0 %int_neg{2}\n"
|
|
"%_w = {0} %int %int_0 %int_dyn_neg{2}\n"
|
|
"%_out_int4 = OpCompositeConstruct %int4 %_x %_y %_z %_w\n",
|
|
op, a, b),
|
|
});
|
|
}
|
|
|
|
// if it's not a divide op, test A/B op 0
|
|
if(!div)
|
|
{
|
|
append_tests({
|
|
fmt::format("%_x = {0} %uint %uint_{1} %uint_0\n"
|
|
"%_y = {0} %uint %uint_{2} %uint_0\n"
|
|
"%_z = {0} %uint %uint_dyn_{1} %uint_dyn_0\n"
|
|
"%_w = {0} %uint %uint_dyn_{2} %uint_dyn_0\n"
|
|
"%_out_uint4 = OpCompositeConstruct %uint4 %_x %_y %_z %_w\n",
|
|
op, a, b),
|
|
});
|
|
|
|
// and if it's a signed non-divide op, test -A / -B op 0
|
|
if(sign)
|
|
{
|
|
append_tests({
|
|
fmt::format("%_x = {0} %int %int_neg{1} %int_0\n"
|
|
"%_y = {0} %int %int_neg{2} %int_0\n"
|
|
"%_z = {0} %int %int_dyn_neg{1} %int_dyn_0\n"
|
|
"%_w = {0} %int %int_dyn_neg{2} %int_dyn_0\n"
|
|
"%_out_int4 = OpCompositeConstruct %int4 %_x %_y %_z %_w\n",
|
|
op, a, b),
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// test unary operations
|
|
append_tests({
|
|
"%_x = OpFNegate %float %float_10_0\n"
|
|
"%_y = OpFNegate %float %float_neg10_0\n"
|
|
"%_z = OpFNegate %float %float_dyn_10_0\n"
|
|
"%_w = OpFNegate %float %float_dyn_neg10_0\n"
|
|
"%_out_float4 = OpCompositeConstruct %float4 %_x %_y %_z %_w\n",
|
|
|
|
"%_x = OpFNegate %float %float_0_0\n"
|
|
"%_y = OpFNegate %float %float_neg0_0\n"
|
|
"%_z = OpFNegate %float %float_dyn_0_0\n"
|
|
"%_w = OpFNegate %float %float_dyn_neg0_0\n"
|
|
"%_out_float4 = OpCompositeConstruct %float4 %_x %_y %_z %_w\n",
|
|
|
|
"%_x = OpSNegate %int %int_10\n"
|
|
"%_y = OpSNegate %int %int_neg10\n"
|
|
"%_z = OpSNegate %int %int_dyn_10\n"
|
|
"%_w = OpSNegate %int %int_dyn_neg10\n"
|
|
"%_out_int4 = OpCompositeConstruct %int4 %_x %_y %_z %_w\n",
|
|
|
|
"%_x = OpSNegate %int %int_0\n"
|
|
"%_y = OpSNegate %int %int_neg0\n"
|
|
"%_z = OpSNegate %int %int_dyn_0\n"
|
|
"%_w = OpSNegate %int %int_dyn_neg0\n"
|
|
"%_out_int4 = OpCompositeConstruct %int4 %_x %_y %_z %_w\n",
|
|
});
|
|
|
|
// test bitwise operations
|
|
append_tests({
|
|
"%_x = OpBitwiseOr %uint %uint_0x1234 %uint_0xb9c5\n"
|
|
"%_y = OpBitwiseXor %uint %uint_0x1234 %uint_0xb9c5\n"
|
|
"%_z = OpBitwiseAnd %uint %uint_0x1234 %uint_0xb9c5\n"
|
|
"%_w = OpNot %uint %uint_0x1234 \n"
|
|
"%_out_uint4 = OpCompositeConstruct %uint4 %_x %_y %_z %_w\n",
|
|
|
|
"%_x = OpBitwiseOr %uint %uint_dyn_0x1234 %uint_dyn_0xb9c5\n"
|
|
"%_y = OpBitwiseXor %uint %uint_dyn_0x1234 %uint_dyn_0xb9c5\n"
|
|
"%_z = OpBitwiseAnd %uint %uint_dyn_0x1234 %uint_dyn_0xb9c5\n"
|
|
"%_w = OpNot %uint %uint_dyn_0xb9c5\n"
|
|
"%_out_uint4 = OpCompositeConstruct %uint4 %_x %_y %_z %_w\n",
|
|
|
|
"%_x = OpBitwiseOr %uint %uint_dyn_0x1234 %uint_0\n"
|
|
"%_y = OpBitwiseXor %uint %uint_dyn_0x1234 %uint_0\n"
|
|
"%_z = OpBitwiseAnd %uint %uint_dyn_0x1234 %uint_0\n"
|
|
"%_w = OpNot %uint %uint_0\n"
|
|
"%_out_uint4 = OpCompositeConstruct %uint4 %_x %_y %_z %_w\n",
|
|
|
|
"%_x = OpBitwiseOr %uint %uint_0 %uint_dyn_0xb9c5\n"
|
|
"%_y = OpBitwiseXor %uint %uint_0 %uint_dyn_0xb9c5\n"
|
|
"%_z = OpBitwiseAnd %uint %uint_0 %uint_dyn_0xb9c5\n"
|
|
"%_w = OpNot %uint %uint_dyn_0xb9c5\n"
|
|
"%_out_uint4 = OpCompositeConstruct %uint4 %_x %_y %_z %_w\n",
|
|
});
|
|
|
|
// test shifts
|
|
for(const std::string &op :
|
|
{"OpShiftLeftLogical", "OpShiftRightLogical", "OpShiftRightArithmetic"})
|
|
{
|
|
for(const std::string &dyn : {"", "_dyn"})
|
|
{
|
|
for(const std::string &intType : {"int", "uint"})
|
|
{
|
|
append_tests({
|
|
fmt::format("%_x = {0} %{1} %{1}{2}_0x1234 %uint_0\n"
|
|
"%_y = {0} %{1} %{1}{2}_0x1234 %uint_1\n"
|
|
"%_z = {0} %{1} %{1}{2}_0x1234 %uint_2\n"
|
|
"%_out_{1}3 = OpCompositeConstruct %{1}3 %_x %_y %_z\n",
|
|
op, intType, dyn),
|
|
|
|
fmt::format("%_x = {0} %{1} %{1}_0x1234 %uint{2}_0\n"
|
|
"%_y = {0} %{1} %{1}_0x1234 %uint{2}_1\n"
|
|
"%_z = {0} %{1} %{1}_0x1234 %uint{2}_2\n"
|
|
"%_out_{1}3 = OpCompositeConstruct %{1}3 %_x %_y %_z\n",
|
|
op, intType, dyn),
|
|
|
|
fmt::format("%_x = {0} %{1} %{1}{2}_0x1234 %uint{2}_0\n"
|
|
"%_y = {0} %{1} %{1}{2}_0x1234 %uint{2}_1\n"
|
|
"%_z = {0} %{1} %{1}{2}_0x1234 %uint{2}_2\n"
|
|
"%_out_{1}3 = OpCompositeConstruct %{1}3 %_x %_y %_z\n",
|
|
op, intType, dyn),
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
// test square 2x2 matrix multiplies
|
|
append_tests({
|
|
R"EOTEST(
|
|
%_cola = OpCompositeConstruct %float2 %randf_0 %randf_1
|
|
%_colb = OpCompositeConstruct %float2 %randf_2 %randf_3
|
|
%_mat = OpCompositeConstruct %float2x2 %_cola %_colb
|
|
|
|
%_vec = OpCompositeConstruct %float2 %randf_4 %randf_5
|
|
|
|
%_out_float2 = OpMatrixTimesVector %float2 %_mat %_vec
|
|
)EOTEST",
|
|
R"EOTEST(
|
|
%_cola = OpCompositeConstruct %float2 %randf_0 %randf_1
|
|
%_colb = OpCompositeConstruct %float2 %randf_2 %randf_3
|
|
%_mat = OpCompositeConstruct %float2x2 %_cola %_colb
|
|
|
|
%_vec = OpCompositeConstruct %float2 %randf_4 %randf_5
|
|
|
|
%_out_float2 = OpVectorTimesMatrix %float2 %_vec %_mat
|
|
)EOTEST",
|
|
R"EOTEST(
|
|
%_cola = OpCompositeConstruct %float2 %randf_0 %randf_1
|
|
%_colb = OpCompositeConstruct %float2 %randf_2 %randf_3
|
|
%_mat1 = OpCompositeConstruct %float2x2 %_cola %_colb
|
|
|
|
%_vec = OpCompositeConstruct %float2 %randf_4 %randf_5
|
|
|
|
%_mat2 = OpMatrixTimesScalar %float2x2 %_mat1 %randf_6
|
|
|
|
%_out_float2 = OpVectorTimesMatrix %float2 %_vec %_mat2
|
|
)EOTEST",
|
|
R"EOTEST(
|
|
%_cola = OpCompositeConstruct %float2 %randf_0 %randf_1
|
|
%_colb = OpCompositeConstruct %float2 %randf_2 %randf_3
|
|
%_mat1 = OpCompositeConstruct %float2x2 %_cola %_colb
|
|
|
|
%_vec = OpCompositeConstruct %float2 %randf_4 %randf_5
|
|
|
|
%_colc = OpCompositeConstruct %float2 %randf_6 %randf_7
|
|
%_cold = OpCompositeConstruct %float2 %randf_8 %randf_9
|
|
%_mat2 = OpCompositeConstruct %float2x2 %_colc %_cold
|
|
|
|
%_mat3 = OpMatrixTimesMatrix %float2x2 %_mat1 %_mat2
|
|
|
|
%_out_float2 = OpVectorTimesMatrix %float2 %_vec %_mat3
|
|
)EOTEST",
|
|
R"EOTEST(
|
|
%_cola = OpCompositeConstruct %float2 %randf_0 %randf_1
|
|
%_colb = OpCompositeConstruct %float2 %randf_2 %randf_3
|
|
%_mat1 = OpCompositeConstruct %float2x2 %_cola %_colb
|
|
|
|
%_vec = OpCompositeConstruct %float2 %randf_4 %randf_5
|
|
|
|
%_colc = OpCompositeConstruct %float2 %randf_6 %randf_7
|
|
%_cold = OpCompositeConstruct %float2 %randf_8 %randf_9
|
|
%_mat2 = OpCompositeConstruct %float2x2 %_colc %_cold
|
|
|
|
%_mat3 = OpMatrixTimesMatrix %float2x2 %_mat2 %_mat1
|
|
|
|
%_out_float2 = OpVectorTimesMatrix %float2 %_vec %_mat3
|
|
)EOTEST",
|
|
});
|
|
|
|
// test rectangular 2x4 / 4x2 matrix multiplies
|
|
append_tests({
|
|
R"EOTEST(
|
|
%_cola = OpCompositeConstruct %float4 %randf_0 %randf_1 %randf_2 %randf_3
|
|
%_colb = OpCompositeConstruct %float4 %randf_4 %randf_5 %randf_6 %randf_7
|
|
%_mat = OpCompositeConstruct %float4x2 %_cola %_colb
|
|
|
|
%_vec = OpCompositeConstruct %float4 %randf_16 %randf_17 %randf_18 %randf_19
|
|
|
|
%_out_float2 = OpVectorTimesMatrix %float2 %_vec %_mat
|
|
)EOTEST",
|
|
R"EOTEST(
|
|
%_colc = OpCompositeConstruct %float2 %randf_8 %randf_9
|
|
%_cold = OpCompositeConstruct %float2 %randf_10 %randf_11
|
|
%_cole = OpCompositeConstruct %float2 %randf_12 %randf_13
|
|
%_colf = OpCompositeConstruct %float2 %randf_14 %randf_15
|
|
%_mat = OpCompositeConstruct %float2x4 %_colc %_cold %_cole %_colf
|
|
|
|
%_vec = OpCompositeConstruct %float4 %randf_16 %randf_17 %randf_18 %randf_19
|
|
|
|
%_out_float2 = OpMatrixTimesVector %float2 %_mat %_vec
|
|
)EOTEST",
|
|
R"EOTEST(
|
|
%_cola = OpCompositeConstruct %float4 %randf_0 %randf_1 %randf_2 %randf_3
|
|
%_colb = OpCompositeConstruct %float4 %randf_4 %randf_5 %randf_6 %randf_7
|
|
%_mat = OpCompositeConstruct %float4x2 %_cola %_colb
|
|
|
|
%_vec = OpCompositeConstruct %float2 %randf_16 %randf_17
|
|
|
|
%_out_float4 = OpMatrixTimesVector %float4 %_mat %_vec
|
|
)EOTEST",
|
|
R"EOTEST(
|
|
%_colc = OpCompositeConstruct %float2 %randf_8 %randf_9
|
|
%_cold = OpCompositeConstruct %float2 %randf_10 %randf_11
|
|
%_cole = OpCompositeConstruct %float2 %randf_12 %randf_13
|
|
%_colf = OpCompositeConstruct %float2 %randf_14 %randf_15
|
|
%_mat = OpCompositeConstruct %float2x4 %_colc %_cold %_cole %_colf
|
|
|
|
%_vec = OpCompositeConstruct %float2 %randf_16 %randf_17
|
|
|
|
%_out_float4 = OpVectorTimesMatrix %float4 %_vec %_mat
|
|
)EOTEST",
|
|
R"EOTEST(
|
|
%_cola = OpCompositeConstruct %float4 %randf_0 %randf_1 %randf_2 %randf_3
|
|
%_colb = OpCompositeConstruct %float4 %randf_4 %randf_5 %randf_6 %randf_7
|
|
%_mat1 = OpCompositeConstruct %float4x2 %_cola %_colb
|
|
|
|
%_colc = OpCompositeConstruct %float2 %randf_8 %randf_9
|
|
%_cold = OpCompositeConstruct %float2 %randf_10 %randf_11
|
|
%_cole = OpCompositeConstruct %float2 %randf_12 %randf_13
|
|
%_colf = OpCompositeConstruct %float2 %randf_14 %randf_15
|
|
%_mat2 = OpCompositeConstruct %float2x4 %_colc %_cold %_cole %_colf
|
|
|
|
%_mat = OpMatrixTimesMatrix %float4x4 %_mat1 %_mat2
|
|
|
|
%_vec = OpCompositeConstruct %float4 %randf_16 %randf_17 %randf_18 %randf_19
|
|
|
|
%_out_float4 = OpMatrixTimesVector %float4 %_mat %_vec
|
|
)EOTEST",
|
|
R"EOTEST(
|
|
%_cola = OpCompositeConstruct %float4 %randf_0 %randf_1 %randf_2 %randf_3
|
|
%_colb = OpCompositeConstruct %float4 %randf_4 %randf_5 %randf_6 %randf_7
|
|
%_mat1 = OpCompositeConstruct %float4x2 %_cola %_colb
|
|
|
|
%_colc = OpCompositeConstruct %float4 %randf_8 %randf_9 %randf_10 %randf_11
|
|
%_cold = OpCompositeConstruct %float4 %randf_12 %randf_13 %randf_14 %randf_15
|
|
%_mat2 = OpCompositeConstruct %float4x2 %_colc %_cold
|
|
|
|
%_mat2t = OpTranspose %float2x4 %_mat2
|
|
|
|
%_mat = OpMatrixTimesMatrix %float4x4 %_mat1 %_mat2t
|
|
|
|
%_vec = OpCompositeConstruct %float4 %randf_16 %randf_17 %randf_18 %randf_19
|
|
|
|
%_out_float4 = OpMatrixTimesVector %float4 %_mat %_vec
|
|
)EOTEST",
|
|
R"EOTEST(
|
|
%_cola = OpCompositeConstruct %float4 %randf_0 %randf_1 %randf_2 %randf_3
|
|
%_colb = OpCompositeConstruct %float4 %randf_4 %randf_5 %randf_6 %randf_7
|
|
|
|
%_mat = OpOuterProduct %float4x4 %_cola %_colb
|
|
|
|
%_vec = OpCompositeConstruct %float4 %randf_16 %randf_17 %randf_18 %randf_19
|
|
|
|
%_out_float4 = OpMatrixTimesVector %float4 %_mat %_vec
|
|
)EOTEST",
|
|
R"EOTEST(
|
|
%_vec = OpCompositeConstruct %float4 %randf_0 %randf_1 %randf_2 %randf_3
|
|
%_out_float4 = OpVectorTimesScalar %float4 %_vec %randf_4
|
|
)EOTEST",
|
|
R"EOTEST(
|
|
%_cola = OpCompositeConstruct %float2 %randf_0 %randf_1
|
|
%_colb = OpCompositeConstruct %float2 %randf_4 %randf_5
|
|
%_colc = OpCompositeConstruct %float2 %randf_8 %randf_9
|
|
%_cold = OpCompositeConstruct %float2 %randf_12 %randf_13
|
|
%_mat1 = OpCompositeConstruct %float2x2 %_cola %_colb
|
|
|
|
%_out_float = OpExtInst %float %glsl450 Determinant %_mat1
|
|
)EOTEST",
|
|
R"EOTEST(
|
|
%_cola = OpCompositeConstruct %float3 %randf_0 %randf_1 %randf_2
|
|
%_colb = OpCompositeConstruct %float3 %randf_4 %randf_5 %randf_6
|
|
%_colc = OpCompositeConstruct %float3 %randf_8 %randf_9 %randf_10
|
|
%_mat1 = OpCompositeConstruct %float3x3 %_cola %_colb %_colc
|
|
|
|
%_out_float = OpExtInst %float %glsl450 Determinant %_mat1
|
|
)EOTEST",
|
|
R"EOTEST(
|
|
%_cola = OpCompositeConstruct %float4 %randf_0 %randf_1 %randf_2 %randf_3
|
|
%_colb = OpCompositeConstruct %float4 %randf_4 %randf_5 %randf_6 %randf_7
|
|
%_colc = OpCompositeConstruct %float4 %randf_8 %randf_9 %randf_10 %randf_11
|
|
%_cold = OpCompositeConstruct %float4 %randf_12 %randf_13 %randf_14 %randf_15
|
|
%_mat1 = OpCompositeConstruct %float4x4 %_cola %_colb %_colc %_cold
|
|
|
|
%_out_float = OpExtInst %float %glsl450 Determinant %_mat1
|
|
)EOTEST",
|
|
});
|
|
|
|
// test matrix inverse, but round the result to avoid needing to lower our global precision
|
|
// epsilon
|
|
for(int dim = 2; dim <= 4; dim++)
|
|
{
|
|
std::string test = fmt::format(R"EOTEST(
|
|
%_cola = OpCompositeConstruct %float{0} %randf_0 %randf_1 {1} %randf_2 {2} %randf_3
|
|
%_colb = OpCompositeConstruct %float{0} %randf_4 %randf_5 {1} %randf_6 {2} %randf_7
|
|
%_colc = OpCompositeConstruct %float{0} %randf_8 %randf_9 {1} %randf_10 {2} %randf_11
|
|
%_cold = OpCompositeConstruct %float{0} %randf_12 %randf_13 {1} %randf_14 {2} %randf_15
|
|
|
|
%_mat = OpCompositeConstruct %float{0}x{0} %_cola %_colb {1} %_colc {2} %_cold
|
|
|
|
%_vec = OpCompositeConstruct %float{0} %randf_16 %randf_17 {1} %randf_18 {2} %randf_19
|
|
|
|
%_mat0 = OpExtInst %float{0}x{0} %glsl450 MatrixInverse %_mat
|
|
)EOTEST",
|
|
dim, dim < 3 ? ";" : "", dim < 4 ? ";" : "");
|
|
|
|
int i = 0;
|
|
for(int col = 0; col < dim; col++)
|
|
{
|
|
for(int row = 0; row < dim; row++)
|
|
{
|
|
test += fmt::format(R"EOTEST(
|
|
%_mat{0}{1}a = OpCompositeExtract %float %_mat{2} {0} {1}
|
|
%_mat{0}{1}b = OpFMul %float %_mat{0}{1}a %float_500_0
|
|
%_mat{0}{1}c = OpExtInst %float %glsl450 RoundEven %_mat{0}{1}b
|
|
%_mat{0}{1}d = OpFDiv %float %_mat{0}{1}c %float_500_0
|
|
|
|
%_mat{3} = OpCompositeInsert %float{4}x{4} %_mat{0}{1}d %_mat{2} {0} {1}
|
|
)EOTEST",
|
|
col, row, i, i + 1, dim);
|
|
i++;
|
|
}
|
|
}
|
|
|
|
test += fmt::format("%_out_float{0} = OpMatrixTimesVector %float{0} %_mat{1} %_vec\n", dim, i);
|
|
|
|
asm_tests.push_back(test);
|
|
}
|
|
|
|
// test OpVectorShuffle
|
|
append_tests({
|
|
"%_out_float4 = OpVectorShuffle %float4 %float4_0000 %float4_1234 7 6 0 1",
|
|
"%_out_float4 = OpVectorShuffle %float4 %float4_0000 %float4_dyn_1234 7 6 0 1",
|
|
"%_out_float4 = OpVectorShuffle %float4 %float4_dyn_0000 %float4_1234 7 6 0 1",
|
|
"%_out_float4 = OpVectorShuffle %float4 %float4_dyn_0000 %float4_dyn_1234 7 6 0 1",
|
|
"%_out_float3 = OpVectorShuffle %float3 %float3_000 %float3_123 3 4 5",
|
|
"%_out_float2 = OpVectorShuffle %float2 %float2_00 %float2_12 2 3",
|
|
|
|
// test 0xffffffff component inputs
|
|
"%_tmp = OpVectorShuffle %float4 %float4_0000 %float4_1234 5 4 4294967295 4294967295\n"
|
|
"%_out_float4 = OpVectorShuffle %float4 %_tmp %float4_dyn_1234 0 1 4 5",
|
|
});
|
|
|
|
// test OpVectorExtractDynamic
|
|
append_tests({
|
|
"%_x = OpVectorExtractDynamic %float %float4_dyn_1234 %uint_dyn_1\n"
|
|
"%_y = OpVectorExtractDynamic %float %float4_dyn_1234 %uint_dyn_3\n"
|
|
"%_z = OpVectorExtractDynamic %float %float4_dyn_1234 %uint_dyn_2\n"
|
|
"%_w = OpVectorExtractDynamic %float %float4_dyn_0000 %uint_dyn_2\n"
|
|
"%_out_float4 = OpCompositeConstruct %float4 %_x %_y %_z %_w\n",
|
|
});
|
|
|
|
// test OpVectorInsertDynamic
|
|
append_tests({
|
|
"%_out_float4 = OpVectorInsertDynamic %float4 %float4_dyn_1234 %float_dyn_8_8 %uint_dyn_1",
|
|
"%_out_float4 = OpVectorInsertDynamic %float4 %float4_dyn_1234 %float_dyn_8_8 %uint_dyn_2",
|
|
"%_out_float4 = OpVectorInsertDynamic %float4 %float4_dyn_1234 %float_dyn_8_8 %uint_dyn_0",
|
|
});
|
|
|
|
// test OpCompositeInsert on vectors
|
|
append_tests({
|
|
" %_b = OpCompositeInsert %float4 %float_15_0 %float4_0000 2\n"
|
|
" %_c = OpCompositeInsert %float4 %float_8_8 %_b 1\n"
|
|
" %_d = OpCompositeInsert %float4 %float_6_1 %_c 3\n"
|
|
"%_out_float4 = OpCompositeInsert %float4 %float_2_222 %_d 0\n",
|
|
|
|
" %_b = OpCompositeInsert %float4 %float_dyn_15_0 %float4_dyn_0000 2\n"
|
|
" %_c = OpCompositeInsert %float4 %float_dyn_8_8 %_b 1\n"
|
|
" %_d = OpCompositeInsert %float4 %float_dyn_6_1 %_c 3\n"
|
|
"%_out_float4 = OpCompositeInsert %float4 %float_dyn_2_222 %_d 0\n",
|
|
});
|
|
|
|
// test OpCompositeExtract on vectors
|
|
append_tests({
|
|
"%_out_float = OpCompositeExtract %float %float4_dyn_1234 0",
|
|
"%_out_float = OpCompositeExtract %float %float4_dyn_1234 1",
|
|
"%_out_float = OpCompositeExtract %float %float4_dyn_1234 3",
|
|
});
|
|
|
|
// test OpCompositeInsert on structs
|
|
asm_tests.push_back(R"EOTEST(
|
|
%_a = OpCompositeConstruct %float4 %float_dyn_4_2 %float_dyn_1_0 %float_dyn_9_5 %float_dyn_0_01
|
|
%_b = OpCompositeConstruct %float3 %float_dyn_3_5 %float_dyn_5_3 %float_dyn_6_2
|
|
|
|
%_c = OpVectorShuffle %float4 %_a %_a 3 2 0 1
|
|
%_d = OpVectorShuffle %float4 %_a %_a 0 1 3 2
|
|
%_e = OpVectorShuffle %float4 %_a %_a 2 0 1 3
|
|
%_f = OpVectorShuffle %float4 %_a %_a 3 1 2 0
|
|
%_g = OpVectorShuffle %float4 %_a %_a 1 3 0 2
|
|
|
|
%_parent1 = OpCompositeInsert %parent %_a %null_parent 0
|
|
|
|
%_parent2 = OpCompositeInsert %parent %_a %_parent1 1 0
|
|
%_parent3 = OpCompositeInsert %parent %_b %_parent2 1 1
|
|
%_parent4 = OpCompositeInsert %parent %float_dyn_9_9 %_parent3 1 2
|
|
|
|
%_parent5 = OpCompositeInsert %parent %_c %_parent4 2 0
|
|
%_parent6 = OpCompositeInsert %parent %_d %_parent5 2 1
|
|
%_parent7 = OpCompositeInsert %parent %_e %_parent6 2 2
|
|
%_parent8 = OpCompositeInsert %parent %_g %_parent7 2 3
|
|
|
|
%_x = OpCompositeExtract %float %_parent8 0 2
|
|
%_y = OpCompositeExtract %float %_parent8 2 1 3
|
|
%_z = OpCompositeExtract %float %_parent8 1 1 1
|
|
%_w = OpCompositeExtract %float %_parent8 1 0 2
|
|
|
|
%_out_float4 = OpCompositeConstruct %float4 %_x %_y %_z %_w
|
|
|
|
)EOTEST");
|
|
|
|
// test OpBitCast
|
|
append_tests({
|
|
"%_a = OpBitcast %uint %float_dyn_15_0\n"
|
|
"%_neg = OpBitwiseOr %uint %_a %uint_dyn_0x80000000\n"
|
|
"%_out_float = OpBitcast %float %_neg\n",
|
|
|
|
"%_result = OpBitwiseOr %uint %uint_dyn_0x4200004d %uint_dyn_0xa28b00\n"
|
|
"%_out_float = OpBitcast %float %_result\n",
|
|
});
|
|
|
|
// Bitcast vector <-> scalar
|
|
if(float16Int8Features.shaderInt8 && features.shaderInt16)
|
|
{
|
|
append_tests({
|
|
// u8[2] -> u16
|
|
"%_result = OpCompositeConstruct %u8v2 %u8_8 %u8_9\n"
|
|
"%_out_u16 = OpBitcast %u16 %_result\n",
|
|
// u8[4] -> u32
|
|
"%_result = OpCompositeConstruct %u8v4 %u8_4 %u8_5 %u8_6 %u8_7\n"
|
|
"%_out_uint = OpBitcast %uint %_result\n",
|
|
// u16[2] -> u32
|
|
"%_result = OpCompositeConstruct %u16v2 %u16_4 %u16_5\n"
|
|
"%_out_uint = OpBitcast %uint %_result\n",
|
|
// u16 -> u8[2]
|
|
"%_out_u8v2 = OpBitcast %u8v2 %u16_1234\n ",
|
|
// u32 -> u8[4]
|
|
"%_out_u8v4 = OpBitcast %u8v4 %uint_1234\n ",
|
|
// u32 -> u16[2]
|
|
"%_out_u16v2 = OpBitcast %u16v2 %uint_12345\n",
|
|
});
|
|
}
|
|
|
|
if(features.shaderInt16 && features.shaderInt64)
|
|
{
|
|
append_tests({
|
|
// u16[4] -> u64
|
|
"%_result = OpCompositeConstruct %u16v4 %u16_0 %u16_1 %u16_2 %u16_3\n"
|
|
"%_out_u64 = OpBitcast %u64 %_result\n",
|
|
// u64 -> u16[4]
|
|
"%_out_u16v4 = OpBitcast %u16v4 %u64_1234\n",
|
|
});
|
|
}
|
|
|
|
if(features.shaderInt64)
|
|
{
|
|
append_tests({
|
|
// u32[2] -> u64
|
|
"%_result = OpCompositeConstruct %uint2 %uint_0 %uint_1\n"
|
|
"%_out_u64 = OpBitcast %u64 %_result\n",
|
|
// u64 -> u32[2]
|
|
"%_out_uint2 = OpBitcast %uint2 %u64_1234\n",
|
|
});
|
|
}
|
|
|
|
if(float16Int8Features.shaderFloat16)
|
|
{
|
|
append_tests({
|
|
// f16[2] -> f32
|
|
"%_result = OpCompositeConstruct %half2 %half_0_25 %half_0_5\n"
|
|
"%_out_float = OpBitcast %float %_result\n",
|
|
// f32 -> f16[2]
|
|
"%_out_half2 = OpBitcast %half2 %float_1_1125\n",
|
|
});
|
|
}
|
|
|
|
if(features.shaderFloat64)
|
|
{
|
|
append_tests({
|
|
// f32[2] -> f64
|
|
"%_result = OpCompositeConstruct %float2 %float_0_5 %float_0_25\n"
|
|
"%_out_double = OpBitcast %double %_result\n",
|
|
// f64 -> f32[2]
|
|
"%_out_float2 = OpBitcast %float2 %double_1024_25\n",
|
|
});
|
|
}
|
|
|
|
// test ExtInst NMin/NMax/NClamp
|
|
append_tests({
|
|
"%_x = OpExtInst %float %glsl450 NMin %nan %oneVal\n"
|
|
"%_y = OpExtInst %float %glsl450 NMin %oneVal %nan\n"
|
|
"%_z = OpExtInst %float %glsl450 NMin %nan %nan\n"
|
|
"%_w = OpExtInst %float %glsl450 NMin %nan %neginf\n"
|
|
"%_out_float4 = OpCompositeConstruct %float4 %_x %_y %_z %_w\n",
|
|
|
|
"%_x = OpExtInst %float %glsl450 NMax %nan %oneVal\n"
|
|
"%_y = OpExtInst %float %glsl450 NMax %oneVal %nan\n"
|
|
"%_z = OpExtInst %float %glsl450 NMax %nan %nan\n"
|
|
"%_w = OpExtInst %float %glsl450 NMax %nan %neginf\n"
|
|
"%_out_float4 = OpCompositeConstruct %float4 %_x %_y %_z %_w\n",
|
|
|
|
"%_out_float = OpExtInst %float %glsl450 NClamp %nan %zerof %oneVal",
|
|
});
|
|
|
|
// test ExtInst Modf/ModfStruct and Frexp/FrexpStruct
|
|
append_tests({
|
|
"%_x = OpExtInst %float %glsl450 Modf %float_dyn_123_456 %priv_float\n"
|
|
"%_y = OpLoad %float %priv_float\n"
|
|
"%_tmp = OpExtInst %f32f32 %glsl450 ModfStruct %float_dyn_789_012\n"
|
|
"%_z = OpCompositeExtract %float %_tmp 0\n"
|
|
"%_w = OpCompositeExtract %float %_tmp 1\n"
|
|
"%_out_float4 = OpCompositeConstruct %float4 %_x %_y %_z %_w\n",
|
|
|
|
"%_x = OpExtInst %float %glsl450 Frexp %float_dyn_123_456 %priv_int\n"
|
|
"%_yi = OpLoad %int %priv_int\n"
|
|
"%_y = OpConvertSToF %float %_yi\n"
|
|
"%_tmp = OpExtInst %f32i32 %glsl450 FrexpStruct %float_dyn_789_012\n"
|
|
"%_z = OpCompositeExtract %float %_tmp 0\n"
|
|
"%_wi = OpCompositeExtract %int %_tmp 1\n"
|
|
"%_w = OpConvertSToF %float %_wi\n"
|
|
"%_out_float4 = OpCompositeConstruct %float4 %_x %_y %_z %_w\n",
|
|
});
|
|
|
|
// test float <-> int conversions
|
|
append_tests({
|
|
"%_x = OpConvertUToF %float %uint_dyn_1234\n"
|
|
"%_y = OpConvertSToF %float %int_dyn_1234\n"
|
|
"%_z = OpConvertSToF %float %int_dyn_neg1234\n"
|
|
"%_w = OpConvertUToF %float %uint_dyn_0\n"
|
|
"%_out_float4 = OpCompositeConstruct %float4 %_x %_y %_z %_w\n",
|
|
|
|
"%_x = OpConvertFToU %uint %float_dyn_1_0\n"
|
|
"%_y = OpConvertFToU %uint %float_dyn_0_0\n"
|
|
"%_z = OpConvertFToU %uint %float_dyn_1_1\n"
|
|
"%_w = OpConvertFToU %uint %float_dyn_1_3\n"
|
|
"%_out_uint4 = OpCompositeConstruct %uint4 %_x %_y %_z %_w\n",
|
|
|
|
"%_x = OpConvertFToU %uint %float_dyn_1_0\n"
|
|
"%_y = OpConvertFToU %uint %float_dyn_1_5\n"
|
|
"%_z = OpConvertFToU %uint %float_dyn_0_5\n"
|
|
"%_w = OpConvertFToU %uint %float_dyn_1_7\n"
|
|
"%_out_uint4 = OpCompositeConstruct %uint4 %_x %_y %_z %_w\n",
|
|
|
|
"%_x = OpConvertFToS %int %float_dyn_1_0\n"
|
|
"%_y = OpConvertFToS %int %float_dyn_0_0\n"
|
|
"%_z = OpConvertFToS %int %float_dyn_neg1_0\n"
|
|
"%_w = OpConvertFToS %int %float_dyn_1_3\n"
|
|
"%_out_int4 = OpCompositeConstruct %int4 %_x %_y %_z %_w\n",
|
|
|
|
"%_x = OpConvertFToS %int %float_dyn_1_0\n"
|
|
"%_y = OpConvertFToS %int %float_dyn_1_5\n"
|
|
"%_z = OpConvertFToS %int %float_dyn_0_5\n"
|
|
"%_w = OpConvertFToS %int %float_dyn_neg1_5\n"
|
|
"%_out_int4 = OpCompositeConstruct %int4 %_x %_y %_z %_w\n",
|
|
});
|
|
|
|
// test copies
|
|
append_tests({
|
|
"OpCopyMemory %Color %gl_FragCoord\n"
|
|
"; no_out\n",
|
|
|
|
"%_src = OpAccessChain %ptr_Uniform_float4 %buffer %uint_2\n"
|
|
"%_dst = OpAccessChain %ptr_Uniform_float4 %buffer %uint_4 %uint_3\n"
|
|
"OpCopyMemory %_dst %_src\n"
|
|
"OpCopyMemory %Color %_src\n"
|
|
"; no_out\n",
|
|
|
|
"%frag = OpLoad %float4 %gl_FragCoord\n"
|
|
"%_out_float4 = OpCopyObject %float4 %frag\n",
|
|
});
|
|
|
|
// test SSBO pointers
|
|
append_tests({
|
|
"%_y = OpAccessChain %ptr_Uniform_dummy %buffer %uint_3\n"
|
|
"%_src = OpAccessChain %ptr_Uniform_uint4 %_y %uint_0\n"
|
|
"%_dst = OpAccessChain %ptr_Uniform_uint4 %_y %uint_1\n"
|
|
"%_tmp = OpLoad %uint4 %_src\n"
|
|
"OpStore %_dst %_tmp\n"
|
|
"%_out_uint4 = OpLoad %uint4 %_dst\n",
|
|
});
|
|
|
|
// disabled while shaderc has a bug that doesn't respect the target environment
|
|
/*
|
|
if(vk_version >= 0x12)
|
|
{
|
|
append_tests({
|
|
"%frag = OpLoad %float4 %gl_FragCoord\n"
|
|
"%_out_float4 = OpCopyLogical %float4 %frag\n",
|
|
});
|
|
}
|
|
*/
|
|
|
|
if(features.shaderFloat64)
|
|
{
|
|
// test pack/unpack from double
|
|
append_tests({
|
|
"%_ptr = OpAccessChain %ptr_Uniform_uint2 %cbuffer %uint_16\n"
|
|
"%_double_pack_source = OpLoad %uint2 %_ptr\n"
|
|
"%_out_double = OpExtInst %double %glsl450 PackDouble2x32 %_double_pack_source\n",
|
|
|
|
"%_ptr = OpAccessChain %ptr_Uniform_double %cbuffer %uint_17\n"
|
|
"%_double_unpack_source = OpLoad %double %_ptr\n"
|
|
"%_out_uint2 = OpExtInst %uint2 %glsl450 UnpackDouble2x32 %_double_unpack_source\n",
|
|
|
|
"%_ptr = OpAccessChain %ptr_Uniform_double %cbuffer %uint_17\n"
|
|
"%_pi = OpLoad %double %_ptr\n"
|
|
"%_two = OpFConvert %double %float_2_0\n"
|
|
"%_out_double = OpFMul %double %_pi %_two\n",
|
|
});
|
|
}
|
|
|
|
// test pointers into columns of matrices
|
|
|
|
append_tests({
|
|
R"EOTEST(
|
|
%_cola = OpCompositeConstruct %float4 %randf_0 %randf_1 %randf_2 %randf_3
|
|
%_colb = OpCompositeConstruct %float4 %randf_4 %randf_5 %randf_6 %randf_7
|
|
%_colc = OpCompositeConstruct %float4 %randf_8 %randf_9 %randf_10 %randf_11
|
|
%_cold = OpCompositeConstruct %float4 %randf_12 %randf_13 %randf_14 %randf_15
|
|
|
|
%_ptra = OpAccessChain %ptr_Private_float4 %priv_float4x4 %uint_0
|
|
%_ptrb = OpAccessChain %ptr_Private_float4 %priv_float4x4 %uint_1
|
|
%_ptrc = OpAccessChain %ptr_Private_float4 %priv_float4x4 %uint_2
|
|
%_ptrd = OpAccessChain %ptr_Private_float4 %priv_float4x4 %uint_3
|
|
|
|
OpStore %_ptra %_cola
|
|
OpStore %_ptrb %_colb
|
|
OpStore %_ptrc %_colc
|
|
OpStore %_ptrd %_cold
|
|
|
|
%_vec = OpCompositeConstruct %float4 %randf_16 %randf_17 %randf_18 %randf_19
|
|
|
|
%_mat = OpLoad %float4x4 %priv_float4x4
|
|
|
|
%_out_float4 = OpMatrixTimesVector %float4 %_mat %_vec
|
|
)EOTEST",
|
|
R"EOTEST(
|
|
%_cola = OpCompositeConstruct %float4 %randf_0 %randf_1 %randf_2 %randf_3
|
|
%_colb = OpCompositeConstruct %float4 %randf_4 %randf_5 %randf_6 %randf_7
|
|
%_colc = OpCompositeConstruct %float4 %randf_8 %randf_9 %randf_10 %randf_11
|
|
%_cold = OpCompositeConstruct %float4 %randf_12 %randf_13 %randf_14 %randf_15
|
|
|
|
%_ptra = OpAccessChain %ptr_Uniform_float4 %buffer %uint_0 %uint_0
|
|
%_ptrb = OpAccessChain %ptr_Uniform_float4 %buffer %uint_0 %uint_1
|
|
%_ptrc = OpAccessChain %ptr_Uniform_float4 %buffer %uint_0 %uint_2
|
|
%_ptrd = OpAccessChain %ptr_Uniform_float4 %buffer %uint_0 %uint_3
|
|
|
|
OpStore %_ptra %_cola
|
|
OpStore %_ptrb %_colb
|
|
OpStore %_ptrc %_colc
|
|
OpStore %_ptrd %_cold
|
|
|
|
%_vec = OpCompositeConstruct %float4 %randf_16 %randf_17 %randf_18 %randf_19
|
|
|
|
%_ptrmat = OpAccessChain %ptr_Uniform_float4x4 %buffer %uint_0
|
|
%_mat = OpLoad %float4x4 %_ptrmat
|
|
|
|
%_out_float4 = OpMatrixTimesVector %float4 %_mat %_vec
|
|
)EOTEST",
|
|
R"EOTEST(
|
|
%_cola = OpCompositeConstruct %float4 %randf_0 %randf_1 %randf_2 %randf_3
|
|
%_colb = OpCompositeConstruct %float4 %randf_4 %randf_5 %randf_6 %randf_7
|
|
%_colc = OpCompositeConstruct %float4 %randf_8 %randf_9 %randf_10 %randf_11
|
|
%_cold = OpCompositeConstruct %float4 %randf_12 %randf_13 %randf_14 %randf_15
|
|
|
|
%_ptra = OpAccessChain %ptr_Uniform_float4 %buffer %uint_1 %uint_0
|
|
%_ptrb = OpAccessChain %ptr_Uniform_float4 %buffer %uint_1 %uint_1
|
|
%_ptrc = OpAccessChain %ptr_Uniform_float4 %buffer %uint_1 %uint_2
|
|
%_ptrd = OpAccessChain %ptr_Uniform_float4 %buffer %uint_1 %uint_3
|
|
|
|
OpStore %_ptra %_cola
|
|
OpStore %_ptrb %_colb
|
|
OpStore %_ptrc %_colc
|
|
OpStore %_ptrd %_cold
|
|
|
|
%_vec = OpCompositeConstruct %float4 %randf_16 %randf_17 %randf_18 %randf_19
|
|
|
|
%_ptrmat = OpAccessChain %ptr_Uniform_float4x4 %buffer %uint_1
|
|
%_mat = OpLoad %float4x4 %_ptrmat
|
|
|
|
%_out_float4 = OpMatrixTimesVector %float4 %_mat %_vec
|
|
)EOTEST",
|
|
});
|
|
|
|
// test variables with initialisers
|
|
append_tests({
|
|
R"EOTEST(
|
|
; this has a constant initialiser, so should already be ready
|
|
%_out_float4 = OpLoad %float4 %priv_float4_init
|
|
)EOTEST",
|
|
R"EOTEST(
|
|
; this is uninitialised, but unforuntately that means we can't test our debugging
|
|
; against the real thing when it's undefined. But we can at least expose it so that
|
|
; when manually checking we see the uninitialised values
|
|
%_uninit = OpLoad %float4 %priv_float4
|
|
%_x = OpExtInst %float4 %glsl450 NClamp %_uninit %float4_0000 %float4_0000
|
|
%_out_float4 = OpFAdd %float4 %_x %float4_1234
|
|
)EOTEST",
|
|
R"EOTEST(
|
|
; this is uninitialised, but unforuntately that means we can't test our debugging
|
|
; against the real thing when it's undefined. But we can at least expose it so that
|
|
; when manually checking we see the uninitialised values
|
|
%_uninit = OpLoad %float4 %Color
|
|
%_x = OpExtInst %float4 %glsl450 NClamp %_uninit %float4_0000 %float4_0000
|
|
%_out_float4 = OpFAdd %float4 %_x %float4_1234
|
|
)EOTEST",
|
|
});
|
|
|
|
// test naming structs. Since we can't easily name auto-generated IDs we use a guid to give the
|
|
// ID a unique name
|
|
append_tests({
|
|
R"EOTEST(
|
|
%_a = OpCompositeConstruct %float4 %float_dyn_4_2 %float_dyn_1_0 %float_dyn_9_5 %float_dyn_0_01
|
|
|
|
%C14FA880_4F83_4982_BEAD_CE9103446C76 = OpCompositeInsert %parent %_a %null_parent 0
|
|
|
|
%_out_float4 = OpCompositeExtract %float4 %C14FA880_4F83_4982_BEAD_CE9103446C76 0
|
|
)EOTEST",
|
|
});
|
|
|
|
spv_debug +=
|
|
"OpName %C14FA880_4F83_4982_BEAD_CE9103446C76 \"C14FA880_4F83_4982_BEAD_CE9103446C76\"\n";
|
|
|
|
// test OpPhi
|
|
append_tests({
|
|
|
|
// basic simple test
|
|
R"EOTEST(
|
|
OpBranch %_toplabel
|
|
%_toplabel = OpLabel
|
|
|
|
%_val = OpDot %float %inpos %float2_12
|
|
%_cond = OpFOrdGreaterThan %bool %_val %float_37_0
|
|
|
|
%_parent1 = OpFMul %float %float_2_0 %float_0_5
|
|
|
|
OpSelectionMerge %_merge None
|
|
OpBranchConditional %_cond %_merge %_branchlabel
|
|
|
|
%_branchlabel = OpLabel
|
|
|
|
%_parent2 = OpFMul %float %float_2_0 %float_0_25
|
|
|
|
OpBranch %_merge
|
|
|
|
%_merge = OpLabel
|
|
|
|
; choose either parent1 or parent2, depending on if we branched
|
|
%_out_float = OpPhi %float %_parent1 %_toplabel %_parent2 %_branchlabel
|
|
|
|
OpBranch %_bottomlabel
|
|
%_bottomlabel = OpLabel
|
|
|
|
)EOTEST",
|
|
|
|
// test with a function call in each branch to ensure we still track the last block
|
|
// accurately
|
|
R"EOTEST(
|
|
OpBranch %_toplabel
|
|
%_toplabel = OpLabel
|
|
|
|
%_val = OpDot %float %inpos %float2_12
|
|
%_cond = OpFOrdGreaterThan %bool %_val %float_37_0
|
|
|
|
%_parent1 = OpFunctionCall %float %doubler %float_0_5
|
|
|
|
OpSelectionMerge %_merge None
|
|
OpBranchConditional %_cond %_merge %_branchlabel
|
|
|
|
%_branchlabel = OpLabel
|
|
|
|
%_parent2 = OpFunctionCall %float %doubler %float_0_25
|
|
|
|
OpBranch %_merge
|
|
|
|
%_merge = OpLabel
|
|
|
|
; choose either parent1 or parent2, depending on if we branched
|
|
%_out_float = OpPhi %float %_parent1 %_toplabel %_parent2 %_branchlabel
|
|
|
|
OpBranch %_bottomlabel
|
|
%_bottomlabel = OpLabel
|
|
|
|
)EOTEST",
|
|
});
|
|
|
|
// test switch for different integer types
|
|
std::vector<std::string> intTypes = {"int", "uint"};
|
|
std::vector<std::string> caseLiterals = {"0x12345678", "0xF2345678"};
|
|
if(features.shaderInt64)
|
|
{
|
|
intTypes.push_back("i64");
|
|
intTypes.push_back("u64");
|
|
caseLiterals.push_back("0x1234567812345678");
|
|
caseLiterals.push_back("0xF234567812345678");
|
|
}
|
|
for(size_t i = 0; i < intTypes.size(); ++i)
|
|
{
|
|
append_tests({fmt::format(
|
|
"%_test_switch_{0} = OpIAdd %{0} %{0}_0 %{0}_{1}\n"
|
|
"OpSelectionMerge %_break_{0} None\n"
|
|
"OpSwitch %_test_switch_{0} %_default_{0} 2 %_case_{0}_2 {1} %_case_{0}_{1}\n"
|
|
"%_case_{0}_2 = OpLabel\n"
|
|
"OpUnreachable\n"
|
|
"%_case_{0}_{1} = OpLabel\n"
|
|
"%_out_{0} = OpIAdd %{0} %{0}_0 %{0}_7\n"
|
|
"OpBranch %_break_{0}\n"
|
|
"%_default_{0} = OpLabel\n"
|
|
"OpUnreachable\n"
|
|
"%_break_{0} = OpLabel\n",
|
|
intTypes[i], caseLiterals[i])});
|
|
}
|
|
|
|
// test buffer device address
|
|
if(bdaFeatures.bufferDeviceAddress)
|
|
{
|
|
// bitcast uint2 address to pointer
|
|
append_tests({
|
|
R"EOTEST(
|
|
%_ptr_addr_bda_data_struct = OpAccessChain %ptr_PushConstant_uint2 %push_data %int_1
|
|
%_addr_bda_data_struct = OpLoad %uint2 %_ptr_addr_bda_data_struct
|
|
%_ptr_bda_data_struct = OpBitcast %ptr_PhysicalStorageBuffer_bda_data_struct %_addr_bda_data_struct
|
|
%_ptr_first = OpAccessChain %ptr_PhysicalStorageBuffer_bda_data_struct_first %_ptr_bda_data_struct %int_0
|
|
%_out_float4 = OpLoad %float4 %_ptr_first Aligned 16
|
|
)EOTEST",
|
|
// OpPtrAccessChain : float[] : ArrayStride 4
|
|
R"EOTEST(
|
|
%_ptr_addr_bda_data_struct = OpAccessChain %ptr_PushConstant_uint2 %push_data %int_1
|
|
%_addr_bda_data_struct = OpLoad %uint2 %_ptr_addr_bda_data_struct
|
|
%_ptr_bda_data_struct = OpBitcast %ptr_PhysicalStorageBuffer_bda_data_struct_f32_4 %_addr_bda_data_struct
|
|
%_ptr_f32 = OpPtrAccessChain %ptr_PhysicalStorageBuffer_f32 %_ptr_bda_data_struct %int_dyn_1
|
|
%_out_float = OpLoad %float %_ptr_f32 Aligned 16
|
|
)EOTEST",
|
|
// OpPtrAccessChain : float[] : ArrayStride 8
|
|
R"EOTEST(
|
|
%_ptr_addr_bda_data_struct = OpAccessChain %ptr_PushConstant_uint2 %push_data %int_1
|
|
%_addr_bda_data_struct = OpLoad %uint2 %_ptr_addr_bda_data_struct
|
|
%_ptr_bda_data_struct = OpBitcast %ptr_PhysicalStorageBuffer_bda_data_struct_f32_8 %_addr_bda_data_struct
|
|
%_ptr_f32 = OpPtrAccessChain %ptr_PhysicalStorageBuffer_f32 %_ptr_bda_data_struct %int_dyn_1
|
|
%_out_float = OpLoad %float %_ptr_f32 Aligned 16
|
|
)EOTEST",
|
|
// OpPtrAccessChain : float[] : ArrayStride 12
|
|
R"EOTEST(
|
|
%_ptr_addr_bda_data_struct = OpAccessChain %ptr_PushConstant_uint2 %push_data %int_1
|
|
%_addr_bda_data_struct = OpLoad %uint2 %_ptr_addr_bda_data_struct
|
|
%_ptr_bda_data_struct = OpBitcast %ptr_PhysicalStorageBuffer_bda_data_struct_f32_12 %_addr_bda_data_struct
|
|
%_ptr_f32 = OpPtrAccessChain %ptr_PhysicalStorageBuffer_f32 %_ptr_bda_data_struct %int_dyn_1
|
|
%_out_float = OpLoad %float %_ptr_f32 Aligned 16
|
|
)EOTEST",
|
|
});
|
|
if(features.shaderInt64)
|
|
{
|
|
append_tests({
|
|
// Convert u64 address to pointer
|
|
R"EOTEST(
|
|
%_ptr_addr_bda_data_struct = OpAccessChain %ptr_PushConstant_u64 %push_data %int_4
|
|
%_addr_bda_data_struct = OpLoad %u64 %_ptr_addr_bda_data_struct
|
|
%_ptr_bda_data_struct = OpConvertUToPtr %ptr_PhysicalStorageBuffer_bda_data_struct %_addr_bda_data_struct
|
|
%_ptr_first = OpAccessChain %ptr_PhysicalStorageBuffer_bda_data_struct_first %_ptr_bda_data_struct %int_1
|
|
%_out_float4 = OpLoad %float4 %_ptr_first Aligned 16
|
|
)EOTEST",
|
|
// Convert u64 address to pointer back to u64 address
|
|
R"EOTEST(
|
|
%_ptr_addr_bda_data_struct = OpAccessChain %ptr_PushConstant_u64 %push_data %int_4
|
|
%_addr = OpLoad %u64 %_ptr_addr_bda_data_struct
|
|
%_addr_bda_data_struct = OpIAdd %u64 %_addr %u64_dyn_8
|
|
%_ptr_bda_data_struct = OpConvertUToPtr %ptr_PhysicalStorageBuffer_bda_data_struct %_addr_bda_data_struct
|
|
%_out_u64 = OpConvertPtrToU %u64 %_ptr_bda_data_struct
|
|
)EOTEST",
|
|
// arithmetic on u64 address then convert u64 address to pointer
|
|
R"EOTEST(
|
|
%_ptr_addr_bda_data_struct = OpAccessChain %ptr_PushConstant_u64 %push_data %int_4
|
|
%_addr = OpLoad %u64 %_ptr_addr_bda_data_struct
|
|
%_addr2 = OpIAdd %u64 %_addr %u64_dyn_1023
|
|
%_addr3 = OpISub %u64 %_addr2 %u64_dyn_1023
|
|
%_addr_bda_data_struct = OpIAdd %u64 %_addr3 %u64_dyn_16
|
|
%_ptr_bda_data_struct = OpConvertUToPtr %ptr_PhysicalStorageBuffer_bda_data_struct %_addr_bda_data_struct
|
|
%_ptr_first = OpInBoundsAccessChain %ptr_PhysicalStorageBuffer_bda_data_struct_first %_ptr_bda_data_struct %int_0
|
|
%_out_float4 = OpLoad %float4 %_ptr_first Aligned 16
|
|
)EOTEST",
|
|
// form u64 address by arithmetic from two u32 values
|
|
R"EOTEST(
|
|
%_ptr_addr_bda_data_struct_hi = OpAccessChain %ptr_PushConstant_uint %push_data %int_2
|
|
%_addr_bda_data_struct_hi = OpLoad %uint %_ptr_addr_bda_data_struct_hi
|
|
%_ptr_addr_bda_data_struct_lo = OpAccessChain %ptr_PushConstant_uint %push_data %int_3
|
|
%_addr_bda_data_struct_lo = OpLoad %uint %_ptr_addr_bda_data_struct_lo
|
|
%_addr_u64_hi = OpUConvert %u64 %_addr_bda_data_struct_hi
|
|
%_addr_u64_lo = OpUConvert %u64 %_addr_bda_data_struct_lo
|
|
%_addr_u64 = OpShiftLeftLogical %u64 %_addr_u64_hi %uint_32
|
|
%_addr_bda_data_struct = OpIAdd %u64 %_addr_u64 %_addr_u64_lo
|
|
%_ptr_bda_data_struct = OpConvertUToPtr %ptr_PhysicalStorageBuffer_bda_data_struct %_addr_bda_data_struct
|
|
%_ptr_first = OpAccessChain %ptr_PhysicalStorageBuffer_bda_data_struct_first %_ptr_bda_data_struct %int_0
|
|
%_out_float4 = OpLoad %float4 %_ptr_first Aligned 16
|
|
)EOTEST",
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string make_pixel_asm()
|
|
{
|
|
std::string switch_str = R"EOSHADER(
|
|
OpSelectionMerge %break None
|
|
OpSwitch %test
|
|
%default
|
|
)EOSHADER";
|
|
|
|
std::set<std::string> null_constants;
|
|
std::set<float> float_constants = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f};
|
|
std::set<int32_t> int_constants = {7};
|
|
std::set<uint32_t> uint_constants;
|
|
std::set<int64_t> i64_constants;
|
|
std::set<uint64_t> u64_constants;
|
|
std::set<uint8_t> u8_constants;
|
|
std::set<uint16_t> u16_constants;
|
|
|
|
std::string cases;
|
|
|
|
for(size_t i = 0; i < asm_tests.size(); i++)
|
|
{
|
|
std::string &test = asm_tests[i];
|
|
// append a newline just so that searching for whitespace always finds it even if the last
|
|
// thing in the test is a %_foo
|
|
test += "\n";
|
|
|
|
// add the test's case
|
|
switch_str += fmt::format("{0} %test_{0}\n", i);
|
|
cases += fmt::format("%test_{} = OpLabel\n", i);
|
|
|
|
std::string test_suffix = fmt::format("_{}", i);
|
|
|
|
// find any identifiers with the prefix %_ in the test, and append _testindex
|
|
size_t offs = test.find("%_");
|
|
while(offs != std::string::npos)
|
|
{
|
|
offs = test.find_first_of("\n\t ", offs);
|
|
test.insert(offs, test_suffix);
|
|
|
|
offs = test.find("%_", offs);
|
|
}
|
|
|
|
// find any null constants referenced
|
|
offs = test.find("%null_");
|
|
while(offs != std::string::npos)
|
|
{
|
|
offs += 6; // past %null_
|
|
size_t begin = offs;
|
|
offs = test.find_first_of("\n\t ", offs);
|
|
null_constants.insert(test.substr(begin, offs - begin));
|
|
|
|
offs = test.find("%null_", offs);
|
|
}
|
|
|
|
// find any float constants referenced
|
|
for(std::string prefix : {"%float_", "%double_", "%half_"})
|
|
{
|
|
offs = test.find(prefix);
|
|
while(offs != std::string::npos)
|
|
{
|
|
offs += prefix.size();
|
|
|
|
// we generate dynamic and negative versions of all constants, skip to the first digit
|
|
offs = test.find_first_of("0123456789", offs);
|
|
|
|
size_t begin = offs;
|
|
offs = test.find_first_of("\n\t ", offs);
|
|
|
|
std::string val = test.substr(begin, offs - begin);
|
|
|
|
// convert any _ to a .
|
|
for(char &c : val)
|
|
if(c == '_')
|
|
c = '.';
|
|
|
|
float_constants.insert(std::strtof(val.c_str(), NULL));
|
|
|
|
offs = test.find(prefix, offs);
|
|
}
|
|
}
|
|
|
|
// find any u8 constants referenced
|
|
offs = test.find("%u8_");
|
|
while(offs != std::string::npos)
|
|
{
|
|
offs += 4; // past %u8_
|
|
|
|
// we generate dynamic and negative versions of all constants, skip to the first digit
|
|
offs = test.find_first_of("0123456789", offs);
|
|
|
|
// handle hex prefix
|
|
int base = 10;
|
|
if(test[offs] == '0' && test[offs + 1] == 'x')
|
|
{
|
|
base = 16;
|
|
offs += 2;
|
|
}
|
|
|
|
uint8_t val = (uint8_t)std::strtoul(&test[offs], NULL, base);
|
|
u8_constants.insert(val);
|
|
|
|
// if it's a hex constant we'll name it in decimal, rename
|
|
if(base == 16)
|
|
{
|
|
size_t end = test.find_first_of("\n\t ", offs);
|
|
test.replace(offs - 2, end - offs + 2, fmt::format("{}", val));
|
|
}
|
|
|
|
offs = test.find("%u8_", offs);
|
|
}
|
|
|
|
// find any u16 constants referenced
|
|
offs = test.find("%u16_");
|
|
while(offs != std::string::npos)
|
|
{
|
|
offs += 5; // past %u16_
|
|
|
|
// we generate dynamic and negative versions of all constants, skip to the first digit
|
|
offs = test.find_first_of("0123456789", offs);
|
|
|
|
// handle hex prefix
|
|
int base = 10;
|
|
if(test[offs] == '0' && test[offs + 1] == 'x')
|
|
{
|
|
base = 16;
|
|
offs += 2;
|
|
}
|
|
|
|
uint16_t val = (uint16_t)std::strtoul(&test[offs], NULL, base);
|
|
u16_constants.insert(val);
|
|
|
|
// if it's a hex constant we'll name it in decimal, rename
|
|
if(base == 16)
|
|
{
|
|
size_t end = test.find_first_of("\n\t ", offs);
|
|
test.replace(offs - 2, end - offs + 2, fmt::format("{}", val));
|
|
}
|
|
|
|
offs = test.find("%u16_", offs);
|
|
}
|
|
|
|
// find any int constants referenced
|
|
offs = test.find("%int_");
|
|
while(offs != std::string::npos)
|
|
{
|
|
offs += 5; // past %int_
|
|
|
|
// we generate dynamic and negative versions of all constants, skip to the first digit
|
|
offs = test.find_first_of("0123456789", offs);
|
|
|
|
// handle hex prefix
|
|
int base = 10;
|
|
if(test[offs] == '0' && test[offs + 1] == 'x')
|
|
{
|
|
base = 16;
|
|
offs += 2;
|
|
}
|
|
|
|
int32_t val = (int32_t)std::strtol(&test[offs], NULL, base);
|
|
int_constants.insert(val);
|
|
|
|
// if it's a hex constant we'll name it in decimal, rename
|
|
if(base == 16)
|
|
{
|
|
size_t end = test.find_first_of("\n\t ", offs);
|
|
test.replace(offs - 2, end - offs + 2, fmt::format("{}", val));
|
|
}
|
|
|
|
offs = test.find("%int_", offs);
|
|
}
|
|
|
|
// find any uint constants referenced
|
|
offs = test.find("%uint_");
|
|
while(offs != std::string::npos)
|
|
{
|
|
offs += 6; // past %uint_
|
|
|
|
// we generate dynamic and negative versions of all constants, skip to the first digit
|
|
offs = test.find_first_of("0123456789", offs);
|
|
|
|
// handle hex prefix
|
|
int base = 10;
|
|
if(test[offs] == '0' && test[offs + 1] == 'x')
|
|
{
|
|
base = 16;
|
|
offs += 2;
|
|
}
|
|
|
|
uint32_t val = (uint32_t)std::strtoul(&test[offs], NULL, base);
|
|
uint_constants.insert(val);
|
|
|
|
// if it's a hex constant we'll name it in decimal, rename
|
|
if(base == 16)
|
|
{
|
|
size_t end = test.find_first_of("\n\t ", offs);
|
|
test.replace(offs - 2, end - offs + 2, fmt::format("{}", val));
|
|
}
|
|
|
|
offs = test.find("%uint_", offs);
|
|
}
|
|
|
|
// find any i64 constants referenced
|
|
offs = test.find("%i64_");
|
|
while(offs != std::string::npos)
|
|
{
|
|
offs += 5; // past %i64_
|
|
|
|
// we generate dynamic and negative versions of all constants, skip to the first digit
|
|
offs = test.find_first_of("0123456789", offs);
|
|
|
|
// handle hex prefix
|
|
int base = 10;
|
|
if(test[offs] == '0' && test[offs + 1] == 'x')
|
|
{
|
|
base = 16;
|
|
offs += 2;
|
|
}
|
|
|
|
int64_t val = std::strtoll(&test[offs], NULL, base);
|
|
i64_constants.insert(val);
|
|
|
|
// if it's a hex constant we'll name it in decimal, rename
|
|
if(base == 16)
|
|
{
|
|
size_t end = test.find_first_of("\n\t ", offs);
|
|
test.replace(offs - 2, end - offs + 2, fmt::format("{}", val));
|
|
}
|
|
|
|
offs = test.find("%i64_", offs);
|
|
}
|
|
|
|
// find any u64 constants referenced
|
|
offs = test.find("%u64_");
|
|
while(offs != std::string::npos)
|
|
{
|
|
offs += 5; // past %u64_
|
|
|
|
// we generate dynamic and negative versions of all constants, skip to the first digit
|
|
offs = test.find_first_of("0123456789", offs);
|
|
|
|
// handle hex prefix
|
|
int base = 10;
|
|
if(test[offs] == '0' && test[offs + 1] == 'x')
|
|
{
|
|
base = 16;
|
|
offs += 2;
|
|
}
|
|
|
|
uint64_t val = std::strtoull(&test[offs], NULL, base);
|
|
u64_constants.insert(val);
|
|
|
|
// if it's a hex constant we'll name it in decimal, rename
|
|
if(base == 16)
|
|
{
|
|
size_t end = test.find_first_of("\n\t ", offs);
|
|
test.replace(offs - 2, end - offs + 2, fmt::format("{}", val));
|
|
}
|
|
|
|
offs = test.find("%u64_", offs);
|
|
}
|
|
|
|
// add the test itself now
|
|
cases += "\n";
|
|
cases += test;
|
|
cases += "\n";
|
|
|
|
bool store_out = true;
|
|
|
|
if(test.find("%_out_float4") != std::string::npos)
|
|
{
|
|
// if the test outputted a float4, we can dump it directly
|
|
cases += fmt::format("OpStore %Color %_out_float4_{}\n", i);
|
|
}
|
|
else
|
|
{
|
|
// otherwise convert and up-swizzle to float4 as needed
|
|
if(test.find("%_out_float_") != std::string::npos)
|
|
{
|
|
cases += fmt::format(
|
|
"%Color_{0} = OpCompositeConstruct %float4 "
|
|
" %_out_float_{0} %_out_float_{0} %_out_float_{0} %_out_float_{0}\n",
|
|
i);
|
|
}
|
|
else if(test.find("%_out_float2_") != std::string::npos)
|
|
{
|
|
cases += fmt::format(
|
|
"%Color_{0} = OpVectorShuffle %float4 %_out_float2_{0} %_out_float2_{0} 0 1 0 1\n", i);
|
|
}
|
|
else if(test.find("%_out_float3_") != std::string::npos)
|
|
{
|
|
cases += fmt::format(
|
|
"%Color_{0} = OpVectorShuffle %float4 %_out_float3_{0} %_out_float3_{0} 0 1 2 0\n", i);
|
|
}
|
|
else if(test.find("%_out_double_") != std::string::npos)
|
|
{
|
|
cases += fmt::format(
|
|
"%_out_float_{0} = OpFConvert %float %_out_double_{0}\n"
|
|
"%Color_{0} = OpCompositeConstruct %float4 "
|
|
" %_out_float_{0} %_out_float_{0} %_out_float_{0} %_out_float_{0}\n",
|
|
i);
|
|
}
|
|
else if(test.find("%_out_double2_") != std::string::npos)
|
|
{
|
|
cases += fmt::format(
|
|
"%_out_float2_{0} = OpFConvert %float2 %_out_double2_{0}\n"
|
|
"%Color_{0} = OpVectorShuffle %float4 %_out_float2_{0} %_out_float2_{0} 0 1 0 1\n",
|
|
i);
|
|
}
|
|
else if(test.find("%_out_double3_") != std::string::npos)
|
|
{
|
|
cases += fmt::format(
|
|
"%_out_float3_{0} = OpFConvert %float3 %_out_double3_{0}\n"
|
|
"%Color_{0} = OpVectorShuffle %float4 %_out_float3_{0} %_out_float3_{0} 0 1 2 0\n",
|
|
i);
|
|
}
|
|
else if(test.find("%_out_double4_") != std::string::npos)
|
|
{
|
|
cases += fmt::format("%Color_{0} = OpFConvert %float4 %_out_double4_{0}\n", i);
|
|
}
|
|
else if(test.find("%_out_int_") != std::string::npos)
|
|
{
|
|
cases += fmt::format(
|
|
"%_f_{0} = OpConvertSToF %float %_out_int_{0}\n"
|
|
"%Color_{0} = OpCompositeConstruct %float4 %_f_{0} %_f_{0} %_f_{0} %_f_{0}\n",
|
|
i);
|
|
}
|
|
else if(test.find("%_out_int2_") != std::string::npos)
|
|
{
|
|
cases += fmt::format(
|
|
"%_f_{0} = OpConvertSToF %float2 %_out_int2_{0}\n"
|
|
"%Color_{0} = OpVectorShuffle %float4 %_f_{0} %_f_{0} 0 1 0 1\n",
|
|
i);
|
|
}
|
|
else if(test.find("%_out_int3_") != std::string::npos)
|
|
{
|
|
cases += fmt::format(
|
|
"%_f_{0} = OpConvertSToF %float3 %_out_int3_{0}\n"
|
|
"%Color_{0} = OpVectorShuffle %float4 %_f_{0} %_f_{0} 0 1 2 0\n",
|
|
i);
|
|
}
|
|
else if(test.find("%_out_int4_") != std::string::npos)
|
|
{
|
|
cases += fmt::format("%Color_{0} = OpConvertSToF %float4 %_out_int4_{0}\n", i);
|
|
}
|
|
else if(test.find("%_out_uint_") != std::string::npos)
|
|
{
|
|
cases += fmt::format(
|
|
"%_f_{0} = OpConvertUToF %float %_out_uint_{0}\n"
|
|
"%Color_{0} = OpCompositeConstruct %float4 %_f_{0} %_f_{0} %_f_{0} %_f_{0}\n",
|
|
i);
|
|
}
|
|
else if(test.find("%_out_uint2_") != std::string::npos)
|
|
{
|
|
cases += fmt::format(
|
|
"%_f_{0} = OpConvertUToF %float2 %_out_uint2_{0}\n"
|
|
"%Color_{0} = OpVectorShuffle %float4 %_f_{0} %_f_{0} 0 1 0 1\n",
|
|
i);
|
|
}
|
|
else if(test.find("%_out_uint3_") != std::string::npos)
|
|
{
|
|
cases += fmt::format(
|
|
"%_f_{0} = OpConvertUToF %float3 %_out_uint3_{0}\n"
|
|
"%Color_{0} = OpVectorShuffle %float4 %_f_{0} %_f_{0} 0 1 2 0\n",
|
|
i);
|
|
}
|
|
else if(test.find("%_out_uint4_") != std::string::npos)
|
|
{
|
|
cases += fmt::format("%Color_{0} = OpConvertUToF %float4 %_out_uint4_{0}\n", i);
|
|
}
|
|
else if(test.find("%_out_i64_") != std::string::npos)
|
|
{
|
|
cases += fmt::format(
|
|
"%_f_{0} = OpConvertSToF %float %_out_i64_{0}\n"
|
|
"%Color_{0} = OpCompositeConstruct %float4 %_f_{0} %_f_{0} %_f_{0} "
|
|
"%_f_{0}\n",
|
|
i);
|
|
}
|
|
else if(test.find("%_out_u64_") != std::string::npos)
|
|
{
|
|
cases += fmt::format(
|
|
"%_f_{0} = OpConvertUToF %float %_out_u64_{0}\n"
|
|
"%Color_{0} = OpCompositeConstruct %float4 %_f_{0} %_f_{0} %_f_{0} "
|
|
"%_f_{0}\n",
|
|
i);
|
|
}
|
|
else if(test.find("%_out_u8v2_") != std::string::npos)
|
|
{
|
|
cases += fmt::format(
|
|
"%_f_{0} = OpConvertUToF %float2 %_out_u8v2_{0}\n"
|
|
"%Color_{0} = OpVectorShuffle %float4 %_f_{0} %_f_{0} 0 1 0 1\n",
|
|
i);
|
|
}
|
|
else if(test.find("%_out_u8v4_") != std::string::npos)
|
|
{
|
|
cases += fmt::format("%Color_{0} = OpConvertUToF %float4 %_out_u8v4_{0}\n", i);
|
|
}
|
|
else if(test.find("%_out_u16_") != std::string::npos)
|
|
{
|
|
cases += fmt::format(
|
|
"%_f_{0} = OpConvertUToF %float %_out_u16_{0}\n"
|
|
"%Color_{0} = OpCompositeConstruct %float4 %_f_{0} %_f_{0} %_f_{0} %_f_{0}\n",
|
|
i);
|
|
}
|
|
else if(test.find("%_out_u16v2_") != std::string::npos)
|
|
{
|
|
cases += fmt::format(
|
|
"%_f_{0} = OpConvertUToF %float2 %_out_u16v2_{0}\n"
|
|
"%Color_{0} = OpVectorShuffle %float4 %_f_{0} %_f_{0} 0 1 0 1\n",
|
|
i);
|
|
}
|
|
else if(test.find("%_out_u16v4_") != std::string::npos)
|
|
{
|
|
cases += fmt::format("%Color_{0} = OpConvertUToF %float4 %_out_u16v4_{0}\n", i);
|
|
}
|
|
else if(test.find("%_out_half2_") != std::string::npos)
|
|
{
|
|
cases += fmt::format(
|
|
"%_f_{0} = OpFConvert %float2 %_out_half2_{0}\n"
|
|
"%Color_{0} = OpVectorShuffle %float4 %_f_{0} %_f_{0} 0 1 0 1\n",
|
|
i);
|
|
}
|
|
else if(test.find("; no_out") != std::string::npos)
|
|
{
|
|
store_out = false;
|
|
}
|
|
else
|
|
{
|
|
TEST_FATAL("Test with no recognised output");
|
|
}
|
|
|
|
if(store_out)
|
|
cases += fmt::format("OpStore %Color %Color_{}\n", i);
|
|
}
|
|
|
|
cases += "OpBranch %break\n";
|
|
}
|
|
|
|
if(features.shaderFloat64)
|
|
{
|
|
typesConstants +=
|
|
"%double = OpTypeFloat 64\n"
|
|
"%double2 = OpTypeVector %double 2\n"
|
|
"%double3 = OpTypeVector %double 3\n"
|
|
"%double4 = OpTypeVector %double 4\n"
|
|
"%double2x2 = OpTypeMatrix %double2 2\n"
|
|
"%double3x3 = OpTypeMatrix %double3 3\n"
|
|
"%double2x4 = OpTypeMatrix %double2 4\n"
|
|
"%double4x2 = OpTypeMatrix %double4 2\n"
|
|
"%double4x4 = OpTypeMatrix %double4 4\n";
|
|
|
|
typesConstants += "%ptr_Uniform_double = OpTypePointer Uniform %double\n";
|
|
capabilities += "OpCapability Float64\n";
|
|
}
|
|
|
|
if(float16Int8Features.shaderFloat16)
|
|
{
|
|
typesConstants +=
|
|
"%half = OpTypeFloat 16\n"
|
|
"%half2 = OpTypeVector %half 2\n";
|
|
capabilities += "OpCapability Float16\n";
|
|
}
|
|
|
|
if(float16Int8Features.shaderInt8 || storage8Features.storageBuffer8BitAccess ||
|
|
storage8Features.uniformAndStorageBuffer8BitAccess || storage8Features.storagePushConstant8)
|
|
{
|
|
typesConstants +=
|
|
"%i8 = OpTypeInt 8 1\n"
|
|
"%u8 = OpTypeInt 8 0\n"
|
|
"%u8v2 = OpTypeVector %u8 2\n"
|
|
"%u8v4 = OpTypeVector %u8 4\n";
|
|
capabilities += "OpCapability Int8\n";
|
|
}
|
|
|
|
if(features.shaderInt64)
|
|
{
|
|
typesConstants +=
|
|
"%i64 = OpTypeInt 64 1\n"
|
|
"%u64 = OpTypeInt 64 0\n";
|
|
capabilities += "OpCapability Int64\n";
|
|
}
|
|
|
|
if(features.shaderInt16 || storage16Features.storageBuffer16BitAccess ||
|
|
storage16Features.uniformAndStorageBuffer16BitAccess ||
|
|
storage16Features.storagePushConstant16 || storage16Features.storageInputOutput16)
|
|
{
|
|
typesConstants +=
|
|
"%i16 = OpTypeInt 16 1\n"
|
|
"%u16 = OpTypeInt 16 0\n"
|
|
"%u16v2 = OpTypeVector %u16 2\n"
|
|
"%u16v4 = OpTypeVector %u16 4\n";
|
|
capabilities += "OpCapability Int16\n";
|
|
}
|
|
|
|
if(bdaFeatures.bufferDeviceAddress)
|
|
{
|
|
capabilities += "OpCapability PhysicalStorageBufferAddresses\n";
|
|
spv_extensions += R"EOSHADER(
|
|
OpExtension "SPV_KHR_physical_storage_buffer"
|
|
)EOSHADER";
|
|
|
|
typesConstants += "%pushdata_struct = OpTypeStruct %int4 %uint2 %uint %uint";
|
|
if(features.shaderInt64)
|
|
typesConstants += " %u64\n";
|
|
else
|
|
typesConstants += " %uint2\n";
|
|
|
|
typesConstants += R"EOSHADER(
|
|
%ptr_PushConstant_pushdata_struct = OpTypePointer PushConstant %pushdata_struct
|
|
%push_data = OpVariable %ptr_PushConstant_pushdata_struct PushConstant
|
|
|
|
%ptr_PushConstant_uint = OpTypePointer PushConstant %uint
|
|
%ptr_PushConstant_uint2 = OpTypePointer PushConstant %uint2
|
|
)EOSHADER";
|
|
|
|
if(features.shaderInt64)
|
|
typesConstants += "%ptr_PushConstant_u64 = OpTypePointer PushConstant %u64\n";
|
|
|
|
typesConstants += "%bda_data_struct = OpTypeStruct %float4 %float4";
|
|
|
|
typesConstants += R"EOSHADER(
|
|
%ptr_PhysicalStorageBuffer_bda_data_struct = OpTypePointer PhysicalStorageBuffer %bda_data_struct
|
|
%ptr_PhysicalStorageBuffer_bda_data_struct_first = OpTypePointer PhysicalStorageBuffer %float4
|
|
%ptr_PhysicalStorageBuffer_bda_data_struct_f32_4 = OpTypePointer PhysicalStorageBuffer %float
|
|
%ptr_PhysicalStorageBuffer_bda_data_struct_f32_8 = OpTypePointer PhysicalStorageBuffer %float
|
|
%ptr_PhysicalStorageBuffer_bda_data_struct_f32_12 = OpTypePointer PhysicalStorageBuffer %float
|
|
%ptr_PhysicalStorageBuffer_f32 = OpTypePointer PhysicalStorageBuffer %float
|
|
)EOSHADER";
|
|
|
|
decorations += R"EOSHADER(
|
|
OpDecorate %ptr_PhysicalStorageBuffer_bda_data_struct_f32_4 ArrayStride 4
|
|
OpDecorate %ptr_PhysicalStorageBuffer_bda_data_struct_f32_8 ArrayStride 8
|
|
OpDecorate %ptr_PhysicalStorageBuffer_bda_data_struct_f32_12 ArrayStride 12
|
|
OpDecorate %pushdata_struct Block
|
|
OpMemberDecorate %pushdata_struct 0 Offset 16 ; int4 data
|
|
OpMemberDecorate %pushdata_struct 1 Offset 32 ; uint2 bda_uvec2
|
|
OpMemberDecorate %pushdata_struct 2 Offset 40 ; uint bda_hi
|
|
OpMemberDecorate %pushdata_struct 3 Offset 44 ; uint bda_lo
|
|
OpMemberDecorate %pushdata_struct 4 Offset 48 ; uint64_t bda_u64
|
|
|
|
OpDecorate %bda_data_struct Block
|
|
OpMemberDecorate %bda_data_struct 0 Offset 0 ; float f32[0..3]
|
|
OpMemberDecorate %bda_data_struct 1 Offset 16 ; float f32[4..7]
|
|
)EOSHADER";
|
|
}
|
|
|
|
std::string cbuffer =
|
|
"%cbuffer_struct = OpTypeStruct %float4 %float4 %float4 %float4 %float4 %float4 %float4 "
|
|
" %float4 %float4 %float4 %float4 %float4 %uint %uint %uint "
|
|
" %uint %uint2";
|
|
|
|
if(features.shaderFloat64)
|
|
cbuffer += " %double";
|
|
else
|
|
cbuffer += " %uint2";
|
|
|
|
cbuffer += "\n";
|
|
|
|
typesConstants += cbuffer;
|
|
decorations += R"EOSHADER(
|
|
|
|
OpDecorate %cbuffer_struct Block
|
|
OpDecorate %cbuffer DescriptorSet 0
|
|
OpDecorate %cbuffer Binding 10
|
|
OpMemberDecorate %cbuffer_struct 0 Offset 0 ; vec4 first
|
|
OpMemberDecorate %cbuffer_struct 1 Offset 16 ; vec4 pad1
|
|
OpMemberDecorate %cbuffer_struct 2 Offset 32 ; vec4 second
|
|
OpMemberDecorate %cbuffer_struct 3 Offset 48 ; vec4 nan
|
|
OpMemberDecorate %cbuffer_struct 4 Offset 64 ; vec4 third
|
|
OpMemberDecorate %cbuffer_struct 5 Offset 80 ; vec4 pad3
|
|
OpMemberDecorate %cbuffer_struct 6 Offset 96 ; vec4 fourth
|
|
OpMemberDecorate %cbuffer_struct 7 Offset 112 ; vec4 unorm2PackSource
|
|
OpMemberDecorate %cbuffer_struct 8 Offset 128 ; vec4 snorm2PackSource
|
|
OpMemberDecorate %cbuffer_struct 9 Offset 144 ; vec4 unorm4PackSource
|
|
OpMemberDecorate %cbuffer_struct 10 Offset 160 ; vec4 snorm4PackSource
|
|
OpMemberDecorate %cbuffer_struct 11 Offset 176 ; vec4 halfPackSource
|
|
OpMemberDecorate %cbuffer_struct 12 Offset 192 ; uint unormUnpackSource
|
|
OpMemberDecorate %cbuffer_struct 13 Offset 196 ; uint snormUnpackSource
|
|
OpMemberDecorate %cbuffer_struct 14 Offset 200 ; uint halfUnpackSource
|
|
OpMemberDecorate %cbuffer_struct 15 Offset 204 ; uint pad
|
|
OpMemberDecorate %cbuffer_struct 16 Offset 208 ; uint2 doubleUnpackSource
|
|
OpMemberDecorate %cbuffer_struct 17 Offset 216 ; double doublePackSource
|
|
)EOSHADER";
|
|
|
|
typesConstants +=
|
|
"%ptr_Uniform_cbuffer_struct = OpTypePointer Uniform %cbuffer_struct\n"
|
|
"%cbuffer = OpVariable %ptr_Uniform_cbuffer_struct Uniform\n";
|
|
|
|
// now generate all the constants
|
|
|
|
for(const std::string &n : null_constants)
|
|
typesConstants += fmt::format("%null_{0} = OpConstantNull %{0}\n", n);
|
|
|
|
typesConstants += "\n";
|
|
|
|
for(float f : float_constants)
|
|
{
|
|
std::string name = fmt::format("{}", f);
|
|
for(char &c : name)
|
|
if(c == '.')
|
|
c = '_';
|
|
typesConstants += fmt::format("%float_{} = OpConstant %float {}\n", name, f);
|
|
typesConstants += fmt::format("%float_neg{} = OpConstant %float -{}\n", name, f);
|
|
|
|
if(float16Int8Features.shaderFloat16)
|
|
{
|
|
typesConstants += fmt::format("%half_{} = OpConstant %half {}\n", name, f);
|
|
typesConstants += fmt::format("%half_neg{} = OpConstant %half -{}\n", name, f);
|
|
}
|
|
|
|
if(features.shaderFloat64)
|
|
{
|
|
typesConstants += fmt::format("%double_{} = OpConstant %double {}\n", name, f);
|
|
typesConstants += fmt::format("%double_neg{} = OpConstant %double -{}\n", name, f);
|
|
}
|
|
}
|
|
|
|
typesConstants += "\n";
|
|
|
|
if(float16Int8Features.shaderInt8)
|
|
{
|
|
typesConstants += "\n";
|
|
for(uint8_t u : u8_constants)
|
|
typesConstants += fmt::format("%u8_{0} = OpConstant %u8 {0}\n", u);
|
|
}
|
|
|
|
if(features.shaderInt16)
|
|
{
|
|
typesConstants += "\n";
|
|
for(uint16_t u : u16_constants)
|
|
typesConstants += fmt::format("%u16_{0} = OpConstant %u16 {0}\n", u);
|
|
}
|
|
|
|
for(int32_t i : int_constants)
|
|
{
|
|
typesConstants += fmt::format("%int_{0} = OpConstant %int {0}\n", i);
|
|
typesConstants += fmt::format("%int_neg{0} = OpConstant %int -{0}\n", i);
|
|
}
|
|
|
|
typesConstants += "\n";
|
|
|
|
for(uint32_t u : uint_constants)
|
|
typesConstants += fmt::format("%uint_{0} = OpConstant %uint {0}\n", u);
|
|
|
|
typesConstants += "\n";
|
|
|
|
if(features.shaderInt64)
|
|
{
|
|
for(int64_t i : i64_constants)
|
|
{
|
|
typesConstants += fmt::format("%i64_{0} = OpConstant %i64 {0}\n", i);
|
|
typesConstants += fmt::format("%i64_neg{0} = OpConstant %i64 -{0}\n", i);
|
|
}
|
|
|
|
typesConstants += "\n";
|
|
|
|
for(uint64_t u : u64_constants)
|
|
{
|
|
typesConstants += fmt::format("%u64_{0} = OpConstant %u64 {0}\n", u);
|
|
}
|
|
|
|
typesConstants += "\n";
|
|
}
|
|
else
|
|
{
|
|
if(!i64_constants.empty())
|
|
TEST_FATAL("Test using i64 constants without shaderInt64 capability");
|
|
if(!u64_constants.empty())
|
|
TEST_FATAL("Test using u64 constants without shaderInt64 capability");
|
|
}
|
|
|
|
for(size_t i = 0; i < 32; i++)
|
|
typesConstants += fmt::format("%randf_{} = OpConstant %float {:.3}\n", i, RANDF(0.0f, 1.0f));
|
|
|
|
typesConstants += "\n";
|
|
|
|
// vector constants here manually, as we can't pull these out easily
|
|
typesConstants += R"EOSHADER(
|
|
|
|
%float4_0000 = OpConstantComposite %float4 %float_0_0 %float_0_0 %float_0_0 %float_0_0
|
|
%float4_1234 = OpConstantComposite %float4 %float_1_0 %float_2_0 %float_3_0 %float_4_0
|
|
|
|
%float3_000 = OpConstantComposite %float3 %float_0_0 %float_0_0 %float_0_0
|
|
%float3_123 = OpConstantComposite %float3 %float_1_0 %float_2_0 %float_3_0
|
|
|
|
%float2_00 = OpConstantComposite %float2 %float_0_0 %float_0_0
|
|
%float2_12 = OpConstantComposite %float2 %float_1_0 %float_2_0
|
|
|
|
%priv_float4_init = OpVariable %ptr_Private_float4 Private %float4_1234
|
|
|
|
)EOSHADER";
|
|
|
|
std::string memory_model =
|
|
(bdaFeatures.bufferDeviceAddress) ? "PhysicalStorageBuffer64" : "Logical";
|
|
std::string ret = capabilities + spv_extensions + extinstimport +
|
|
R"EOSHADER(
|
|
OpMemoryModel )EOSHADER" +
|
|
memory_model + " GLSL450\n" +
|
|
R"EOSHADER(
|
|
OpEntryPoint Fragment %main "main" %flatData %linearData %Color %gl_FragCoord
|
|
)EOSHADER" + executionmodes +
|
|
spv_debug + decorations + typesConstants + functions +
|
|
R"EOSHADER(
|
|
%main = OpFunction %void None %mainfunc
|
|
%main_begin = OpLabel
|
|
%test_ptr = OpAccessChain %ptr_Input_uint %flatData %flatv2f_test_idx
|
|
%test = OpLoad %uint %test_ptr
|
|
|
|
%zeroVal_ptr = OpAccessChain %ptr_Input_float2 %linearData %v2f_zeroVal_idx
|
|
%zeroVal = OpLoad %float2 %zeroVal_ptr
|
|
%zeroVal_x = OpCompositeExtract %float %zeroVal 0
|
|
%zeroVal_y = OpCompositeExtract %float %zeroVal 1
|
|
%zerof = OpCompositeExtract %float %zeroVal 0
|
|
|
|
%inpos_ptr = OpAccessChain %ptr_Input_float2 %linearData %v2f_inpos_idx
|
|
%inpos = OpLoad %float2 %inpos_ptr
|
|
|
|
%inposIncreased_ptr = OpAccessChain %ptr_Input_float2 %linearData %v2f_inposIncreased_idx
|
|
%inposIncreased = OpLoad %float2 %inposIncreased_ptr
|
|
|
|
%tinyVal_ptr = OpAccessChain %ptr_Input_float %linearData %v2f_tinyVal_idx
|
|
%tinyVal = OpLoad %float %tinyVal_ptr
|
|
|
|
%oneVal_ptr = OpAccessChain %ptr_Input_float %linearData %v2f_oneVal_idx
|
|
%oneVal = OpLoad %float %oneVal_ptr
|
|
|
|
%negoneVal_ptr = OpAccessChain %ptr_Input_float %linearData %v2f_negoneVal_idx
|
|
%negoneVal = OpLoad %float %negoneVal_ptr
|
|
|
|
%posinf = OpFDiv %float %oneVal %zerof
|
|
%neginf = OpFDiv %float %negoneVal %zerof
|
|
|
|
; NaN generation is hard and we want to avoid compilers compiling it out, so generate
|
|
; it in shader and multiply by one from a UBO so we get NaN either way
|
|
; (since NaN * anything = NaN)
|
|
%nan_shad = OpFDiv %float %zerof %zerof
|
|
|
|
%nan_ptr = OpAccessChain %ptr_Uniform_float4 %cbuffer %uint_3
|
|
%nan_ubo = OpLoad %float4 %nan_ptr
|
|
%nan_ubo_x = OpCompositeExtract %float %nan_ubo 0
|
|
%nan = OpFMul %float %nan_shad %nan_ubo_x
|
|
|
|
%intval_ptr = OpAccessChain %ptr_Input_uint %flatData %flatv2f_intval_idx
|
|
%intval = OpLoad %uint %intval_ptr
|
|
%tmp = OpISub %uint %intval %test
|
|
%zerou = OpISub %uint %tmp %int_7
|
|
%zeroi = OpBitcast %int %zerou
|
|
|
|
)EOSHADER";
|
|
|
|
if(features.shaderFloat64)
|
|
ret += "%zerof64 = OpFConvert %double %zerof\n";
|
|
|
|
if(features.shaderInt64)
|
|
{
|
|
ret +=
|
|
"%_temp = OpCompositeConstruct %uint2 %zerou %zerou\n"
|
|
"%zerou64 = OpBitcast %u64 %_temp\n";
|
|
}
|
|
|
|
// generate dynamic versions of the constants
|
|
for(float f : float_constants)
|
|
{
|
|
std::string name = fmt::format("{}", f);
|
|
for(char &c : name)
|
|
if(c == '.')
|
|
c = '_';
|
|
ret += fmt::format("%float_dyn_{0} = OpFAdd %float %zerof %float_{0}\n", name);
|
|
ret += fmt::format("%float_dyn_neg{0} = OpFAdd %float %zerof %float_neg{0}\n", name);
|
|
|
|
if(features.shaderFloat64)
|
|
{
|
|
ret += fmt::format("%double_dyn_{0} = OpFAdd %double %zerof64 %double_{0}\n", name);
|
|
ret += fmt::format("%double_dyn_neg{0} = OpFAdd %double %zerof64 %double_neg{0}\n", name);
|
|
}
|
|
}
|
|
|
|
ret += "\n";
|
|
|
|
for(int32_t i : int_constants)
|
|
{
|
|
ret += fmt::format("%int_dyn_{0} = OpIAdd %int %zeroi %int_{0}\n", i);
|
|
ret += fmt::format("%int_dyn_neg{0} = OpIAdd %int %zeroi %int_neg{0}\n", i);
|
|
}
|
|
|
|
ret += "\n";
|
|
|
|
for(uint32_t u : uint_constants)
|
|
ret += fmt::format("%uint_dyn_{0} = OpIAdd %uint %zerou %uint_{0}\n", u);
|
|
|
|
for(uint64_t u : u64_constants)
|
|
ret += fmt::format("%u64_dyn_{0} = OpIAdd %u64 %zerou64 %u64_{0}\n", u);
|
|
|
|
ret += "\n";
|
|
|
|
for(size_t i = 0; i < 32; i++)
|
|
ret += fmt::format("%randf_dyn_{0} = OpFAdd %float %zerof %randf_{0}\n", i);
|
|
|
|
ret += "\n";
|
|
|
|
ret += R"EOSHADER(
|
|
|
|
%float4_dyn_0000 = OpCompositeConstruct %float4 %float_dyn_0_0 %float_dyn_0_0 %float_dyn_0_0 %float_dyn_0_0
|
|
%float4_dyn_1234 = OpCompositeConstruct %float4 %float_dyn_1_0 %float_dyn_2_0 %float_dyn_3_0 %float_dyn_4_0
|
|
|
|
%float3_dyn_000 = OpCompositeConstruct %float3 %float_dyn_0_0 %float_dyn_0_0 %float_dyn_0_0
|
|
%float3_dyn_123 = OpCompositeConstruct %float3 %float_dyn_1_0 %float_dyn_2_0 %float_dyn_3_0
|
|
|
|
%float2_dyn_00 = OpCompositeConstruct %float2 %float_dyn_0_0 %float_dyn_0_0
|
|
%float2_dyn_12 = OpCompositeConstruct %float2 %float_dyn_1_0 %float_dyn_2_0
|
|
|
|
)EOSHADER";
|
|
|
|
ret += switch_str;
|
|
ret += cases;
|
|
|
|
ret += R"EOSHADER(
|
|
|
|
%default = OpLabel
|
|
OpStore %Color %float4_0000
|
|
OpBranch %break
|
|
|
|
%break = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)EOSHADER";
|
|
|
|
return ret;
|
|
}
|
|
|
|
uint32_t vk_version = 0x10;
|
|
|
|
VkPhysicalDevice16BitStorageFeaturesKHR storage16Features = {
|
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR,
|
|
};
|
|
VkPhysicalDevice8BitStorageFeaturesKHR storage8Features = {
|
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR,
|
|
};
|
|
VkPhysicalDeviceFloat16Int8FeaturesKHR float16Int8Features = {
|
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR,
|
|
};
|
|
VkPhysicalDeviceBufferDeviceAddressFeaturesEXT bdaFeatures = {
|
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR,
|
|
};
|
|
|
|
void Prepare(int argc, char **argv)
|
|
{
|
|
// require descriptor indexing
|
|
optDevExts.push_back(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
|
|
|
|
// dependencies of VK_EXT_descriptor_indexing
|
|
optDevExts.push_back(VK_KHR_MAINTENANCE3_EXTENSION_NAME);
|
|
|
|
// add float16/int8 extensions
|
|
optDevExts.push_back(VK_KHR_8BIT_STORAGE_EXTENSION_NAME);
|
|
optDevExts.push_back(VK_KHR_16BIT_STORAGE_EXTENSION_NAME);
|
|
optDevExts.push_back(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME);
|
|
|
|
// dependencies of VK_KHR_8bit_storage
|
|
optDevExts.push_back(VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME);
|
|
|
|
// add BDA extension
|
|
optDevExts.push_back(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
|
|
|
|
// we require this to pixel shader debug anyway, so we might as well require it for all tests.
|
|
features.fragmentStoresAndAtomics = VK_TRUE;
|
|
|
|
// this is so widely supported just require it without fallback
|
|
features.imageCubeArray = VK_TRUE;
|
|
|
|
VulkanGraphicsTest::Prepare(argc, argv);
|
|
|
|
if(!Avail.empty())
|
|
return;
|
|
|
|
const bool descIndexing = std::find(devExts.begin(), devExts.end(),
|
|
VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME) != devExts.end();
|
|
const bool storage16 = std::find(devExts.begin(), devExts.end(),
|
|
VK_KHR_16BIT_STORAGE_EXTENSION_NAME) != devExts.end();
|
|
const bool storage8 = std::find(devExts.begin(), devExts.end(),
|
|
VK_KHR_8BIT_STORAGE_EXTENSION_NAME) != devExts.end();
|
|
const bool float16int8 = std::find(devExts.begin(), devExts.end(),
|
|
VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME) != devExts.end();
|
|
const bool bda = std::find(devExts.begin(), devExts.end(),
|
|
VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME) != devExts.end();
|
|
|
|
vk_version = 0x10;
|
|
|
|
if(physProperties.apiVersion >= VK_MAKE_VERSION(1, 1, 0))
|
|
vk_version = 0x11;
|
|
|
|
if(physProperties.apiVersion >= VK_MAKE_VERSION(1, 2, 0))
|
|
vk_version = 0x12;
|
|
|
|
#define LIMIT_CHECK(limit, req) \
|
|
if(physProperties.limits.limit < req) \
|
|
Avail = fmt::format("Limit '" #limit "' {} is insufficient (need at least {})", \
|
|
physProperties.limits.limit, req);
|
|
|
|
if(descIndexing)
|
|
{
|
|
LIMIT_CHECK(maxPerStageDescriptorSampledImages, 128);
|
|
LIMIT_CHECK(maxPerStageDescriptorSamplers, 64);
|
|
LIMIT_CHECK(maxPerStageDescriptorStorageBuffers, 16);
|
|
LIMIT_CHECK(maxPerStageDescriptorStorageImages, 64);
|
|
}
|
|
|
|
VkFormatProperties props = {};
|
|
vkGetPhysicalDeviceFormatProperties(phys, VK_FORMAT_A2B10G10R10_UINT_PACK32, &props);
|
|
|
|
if((props.bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT) == 0)
|
|
{
|
|
Avail = "VK_FORMAT_A2B10G10R10_UINT_PACK32 not supported in texel buffers";
|
|
return;
|
|
}
|
|
if((props.bufferFeatures & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT) == 0)
|
|
{
|
|
Avail = "VK_FORMAT_A2B10G10R10_UINT_PACK32 not supported in texel buffers";
|
|
return;
|
|
}
|
|
|
|
vkGetPhysicalDeviceFormatProperties(phys, VK_FORMAT_A2B10G10R10_UNORM_PACK32, &props);
|
|
|
|
if((props.bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT) == 0)
|
|
{
|
|
Avail = "VK_FORMAT_A2B10G10R10_UNORM_PACK32 not supported in texel buffers";
|
|
return;
|
|
}
|
|
if((props.bufferFeatures & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT) == 0)
|
|
{
|
|
Avail = "VK_FORMAT_A2B10G10R10_UNORM_PACK32 not supported in texel buffers";
|
|
return;
|
|
}
|
|
|
|
// enable features we can optionally test with.
|
|
VkPhysicalDeviceFeatures supported;
|
|
vkGetPhysicalDeviceFeatures(phys, &supported);
|
|
|
|
if(supported.shaderFloat64)
|
|
features.shaderFloat64 = VK_TRUE;
|
|
if(supported.shaderInt64)
|
|
features.shaderInt64 = VK_TRUE;
|
|
if(supported.shaderInt16)
|
|
features.shaderInt16 = VK_TRUE;
|
|
|
|
if(descIndexing)
|
|
{
|
|
static VkPhysicalDeviceDescriptorIndexingFeaturesEXT descIndexingFeatures = {
|
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT,
|
|
};
|
|
|
|
getPhysFeatures2(&descIndexingFeatures);
|
|
|
|
// enable descriptor indexing on arrays of all types
|
|
|
|
if(!descIndexingFeatures.runtimeDescriptorArray)
|
|
Avail = "Descriptor indexing feature 'runtimeDescriptorArray' not available";
|
|
else if(!descIndexingFeatures.shaderUniformTexelBufferArrayDynamicIndexing)
|
|
Avail =
|
|
"Descriptor indexing feature 'shaderUniformTexelBufferArrayDynamicIndexing' not "
|
|
"available";
|
|
else if(!descIndexingFeatures.shaderStorageTexelBufferArrayDynamicIndexing)
|
|
Avail =
|
|
"Descriptor indexing feature 'shaderStorageTexelBufferArrayDynamicIndexing' not "
|
|
"available";
|
|
else if(!descIndexingFeatures.shaderUniformBufferArrayNonUniformIndexing)
|
|
Avail =
|
|
"Descriptor indexing feature 'shaderUniformBufferArrayNonUniformIndexing' not "
|
|
"available";
|
|
else if(!descIndexingFeatures.shaderSampledImageArrayNonUniformIndexing)
|
|
Avail =
|
|
"Descriptor indexing feature 'shaderSampledImageArrayNonUniformIndexing' not available";
|
|
else if(!descIndexingFeatures.shaderStorageBufferArrayNonUniformIndexing)
|
|
Avail =
|
|
"Descriptor indexing feature 'shaderStorageBufferArrayNonUniformIndexing' not "
|
|
"available";
|
|
else if(!descIndexingFeatures.shaderStorageImageArrayNonUniformIndexing)
|
|
Avail =
|
|
"Descriptor indexing feature 'shaderStorageImageArrayNonUniformIndexing' not available";
|
|
else if(!descIndexingFeatures.shaderUniformTexelBufferArrayNonUniformIndexing)
|
|
Avail =
|
|
"Descriptor indexing feature 'shaderUniformTexelBufferArrayNonUniformIndexing' not "
|
|
"available";
|
|
else if(!descIndexingFeatures.shaderStorageTexelBufferArrayNonUniformIndexing)
|
|
Avail =
|
|
"Descriptor indexing feature 'shaderStorageTexelBufferArrayNonUniformIndexing' not "
|
|
"available";
|
|
|
|
devInfoNext = &descIndexingFeatures;
|
|
}
|
|
|
|
if(storage16)
|
|
{
|
|
// enable all available features
|
|
getPhysFeatures2(&storage16Features);
|
|
|
|
storage16Features.pNext = (void *)devInfoNext;
|
|
devInfoNext = &storage16Features;
|
|
}
|
|
|
|
if(storage8)
|
|
{
|
|
// enable all available features
|
|
getPhysFeatures2(&storage8Features);
|
|
|
|
storage8Features.pNext = (void *)devInfoNext;
|
|
devInfoNext = &storage8Features;
|
|
}
|
|
|
|
if(float16int8)
|
|
{
|
|
// enable all available features
|
|
getPhysFeatures2(&float16Int8Features);
|
|
|
|
float16Int8Features.pNext = (void *)devInfoNext;
|
|
devInfoNext = &float16Int8Features;
|
|
}
|
|
|
|
if(bda)
|
|
{
|
|
getPhysFeatures2(&bdaFeatures);
|
|
bdaFeatures.pNext = (void *)devInfoNext;
|
|
devInfoNext = &bdaFeatures;
|
|
}
|
|
}
|
|
|
|
int main()
|
|
{
|
|
// initialise, create window, create context, etc
|
|
if(!Init())
|
|
return 3;
|
|
|
|
make_asm_tests();
|
|
|
|
const bool descIndexing = std::find(devExts.begin(), devExts.end(),
|
|
VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME) != devExts.end();
|
|
const bool storage16 = std::find(devExts.begin(), devExts.end(),
|
|
VK_KHR_16BIT_STORAGE_EXTENSION_NAME) != devExts.end();
|
|
const bool storage8 = std::find(devExts.begin(), devExts.end(),
|
|
VK_KHR_8BIT_STORAGE_EXTENSION_NAME) != devExts.end();
|
|
const bool float16int8 = std::find(devExts.begin(), devExts.end(),
|
|
VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME) != devExts.end();
|
|
const bool bda = std::find(devExts.begin(), devExts.end(),
|
|
VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME) != devExts.end();
|
|
|
|
if(storage16)
|
|
TEST_LOG("Running tests on 16-bit storage");
|
|
|
|
if(storage8)
|
|
TEST_LOG("Running tests on 8-bit storage");
|
|
|
|
if(float16int8)
|
|
TEST_LOG("Running tests on half and int8 arithmetic");
|
|
|
|
if(bda)
|
|
TEST_LOG("Running tests on buffer device address");
|
|
|
|
if(features.shaderFloat64)
|
|
TEST_LOG("Running tests on doubles");
|
|
|
|
if(features.shaderInt64)
|
|
TEST_LOG("Running tests on int64");
|
|
|
|
if(features.shaderInt16)
|
|
TEST_LOG("Running tests on int16 arithmetic");
|
|
|
|
pixel_glsl1.replace(pixel_glsl1.find("#define TEST_DESC_INDEXING"),
|
|
sizeof("#define TEST_DESC_INDEXING"),
|
|
fmt::format("#define TEST_DESC_INDEXING {}", descIndexing ? 1 : 0));
|
|
|
|
pixel_glsl2.replace(pixel_glsl2.find("#define TEST_DESC_INDEXING"),
|
|
sizeof("#define TEST_DESC_INDEXING"),
|
|
fmt::format("#define TEST_DESC_INDEXING {}", descIndexing ? 1 : 0));
|
|
|
|
size_t lastTest = pixel_glsl1.rfind("case ");
|
|
lastTest += sizeof("case ") - 1;
|
|
|
|
const uint32_t numGLSL1Tests = atoi(pixel_glsl1.c_str() + lastTest) + 1;
|
|
|
|
lastTest = pixel_glsl2.rfind("case ");
|
|
lastTest += sizeof("case ") - 1;
|
|
|
|
const uint32_t numGLSL2Tests = atoi(pixel_glsl2.c_str() + lastTest) + 1;
|
|
|
|
const uint32_t numASMTests = (uint32_t)asm_tests.size();
|
|
|
|
VkDescriptorSetLayout setlayout0 = createDescriptorSetLayout(vkh::DescriptorSetLayoutCreateInfo({
|
|
{0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT},
|
|
{10, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{11, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{12, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{13, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{14, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{15, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{16, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{17, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{18, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{19, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{20, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{21, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{22, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{30, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{31, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{32, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{33, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{34, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{35, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{36, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
}));
|
|
|
|
std::vector<VkDescriptorSetLayout> setLayouts = {setlayout0};
|
|
|
|
// this set layout has arrays of each type. We'll uniformly, dynamic-uniformly, and
|
|
// non-uniformly access each of these
|
|
VkDescriptorSetLayout setlayout1 = VK_NULL_HANDLE;
|
|
VkDescriptorSetLayout setlayout2 = VK_NULL_HANDLE;
|
|
|
|
if(descIndexing)
|
|
{
|
|
setlayout1 = createDescriptorSetLayout(vkh::DescriptorSetLayoutCreateInfo({
|
|
{1, VK_DESCRIPTOR_TYPE_SAMPLER, 14, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{2, VK_DESCRIPTOR_TYPE_SAMPLER, 14, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{3, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 14, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 14, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 14, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{6, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 14, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{7, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 14, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{8, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 14, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{9, VK_DESCRIPTOR_TYPE_SAMPLER, 14, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{20, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 14, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{21, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 14, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
}));
|
|
|
|
setlayout2 = createDescriptorSetLayout(vkh::DescriptorSetLayoutCreateInfo({
|
|
{0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{5, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{6, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{7, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{8, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{9, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
|
|
{10, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{11, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{12, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{13, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{14, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{15, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{16, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{17, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{18, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{19, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
|
|
{20, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{21, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{22, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{23, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{24, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{25, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{26, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{27, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{28, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{29, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
|
|
{30, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{31, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{32, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{33, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{34, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{35, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{36, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{37, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{38, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{39, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
|
|
{40, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{41, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{42, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{43, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{44, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{45, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{46, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{47, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{48, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{49, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
|
|
{50, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{51, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{52, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{53, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{54, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{55, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{56, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{57, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{58, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
{59, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
|
}));
|
|
|
|
setLayouts.push_back(setlayout1);
|
|
setLayouts.push_back(setlayout2);
|
|
}
|
|
|
|
VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo(
|
|
setLayouts, {
|
|
vkh::PushConstantRange(VK_SHADER_STAGE_FRAGMENT_BIT, 16, sizeof(PushData)),
|
|
}));
|
|
|
|
// calculate number of tests, wrapping each row at 256
|
|
uint32_t texWidth = AlignUp(std::max(std::max(numGLSL1Tests, numGLSL2Tests), numASMTests), 256U);
|
|
uint32_t texHeight = std::max(1U, texWidth / 256U);
|
|
texWidth /= texHeight;
|
|
|
|
// 4x4 for each test
|
|
texWidth *= 4;
|
|
texHeight *= 4;
|
|
|
|
AllocatedImage img(
|
|
this,
|
|
vkh::ImageCreateInfo(texWidth, texHeight, 0, VK_FORMAT_R32G32B32A32_SFLOAT,
|
|
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT),
|
|
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
|
|
|
|
VkImageView imgview = createImageView(
|
|
vkh::ImageViewCreateInfo(img.image, VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R32G32B32A32_SFLOAT));
|
|
|
|
vkh::RenderPassCreator renderPassCreateInfo;
|
|
|
|
renderPassCreateInfo.attachments.push_back(
|
|
vkh::AttachmentDescription(VK_FORMAT_R32G32B32A32_SFLOAT, VK_IMAGE_LAYOUT_UNDEFINED,
|
|
VK_IMAGE_LAYOUT_GENERAL, VK_ATTACHMENT_LOAD_OP_CLEAR));
|
|
|
|
renderPassCreateInfo.addSubpass({VkAttachmentReference({0, VK_IMAGE_LAYOUT_GENERAL})});
|
|
|
|
VkRenderPass renderPass = createRenderPass(renderPassCreateInfo);
|
|
|
|
VkFramebuffer framebuffer =
|
|
createFramebuffer(vkh::FramebufferCreateInfo(renderPass, {imgview}, {texWidth, texHeight}));
|
|
|
|
vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
|
|
|
|
pipeCreateInfo.layout = layout;
|
|
pipeCreateInfo.renderPass = renderPass;
|
|
|
|
pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, ConstsA2V)};
|
|
pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
|
|
vkh::vertexAttr(0, 0, ConstsA2V, pos), vkh::vertexAttr(1, 0, ConstsA2V, zero),
|
|
vkh::vertexAttr(2, 0, ConstsA2V, one), vkh::vertexAttr(3, 0, ConstsA2V, negone),
|
|
vkh::vertexAttr(4, 0, ConstsA2V, uv),
|
|
};
|
|
|
|
pipeCreateInfo.stages = {
|
|
CompileShaderModule(vertex, ShaderLang::glsl, ShaderStage::vert, "main"),
|
|
CompileShaderModule(pixel_glsl1, ShaderLang::glsl, ShaderStage::frag, "main"),
|
|
};
|
|
|
|
VkPipeline glslpipe1 = createGraphicsPipeline(pipeCreateInfo);
|
|
|
|
pipeCreateInfo.stages = {
|
|
CompileShaderModule(vertex2, ShaderLang::glsl, ShaderStage::vert, "main"),
|
|
CompileShaderModule(pixel_glsl2, ShaderLang::glsl, ShaderStage::frag, "main"),
|
|
};
|
|
|
|
VkPipeline glslpipe2 = createGraphicsPipeline(pipeCreateInfo);
|
|
|
|
SPIRVTarget target = SPIRVTarget::vulkan;
|
|
|
|
if(vk_version >= 0x11)
|
|
target = SPIRVTarget::vulkan11;
|
|
if(vk_version >= 0x12)
|
|
target = SPIRVTarget::vulkan12;
|
|
|
|
pipeCreateInfo.stages = {
|
|
CompileShaderModule(vertex, ShaderLang::glsl, ShaderStage::vert, "main"),
|
|
CompileShaderModule(make_pixel_asm(), ShaderLang::spvasm, ShaderStage::frag, "main", {},
|
|
target),
|
|
};
|
|
|
|
VkPipeline asmpipe = createGraphicsPipeline(pipeCreateInfo);
|
|
|
|
float triWidth = 8.0f / float(texWidth);
|
|
float triHeight = 8.0f / float(texHeight);
|
|
|
|
ConstsA2V triangle[] = {
|
|
{Vec4f(-1.0f, -1.0f, triWidth, triHeight), 0.0f, 1.0f, -1.0f, Vec2f(0.0f, 0.0f)},
|
|
{Vec4f(-1.0f + triWidth, -1.0f, triWidth, triHeight), 0.0f, 1.0f, -1.0f, Vec2f(1.0f, 0.0f)},
|
|
{Vec4f(-1.0f, -1.0f + triHeight, triWidth, triHeight), 0.0f, 1.0f, -1.0f, Vec2f(0.0f, 1.0f)},
|
|
};
|
|
|
|
AllocatedBuffer vb(this,
|
|
vkh::BufferCreateInfo(sizeof(triangle), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
|
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT),
|
|
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));
|
|
|
|
vb.upload(triangle);
|
|
|
|
Texture rgba8;
|
|
LoadXPM(SmileyTexture, rgba8);
|
|
|
|
AllocatedImage queryTest(this,
|
|
vkh::ImageCreateInfo(183, 347, 0, VK_FORMAT_R8G8B8A8_UNORM,
|
|
VK_IMAGE_USAGE_SAMPLED_BIT, 4, 3),
|
|
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
|
|
|
|
VkImageView queryTestView = createImageView(vkh::ImageViewCreateInfo(
|
|
queryTest.image, VK_IMAGE_VIEW_TYPE_2D_ARRAY, VK_FORMAT_R8G8B8A8_UNORM));
|
|
|
|
AllocatedImage queryTestMS(
|
|
this,
|
|
vkh::ImageCreateInfo(183, 347, 0, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, 1,
|
|
5, VK_SAMPLE_COUNT_4_BIT),
|
|
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
|
|
|
|
VkImageView queryTestMSView = createImageView(vkh::ImageViewCreateInfo(
|
|
queryTestMS.image, VK_IMAGE_VIEW_TYPE_2D_ARRAY, VK_FORMAT_R8G8B8A8_UNORM));
|
|
|
|
AllocatedImage smiley(
|
|
this,
|
|
vkh::ImageCreateInfo(rgba8.width, rgba8.height, 0, VK_FORMAT_R8G8B8A8_UNORM,
|
|
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT),
|
|
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
|
|
|
|
VkImageView smileyview = createImageView(
|
|
vkh::ImageViewCreateInfo(smiley.image, VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM));
|
|
AllocatedBuffer uploadBuf(this,
|
|
vkh::BufferCreateInfo(rgba8.data.size() * sizeof(uint32_t),
|
|
VK_BUFFER_USAGE_TRANSFER_SRC_BIT),
|
|
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));
|
|
|
|
AllocatedImage shadowimg(this,
|
|
vkh::ImageCreateInfo(16, 16, 0, VK_FORMAT_D32_SFLOAT,
|
|
VK_IMAGE_USAGE_TRANSFER_DST_BIT |
|
|
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
|
|
VK_IMAGE_USAGE_SAMPLED_BIT),
|
|
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
|
|
|
|
VkImageView shadowview = createImageView(
|
|
vkh::ImageViewCreateInfo(shadowimg.image, VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_D32_SFLOAT, {},
|
|
vkh::ImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT)));
|
|
|
|
uploadBuf.upload(rgba8.data.data(), rgba8.data.size() * sizeof(uint32_t));
|
|
|
|
std::vector<byte> typeData;
|
|
typeData.resize(sizeof(Vec4f) * 16 * 16 * 32 * 3);
|
|
|
|
uint32_t typeOffset[] = {
|
|
// float data
|
|
sizeof(Vec4f) * 16 * 16 * 32 * 0,
|
|
// uint data
|
|
sizeof(Vec4f) * 16 * 16 * 32 * 1,
|
|
// int data
|
|
sizeof(Vec4f) * 16 * 16 * 32 * 2,
|
|
};
|
|
|
|
for(size_t typeVariant = 0; typeVariant < 3; typeVariant++)
|
|
{
|
|
byte *dst = typeData.data() + typeOffset[typeVariant];
|
|
union
|
|
{
|
|
float f[4];
|
|
int i[4];
|
|
} rnd;
|
|
memset(&rnd, 0, sizeof(rnd));
|
|
|
|
for(size_t x = 0; x < 16; x++)
|
|
{
|
|
for(size_t y = 0; y < 16; y++)
|
|
{
|
|
for(size_t z = 0; z < 32; z++)
|
|
{
|
|
if(typeVariant == 0)
|
|
{
|
|
rnd.f[0] = RANDF(-10.0f, 10.0f);
|
|
rnd.f[1] = RANDF(-10.0f, 10.0f);
|
|
rnd.f[2] = RANDF(-10.0f, 10.0f);
|
|
rnd.f[3] = RANDF(-10.0f, 10.0f);
|
|
}
|
|
else if(typeVariant == 1)
|
|
{
|
|
rnd.i[0] = (int32_t)RANDF(100.0f, 500.0f);
|
|
rnd.i[1] = (int32_t)RANDF(100.0f, 500.0f);
|
|
rnd.i[2] = (int32_t)RANDF(100.0f, 500.0f);
|
|
rnd.i[3] = (int32_t)RANDF(100.0f, 500.0f);
|
|
}
|
|
else if(typeVariant == 2)
|
|
{
|
|
rnd.i[0] = (int32_t)RANDF(-200.0f, 200.0f);
|
|
rnd.i[1] = (int32_t)RANDF(-200.0f, 200.0f);
|
|
rnd.i[2] = (int32_t)RANDF(-200.0f, 200.0f);
|
|
rnd.i[3] = (int32_t)RANDF(-200.0f, 200.0f);
|
|
}
|
|
memcpy(dst, &rnd.f, sizeof(Vec4f));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
AllocatedBuffer typeDataBuf(
|
|
this, vkh::BufferCreateInfo(typeData.size(), VK_BUFFER_USAGE_TRANSFER_SRC_BIT),
|
|
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));
|
|
|
|
typeDataBuf.upload(typeData.data(), typeData.size());
|
|
|
|
AllocatedImage randomcube(
|
|
this,
|
|
vkh::ImageCreateInfo(rgba8.width, rgba8.height, 0, VK_FORMAT_R8G8B8A8_UNORM,
|
|
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 1, 6,
|
|
VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT),
|
|
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
|
|
|
|
VkImageView randomcubeview = createImageView(vkh::ImageViewCreateInfo(
|
|
randomcube.image, VK_IMAGE_VIEW_TYPE_CUBE, VK_FORMAT_R8G8B8A8_UNORM));
|
|
|
|
{
|
|
VkCommandBuffer cmd = GetCommandBuffer();
|
|
|
|
vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());
|
|
|
|
vkh::cmdPipelineBarrier(
|
|
cmd,
|
|
{
|
|
vkh::ImageMemoryBarrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
|
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, smiley.image),
|
|
vkh::ImageMemoryBarrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
|
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, randomcube.image),
|
|
vkh::ImageMemoryBarrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
|
|
VK_IMAGE_LAYOUT_GENERAL, queryTest.image),
|
|
vkh::ImageMemoryBarrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
|
|
VK_IMAGE_LAYOUT_GENERAL, queryTestMS.image),
|
|
});
|
|
|
|
VkBufferImageCopy copy = {};
|
|
copy.imageExtent = {rgba8.width, rgba8.height, 1};
|
|
copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
copy.imageSubresource.layerCount = 1;
|
|
|
|
vkCmdCopyBufferToImage(cmd, uploadBuf.buffer, smiley.image,
|
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©);
|
|
|
|
for(uint32_t i = 0; i < 6; i++)
|
|
{
|
|
copy.imageSubresource.baseArrayLayer = i;
|
|
vkCmdCopyBufferToImage(cmd, typeDataBuf.buffer, randomcube.image,
|
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©);
|
|
}
|
|
|
|
vkh::cmdPipelineBarrier(
|
|
cmd,
|
|
{
|
|
vkh::ImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
|
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, smiley.image),
|
|
vkh::ImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
|
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, randomcube.image),
|
|
});
|
|
|
|
vkEndCommandBuffer(cmd);
|
|
|
|
Submit(99, 99, {cmd});
|
|
|
|
vkDeviceWaitIdle(device);
|
|
}
|
|
|
|
VkSampler pointsampler = createSampler(vkh::SamplerCreateInfo(VK_FILTER_NEAREST));
|
|
VkSampler linearsampler = createSampler(vkh::SamplerCreateInfo(VK_FILTER_LINEAR));
|
|
VkSampler mipsampler = createSampler(vkh::SamplerCreateInfo(VK_FILTER_LINEAR));
|
|
VkSampler shadowsampler = createSampler(vkh::SamplerCreateInfo(
|
|
VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_REPEAT, 0.0f,
|
|
VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, 0.0f, 0.0f, 0.0f, VK_COMPARE_OP_LESS_OR_EQUAL));
|
|
|
|
VkDescriptorSet descset0 = allocateDescriptorSet(setlayout0);
|
|
VkDescriptorSet descset1 = VK_NULL_HANDLE;
|
|
VkDescriptorSet descset2 = VK_NULL_HANDLE;
|
|
|
|
if(descIndexing)
|
|
{
|
|
descset1 = allocateDescriptorSet(setlayout1);
|
|
descset2 = allocateDescriptorSet(setlayout2);
|
|
}
|
|
|
|
Vec4f cbufferdata[64] = {};
|
|
|
|
AllocatedBuffer cb(
|
|
this,
|
|
vkh::BufferCreateInfo(sizeof(cbufferdata) * 2, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
|
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT),
|
|
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));
|
|
|
|
cbufferdata[1] = Vec4f(1.1f, 2.2f, 3.3f, 4.4f);
|
|
cbufferdata[2] = Vec4f(5.5f, 6.6f, 7.7f, 8.8f);
|
|
cbufferdata[3] = Vec4f(std::numeric_limits<float>::quiet_NaN());
|
|
cbufferdata[4] = Vec4f(9.9f, 9.99f, 9.999f, 9.999f);
|
|
cbufferdata[6] = Vec4f(100.0f, 200.0f, 300.0f, 400.0f);
|
|
|
|
// unorm2PackSource
|
|
cbufferdata[7] = Vec4f(99.0f, 28099.0f / 65535.0f, 0.0f, 0.0f);
|
|
// snorm2PackSource
|
|
cbufferdata[8] = Vec4f(99.0f, -28099.0f / 32767.0f, 0.0f, 0.0f);
|
|
// unorm4PackSource
|
|
cbufferdata[9] = Vec4f(99.0f, 28.0f / 255.0f, 99.0f / 255.0f, 182.0f / 255.0f);
|
|
// snorm4PackSource
|
|
cbufferdata[10] = Vec4f(99.0f, -28.0f / 127.0f, 99.0f / 127.0f, -102.0f / 127.0f);
|
|
// halfPackSource - we pick exact half values to avoid rounding problems
|
|
cbufferdata[11] = Vec4f(98.125f, 76.375f, 54.5625f, 32.78125f);
|
|
|
|
uint32_t index = 4;
|
|
memcpy(&cbufferdata[1], &index, sizeof(index));
|
|
|
|
Vec4u unpack = {};
|
|
|
|
// unormUnpackSource
|
|
unpack.x = 0xf0dd103c;
|
|
// snormUnpackSource
|
|
unpack.y = 0xf0dd103c;
|
|
// halfUnpackSource
|
|
unpack.z = (uint32_t(MakeHalf(81.5f)) << 16) | MakeHalf(101.03f);
|
|
|
|
// unpack sources
|
|
memcpy(&cbufferdata[12], &unpack, sizeof(unpack));
|
|
|
|
double unpackDouble = 3.1415926535;
|
|
memcpy(&cbufferdata[13].x, &unpackDouble, sizeof(unpackDouble));
|
|
memcpy(&cbufferdata[14].z, &unpackDouble, sizeof(unpackDouble));
|
|
|
|
// move to account for offset
|
|
memmove(&cbufferdata[16], &cbufferdata[0], sizeof(Vec4f) * 16);
|
|
memset(&cbufferdata[0], 0, sizeof(Vec4f) * 16);
|
|
|
|
cb.upload(cbufferdata);
|
|
|
|
AllocatedBuffer texbuffer(
|
|
this,
|
|
vkh::BufferCreateInfo(sizeof(cbufferdata), VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT |
|
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT),
|
|
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));
|
|
|
|
texbuffer.upload(cbufferdata);
|
|
|
|
AllocatedBuffer store_buffer(
|
|
this,
|
|
vkh::BufferCreateInfo(1024 * sizeof(Vec4f), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
|
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT),
|
|
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
|
|
|
|
AllocatedBuffer atomic_buffer(
|
|
this,
|
|
vkh::BufferCreateInfo(texWidth * texHeight * sizeof(Vec4f),
|
|
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT),
|
|
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
|
|
|
|
AllocatedBuffer store_texbuffer(
|
|
this,
|
|
vkh::BufferCreateInfo(1024 * sizeof(Vec4f), VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT |
|
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT),
|
|
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
|
|
|
|
AllocatedBuffer texbuffer_1010102unorm(
|
|
this,
|
|
vkh::BufferCreateInfo(1024 * sizeof(uint32_t), VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT |
|
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT),
|
|
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));
|
|
|
|
AllocatedBuffer store_texbuffer_1010102unorm(
|
|
this,
|
|
vkh::BufferCreateInfo(1024 * sizeof(uint32_t), VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT |
|
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT),
|
|
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
|
|
|
|
uint32_t unormdata[64] = {};
|
|
memset(unormdata, 0x42, sizeof(unormdata));
|
|
|
|
texbuffer_1010102unorm.upload(unormdata);
|
|
|
|
AllocatedBuffer texbuffer_1010102uint(
|
|
this,
|
|
vkh::BufferCreateInfo(1024 * sizeof(uint32_t), VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT |
|
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT),
|
|
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));
|
|
|
|
texbuffer_1010102uint.upload(unormdata);
|
|
|
|
AllocatedBuffer store_texbuffer_1010102uint(
|
|
this,
|
|
vkh::BufferCreateInfo(1024 * sizeof(uint32_t), VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT |
|
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT),
|
|
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
|
|
|
|
VkBuffer bda_data_buffer = VK_NULL_HANDLE;
|
|
VkDeviceMemory bda_deviceMem = VK_NULL_HANDLE;
|
|
byte *bda_base_gpuptr = NULL;
|
|
if(bda)
|
|
{
|
|
vkh::BufferCreateInfo bda_buffer_info(sizeof(BDA_Data),
|
|
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR);
|
|
VkMemoryAllocateInfo memAllocInfo = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
|
|
VkMemoryAllocateFlagsInfo memAllocFlags = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO};
|
|
|
|
memAllocFlags.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;
|
|
memAllocInfo.pNext = &memAllocFlags;
|
|
|
|
const VkPhysicalDeviceMemoryProperties *memProps = NULL;
|
|
vmaGetMemoryProperties(allocator, &memProps);
|
|
|
|
vkCreateBuffer(device, bda_buffer_info, NULL, &bda_data_buffer);
|
|
|
|
VkMemoryRequirements mrq;
|
|
vkGetBufferMemoryRequirements(device, bda_data_buffer, &mrq);
|
|
memAllocInfo.allocationSize = mrq.size;
|
|
for(uint32_t i = 0; i < memProps->memoryTypeCount; i++)
|
|
{
|
|
if((mrq.memoryTypeBits & (1u << i)) &&
|
|
(memProps->memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))
|
|
{
|
|
memAllocInfo.memoryTypeIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
vkAllocateMemory(device, &memAllocInfo, NULL, &bda_deviceMem);
|
|
vkBindBufferMemory(device, bda_data_buffer, bda_deviceMem, 0);
|
|
|
|
VkBufferDeviceAddressInfoKHR bda_info = {VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR};
|
|
bda_info.buffer = bda_data_buffer;
|
|
|
|
VkDeviceAddress bda_Addr = vkGetBufferDeviceAddressKHR(device, &bda_info);
|
|
bda_base_gpuptr = (byte *)bda_Addr; // not a valid cpu pointer
|
|
|
|
byte *bda_base_cpuptr = NULL;
|
|
vkMapMemory(device, bda_deviceMem, 0, mrq.size, 0, (void **)&bda_base_cpuptr);
|
|
|
|
BDA_Data *bda_data_cpu = (BDA_Data *)bda_base_cpuptr;
|
|
bda_data_cpu->f32[0] = 0.1f;
|
|
bda_data_cpu->f32[1] = 0.2f;
|
|
bda_data_cpu->f32[2] = 0.3f;
|
|
bda_data_cpu->f32[3] = 0.8f;
|
|
bda_data_cpu->f32[4] = 0.3f;
|
|
bda_data_cpu->f32[5] = 0.2f;
|
|
bda_data_cpu->f32[6] = 0.1f;
|
|
bda_data_cpu->f32[7] = 0.9f;
|
|
}
|
|
|
|
AllocatedImage store_image(
|
|
this,
|
|
vkh::ImageCreateInfo(128, 128, 0, VK_FORMAT_R32G32B32A32_SFLOAT,
|
|
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT),
|
|
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
|
|
VkImageView store_view = createImageView(vkh::ImageViewCreateInfo(
|
|
store_image.image, VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R32G32B32A32_SFLOAT));
|
|
|
|
AllocatedImage atomic_image(
|
|
this,
|
|
vkh::ImageCreateInfo(texWidth, texHeight, 0, VK_FORMAT_R32_UINT,
|
|
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT),
|
|
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
|
|
VkImageView atomic_view = createImageView(
|
|
vkh::ImageViewCreateInfo(atomic_image.image, VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R32_UINT));
|
|
|
|
VkBufferView bufview =
|
|
createBufferView(vkh::BufferViewCreateInfo(texbuffer.buffer, VK_FORMAT_R32G32B32A32_SFLOAT));
|
|
VkBufferView store_bufview = createBufferView(
|
|
vkh::BufferViewCreateInfo(store_texbuffer.buffer, VK_FORMAT_R32G32B32A32_SFLOAT));
|
|
|
|
VkBufferView bufview_1010102unorm = createBufferView(vkh::BufferViewCreateInfo(
|
|
texbuffer_1010102unorm.buffer, VK_FORMAT_A2B10G10R10_UNORM_PACK32, 96));
|
|
VkBufferView store_bufview_1010102unorm = createBufferView(vkh::BufferViewCreateInfo(
|
|
store_texbuffer_1010102unorm.buffer, VK_FORMAT_A2B10G10R10_UNORM_PACK32, 96));
|
|
VkBufferView bufview_1010102uint = createBufferView(vkh::BufferViewCreateInfo(
|
|
texbuffer_1010102uint.buffer, VK_FORMAT_A2B10G10R10_UINT_PACK32, 96));
|
|
VkBufferView store_bufview_1010102uint = createBufferView(vkh::BufferViewCreateInfo(
|
|
store_texbuffer_1010102uint.buffer, VK_FORMAT_A2B10G10R10_UINT_PACK32, 96));
|
|
|
|
setName(pointsampler, "pointsampler");
|
|
setName(linearsampler, "linearsampler");
|
|
setName(mipsampler, "mipsampler");
|
|
setName(queryTest.image, "queryTest");
|
|
setName(queryTestMS.image, "queryTestMS");
|
|
setName(smiley.image, "smiley");
|
|
setName(texbuffer.buffer, "texbuffer");
|
|
setName(store_buffer.buffer, "store_buffer");
|
|
setName(atomic_buffer.buffer, "atomic_buffer");
|
|
setName(store_texbuffer.buffer, "store_texbuffer");
|
|
setName(store_image.image, "store_image");
|
|
setName(atomic_image.image, "atomic_image");
|
|
setName(bufview_1010102unorm, "bufview_1010102unorm");
|
|
setName(store_bufview_1010102unorm, "store_texbuffer_1010102unorm");
|
|
setName(bufview_1010102uint, "bufview_1010102uint");
|
|
setName(store_bufview_1010102uint, "store_bufview_1010102uint");
|
|
|
|
AllocatedImage storezoo_u2D(
|
|
this,
|
|
vkh::ImageCreateInfo(16, 16, 0, VK_FORMAT_R32G32B32A32_UINT,
|
|
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT),
|
|
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
|
|
VkImageView storezoo_u2D_view = createImageView(vkh::ImageViewCreateInfo(
|
|
storezoo_u2D.image, VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R32G32B32A32_UINT));
|
|
|
|
setName(storezoo_u2D.image, "storezoo_u2D");
|
|
|
|
vkh::updateDescriptorSets(
|
|
device,
|
|
{
|
|
vkh::WriteDescriptorSet(descset0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
|
|
{vkh::DescriptorBufferInfo(cb.buffer, 0, sizeof(cbufferdata))}),
|
|
vkh::WriteDescriptorSet(descset0, 10, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
|
|
{vkh::DescriptorBufferInfo(cb.buffer, 0, sizeof(cbufferdata))}),
|
|
vkh::WriteDescriptorSet(
|
|
descset0, 11, VK_DESCRIPTOR_TYPE_SAMPLER,
|
|
{vkh::DescriptorImageInfo(VK_NULL_HANDLE, VK_IMAGE_LAYOUT_UNDEFINED, pointsampler)}),
|
|
vkh::WriteDescriptorSet(
|
|
descset0, 12, VK_DESCRIPTOR_TYPE_SAMPLER,
|
|
{vkh::DescriptorImageInfo(VK_NULL_HANDLE, VK_IMAGE_LAYOUT_UNDEFINED, linearsampler)}),
|
|
vkh::WriteDescriptorSet(
|
|
descset0, 13, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
|
{vkh::DescriptorImageInfo(smileyview, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
|
VK_NULL_HANDLE)}),
|
|
vkh::WriteDescriptorSet(
|
|
descset0, 14, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
{vkh::DescriptorImageInfo(smileyview, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
|
linearsampler)}),
|
|
vkh::WriteDescriptorSet(descset0, 15, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
|
{vkh::DescriptorBufferInfo(store_buffer.buffer)}),
|
|
vkh::WriteDescriptorSet(
|
|
descset0, 16, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
|
{vkh::DescriptorImageInfo(store_view, VK_IMAGE_LAYOUT_GENERAL, VK_NULL_HANDLE)}),
|
|
vkh::WriteDescriptorSet(descset0, 17, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, {bufview}),
|
|
vkh::WriteDescriptorSet(descset0, 18, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
|
|
{store_bufview}),
|
|
vkh::WriteDescriptorSet(
|
|
descset0, 19, VK_DESCRIPTOR_TYPE_SAMPLER,
|
|
{vkh::DescriptorImageInfo(VK_NULL_HANDLE, VK_IMAGE_LAYOUT_UNDEFINED, shadowsampler)}),
|
|
vkh::WriteDescriptorSet(
|
|
descset0, 20, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
{vkh::DescriptorImageInfo(randomcubeview, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
|
linearsampler)}),
|
|
vkh::WriteDescriptorSet(descset0, 21, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
|
{vkh::DescriptorBufferInfo(atomic_buffer.buffer)}),
|
|
vkh::WriteDescriptorSet(
|
|
descset0, 22, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
|
{vkh::DescriptorImageInfo(atomic_view, VK_IMAGE_LAYOUT_GENERAL, VK_NULL_HANDLE)}),
|
|
|
|
vkh::WriteDescriptorSet(
|
|
descset0, 30, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
{vkh::DescriptorImageInfo(queryTestView, VK_IMAGE_LAYOUT_GENERAL, mipsampler)}),
|
|
vkh::WriteDescriptorSet(
|
|
descset0, 31, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
{vkh::DescriptorImageInfo(queryTestMSView, VK_IMAGE_LAYOUT_GENERAL, mipsampler)}),
|
|
vkh::WriteDescriptorSet(
|
|
descset0, 32, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
|
{vkh::DescriptorImageInfo(shadowview, VK_IMAGE_LAYOUT_GENERAL, VK_NULL_HANDLE)}),
|
|
|
|
vkh::WriteDescriptorSet(descset0, 33, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
|
|
{bufview_1010102unorm}),
|
|
vkh::WriteDescriptorSet(descset0, 34, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
|
|
{store_bufview_1010102unorm}),
|
|
vkh::WriteDescriptorSet(descset0, 35, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
|
|
{bufview_1010102uint}),
|
|
vkh::WriteDescriptorSet(descset0, 36, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
|
|
{store_bufview_1010102uint}),
|
|
});
|
|
|
|
if(descIndexing)
|
|
{
|
|
vkh::updateDescriptorSets(
|
|
device, {
|
|
vkh::WriteDescriptorSet(
|
|
descset2, 41, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
|
{vkh::DescriptorImageInfo(storezoo_u2D_view, VK_IMAGE_LAYOUT_GENERAL,
|
|
VK_NULL_HANDLE)}),
|
|
});
|
|
|
|
for(uint32_t i = 0; i < 14; i++)
|
|
{
|
|
vkh::updateDescriptorSets(
|
|
device,
|
|
{
|
|
vkh::WriteDescriptorSet(descset1, 1, i, VK_DESCRIPTOR_TYPE_SAMPLER,
|
|
{vkh::DescriptorImageInfo(
|
|
VK_NULL_HANDLE, VK_IMAGE_LAYOUT_UNDEFINED, pointsampler)}),
|
|
vkh::WriteDescriptorSet(
|
|
descset1, 2, i, VK_DESCRIPTOR_TYPE_SAMPLER,
|
|
{vkh::DescriptorImageInfo(VK_NULL_HANDLE, VK_IMAGE_LAYOUT_UNDEFINED,
|
|
linearsampler)}),
|
|
vkh::WriteDescriptorSet(
|
|
descset1, 3, i, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
|
{vkh::DescriptorImageInfo(shadowview, VK_IMAGE_LAYOUT_GENERAL, VK_NULL_HANDLE)}),
|
|
vkh::WriteDescriptorSet(
|
|
descset1, 4, i, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
{vkh::DescriptorImageInfo(smileyview, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
|
linearsampler)}),
|
|
vkh::WriteDescriptorSet(descset1, 5, i, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
|
{vkh::DescriptorBufferInfo(store_buffer.buffer)}),
|
|
vkh::WriteDescriptorSet(
|
|
descset1, 6, i, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
|
{vkh::DescriptorImageInfo(store_view, VK_IMAGE_LAYOUT_GENERAL, VK_NULL_HANDLE)}),
|
|
vkh::WriteDescriptorSet(descset1, 7, i, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
|
|
{bufview}),
|
|
vkh::WriteDescriptorSet(descset1, 8, i, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
|
|
{store_bufview}),
|
|
vkh::WriteDescriptorSet(
|
|
descset1, 9, i, VK_DESCRIPTOR_TYPE_SAMPLER,
|
|
{vkh::DescriptorImageInfo(VK_NULL_HANDLE, VK_IMAGE_LAYOUT_UNDEFINED,
|
|
shadowsampler)}),
|
|
|
|
vkh::WriteDescriptorSet(
|
|
descset1, 20, i, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
{vkh::DescriptorImageInfo(queryTestView, VK_IMAGE_LAYOUT_GENERAL, mipsampler)}),
|
|
vkh::WriteDescriptorSet(
|
|
descset1, 21, i, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
{vkh::DescriptorImageInfo(queryTestMSView, VK_IMAGE_LAYOUT_GENERAL, mipsampler)}),
|
|
});
|
|
}
|
|
}
|
|
|
|
while(Running())
|
|
{
|
|
VkCommandBuffer cmd = GetCommandBuffer();
|
|
|
|
vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());
|
|
|
|
VkImage swapimg =
|
|
StartUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
|
|
|
|
vkCmdClearColorImage(cmd, swapimg, VK_IMAGE_LAYOUT_GENERAL,
|
|
vkh::ClearColorValue(0.2f, 0.2f, 0.2f, 1.0f), 1,
|
|
vkh::ImageSubresourceRange());
|
|
|
|
vkh::cmdPipelineBarrier(
|
|
cmd,
|
|
{
|
|
vkh::ImageMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT,
|
|
VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
|
|
VK_IMAGE_LAYOUT_GENERAL, store_image.image),
|
|
vkh::ImageMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT,
|
|
VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
|
|
VK_IMAGE_LAYOUT_GENERAL, atomic_image.image),
|
|
vkh::ImageMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT,
|
|
VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
|
|
VK_IMAGE_LAYOUT_GENERAL, storezoo_u2D.image),
|
|
vkh::ImageMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT,
|
|
VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
|
|
VK_IMAGE_LAYOUT_GENERAL, shadowimg.image,
|
|
vkh::ImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT)),
|
|
},
|
|
{
|
|
vkh::BufferMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
|
|
VK_ACCESS_TRANSFER_WRITE_BIT, store_buffer.buffer),
|
|
vkh::BufferMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
|
|
VK_ACCESS_TRANSFER_WRITE_BIT, atomic_buffer.buffer),
|
|
vkh::BufferMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
|
|
VK_ACCESS_TRANSFER_WRITE_BIT, store_texbuffer.buffer),
|
|
vkh::BufferMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
|
|
VK_ACCESS_TRANSFER_WRITE_BIT,
|
|
store_texbuffer_1010102uint.buffer),
|
|
vkh::BufferMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
|
|
VK_ACCESS_TRANSFER_WRITE_BIT,
|
|
store_texbuffer_1010102unorm.buffer),
|
|
});
|
|
|
|
vkCmdClearDepthStencilImage(cmd, shadowimg.image, VK_IMAGE_LAYOUT_GENERAL,
|
|
vkh::ClearDepthStencilValue({0.5f, 0}), 1,
|
|
vkh::ImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT));
|
|
|
|
vkCmdClearColorImage(cmd, store_image.image, VK_IMAGE_LAYOUT_GENERAL,
|
|
vkh::ClearColorValue(6.66f, 6.66f, 6.66f, 6.66f), 1,
|
|
vkh::ImageSubresourceRange());
|
|
vkCmdClearColorImage(cmd, atomic_image.image, VK_IMAGE_LAYOUT_GENERAL,
|
|
vkh::ClearColorValue(0x42424242U, 0x42424242U, 0x42424242U, 0x42424242U),
|
|
1, vkh::ImageSubresourceRange());
|
|
vkCmdClearColorImage(cmd, storezoo_u2D.image, VK_IMAGE_LAYOUT_GENERAL,
|
|
vkh::ClearColorValue(8U, 18U, 28U, 38U), 1, vkh::ImageSubresourceRange());
|
|
vkCmdFillBuffer(cmd, store_buffer.buffer, 0, VK_WHOLE_SIZE, 0x42424242);
|
|
vkCmdFillBuffer(cmd, atomic_buffer.buffer, 0, VK_WHOLE_SIZE, 0x42424242);
|
|
const float val = 1.234f;
|
|
vkCmdFillBuffer(cmd, store_texbuffer.buffer, 0, 128, *(uint32_t *)&val);
|
|
vkCmdFillBuffer(cmd, store_texbuffer.buffer, 128, VK_WHOLE_SIZE, 0);
|
|
vkCmdFillBuffer(cmd, store_texbuffer_1010102uint.buffer, 0, 104, 0x42424242);
|
|
vkCmdFillBuffer(cmd, store_texbuffer_1010102uint.buffer, 104, VK_WHOLE_SIZE, 0);
|
|
vkCmdFillBuffer(cmd, store_texbuffer_1010102unorm.buffer, 0, 104, 0x42424242);
|
|
vkCmdFillBuffer(cmd, store_texbuffer_1010102unorm.buffer, 104, VK_WHOLE_SIZE, 0);
|
|
|
|
vkh::cmdPipelineBarrier(
|
|
cmd,
|
|
{
|
|
vkh::ImageMemoryBarrier(
|
|
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT,
|
|
VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, store_image.image),
|
|
vkh::ImageMemoryBarrier(
|
|
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT,
|
|
VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, atomic_image.image),
|
|
vkh::ImageMemoryBarrier(
|
|
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT,
|
|
VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, storezoo_u2D.image),
|
|
},
|
|
{
|
|
vkh::BufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT,
|
|
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
|
|
store_buffer.buffer),
|
|
vkh::BufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT,
|
|
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
|
|
atomic_buffer.buffer),
|
|
vkh::BufferMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
|
|
VK_ACCESS_TRANSFER_WRITE_BIT, store_texbuffer.buffer),
|
|
});
|
|
|
|
VkViewport v = {};
|
|
v.maxDepth = 1.0f;
|
|
v.width = (float)texWidth;
|
|
v.height = (float)texHeight;
|
|
|
|
VkRect2D s = {};
|
|
s.extent.width = texWidth;
|
|
s.extent.height = texHeight;
|
|
|
|
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, glslpipe1);
|
|
vkCmdSetViewport(cmd, 0, 1, &v);
|
|
vkCmdSetScissor(cmd, 0, 1, &s);
|
|
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
|
|
|
|
BDA_Data *bda_gpuptr = (BDA_Data *)bda_base_gpuptr;
|
|
|
|
PushData pushData;
|
|
pushData.push = Vec4i(101, 103, 107, 109);
|
|
pushData.bda_uvec2 = *(Vec2u *)(&bda_gpuptr);
|
|
pushData.bda_hi = (uint64_t)bda_gpuptr >> 32;
|
|
pushData.bda_lo = (uint64_t)bda_gpuptr & 0xFFFFFFFF;
|
|
pushData.bda_u64 = *(uint64_t *)(&bda_gpuptr);
|
|
|
|
std::vector<VkDescriptorSet> descSets = {descset0};
|
|
|
|
if(descIndexing)
|
|
{
|
|
descSets.push_back(descset1);
|
|
descSets.push_back(descset2);
|
|
}
|
|
|
|
vkh::cmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descSets,
|
|
{0, sizeof(Vec4f) * 16});
|
|
vkCmdPushConstants(cmd, layout, VK_SHADER_STAGE_FRAGMENT_BIT, 16, sizeof(PushData), &pushData);
|
|
|
|
vkCmdBeginRenderPass(cmd,
|
|
vkh::RenderPassBeginInfo(renderPass, framebuffer, s,
|
|
{vkh::ClearValue(0.0f, 0.0f, 0.0f, 0.0f)}),
|
|
VK_SUBPASS_CONTENTS_INLINE);
|
|
|
|
pushMarker(cmd, "GLSL1 tests");
|
|
uint32_t numTests = numGLSL1Tests;
|
|
uint32_t offset = 0;
|
|
// loop drawing 256 tests at a time
|
|
while(numTests > 0)
|
|
{
|
|
uint32_t num = std::min(numTests, 256U);
|
|
vkCmdDraw(cmd, 3, num, 0, offset);
|
|
offset += num;
|
|
numTests -= num;
|
|
}
|
|
popMarker(cmd);
|
|
|
|
vkCmdEndRenderPass(cmd);
|
|
|
|
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, asmpipe);
|
|
|
|
vkCmdBeginRenderPass(cmd,
|
|
vkh::RenderPassBeginInfo(renderPass, framebuffer, s,
|
|
{vkh::ClearValue(0.0f, 0.0f, 0.0f, 0.0f)}),
|
|
VK_SUBPASS_CONTENTS_INLINE);
|
|
|
|
pushMarker(cmd, "ASM tests");
|
|
numTests = numASMTests;
|
|
offset = 0;
|
|
// loop drawing 256 tests at a time
|
|
while(numTests > 0)
|
|
{
|
|
uint32_t num = std::min(numTests, 256U);
|
|
vkCmdDraw(cmd, 3, num, 0, offset);
|
|
offset += num;
|
|
numTests -= num;
|
|
}
|
|
popMarker(cmd);
|
|
|
|
vkCmdEndRenderPass(cmd);
|
|
|
|
// sync all the storage work
|
|
vkh::cmdPipelineBarrier(
|
|
cmd,
|
|
{
|
|
vkh::ImageMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
|
|
VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT,
|
|
VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
|
|
store_image.image),
|
|
vkh::ImageMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
|
|
VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT,
|
|
VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
|
|
atomic_image.image),
|
|
vkh::ImageMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
|
|
VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT,
|
|
VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
|
|
storezoo_u2D.image),
|
|
},
|
|
{
|
|
vkh::BufferMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
|
|
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
|
|
store_buffer.buffer),
|
|
vkh::BufferMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
|
|
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
|
|
atomic_buffer.buffer),
|
|
vkh::BufferMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
|
|
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
|
|
store_texbuffer.buffer),
|
|
});
|
|
|
|
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, glslpipe2);
|
|
|
|
vkCmdBeginRenderPass(cmd,
|
|
vkh::RenderPassBeginInfo(renderPass, framebuffer, s,
|
|
{vkh::ClearValue(0.0f, 0.0f, 0.0f, 0.0f)}),
|
|
VK_SUBPASS_CONTENTS_INLINE);
|
|
|
|
pushMarker(cmd, "GLSL2 tests");
|
|
numTests = numGLSL2Tests;
|
|
offset = 0;
|
|
// loop drawing 256 tests at a time
|
|
while(numTests > 0)
|
|
{
|
|
uint32_t num = std::min(numTests, 256U);
|
|
vkCmdDraw(cmd, 3, num, 0, offset);
|
|
offset += num;
|
|
numTests -= num;
|
|
}
|
|
popMarker(cmd);
|
|
|
|
vkCmdEndRenderPass(cmd);
|
|
|
|
FinishUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
|
|
|
|
vkEndCommandBuffer(cmd);
|
|
|
|
Submit(0, 1, {cmd});
|
|
|
|
Present();
|
|
}
|
|
CHECK_VKR(vkDeviceWaitIdle(device));
|
|
|
|
if(bda)
|
|
{
|
|
vkDestroyBuffer(device, bda_data_buffer, NULL);
|
|
vkUnmapMemory(device, bda_deviceMem);
|
|
vkFreeMemory(device, bda_deviceMem, NULL);
|
|
}
|
|
return 0;
|
|
}
|
|
};
|
|
|
|
REGISTER_TEST();
|