From 9ef6bdc9cee84a313d56b22cd167a2ce33607177 Mon Sep 17 00:00:00 2001 From: Chang-hwi Park Date: Thu, 30 Apr 2026 15:56:09 +0100 Subject: [PATCH 1/2] spirv-val: Check for image declaration with TileImageEXT storage class Change-Id: I9d97fb16af9848b3a3871f5f6a8043b859415fa3 --- source/val/validate_memory.cpp | 31 +++++++++++++++++++++++++++++++ test/val/val_storage_test.cpp | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/source/val/validate_memory.cpp b/source/val/validate_memory.cpp index 47d1a3c029..2f7c5cb1f9 100644 --- a/source/val/validate_memory.cpp +++ b/source/val/validate_memory.cpp @@ -1124,6 +1124,32 @@ spv_result_t ValidateVariableTileShadingQCOM(ValidationState_t& _, return SPV_SUCCESS; } +spv_result_t ValidateVariableTileImageEXT(ValidationState_t& _, + const Instruction* inst) { + bool is_valid_decl = true; + + auto result_type = _.FindDef(inst->type_id()); + if (result_type->opcode() == spv::Op::OpTypePointer) { + const auto pointee_type = _.FindDef(result_type->GetOperandAs(2)); + if (pointee_type && pointee_type->opcode() == spv::Op::OpTypeImage) { + spv::Dim dim = static_cast(pointee_type->word(3)); + if (dim != spv::Dim::TileImageDataEXT) { + is_valid_decl = false; + } + } else { + is_valid_decl = false; + } + } + + if (!is_valid_decl) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "The TileImageEXT Storage Class must only be used for declaring " + "tile image variables"; + } else { + return SPV_SUCCESS; + } +} + spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { const bool untyped_pointer = inst->opcode() == spv::Op::OpUntypedVariableKHR; @@ -1242,6 +1268,11 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { if (auto error = ValidateVariableTileShadingQCOM(_, inst)) return error; } + if (_.HasCapability(spv::Capability::TileImageColorReadAccessEXT) && + storage_class == spv::StorageClass::TileImageEXT) { + if (auto error = ValidateVariableTileImageEXT(_, inst)) return error; + } + return SPV_SUCCESS; } diff --git a/test/val/val_storage_test.cpp b/test/val/val_storage_test.cpp index b583fe30e3..8d84eee9f8 100644 --- a/test/val/val_storage_test.cpp +++ b/test/val/val_storage_test.cpp @@ -437,6 +437,38 @@ TEST_F(ValidateStorage, TileAttachmentQCOMBad6) { HasSubstr("requires one of these capabilities: TileShadingQCOM")); } +TEST_F(ValidateStorage, WrongDimTileImageEXT) { + const std::string spirv = R"( + OpCapability Shader + OpCapability Sampled1D + OpCapability TileImageColorReadAccessEXT + OpExtension "SPV_EXT_shader_tile_image" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" + OpExecutionMode %main OriginUpperLeft + OpSource GLSL 450 + %void = OpTypeVoid + %int = OpTypeInt 32 1 + %img = OpTypeImage %int 1D 0 0 0 2 Rgba32i + %ptr_img = OpTypePointer TileImageEXT %img + %color1 = OpVariable %ptr_img TileImageEXT + %3 = OpTypeFunction %void + %main = OpFunction %void None %3 + %5 = OpLabel + OpReturn + OpFunctionEnd + )"; + + spv_target_env env = SPV_ENV_VULKAN_1_4; + CompileSuccessfully(spirv, env); + EXPECT_THAT(SPV_ERROR_INVALID_DATA, ValidateInstructions(env)); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr( + "The TileImageEXT Storage Class must only be used for declaring " + "tile image variables")); +} + std::string GenerateExecutionModelCode(const std::string& execution_model, const std::string& storage_class, bool store) { From 66ccb64dbcd79e77ed0b3b49c4f51859ee3b6ae3 Mon Sep 17 00:00:00 2001 From: Chang-hwi Park Date: Thu, 30 Apr 2026 16:40:07 +0100 Subject: [PATCH 2/2] Fix TileImageNotFragment test to use valid TileImageEXT type Change-Id: Ia2e52c822378ea1b3522a48d975da59eaafad99b --- test/val/val_image_test.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/val/val_image_test.cpp b/test/val/val_image_test.cpp index 15880c9de0..403487ea28 100644 --- a/test/val/val_image_test.cpp +++ b/test/val/val_image_test.cpp @@ -11477,12 +11477,12 @@ TEST_F(ValidateImage, TileImageNotFragment) { %void = OpTypeVoid %func = OpTypeFunction %void %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 - %ptr = OpTypePointer TileImageEXT %v4float + %image = OpTypeImage %float TileImageDataEXT 0 0 0 2 Unknown + %ptr = OpTypePointer TileImageEXT %image %var = OpVariable %ptr TileImageEXT %main = OpFunction %void None %func %label = OpLabel - %val = OpLoad %v4float %var + %val = OpLoad %image %var OpReturn OpFunctionEnd )";