Add test for sampler image arrays.

This commit is contained in:
Hans-Kristian Arntzen 2018-04-03 14:26:24 +02:00
Родитель 382101bd05
Коммит e8ca39b7b5
10 изменённых файлов: 253 добавлений и 11 удалений

Просмотреть файл

@ -2,7 +2,7 @@ language: cpp
os:
- linux
- osx
osx_image: xcode8.3
osx_image: xcode9.3beta
# Use Ubuntu 14.04 LTS (Trusty) as the Linux testing environment.
sudo: required

Просмотреть файл

@ -0,0 +1,39 @@
Texture2D<float4> uSampler[4] : register(t0);
SamplerState _uSampler_sampler[4] : register(s0);
Texture2D<float4> uTextures[4] : register(t8);
SamplerState uSamplers[4] : register(s4);
static int vIndex;
static float2 vTex;
static float4 FragColor;
struct SPIRV_Cross_Input
{
nointerpolation float2 vTex : TEXCOORD0;
nointerpolation int vIndex : TEXCOORD1;
};
struct SPIRV_Cross_Output
{
float4 FragColor : SV_Target0;
};
void frag_main()
{
FragColor = 0.0f.xxxx;
FragColor += uTextures[2].Sample(uSamplers[1], vTex);
FragColor += uSampler[vIndex].Sample(_uSampler_sampler[vIndex], vTex);
FragColor += uSampler[vIndex].Sample(_uSampler_sampler[vIndex], vTex + 0.100000001490116119384765625f.xx);
FragColor += uSampler[vIndex].Sample(_uSampler_sampler[vIndex], vTex + 0.20000000298023223876953125f.xx);
FragColor += uSampler[3].Sample(_uSampler_sampler[3], vTex + 0.300000011920928955078125f.xx);
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
vIndex = stage_input.vIndex;
vTex = stage_input.vTex;
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.FragColor = FragColor;
return stage_output;
}

Просмотреть файл

@ -0,0 +1,28 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_in
{
int vIndex [[user(locn1)]];
float2 vTex [[user(locn0)]];
};
struct main0_out
{
float4 FragColor [[color(0)]];
};
fragment main0_out main0(main0_in in [[stage_in]], array<texture2d<float>, 4> uSampler [[texture(0)]], array<texture2d<float>, 4> uTextures [[texture(1)]], array<sampler, 4> uSamplerSmplr [[sampler(0)]], array<sampler, 4> uSamplers [[sampler(1)]])
{
main0_out out = {};
out.FragColor = float4(0.0);
out.FragColor += uTextures[2].sample(uSamplers[1], in.vTex);
out.FragColor += uSampler[in.vIndex].sample(uSamplerSmplr[in.vIndex], in.vTex);
out.FragColor += uSampler[in.vIndex].sample(uSamplerSmplr[in.vIndex], (in.vTex + float2(0.100000001490116119384765625)));
out.FragColor += uSampler[in.vIndex].sample(uSamplerSmplr[in.vIndex], (in.vTex + float2(0.20000000298023223876953125)));
out.FragColor += uSampler[3].sample(uSamplerSmplr[3], (in.vTex + float2(0.300000011920928955078125)));
return out;
}

Просмотреть файл

@ -0,0 +1,54 @@
Texture2D<float4> uSampler[4] : register(t0);
SamplerState _uSampler_sampler[4] : register(s0);
Texture2D<float4> uTextures[4] : register(t8);
SamplerState uSamplers[4] : register(s4);
static int vIndex;
static float2 vTex;
static float4 FragColor;
struct SPIRV_Cross_Input
{
nointerpolation float2 vTex : TEXCOORD0;
nointerpolation int vIndex : TEXCOORD1;
};
struct SPIRV_Cross_Output
{
float4 FragColor : SV_Target0;
};
float4 sample_from_global()
{
return uSampler[vIndex].Sample(_uSampler_sampler[vIndex], vTex + 0.100000001490116119384765625f.xx);
}
float4 sample_from_argument(Texture2D<float4> samplers[4], SamplerState _samplers_sampler[4])
{
return samplers[vIndex].Sample(_samplers_sampler[vIndex], vTex + 0.20000000298023223876953125f.xx);
}
float4 sample_single_from_argument(Texture2D<float4> samp, SamplerState _samp_sampler)
{
return samp.Sample(_samp_sampler, vTex + 0.300000011920928955078125f.xx);
}
void frag_main()
{
FragColor = 0.0f.xxxx;
FragColor += uTextures[2].Sample(uSamplers[1], vTex);
FragColor += uSampler[vIndex].Sample(_uSampler_sampler[vIndex], vTex);
FragColor += sample_from_global();
FragColor += sample_from_argument(uSampler, _uSampler_sampler);
FragColor += sample_single_from_argument(uSampler[3], _uSampler_sampler[3]);
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
vIndex = stage_input.vIndex;
vTex = stage_input.vTex;
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.FragColor = FragColor;
return stage_output;
}

