Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions naga/src/back/spv/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ struct ImageCoordinates {
/// The number of components in `value`, if it is a vector, or `None` if it
/// is a scalar.
size: Option<crate::VectorSize>,

/// The type of each component of `value`.
scalar: crate::Scalar,
}

/// A trait for image access (load or store) code generators.
Expand Down Expand Up @@ -274,15 +277,16 @@ impl BlockContext<'_> {
None => {
let value_id = coordinates_id;
let type_id = self.get_expression_type_id(ty);
let size = match *inner_ty {
Ti::Scalar { .. } => None,
Ti::Vector { size, .. } => Some(size),
let (size, scalar) = match *inner_ty {
Ti::Scalar(scalar) => (None, scalar),
Ti::Vector { size, scalar } => (Some(size), scalar),
_ => return Err(Error::Validation("coordinate type")),
};
return Ok(ImageCoordinates {
value_id,
type_id,
size,
scalar,
});
}
Some(ix) => ix,
Expand Down Expand Up @@ -369,6 +373,7 @@ impl BlockContext<'_> {
value_id,
type_id,
size: Some(size),
scalar: component_scalar,
})
}

Expand Down Expand Up @@ -401,7 +406,12 @@ impl BlockContext<'_> {
/// If `coordinates` is a scalar, return a scalar one. Otherwise, return
/// a vector of ones.
fn write_coordinate_one(&mut self, coordinates: &ImageCoordinates) -> Result<Word, Error> {
let one = self.get_scope_constant(1);
let one = self
.writer
.get_constant_scalar(match coordinates.scalar.kind {
crate::ScalarKind::Uint => crate::Literal::U32(1),
_ => crate::Literal::I32(1),
});
match coordinates.size {
None => Ok(one),
Some(vector_size) => {
Expand Down
8 changes: 8 additions & 0 deletions naga/tests/in/wgsl/bounds-check-image-restrict-unsigned.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
targets = "SPIRV"

[bounds_check_policies]
image_load = "Restrict"

[spv]
debug = true
version = [1, 1]
36 changes: 36 additions & 0 deletions naga/tests/in/wgsl/bounds-check-image-restrict-unsigned.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
@group(0) @binding(0)
var image_1d: texture_1d<f32>;

fn test_textureLoad_1d(coords: u32, level: u32) -> vec4<f32> {
return textureLoad(image_1d, coords, level);
}

@group(0) @binding(1)
var image_2d: texture_2d<f32>;

fn test_textureLoad_2d(coords: vec2<u32>, level: u32) -> vec4<f32> {
return textureLoad(image_2d, coords, level);
}

@group(0) @binding(2)
var image_2d_array: texture_2d_array<f32>;

fn test_textureLoad_2d_array(coords: vec2<u32>, index: i32, level: u32) -> vec4<f32> {
return textureLoad(image_2d_array, coords, index, level);
}

@group(0) @binding(3)
var image_depth_2d: texture_depth_2d;

fn test_textureLoad_depth_2d(coords: vec2<u32>, level: u32) -> f32 {
return textureLoad(image_depth_2d, coords, level);
}

@fragment
fn fragment_shader() -> @location(0) vec4<f32> {
test_textureLoad_1d(0u, 0u);
test_textureLoad_2d(vec2<u32>(), 0u);
test_textureLoad_2d_array(vec2<u32>(), 0, 0u);
test_textureLoad_depth_2d(vec2<u32>(), 0u);
return vec4<f32>(0.,0.,0.,0.);
}
204 changes: 204 additions & 0 deletions naga/tests/out/spv/wgsl-bounds-check-image-restrict-unsigned.spvasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
; SPIR-V
; Version: 1.1
; Generator: rspirv
; Bound: 106
OpCapability Shader
OpCapability Sampled1D
OpCapability ImageQuery
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %90 "fragment_shader" %88
OpExecutionMode %90 OriginUpperLeft
%3 = OpString "bounds-check-image-restrict-unsigned.wgsl"
OpSource Unknown 0 %3 "@group(0) @binding(0)
var image_1d: texture_1d<f32>;

fn test_textureLoad_1d(coords: u32, level: u32) -> vec4<f32> {
return textureLoad(image_1d, coords, level);
}

@group(0) @binding(1)
var image_2d: texture_2d<f32>;

fn test_textureLoad_2d(coords: vec2<u32>, level: u32) -> vec4<f32> {
return textureLoad(image_2d, coords, level);
}

@group(0) @binding(2)
var image_2d_array: texture_2d_array<f32>;

fn test_textureLoad_2d_array(coords: vec2<u32>, index: i32, level: u32) -> vec4<f32> {
return textureLoad(image_2d_array, coords, index, level);
}

@group(0) @binding(3)
var image_depth_2d: texture_depth_2d;

fn test_textureLoad_depth_2d(coords: vec2<u32>, level: u32) -> f32 {
return textureLoad(image_depth_2d, coords, level);
}

@fragment
fn fragment_shader() -> @location(0) vec4<f32> {
test_textureLoad_1d(0u, 0u);
test_textureLoad_2d(vec2<u32>(), 0u);
test_textureLoad_2d_array(vec2<u32>(), 0, 0u);
test_textureLoad_depth_2d(vec2<u32>(), 0u);
return vec4<f32>(0.,0.,0.,0.);
}
"
OpName %13 "image_1d"
OpName %15 "image_2d"
OpName %17 "image_2d_array"
OpName %19 "image_depth_2d"
OpName %22 "coords"
OpName %23 "level"
OpName %24 "test_textureLoad_1d"
OpName %38 "coords"
OpName %39 "level"
OpName %40 "test_textureLoad_2d"
OpName %53 "coords"
OpName %54 "index"
OpName %55 "level"
OpName %56 "test_textureLoad_2d_array"
OpName %72 "coords"
OpName %73 "level"
OpName %74 "test_textureLoad_depth_2d"
OpName %90 "fragment_shader"
OpDecorate %13 DescriptorSet 0
OpDecorate %13 Binding 0
OpDecorate %15 DescriptorSet 0
OpDecorate %15 Binding 1
OpDecorate %17 DescriptorSet 0
OpDecorate %17 Binding 2
OpDecorate %19 DescriptorSet 0
OpDecorate %19 Binding 3
OpDecorate %88 Location 0
%2 = OpTypeVoid
%4 = OpTypeFloat 32
%5 = OpTypeImage %4 1D 0 0 0 1 Unknown
%6 = OpTypeInt 32 0
%7 = OpTypeVector %4 4
%8 = OpTypeImage %4 2D 0 0 0 1 Unknown
%9 = OpTypeVector %6 2
%10 = OpTypeImage %4 2D 0 1 0 1 Unknown
%11 = OpTypeInt 32 1
%12 = OpTypeImage %4 2D 1 0 0 1 Unknown
%14 = OpTypePointer UniformConstant %5
%13 = OpVariable %14 UniformConstant
%16 = OpTypePointer UniformConstant %8
%15 = OpVariable %16 UniformConstant
%18 = OpTypePointer UniformConstant %10
%17 = OpVariable %18 UniformConstant
%20 = OpTypePointer UniformConstant %12
%19 = OpVariable %20 UniformConstant
%25 = OpTypeFunction %7 %6 %6
%29 = OpConstant %11 1
%33 = OpConstant %6 1
%41 = OpTypeFunction %7 %9 %6
%48 = OpConstantComposite %9 %33 %33
%57 = OpTypeFunction %7 %9 %11 %6
%61 = OpTypeVector %6 3
%67 = OpConstantComposite %61 %33 %33 %33
%75 = OpTypeFunction %4 %9 %6
%82 = OpConstantComposite %9 %33 %33
%89 = OpTypePointer Output %7
%88 = OpVariable %89 Output
%91 = OpTypeFunction %2
%96 = OpConstant %6 0
%97 = OpConstantNull %9
%98 = OpConstant %11 0
%99 = OpConstant %4 0
%100 = OpConstantComposite %7 %99 %99 %99 %99
%24 = OpFunction %7 None %25
%22 = OpFunctionParameter %6
%23 = OpFunctionParameter %6
%21 = OpLabel
%26 = OpLoad %5 %13
OpBranch %27
%27 = OpLabel
OpLine %3 5 11
%28 = OpImageQueryLevels %11 %26
%30 = OpISub %11 %28 %29
%31 = OpExtInst %11 %1 UMin %23 %30
%32 = OpImageQuerySizeLod %6 %26 %31
%34 = OpISub %6 %32 %33
%35 = OpExtInst %6 %1 UMin %22 %34
%36 = OpImageFetch %7 %26 %35 Lod %31
OpReturnValue %36
OpFunctionEnd
%40 = OpFunction %7 None %41
%38 = OpFunctionParameter %9
%39 = OpFunctionParameter %6
%37 = OpLabel
%42 = OpLoad %8 %15
OpBranch %43
%43 = OpLabel
OpLine %3 12 11
%44 = OpImageQueryLevels %11 %42
%45 = OpISub %11 %44 %29
%46 = OpExtInst %11 %1 UMin %39 %45
%47 = OpImageQuerySizeLod %9 %42 %46
%49 = OpISub %9 %47 %48
%50 = OpExtInst %9 %1 UMin %38 %49
%51 = OpImageFetch %7 %42 %50 Lod %46
OpReturnValue %51
OpFunctionEnd
%56 = OpFunction %7 None %57
%53 = OpFunctionParameter %9
%54 = OpFunctionParameter %11
%55 = OpFunctionParameter %6
%52 = OpLabel
%58 = OpLoad %10 %17
OpBranch %59
%59 = OpLabel
OpLine %3 19 11
%60 = OpBitcast %6 %54
%62 = OpCompositeConstruct %61 %53 %60
%63 = OpImageQueryLevels %11 %58
%64 = OpISub %11 %63 %29
%65 = OpExtInst %11 %1 UMin %55 %64
%66 = OpImageQuerySizeLod %61 %58 %65
%68 = OpISub %61 %66 %67
%69 = OpExtInst %61 %1 UMin %62 %68
%70 = OpImageFetch %7 %58 %69 Lod %65
OpReturnValue %70
OpFunctionEnd
%74 = OpFunction %4 None %75
%72 = OpFunctionParameter %9
%73 = OpFunctionParameter %6
%71 = OpLabel
%76 = OpLoad %12 %19
OpBranch %77
%77 = OpLabel
OpLine %3 26 11
%78 = OpImageQueryLevels %11 %76
%79 = OpISub %11 %78 %29
%80 = OpExtInst %11 %1 UMin %73 %79
%81 = OpImageQuerySizeLod %9 %76 %80
%83 = OpISub %9 %81 %82
%84 = OpExtInst %9 %1 UMin %72 %83
%85 = OpImageFetch %7 %76 %84 Lod %80
%86 = OpCompositeExtract %4 %85 0
OpReturnValue %86
OpFunctionEnd
%90 = OpFunction %2 None %91
%87 = OpLabel
%92 = OpLoad %5 %13
%93 = OpLoad %8 %15
%94 = OpLoad %10 %17
%95 = OpLoad %12 %19
OpBranch %101
%101 = OpLabel
OpLine %3 31 5
%102 = OpFunctionCall %7 %24 %96 %96
OpLine %3 32 5
%103 = OpFunctionCall %7 %40 %97 %96
OpLine %3 33 5
%104 = OpFunctionCall %7 %56 %97 %98 %96
OpLine %3 34 5
%105 = OpFunctionCall %4 %74 %97 %96
OpLine %3 35 12
OpStore %88 %100
OpReturn
OpFunctionEnd
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#version 460
#extension GL_EXT_samplerless_texture_functions : require

layout(set = 0, binding = 0) uniform texture1D image_1d;
layout(set = 0, binding = 1) uniform texture2D image_2d;
layout(set = 0, binding = 2) uniform texture2DArray image_2d_array;
layout(set = 0, binding = 3) uniform texture2D image_depth_2d;

layout(location = 0) out vec4 _88;

vec4 test_textureLoad_1d(uint coords, uint level)
{
int _31 = int(min(level, uint(textureQueryLevels(image_1d) - 1)));
return texelFetch(image_1d, int(min(coords, (uint(textureSize(image_1d, _31)) - 1u))), _31);
}

vec4 test_textureLoad_2d(uvec2 coords, uint level)
{
int _46 = int(min(level, uint(textureQueryLevels(image_2d) - 1)));
return texelFetch(image_2d, ivec2(min(coords, (uvec2(textureSize(image_2d, _46)) - uvec2(1u)))), _46);
}

vec4 test_textureLoad_2d_array(uvec2 coords, int index, uint level)
{
int _65 = int(min(level, uint(textureQueryLevels(image_2d_array) - 1)));
return texelFetch(image_2d_array, ivec3(min(uvec3(coords, uint(index)), (uvec3(textureSize(image_2d_array, _65)) - uvec3(1u)))), _65);
}

float test_textureLoad_depth_2d(uvec2 coords, uint level)
{
int _80 = int(min(level, uint(textureQueryLevels(image_depth_2d) - 1)));
return texelFetch(image_depth_2d, ivec2(min(coords, (uvec2(textureSize(image_depth_2d, _80)) - uvec2(1u)))), _80).x;
}

void main()
{
_88 = vec4(0.0);
}

Loading