diff --git a/renderdoc/driver/shaders/spirv/spirv_debug.cpp b/renderdoc/driver/shaders/spirv/spirv_debug.cpp index ef6a6929a..45376f786 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_debug.cpp @@ -1829,8 +1829,16 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray case Op::ImageQuerySize: case Op::ImageQuerySizeLod: case Op::ImageFetch: + case Op::ImageGather: + case Op::ImageDrefGather: case Op::ImageSampleExplicitLod: case Op::ImageSampleImplicitLod: + case Op::ImageSampleDrefExplicitLod: + case Op::ImageSampleDrefImplicitLod: + case Op::ImageSampleProjExplicitLod: + case Op::ImageSampleProjImplicitLod: + case Op::ImageSampleProjDrefExplicitLod: + case Op::ImageSampleProjDrefImplicitLod: { ShaderVariable img; ShaderVariable sampler; @@ -1851,6 +1859,25 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray uv = GetSrc(image.coordinate); operands = image.imageOperands; } + else if(opdata.op == Op::ImageGather) + { + OpImageGather image(it); + + sampler = img = GetSrc(image.sampledImage); + uv = GetSrc(image.coordinate); + gather = GatherChannel(GetSrc(image.component).value.u.x); + operands = image.imageOperands; + } + else if(opdata.op == Op::ImageDrefGather) + { + OpImageDrefGather image(it); + + sampler = img = GetSrc(image.sampledImage); + uv = GetSrc(image.coordinate); + operands = image.imageOperands; + gather = GatherChannel::Red; + compare = GetSrc(image.dref); + } else if(opdata.op == Op::ImageSampleExplicitLod) { OpImageSampleExplicitLod image(it); @@ -1869,6 +1896,64 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray derivId = image.coordinate; } + else if(opdata.op == Op::ImageSampleDrefExplicitLod) + { + OpImageSampleDrefExplicitLod image(it); + + sampler = img = GetSrc(image.sampledImage); + uv = GetSrc(image.coordinate); + operands = image.imageOperands; + compare = GetSrc(image.dref); + } + else if(opdata.op == Op::ImageSampleDrefImplicitLod) + { + OpImageSampleDrefImplicitLod image(it); + + sampler = img = GetSrc(image.sampledImage); + uv = GetSrc(image.coordinate); + operands = image.imageOperands; + compare = GetSrc(image.dref); + + derivId = image.coordinate; + } + else if(opdata.op == Op::ImageSampleProjExplicitLod) + { + OpImageSampleProjExplicitLod image(it); + + sampler = img = GetSrc(image.sampledImage); + uv = GetSrc(image.coordinate); + operands = image.imageOperands; + } + else if(opdata.op == Op::ImageSampleProjImplicitLod) + { + OpImageSampleProjImplicitLod image(it); + + sampler = img = GetSrc(image.sampledImage); + uv = GetSrc(image.coordinate); + operands = image.imageOperands; + + derivId = image.coordinate; + } + else if(opdata.op == Op::ImageSampleProjDrefExplicitLod) + { + OpImageSampleProjDrefExplicitLod image(it); + + sampler = img = GetSrc(image.sampledImage); + uv = GetSrc(image.coordinate); + operands = image.imageOperands; + compare = GetSrc(image.dref); + } + else if(opdata.op == Op::ImageSampleProjDrefImplicitLod) + { + OpImageSampleProjDrefImplicitLod image(it); + + sampler = img = GetSrc(image.sampledImage); + uv = GetSrc(image.coordinate); + operands = image.imageOperands; + compare = GetSrc(image.dref); + + derivId = image.coordinate; + } else if(opdata.op == Op::ImageQueryLevels || opdata.op == Op::ImageQuerySamples || opdata.op == Op::ImageQuerySize) { diff --git a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp index 5901c23b6..6876abe9c 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp @@ -148,6 +148,7 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader case Capability::Tessellation: case Capability::TessellationPointSize: case Capability::GeometryPointSize: + case Capability::ImageGatherExtended: case Capability::UniformBufferArrayDynamicIndexing: case Capability::SampledImageArrayDynamicIndexing: case Capability::StorageBufferArrayDynamicIndexing: @@ -207,7 +208,6 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader // we plan to support these but needs additional testing/proving // image gather operations - case Capability::ImageGatherExtended: // image storage case Capability::StorageImageMultisample: diff --git a/renderdoc/driver/vulkan/vk_shaderdebug.cpp b/renderdoc/driver/vulkan/vk_shaderdebug.cpp index 13f0da5f5..812a63d42 100644 --- a/renderdoc/driver/vulkan/vk_shaderdebug.cpp +++ b/renderdoc/driver/vulkan/vk_shaderdebug.cpp @@ -88,10 +88,16 @@ struct Vec3i int32_t x, y, z; }; +struct GatherOffsets +{ + int32_t u0, v0, u1, v1, u2, v2, u3, v3; +}; + struct ShaderDebugParameters { uint32_t operation; VkBool32 useGrad; + VkBool32 useGatherOffsets; ShaderDebugBind dim; Vec3i texel_uvw; int texel_lod; @@ -104,6 +110,7 @@ struct ShaderDebugParameters float lod; float minlod; rdcspv::GatherChannel gatherChannel; + GatherOffsets gatherOffsets; }; class VulkanAPIWrapper : public rdcspv::DebugAPIWrapper @@ -583,6 +590,36 @@ public: params.operation = (uint32_t)opcode; + // proj opcodes have an extra q parameter + switch(opcode) + { + case rdcspv::Op::ImageSampleProjExplicitLod: + case rdcspv::Op::ImageSampleProjImplicitLod: + case rdcspv::Op::ImageSampleProjDrefExplicitLod: + case rdcspv::Op::ImageSampleProjDrefImplicitLod: + { + coords++; + gradCoords++; + break; + } + default: break; + } + + bool useCompare = false; + switch(opcode) + { + case rdcspv::Op::ImageDrefGather: + case rdcspv::Op::ImageSampleDrefExplicitLod: + case rdcspv::Op::ImageSampleDrefImplicitLod: + case rdcspv::Op::ImageSampleProjDrefExplicitLod: + case rdcspv::Op::ImageSampleProjDrefImplicitLod: + { + useCompare = true; + break; + } + default: break; + } + switch(opcode) { case rdcspv::Op::ImageFetch: @@ -605,8 +642,70 @@ public: break; } + case rdcspv::Op::ImageGather: + case rdcspv::Op::ImageDrefGather: + { + params.uvw.x = uv.value.f.x; + if(coords >= 2) + params.uvw.y = uv.value.f.y; + if(coords >= 3) + params.uvw.z = uv.value.f.z; + + if(useCompare) + params.compare = compare.value.f.x; + + params.gatherChannel = gatherChannel; + + if(operands.flags & rdcspv::ImageOperands::ConstOffsets) + { + ShaderVariable constOffsets = lane.GetSrc(operands.constOffsets); + + params.useGatherOffsets = VK_TRUE; + + // should be an array of ivec2 + RDCASSERT(constOffsets.members.size() == 4); + + params.gatherOffsets.u0 = constOffsets.members[0].value.i.x; + params.gatherOffsets.v0 = constOffsets.members[0].value.i.y; + params.gatherOffsets.u1 = constOffsets.members[1].value.i.x; + params.gatherOffsets.v1 = constOffsets.members[1].value.i.y; + params.gatherOffsets.u2 = constOffsets.members[1].value.i.x; + params.gatherOffsets.v2 = constOffsets.members[1].value.i.y; + params.gatherOffsets.u3 = constOffsets.members[1].value.i.x; + params.gatherOffsets.v3 = constOffsets.members[1].value.i.y; + } + + params.useGatherOffsets = VK_FALSE; + + if(operands.flags & rdcspv::ImageOperands::ConstOffset) + { + ShaderVariable constOffset = lane.GetSrc(operands.constOffset); + params.offset.x = constOffset.value.i.x; + if(gradCoords >= 2) + params.offset.y = constOffset.value.i.y; + if(gradCoords >= 3) + params.offset.z = constOffset.value.i.z; + } + else if(operands.flags & rdcspv::ImageOperands::Offset) + { + ShaderVariable offset = lane.GetSrc(operands.offset); + params.offset.x = offset.value.i.x; + if(gradCoords >= 2) + params.offset.y = offset.value.i.y; + if(gradCoords >= 3) + params.offset.z = offset.value.i.z; + } + + break; + } case rdcspv::Op::ImageSampleExplicitLod: case rdcspv::Op::ImageSampleImplicitLod: + case rdcspv::Op::ImageSampleProjExplicitLod: + case rdcspv::Op::ImageSampleProjImplicitLod: + case rdcspv::Op::ImageSampleDrefExplicitLod: + case rdcspv::Op::ImageSampleDrefImplicitLod: + case rdcspv::Op::ImageSampleProjDrefExplicitLod: + case rdcspv::Op::ImageSampleProjDrefImplicitLod: { params.uvw.x = uv.value.f.x; if(coords >= 2) @@ -617,6 +716,9 @@ public: if(operands.flags & rdcspv::ImageOperands::MinLod) params.minlod = lane.GetSrc(operands.minLod).value.f.x; + if(useCompare) + params.compare = compare.value.f.x; + if(operands.flags & rdcspv::ImageOperands::Lod) { params.lod = lane.GetSrc(operands.lod).value.f.x; @@ -642,7 +744,8 @@ public: params.ddy.z = ddy.value.f.z; } - if(opcode == rdcspv::Op::ImageSampleImplicitLod) + if(opcode == rdcspv::Op::ImageSampleImplicitLod || + opcode == rdcspv::Op::ImageSampleProjImplicitLod) { // use grad to sub in for the implicit lod params.useGrad = VK_TRUE; @@ -1320,6 +1423,10 @@ private: rdcspv::Id v2f32 = editor.DeclareType(rdcspv::Vector(rdcspv::scalar(), 2)); rdcspv::Id v3f32 = editor.DeclareType(rdcspv::Vector(rdcspv::scalar(), 3)); + // int2[4] + rdcspv::Id a4v2i32 = editor.AddType( + rdcspv::OpTypeArray(editor.MakeId(), v2i32, editor.AddConstantImmediate(4))); + rdcspv::Scalar base = rdcspv::scalar(); if(uintTex) base = rdcspv::scalar(); @@ -1337,6 +1444,7 @@ private: DECL_SPECID(uint32_t, operation, operation); DECL_SPECID(bool, useGrad, useGrad); + DECL_SPECID(bool, useGatherOffsets, useGatherOffsets); DECL_SPECID(uint32_t, dim, dim); DECL_SPECID(int32_t, texel_u, texel_uvw.x); DECL_SPECID(int32_t, texel_v, texel_uvw.y); @@ -1359,6 +1467,14 @@ private: DECL_SPECID(float, lod, lod); DECL_SPECID(float, minlod, minlod); DECL_SPECID(int32_t, gatherChannel, gatherChannel); + DECL_SPECID(int32_t, gather_u0, gatherOffsets.u0); + DECL_SPECID(int32_t, gather_v0, gatherOffsets.v0); + DECL_SPECID(int32_t, gather_u1, gatherOffsets.u1); + DECL_SPECID(int32_t, gather_v1, gatherOffsets.v1); + DECL_SPECID(int32_t, gather_u2, gatherOffsets.u2); + DECL_SPECID(int32_t, gather_v2, gatherOffsets.v2); + DECL_SPECID(int32_t, gather_u3, gatherOffsets.u3); + DECL_SPECID(int32_t, gather_v3, gatherOffsets.v3); rdcspv::Id texel_uv = editor.AddConstant( rdcspv::OpSpecConstantComposite(v2i32, editor.MakeId(), {texel_u, texel_v})); @@ -1400,6 +1516,20 @@ private: editor.SetName(offset_xy, "offset_xy"); editor.SetName(offset_xyz, "offset_xyz"); + rdcspv::Id gather_0 = editor.AddConstant( + rdcspv::OpSpecConstantComposite(v2i32, editor.MakeId(), {gather_u0, gather_v0})); + rdcspv::Id gather_1 = editor.AddConstant( + rdcspv::OpSpecConstantComposite(v2i32, editor.MakeId(), {gather_u1, gather_v1})); + rdcspv::Id gather_2 = editor.AddConstant( + rdcspv::OpSpecConstantComposite(v2i32, editor.MakeId(), {gather_u2, gather_v2})); + rdcspv::Id gather_3 = editor.AddConstant( + rdcspv::OpSpecConstantComposite(v2i32, editor.MakeId(), {gather_u3, gather_v3})); + + rdcspv::Id gatherOffsets = editor.AddConstant(rdcspv::OpSpecConstantComposite( + a4v2i32, editor.MakeId(), {gather_0, gather_1, gather_2, gather_3})); + + editor.SetName(gatherOffsets, "gatherOffsets"); + // create the output. It's always a 4-wide vector rdcspv::Id outPtrType = editor.DeclareType(rdcspv::Pointer(resultType, rdcspv::StorageClass::Output)); @@ -1535,6 +1665,8 @@ private: uint32_t sampIdx = (uint32_t)ShaderDebugBind::Sampler; + // TODO handle Proj opcodes, that need non-arrayed texture views, or else a manual divide + for(uint32_t i = (uint32_t)ShaderDebugBind::First; i < (uint32_t)ShaderDebugBind::Count; i++) { if(i == sampIdx) @@ -1551,6 +1683,9 @@ private: if(i != (uint32_t)ShaderDebugBind::Buffer && i != (uint32_t)ShaderDebugBind::Tex2DMS) imageOperands.setLod(texel_lod); + if(i == (uint32_t)ShaderDebugBind::Tex2DMS) + imageOperands.setSample(sampleIdx); + cases.add(rdcspv::OpLabel(label)); rdcspv::Id loaded = cases.add(rdcspv::OpLoad(texSampTypes[i], editor.MakeId(), texSampVars[i])); @@ -1593,8 +1728,14 @@ private: operands.setLod(lod); rdcspv::Id combined = cases.add(rdcspv::OpSampledImage( texSampCombinedTypes[i], editor.MakeId(), loadedImage, loadedSampler)); - lodResult = cases.add(rdcspv::OpImageSampleExplicitLod(resultType, editor.MakeId(), - combined, coord[i], operands)); + + if(op == rdcspv::Op::ImageSampleExplicitLod || op == rdcspv::Op::ImageSampleImplicitLod) + lodResult = cases.add(rdcspv::OpImageSampleExplicitLod(resultType, editor.MakeId(), + combined, coord[i], operands)); + else + lodResult = cases.add(rdcspv::OpImageSampleProjExplicitLod( + resultType, editor.MakeId(), combined, coord[i], operands)); + cases.add(rdcspv::OpBranch(mergeLabel)); } @@ -1603,10 +1744,18 @@ private: cases.add(rdcspv::OpLabel(gradCase)); rdcspv::ImageOperandsAndParamDatas operands = imageOperands; operands.setGrad(ddxs[i], ddys[i]); + if(m_pDriver->GetDeviceFeatures().shaderResourceMinLod) + operands.setMinLod(minlod); rdcspv::Id combined = cases.add(rdcspv::OpSampledImage( texSampCombinedTypes[i], editor.MakeId(), loadedImage, loadedSampler)); - gradResult = cases.add(rdcspv::OpImageSampleExplicitLod(resultType, editor.MakeId(), - combined, coord[i], operands)); + + if(op == rdcspv::Op::ImageSampleExplicitLod || op == rdcspv::Op::ImageSampleImplicitLod) + gradResult = cases.add(rdcspv::OpImageSampleExplicitLod(resultType, editor.MakeId(), + combined, coord[i], operands)); + else + gradResult = cases.add(rdcspv::OpImageSampleProjExplicitLod( + resultType, editor.MakeId(), combined, coord[i], operands)); + cases.add(rdcspv::OpBranch(mergeLabel)); } @@ -1616,6 +1765,160 @@ private: cases.add(rdcspv::OpStore(outVar, sampleResult)); cases.add(rdcspv::OpBranch(breakLabel)); } + + for(rdcspv::Op op : + {rdcspv::Op::ImageSampleDrefExplicitLod, rdcspv::Op::ImageSampleDrefImplicitLod}) + { + rdcspv::Id label = editor.MakeId(); + targets.push_back({(uint32_t)op * 10 + i, label}); + + rdcspv::ImageOperandsAndParamDatas imageOperands; + + imageOperands.setConstOffset(offsets[i]); + + cases.add(rdcspv::OpLabel(label)); + rdcspv::Id loadedImage = + cases.add(rdcspv::OpLoad(texSampTypes[i], editor.MakeId(), texSampVars[i])); + rdcspv::Id loadedSampler = + cases.add(rdcspv::OpLoad(texSampTypes[sampIdx], editor.MakeId(), texSampVars[sampIdx])); + + rdcspv::Id mergeLabel = editor.MakeId(); + rdcspv::Id gradCase = editor.MakeId(); + rdcspv::Id lodCase = editor.MakeId(); + cases.add(rdcspv::OpSelectionMerge(mergeLabel, rdcspv::SelectionControl::None)); + cases.add(rdcspv::OpBranchConditional(useGrad, gradCase, lodCase)); + + rdcspv::Id lodResult; + { + cases.add(rdcspv::OpLabel(lodCase)); + rdcspv::ImageOperandsAndParamDatas operands = imageOperands; + operands.setLod(lod); + rdcspv::Id combined = cases.add(rdcspv::OpSampledImage( + texSampCombinedTypes[i], editor.MakeId(), loadedImage, loadedSampler)); + + if(op == rdcspv::Op::ImageSampleDrefExplicitLod || + op == rdcspv::Op::ImageSampleDrefImplicitLod) + lodResult = cases.add(rdcspv::OpImageSampleDrefExplicitLod( + resultType, editor.MakeId(), combined, compare, coord[i], operands)); + else + lodResult = cases.add(rdcspv::OpImageSampleProjDrefExplicitLod( + resultType, editor.MakeId(), combined, compare, coord[i], operands)); + + cases.add(rdcspv::OpBranch(mergeLabel)); + } + + rdcspv::Id gradResult; + { + cases.add(rdcspv::OpLabel(gradCase)); + rdcspv::ImageOperandsAndParamDatas operands = imageOperands; + operands.setGrad(ddxs[i], ddys[i]); + if(m_pDriver->GetDeviceFeatures().shaderResourceMinLod) + operands.setMinLod(minlod); + rdcspv::Id combined = cases.add(rdcspv::OpSampledImage( + texSampCombinedTypes[i], editor.MakeId(), loadedImage, loadedSampler)); + + if(op == rdcspv::Op::ImageSampleDrefExplicitLod || + op == rdcspv::Op::ImageSampleDrefImplicitLod) + gradResult = cases.add(rdcspv::OpImageSampleDrefExplicitLod( + resultType, editor.MakeId(), combined, compare, coord[i], operands)); + else + gradResult = cases.add(rdcspv::OpImageSampleProjDrefExplicitLod( + resultType, editor.MakeId(), combined, compare, coord[i], operands)); + + cases.add(rdcspv::OpBranch(mergeLabel)); + } + + cases.add(rdcspv::OpLabel(mergeLabel)); + rdcspv::Id sampleResult = cases.add(rdcspv::OpPhi( + resultType, editor.MakeId(), {{lodResult, lodCase}, {gradResult, gradCase}})); + cases.add(rdcspv::OpStore(outVar, sampleResult)); + cases.add(rdcspv::OpBranch(breakLabel)); + } + + // can only gather with 2D textures + if(i == (uint32_t)ShaderDebugBind::Tex1D || i == (uint32_t)ShaderDebugBind::Tex3D) + continue; + + for(rdcspv::Op op : {rdcspv::Op::ImageGather, rdcspv::Op::ImageDrefGather}) + { + rdcspv::Id label = editor.MakeId(); + targets.push_back({(uint32_t)op * 10 + i, label}); + + rdcspv::ImageOperandsAndParamDatas imageOperands; + + cases.add(rdcspv::OpLabel(label)); + rdcspv::Id loadedImage = + cases.add(rdcspv::OpLoad(texSampTypes[i], editor.MakeId(), texSampVars[i])); + rdcspv::Id loadedSampler = + cases.add(rdcspv::OpLoad(texSampTypes[sampIdx], editor.MakeId(), texSampVars[sampIdx])); + + rdcspv::Id sampleResult; + if(m_pDriver->GetDeviceFeatures().shaderImageGatherExtended) + { + rdcspv::Id mergeLabel = editor.MakeId(); + rdcspv::Id constsCase = editor.MakeId(); + rdcspv::Id baseCase = editor.MakeId(); + cases.add(rdcspv::OpSelectionMerge(mergeLabel, rdcspv::SelectionControl::None)); + cases.add(rdcspv::OpBranchConditional(useGatherOffsets, constsCase, baseCase)); + + rdcspv::Id baseResult; + { + cases.add(rdcspv::OpLabel(baseCase)); + rdcspv::ImageOperandsAndParamDatas operands = imageOperands; + imageOperands.setConstOffset(offsets[i]); + rdcspv::Id combined = cases.add(rdcspv::OpSampledImage( + texSampCombinedTypes[i], editor.MakeId(), loadedImage, loadedSampler)); + + if(op == rdcspv::Op::ImageGather) + baseResult = cases.add(rdcspv::OpImageGather(resultType, editor.MakeId(), combined, + coord[i], gatherChannel, imageOperands)); + else + baseResult = cases.add(rdcspv::OpImageDrefGather( + resultType, editor.MakeId(), combined, coord[i], compare, imageOperands)); + + cases.add(rdcspv::OpBranch(mergeLabel)); + } + + rdcspv::Id constsResult; + { + cases.add(rdcspv::OpLabel(constsCase)); + rdcspv::ImageOperandsAndParamDatas operands = imageOperands; + operands.setConstOffsets(gatherOffsets); + rdcspv::Id combined = cases.add(rdcspv::OpSampledImage( + texSampCombinedTypes[i], editor.MakeId(), loadedImage, loadedSampler)); + + if(op == rdcspv::Op::ImageGather) + constsResult = cases.add(rdcspv::OpImageGather( + resultType, editor.MakeId(), combined, coord[i], gatherChannel, imageOperands)); + else + constsResult = cases.add(rdcspv::OpImageDrefGather( + resultType, editor.MakeId(), combined, coord[i], compare, imageOperands)); + + cases.add(rdcspv::OpBranch(mergeLabel)); + } + + cases.add(rdcspv::OpLabel(mergeLabel)); + sampleResult = cases.add(rdcspv::OpPhi( + resultType, editor.MakeId(), {{baseResult, baseCase}, {constsResult, constsCase}})); + } + else + { + imageOperands.setConstOffset(offsets[i]); + + rdcspv::Id combined = cases.add(rdcspv::OpSampledImage( + texSampCombinedTypes[i], editor.MakeId(), loadedImage, loadedSampler)); + + if(op == rdcspv::Op::ImageGather) + sampleResult = cases.add(rdcspv::OpImageGather(resultType, editor.MakeId(), combined, + coord[i], gatherChannel, imageOperands)); + else + sampleResult = cases.add(rdcspv::OpImageDrefGather( + resultType, editor.MakeId(), combined, coord[i], compare, imageOperands)); + } + + cases.add(rdcspv::OpStore(outVar, sampleResult)); + cases.add(rdcspv::OpBranch(breakLabel)); + } } func.add(rdcspv::OpSelectionMerge(breakLabel, rdcspv::SelectionControl::None)); diff --git a/util/test/demos/vk/vk_shader_debug_zoo.cpp b/util/test/demos/vk/vk_shader_debug_zoo.cpp index 171f3385c..f8c0df8ae 100644 --- a/util/test/demos/vk/vk_shader_debug_zoo.cpp +++ b/util/test/demos/vk/vk_shader_debug_zoo.cpp @@ -134,6 +134,8 @@ layout(set = 0, binding = 5, std430) buffer storebuftype layout(set = 0, binding = 7) uniform samplerBuffer texBuffer; //layout(set = 0, binding = 8, rgba32f) uniform coherent imageBuffer storeTexBuffer; +layout(set = 0, binding = 9) uniform sampler shadowSampler; + layout(set = 0, binding = 20) uniform sampler2DArray queryTest; layout(set = 0, binding = 21) uniform sampler2DMSArray queryTestMS; @@ -914,6 +916,43 @@ void main() Color = texelFetch(texBuffer, int(zeroi+2)); break; } + case 112: + { + float x = texture(sampler2DShadow(sampledImage, shadowSampler), vec3(inpos, 0.1f)); + float y = texture(sampler2DShadow(sampledImage, shadowSampler), vec3(inpos, 0.3f)); + float z = texture(sampler2DShadow(sampledImage, shadowSampler), vec3(inpos, 0.7f)); + float w = texture(sampler2DShadow(sampledImage, 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(sampledImage, shadowSampler), coord, 0.8f); + break; + } default: break; } } @@ -2066,6 +2105,7 @@ void main() {6, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT}, {7, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT}, {8, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT}, + {9, 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_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT}, })); @@ -2222,6 +2262,7 @@ void main() VkSampler pointsampler = VK_NULL_HANDLE; VkSampler linearsampler = VK_NULL_HANDLE; VkSampler mipsampler = VK_NULL_HANDLE; + VkSampler shadowsampler = VK_NULL_HANDLE; VkSamplerCreateInfo sampInfo = {VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO}; sampInfo.magFilter = VK_FILTER_NEAREST; @@ -2238,6 +2279,11 @@ void main() vkCreateSampler(device, &sampInfo, NULL, &mipsampler); + sampInfo.compareEnable = VK_TRUE; + sampInfo.compareOp = VK_COMPARE_OP_LESS_OR_EQUAL; + + vkCreateSampler(device, &sampInfo, NULL, &shadowsampler); + VkDescriptorSet descset = allocateDescriptorSet(setlayout); Vec4f cbufferdata[16] = {}; @@ -2321,6 +2367,9 @@ void main() vkh::WriteDescriptorSet(descset, 7, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, {bufview}), vkh::WriteDescriptorSet(descset, 8, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, {store_bufview}), + vkh::WriteDescriptorSet( + descset, 9, VK_DESCRIPTOR_TYPE_SAMPLER, + {vkh::DescriptorImageInfo(VK_NULL_HANDLE, VK_IMAGE_LAYOUT_UNDEFINED, shadowsampler)}), vkh::WriteDescriptorSet( descset, 20, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, @@ -2453,6 +2502,7 @@ void main() vkDestroySampler(device, pointsampler, NULL); vkDestroySampler(device, linearsampler, NULL); vkDestroySampler(device, mipsampler, NULL); + vkDestroySampler(device, shadowsampler, NULL); return 0; }