Просмотреть файл

@ -0,0 +1,45 @@
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_in
{
int vIndex [[user(locn1)]];
float2 vTex [[user(locn0)]];
};
struct main0_out
{
float4 FragColor [[color(0)]];
};
float4 sample_from_global(thread int& vIndex, thread float2& vTex, thread const array<texture2d<float>, 4> uSampler, thread const array<sampler, 4> uSamplerSmplr)
{
return uSampler[vIndex].sample(uSamplerSmplr[vIndex], (vTex + float2(0.100000001490116119384765625)));
}
float4 sample_from_argument(thread const array<texture2d<float>, 4> samplers, thread const array<sampler, 4> samplersSmplr, thread int& vIndex, thread float2& vTex)
{
return samplers[vIndex].sample(samplersSmplr[vIndex], (vTex + float2(0.20000000298023223876953125)));
}
float4 sample_single_from_argument(thread const texture2d<float> samp, thread const sampler sampSmplr, thread float2& vTex)
{
return samp.sample(sampSmplr, (vTex + float2(0.300000011920928955078125)));
}
fragment main0_out main0(main0_in in [[stage_in]], array<texture2d<float>, 4> uSampler [[texture(0)]], array<texture2d<float>, 4> uTextures [[texture(1)]], array<sampler, 4> uSamplerSmplr [[sampler(0)]], array<sampler, 4> uSamplers [[sampler(1)]])
{
main0_out out = {};
out.FragColor = float4(0.0);
out.FragColor += uTextures[2].sample(uSamplers[1], in.vTex);
out.FragColor += uSampler[in.vIndex].sample(uSamplerSmplr[in.vIndex], in.vTex);
out.FragColor += sample_from_global(in.vIndex, in.vTex, uSampler, uSamplerSmplr);
out.FragColor += sample_from_argument(uSampler, uSamplerSmplr, in.vIndex, in.vTex);
out.FragColor += sample_single_from_argument(uSampler[3], uSamplerSmplr[3], in.vTex);
return out;
}

Просмотреть файл

@ -16,7 +16,7 @@ struct main0_out
float4 FragColor [[color(0)]];
};
float4 sample_texture(thread const texture2d<float> tex, thread const sampler& texSmplr, thread const float2& uv)
float4 sample_texture(thread const texture2d<float> tex, thread const sampler texSmplr, thread const float2& uv)
{
return tex.sample(texSmplr, uv);
}

Просмотреть файл

@ -0,0 +1,33 @@
#version 450
layout(location = 0) out vec4 FragColor;
layout(location = 0) flat in vec2 vTex;
layout(location = 1) flat in int vIndex;
layout(binding = 0) uniform sampler2D uSampler[4];
layout(binding = 4) uniform sampler uSamplers[4];
layout(binding = 8) uniform texture2D uTextures[4];
vec4 sample_from_argument(sampler2D samplers[4])
{
return texture(samplers[vIndex], vTex + 0.2);
}
vec4 sample_single_from_argument(sampler2D samp)
{
return texture(samp, vTex + 0.3);
}
vec4 sample_from_global()
{
return texture(uSampler[vIndex], vTex + 0.1);
}
void main()
{
FragColor = vec4(0.0);
FragColor += texture(sampler2D(uTextures[2], uSamplers[1]), vTex);
FragColor += texture(uSampler[vIndex], vTex);
FragColor += sample_from_global();
FragColor += sample_from_argument(uSampler);
FragColor += sample_single_from_argument(uSampler[3]);
}

Просмотреть файл

@ -0,0 +1,33 @@
#version 450
layout(location = 0) out vec4 FragColor;
layout(location = 0) flat in vec2 vTex;
layout(location = 1) flat in int vIndex;
layout(binding = 0) uniform sampler2D uSampler[4];
layout(binding = 4) uniform sampler uSamplers[4];
layout(binding = 8) uniform texture2D uTextures[4];
vec4 sample_from_argument(sampler2D samplers[4])
{
return texture(samplers[vIndex], vTex + 0.2);
}
vec4 sample_single_from_argument(sampler2D samp)
{
return texture(samp, vTex + 0.3);
}
vec4 sample_from_global()
{
return texture(uSampler[vIndex], vTex + 0.1);
}
void main()
{
FragColor = vec4(0.0);
FragColor += texture(sampler2D(uTextures[2], uSamplers[1]), vTex);
FragColor += texture(uSampler[vIndex], vTex);
FragColor += sample_from_global();
FragColor += sample_from_argument(uSampler);
FragColor += sample_single_from_argument(uSampler[3]);
}

