blob: 89869a47002f233b4637bb8275e0a09c001a903d [file] [log] [blame]
/*
* Copyright (c) 2023-2025 LunarG, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#include "../framework/layer_validation_tests.h"
#include "../framework/pipeline_helper.h"
class PositiveTileMemoryHeap : public TileMemoryHeapTest {};
TEST_F(PositiveTileMemoryHeap, BasicBuffer) {
TEST_DESCRIPTION("Create tile memory storage buffer and use it within a draw.");
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_QCOM_TILE_MEMORY_HEAP_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::tileMemoryHeap);
RETURN_IF_SKIP(Init());
// Create a Tile Memory Buffer
vkt::Buffer buffer(*m_device,
vkt::Buffer::CreateInfo(4096, VK_BUFFER_USAGE_2_TILE_MEMORY_BIT_QCOM | VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT),
vkt::no_mem);
// Query Tile Memory Buffer Requirements
VkBufferMemoryRequirementsInfo2 buffer_info = vku::InitStructHelper();
VkTileMemoryRequirementsQCOM tile_mem_reqs = vku::InitStructHelper();
VkMemoryRequirements2 buffer_reqs = vku::InitStructHelper(&tile_mem_reqs);
buffer_info.buffer = buffer;
vk::GetBufferMemoryRequirements2(device(), &buffer_info, &buffer_reqs);
if (tile_mem_reqs.size == 0) {
GTEST_SKIP() << "Buffer not eligible to be bound with Tile Memory.";
}
// Find a memory configuration for the Tile Memory Buffer, otherwise exit
VkMemoryAllocateInfo alloc_info = vku::InitStructHelper();
alloc_info.memoryTypeIndex = 0;
alloc_info.allocationSize = tile_mem_reqs.size;
bool pass = m_device->Physical().SetMemoryType(buffer_reqs.memoryRequirements.memoryTypeBits, &alloc_info,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0, VK_MEMORY_HEAP_TILE_MEMORY_BIT_QCOM);
if (!pass) {
GTEST_SKIP() << "Could not find an eligible Tile Memory Type.";
}
// Bind Tile Memory to Buffer
vkt::DeviceMemory buffer_memory(*m_device, alloc_info);
vk::BindBufferMemory(device(), buffer, buffer_memory, 0);
// Create Compute Shader to write to Tile Memory Buffer
const char *cs_source = R"glsl(
#version 450
layout(set = 0, binding = 0) buffer ssbo { float tileMemBuffer; };
void main() {
tileMemBuffer = 1.0f;
}
)glsl";
CreateComputePipelineHelper pipe(*this);
// Requires SPIR-V 1.3 for SPV_KHR_storage_buffer_storage_class
pipe.cs_ = VkShaderObj(*m_device, cs_source, VK_SHADER_STAGE_COMPUTE_BIT, SPV_ENV_VULKAN_1_1);
pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}};
pipe.CreateComputePipeline();
pipe.descriptor_set_.WriteDescriptorBufferInfo(0, buffer, 0, 4096, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
pipe.descriptor_set_.UpdateDescriptorSets();
VkTileMemoryBindInfoQCOM tile_mem_bind_info = vku::InitStructHelper();
tile_mem_bind_info.memory = buffer_memory;
m_command_buffer.Begin();
vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_, 0, 1,
&pipe.descriptor_set_.set_, 0, nullptr);
vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipe);
vk::CmdBindTileMemoryQCOM(m_command_buffer, &tile_mem_bind_info);
vk::CmdDispatch(m_command_buffer, 1, 1, 1);
m_command_buffer.End();
}