void flush(const type::supplier<type::serialize_type> &constants,
	VkPipelineLayout pipeline_layout,
	const std::vector<VkPushConstantRange> &push_constant_ranges,
	queue::queue_type &queue) {
	if (type::dirty(*constants)) {
		const type::supplier<device::device_type> device(
			vcc::internal::get_parent(queue));
		std::string buffer(type::size(*constants), '\0');
		type::flush(*constants, &buffer[0]);
		command_pool::command_pool_type command_pool(command_pool::create(
			device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queue::get_family_index(queue)));
		command_buffer::command_buffer_type cmd(std::move(
			command_buffer::allocate(device, std::ref(command_pool),
				VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1).front()));
		{
			command_buffer::begin_type begin(command_buffer::begin(
				std::ref(cmd), VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
				VK_FALSE, 0, 0));
			for (const VkPushConstantRange &range : push_constant_ranges) {
				assert(range.offset + range.size <= buffer.size());
				vkCmdPushConstants(vcc::internal::get_instance(cmd), pipeline_layout,
					range.stageFlags, range.offset, range.size,
					&buffer[range.offset]);
			}
		}
		// Must block until our command finish executing.
		fence::fence_type fence(fence::create(device));
		queue::submit(queue, {}, { std::ref(cmd) }, {}, fence);
		fence::wait(*device, { std::ref(fence) }, true,
			std::chrono::nanoseconds::max());
	}
}
bool flush(queue::queue_type &queue, input_buffer_type &buffer) {
	if (flush(buffer)) {
		command_pool::command_pool_type command_pool(command_pool::create(
			vcc::internal::get_parent(queue), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queue::get_family_index(queue)));
		command_buffer::command_buffer_type cmd(std::move(
			command_buffer::allocate(vcc::internal::get_parent(queue),
				std::ref(command_pool), VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1)
			.front()));

		command_buffer::compile(cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
			VK_FALSE, 0, 0,
			command::pipeline_barrier{ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
				VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0,
				{},
				{
					command::buffer_memory_barrier_type{
						VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT,
						VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
						std::ref(buffer.buffer)}
				},
				{}
		});
		// Must block until our command finish executing.
		fence::fence_type fence(vcc::fence::create(vcc::internal::get_parent(queue)));
		queue::submit(queue, {}, { std::move(cmd) }, {}, fence);
		fence::wait(*vcc::internal::get_parent(queue), { std::ref(fence) }, true,
			std::chrono::nanoseconds::max());
		return true;
	} else {
		return false;
	}
}
示例#3
0
int vr_type::run(const draw_callback_type &draw_callback,
		const event_callback_type &event_callback) {
	vcc::command_pool::command_pool_type command_pool(
		vcc::command_pool::create(vcc::internal::get_parent(*queue),
			0, vcc::queue::get_family_index(*queue)));
	vcc::command_buffer::command_buffer_type pre_draw_command_buffer(std::move(
		vcc::command_buffer::allocate(vcc::internal::get_parent(*queue),
			std::ref(command_pool), VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1)
		.front())),
		post_draw_command_buffer(std::move(vcc::command_buffer::allocate(
			vcc::internal::get_parent(*queue), std::ref(command_pool),
			VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1).front()));

	vcc::command::compile(
		vcc::command::build(std::ref(pre_draw_command_buffer), 0, VK_FALSE, 0, 0),
		vcc::command::pipeline_barrier(
			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, {},
			{}, {
				vcc::command::image_memory_barrier{ 0, 0,
					VK_IMAGE_LAYOUT_UNDEFINED,
					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
					VK_QUEUE_FAMILY_IGNORED,
					vcc::queue::get_family_index(*queue),
					std::ref(image),
					{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
				}
			}));
	vcc::command::compile(
		vcc::command::build(std::ref(post_draw_command_buffer), 0, VK_FALSE, 0, 0),
		vcc::command::pipeline_barrier(
			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
			VK_PIPELINE_STAGE_TRANSFER_BIT, 0, {}, {},
			{
				vcc::command::image_memory_barrier{ 0, 0,
					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
					VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
					VK_QUEUE_FAMILY_IGNORED,
					VK_QUEUE_FAMILY_IGNORED,
					std::ref(image),
					{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
				}
			}));

	std::array<vr::TrackedDevicePose_t, vr::k_unMaxTrackedDeviceCount>
		trackedDevicePose;
	std::array<glm::mat4x3, vr::k_unMaxTrackedDeviceCount> mat4DevicePose;
	std::array<bool, vr::k_unMaxTrackedDeviceCount> bPoseIsValid;
	for (;;) {
		vr::VREvent_t event;
		while (hmd.hmd->PollNextEvent(&event, sizeof(event))) {
			event_callback(event);
		}

		for (vr::TrackedDeviceIndex_t unDevice = 0;
			unDevice < vr::k_unMaxTrackedDeviceCount; unDevice++) {
			vr::VRControllerState_t state;
			if (hmd.hmd->GetControllerState(unDevice, &state, sizeof(vr::VRControllerState_t))) {
				//m_rbShowTrackedDevice[unDevice] = state.ulButtonPressed == 0;
			}
		}
		vr::IVRCompositor *compositor(vr::VRCompositor());
		compositor->WaitGetPoses(trackedDevicePose.data(),
			vr::k_unMaxTrackedDeviceCount, NULL, 0);

		for (int nDevice = 0; nDevice < vr::k_unMaxTrackedDeviceCount; ++nDevice) {
			bPoseIsValid[nDevice] = trackedDevicePose[nDevice].bPoseIsValid;
			if (bPoseIsValid[nDevice]) {
				mat4DevicePose[nDevice] = convert(
					trackedDevicePose[nDevice].mDeviceToAbsoluteTracking);
			}
		}

		type::supplier<const vcc::device::device_type> device(
			vcc::internal::get_parent(*queue));

		vcc::queue::submit(*queue, { }, { pre_draw_command_buffer }, {});

		draw_callback(mat4DevicePose);

		vcc::queue::submit(*queue, {}, { post_draw_command_buffer }, { });

		vr::VRVulkanTextureData_t texture_data{
			uint64_t(VkImage(vcc::internal::get_instance(image))),
			vcc::internal::get_instance(*device),
			vcc::device::get_physical_device(*device),
			vcc::internal::get_instance(*instance),
			vcc::internal::get_instance(*queue),
			vcc::queue::get_family_index(*queue),
			extent.width, extent.height, VK_FORMAT_R8G8B8A8_UNORM, 1
		};
		const vr::Texture_t texdesc = { (void*)&texture_data,
			vr::TextureType_Vulkan, vr::ColorSpace_Gamma };
		{
			const vr::VRTextureBounds_t bounds = { 0.f, 0.f, .5f, 1.f };
			vr::EVRCompositorError error(compositor->Submit(vr::Eye_Left, &texdesc, &bounds));
			assert(error == vr::VRCompositorError_None);
		}
		{
			const vr::VRTextureBounds_t bounds = { .5f, 0.f, 1.f, 1.f };
			vr::EVRCompositorError error(compositor->Submit(vr::Eye_Right, &texdesc, &bounds));
			assert(error == vr::VRCompositorError_None);
		}
	}
}