Просмотреть файл

@ -2292,11 +2292,7 @@ void CompilerMSL::emit_function_prototype(SPIRFunction &func, const Bitset &)
// Manufacture automatic sampler arg for SampledImage texture
auto &arg_type = get<SPIRType>(arg.type);
if (arg_type.basetype == SPIRType::SampledImage && arg_type.image.dim != DimBuffer)
{
//const char *reference = arg_type.array.empty() ? "& " : " ";
const char *reference = " ";
decl += join(", thread const ", sampler_type(arg_type), reference, to_sampler_expression(arg.id));
}
decl += join(", thread const ", sampler_type(arg_type), " ", to_sampler_expression(arg.id));
if (&arg != &func.arguments.back())
decl += ", ";
@ -3119,13 +3115,13 @@ string CompilerMSL::entry_point_args(bool append_comma)
case SPIRType::Sampler:
if (!ep_args.empty())
ep_args += ", ";
ep_args += type_to_glsl(type) + " " + r.name;
ep_args += sampler_type(type) + " " + r.name;
ep_args += " [[sampler(" + convert_to_string(r.index) + ")]]";
break;
case SPIRType::Image:
if (!ep_args.empty())
ep_args += ", ";
ep_args += type_to_glsl(type, var_id) + " " + r.name;
ep_args += image_type_glsl(type, var_id) + " " + r.name;
ep_args += " [[texture(" + convert_to_string(r.index) + ")]]";
break;
default:
@ -3456,6 +3452,9 @@ std::string CompilerMSL::sampler_type(const SPIRType &type)
{
if (!type.array.empty())
{
if (!msl_options.supports_msl_version(2))
SPIRV_CROSS_THROW("MSL 2.0 or greater is required for arrays of samplers.");
// Arrays of samplers in MSL must be declared with a special array<T, N> syntax ala C++11 std::array.
auto *parent = &type;
while (parent->pointer)
@ -3478,6 +3477,9 @@ string CompilerMSL::image_type_glsl(const SPIRType &type, uint32_t id)
{
if (!type.array.empty())
{
if (!msl_options.supports_msl_version(2))
SPIRV_CROSS_THROW("MSL 2.0 or greater is required for arrays of textures.");
// Arrays of images in MSL must be declared with a special array<T, N> syntax ala C++11 std::array.
auto *parent = &type;
while (parent->pointer)

Просмотреть файл

@ -73,11 +73,12 @@ def print_msl_compiler_version():
raise
def validate_shader_msl(shader, opt):
msl2 = '.msl2.' in shader
msl_path = reference_path(shader[0], shader[1], opt)
try:
msl_os = 'macosx'
# msl_os = 'iphoneos'
subprocess.check_call(['xcrun', '--sdk', msl_os, 'metal', '-x', 'metal', '-std=osx-metal1.2', '-Werror', '-Wno-unused-variable', msl_path])
subprocess.check_call(['xcrun', '--sdk', msl_os, 'metal', '-x', 'metal', '-std=osx-metal{}'.format('2.0' if msl2 else '1.2'), '-Werror', '-Wno-unused-variable', msl_path])
print('Compiled Metal shader: ' + msl_path) # display after so xcrun FNF is silent
except OSError as oe:
if (oe.errno != os.errno.ENOENT): # Ignore xcrun not found error
@ -87,6 +88,7 @@ def validate_shader_msl(shader, opt):
sys.exit(1)
def cross_compile_msl(shader, spirv, opt):
msl2 = '.msl2.' in shader
spirv_f, spirv_path = tempfile.mkstemp()
msl_f, msl_path = tempfile.mkstemp(suffix = os.path.basename(shader))
os.close(spirv_f)
@ -101,7 +103,13 @@ def cross_compile_msl(shader, spirv, opt):
subprocess.check_call(['spirv-opt', '-O', '-o', spirv_path, spirv_path])
spirv_cross_path = './spirv-cross'
subprocess.check_call([spirv_cross_path, '--entry', 'main', '--output', msl_path, spirv_path, '--msl'])
msl_args = [spirv_cross_path, '--entry', 'main', '--output', msl_path, spirv_path, '--msl']
if msl2:
msl_args.append('--msl-version')
msl_args.append('20000')
subprocess.check_call(msl_args)
subprocess.check_call(['spirv-val', spirv_path])
return (spirv_path, msl_path)