Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vkcubepp: Support protected output #1078

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
36 changes: 35 additions & 1 deletion cube/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ group("cube") {
testonly = true
deps = [
":vkcube-on-fb",
":vkcube-on-fb-protected",
":vkcube-on-scenic",
]
}
Expand All @@ -46,6 +47,25 @@ fuchsia_test_package("vkcube-on-fb") {
}
}

fuchsia_test_component("vkcube-on-fb-protected-component") {
deps = [
":vkcube",
"//src/lib/vulkan/swapchain:image_pipe_swapchain_fb_layer",
"//src/lib/vulkan/validation_layers",
]

manifest = "fuchsia/meta/vkcube-on-fb-protected.cml"
test_type = "system"
}

fuchsia_test_package("vkcube-on-fb-protected") {
test_components = [ ":vkcube-on-fb-protected-component" ]
test_specs = {
# vkcube runs forever, so only run manually.
environments = []
}
}

fuchsia_component("vkcube-on-scenic-component") {
component_name = "vkcube-on-scenic"
deps = [
Expand All @@ -57,8 +77,22 @@ fuchsia_component("vkcube-on-scenic-component") {
manifest = "fuchsia/meta/vkcube-on-scenic.cml"
}

fuchsia_component("vkcube-on-scenic-protected-component") {
component_name = "vkcube-on-scenic-protected"
deps = [
":vkcube",
"//src/lib/vulkan/swapchain:image_pipe_swapchain_layer",
"//src/lib/vulkan/validation_layers",
]

manifest = "fuchsia/meta/vkcube-on-scenic-protected.cml"
}

fuchsia_package("vkcube-on-scenic") {
deps = [ ":vkcube-on-scenic-component" ]
deps = [
":vkcube-on-scenic-component",
":vkcube-on-scenic-protected-component",
]
}

config("cube_config") {
Expand Down
56 changes: 50 additions & 6 deletions cube/cube.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,10 @@ struct Demo {
bool invalid_gpu_selection = false;
int32_t gpu_number = 0;

// If true, the Demo renders on the protected memory. This requires the
// physical device to support protected memory.
bool protected_output = false;

vk::Instance inst;
vk::DebugUtilsMessengerEXT debug_messenger;
vk::PhysicalDevice gpu;
Expand Down Expand Up @@ -799,14 +803,16 @@ void Demo::create_device() {
float priorities = 0.0;

std::vector<vk::DeviceQueueCreateInfo> queues;
queues.push_back(vk::DeviceQueueCreateInfo().setQueueFamilyIndex(graphics_queue_family_index).setQueuePriorities(priorities));
const vk::DeviceQueueCreateFlags queue_create_flags = protected_output ? vk::DeviceQueueCreateFlagBits::eProtected : vk::DeviceQueueCreateFlags{};
queues.push_back(vk::DeviceQueueCreateInfo().setQueueFamilyIndex(graphics_queue_family_index).setQueuePriorities(priorities).setFlags(queue_create_flags));

if (separate_present_queue) {
queues.push_back(
vk::DeviceQueueCreateInfo().setQueueFamilyIndex(present_queue_family_index).setQueuePriorities(priorities));
}

auto deviceInfo = vk::DeviceCreateInfo().setQueueCreateInfos(queues).setPEnabledExtensionNames(enabled_device_extensions);
auto const protected_memory_features = vk::PhysicalDeviceProtectedMemoryFeatures().setProtectedMemory(protected_output);
auto deviceInfo = vk::DeviceCreateInfo().setPNext(&protected_memory_features).setQueueCreateInfos(queues).setPEnabledExtensionNames(enabled_device_extensions);
auto device_return = gpu.createDevice(deviceInfo);
VERIFY(device_return.result == vk::Result::eSuccess);
device = device_return.value;
Expand Down Expand Up @@ -854,8 +860,10 @@ void Demo::draw() {
// engine has fully released ownership to the application, and it is
// okay to render to the image.
vk::PipelineStageFlags const pipe_stage_flags = vk::PipelineStageFlagBits::eColorAttachmentOutput;
auto protected_submit_info = vk::ProtectedSubmitInfo().setProtectedSubmit(protected_output);

auto submit_result = graphics_queue.submit(vk::SubmitInfo()
.setPNext(&protected_submit_info)
.setWaitDstStageMask(pipe_stage_flags)
.setWaitSemaphores(image_acquired_semaphores[frame_index])
.setCommandBuffers(swapchain_image_resources[current_buffer].cmd)
Expand Down Expand Up @@ -981,7 +989,10 @@ void Demo::draw_build_cmd(const SwapchainImageResources &swapchain_image_resourc
}

void Demo::prepare_init_cmd() {
auto cmd_pool_return = device.createCommandPool(vk::CommandPoolCreateInfo().setQueueFamilyIndex(graphics_queue_family_index));
vk::CommandPoolCreateFlags cmd_pool_create_flags =
protected_output ? vk::CommandPoolCreateFlagBits::eProtected : vk::CommandPoolCreateFlags{};
auto cmd_pool_return = device.createCommandPool(
vk::CommandPoolCreateInfo().setQueueFamilyIndex(graphics_queue_family_index).setFlags(cmd_pool_create_flags));
VERIFY(cmd_pool_return.result == vk::Result::eSuccess);
cmd_pool = cmd_pool_return.value;

Expand Down Expand Up @@ -1009,7 +1020,8 @@ void Demo::flush_init_cmd() {
VERIFY(fence_return.result == vk::Result::eSuccess);
auto fence = fence_return.value;

result = graphics_queue.submit(vk::SubmitInfo().setCommandBuffers(cmd), fence);
auto const protected_submit_info = vk::ProtectedSubmitInfo().setProtectedSubmit(protected_output);
result = graphics_queue.submit(vk::SubmitInfo().setPNext(&protected_submit_info).setCommandBuffers(cmd), fence);
VERIFY(result == vk::Result::eSuccess);

result = device.waitForFences(fence, VK_TRUE, UINT64_MAX);
Expand Down Expand Up @@ -1098,6 +1110,10 @@ void Demo::init(int argc, char **argv) {
force_errors = true;
continue;
}
if (strcmp(argv[i], "--protected_output") == 0) {
protected_output = true;
continue;
}
if ((strcmp(argv[i], "--wsi") == 0) && (i < argc - 1)) {
std::string selection_input = argv[i + 1];
for (char &c : selection_input) {
Expand Down Expand Up @@ -1166,6 +1182,7 @@ void Demo::init(int argc, char **argv) {
<< "\t[--present_mode <present mode enum>]\n"
<< "\t[--width <width>] [--height <height>]\n"
<< "\t[--force_errors]\n"
<< "\t[--protected_output]\n"
<< "\t[--wsi <" << wsi_platforms << ">]\n"
<< "\t<present_mode_enum>\n"
<< "\t\tVK_PRESENT_MODE_IMMEDIATE_KHR = " << VK_PRESENT_MODE_IMMEDIATE_KHR << "\n"
Expand Down Expand Up @@ -1501,6 +1518,17 @@ void Demo::init_vk() {

VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr);

uint32_t apiVersion = 0;
vk::Result enumerate_instance_version_result = vk::enumerateInstanceVersion(&apiVersion);
if (protected_output) {
if (enumerate_instance_version_result != vk::Result::eSuccess) {
ERR_EXIT("Failed to query instance version.", "vkCreateInstance Failure");
}
if (apiVersion < VK_MAKE_VERSION(1, 1, 0)) {
ERR_EXIT("Need Vulkan 1.1 instance for protected output.", "vkCreateInstance Failure");
}
}

std::vector<char const *> instance_validation_layers = {"VK_LAYER_KHRONOS_validation"};

// Look for validation layers
Expand Down Expand Up @@ -1893,6 +1921,10 @@ void Demo::select_physical_device() {

gpu.getProperties(&gpu_props);

if (protected_output && gpu_props.apiVersion < VK_MAKE_VERSION(1, 1, 0)) {
ERR_EXIT("Need Vulkan 1.1 physical device for protected output.", "VkPhysicalDevice failure");
}

/* Call with nullptr data to get count */
queue_props = gpu.getQueueFamilyProperties();
assert(queue_props.size() >= 1);
Expand Down Expand Up @@ -2035,7 +2067,16 @@ void Demo::init_vk_swapchain() {

create_device();

graphics_queue = device.getQueue(graphics_queue_family_index, 0);
if (protected_output) {
auto const queue_info2 = vk::DeviceQueueInfo2()
.setFlags(vk::DeviceQueueCreateFlagBits::eProtected)
.setQueueFamilyIndex(graphics_queue_family_index)
.setQueueIndex(0);
device.getQueue2(&queue_info2, &graphics_queue);
} else {
graphics_queue = device.getQueue(graphics_queue_family_index, 0);
}

if (!separate_present_queue) {
present_queue = graphics_queue;
} else {
Expand Down Expand Up @@ -2263,6 +2304,8 @@ void Demo::prepare_buffers() {
}
}

const vk::SwapchainCreateFlagsKHR swapchain_create_flags =
protected_output ? vk::SwapchainCreateFlagBitsKHR::eProtected : vk::SwapchainCreateFlagsKHR{};
auto swapchain_return = device.createSwapchainKHR(vk::SwapchainCreateInfoKHR()
.setSurface(surface)
.setMinImageCount(desiredNumOfSwapchainImages)
Expand All @@ -2276,7 +2319,8 @@ void Demo::prepare_buffers() {
.setCompositeAlpha(compositeAlpha)
.setPresentMode(swapchainPresentMode)
.setClipped(true)
.setOldSwapchain(oldSwapchain));
.setOldSwapchain(oldSwapchain)
.setFlags(swapchain_create_flags));
VERIFY(swapchain_return.result == vk::Result::eSuccess);
swapchain = swapchain_return.value;

Expand Down
27 changes: 27 additions & 0 deletions cube/fuchsia/meta/vkcube-on-fb-protected.cml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) 2025 The Fuchsia Authors.
//
// 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
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
{
include: [
"//src/lib/vulkan/swapchain/VkLayer_image_pipe_swapchain_fb.shard.cml",
"sys/testing/elf_test_runner.shard.cml",
],
program: {
binary: "bin/vkcube",
args: [
"--protected_output",
"--wsi",
"fuchsia_display",
],
},
}
45 changes: 45 additions & 0 deletions cube/fuchsia/meta/vkcube-on-scenic-protected.cml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) 2025 The Fuchsia Authors.
//
// 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
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
{
include: [ "//src/lib/vulkan/swapchain/VkLayer_image_pipe_swapchain.shard.cml" ],
program: {
runner: "elf",
binary: "bin/vkcube",
args: [
"--protected_output",
"--wsi",
"fuchsia_scenic",
],
},
capabilities: [
{
protocol: [ "fuchsia.ui.app.ViewProvider" ],
},
],
use: [
{
protocol: [
"fuchsia.ui.composition.Allocator",
"fuchsia.ui.composition.Flatland",
],
},
],
expose: [
{
protocol: [ "fuchsia.ui.app.ViewProvider" ],
from: "self",
to: "parent",
},
],
}
Loading