Как заставить рендеринг OpenVR многовидовой работать? - PullRequest
0 голосов
/ 01 декабря 2019

Я оптимизирую уже работающий рендеринг виртуальной реальности, внедряя рендеринг в многофакторном режиме в свой собственный движок C ++, но не вижу другого глаза для рендеринга. Вот мой вершинный шейдер:

layout(set=0, binding=2) Buffer<float3> positions : register(b2);

VSOutput unlitVS( uint vertexId : SV_VertexID, uint viewId : SV_ViewID )
{
    VSOutput vsOut;
    vsOut.uv = uvs[ vertexId ];
    vsOut.pos = mul( data.localToClip[ viewId ], float4( positions[ vertexId ], 1 ) );

    return vsOut;
}

Если я использую viewId для выбора матрицы преобразования, я получаю сообщение об ошибке:

ERROR: Vertex shader consumes input at location 0 but not provided

Если я не использую viewId мой другой глаз вообще не рендерится. Вот как я настраиваю свой кадровый буфер, у него 2 слоя, и после рендеринга левого глаза я копирую второй слой в правый глаз.

VkImageCreateInfo imageCreateInfo = {};
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageCreateInfo.pNext = nullptr;
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
imageCreateInfo.extent.width = width;
imageCreateInfo.extent.height = height;
imageCreateInfo.extent.depth = 1;
imageCreateInfo.mipLevels = 1;
imageCreateInfo.arrayLayers = 2;
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageCreateInfo.format = VK_FORMAT_R8G8B8A8_SRGB;
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageCreateInfo.samples = sampleCount == 4 ? VK_SAMPLE_COUNT_4_BIT : VK_SAMPLE_COUNT_1_BIT;
imageCreateInfo.usage = (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
imageCreateInfo.flags = 0;

VkResult result = vkCreateImage( dev, &imageCreateInfo, nullptr, &outFramebufferDesc.image );

...

// Bit mask that specifies which view rendering is broadcast to.
// 0011 = Broadcast to first and second view (layer)
const uint32_t viewMask = 0b00000011;

// Bit mask that specifices correlation between views
// An implementation may use this for optimizations (concurrent render)
const uint32_t correlationMask = 0b00000011;

VkRenderPassMultiviewCreateInfo renderPassMultiviewCI{};
renderPassMultiviewCI.sType = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO;
renderPassMultiviewCI.subpassCount = 1;
renderPassMultiviewCI.pViewMasks = &viewMask;
renderPassMultiviewCI.correlationMaskCount = 1;
renderPassMultiviewCI.pCorrelationMasks = &correlationMask;

VkRenderPassCreateInfo renderPassCreateInfo = {};
renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassCreateInfo.flags = 0;
renderPassCreateInfo.pNext = &renderPassMultiviewCI;
renderPassCreateInfo.attachmentCount = 2;
renderPassCreateInfo.pAttachments = &attachmentDescs[ 0 ];
renderPassCreateInfo.subpassCount = 1;
renderPassCreateInfo.pSubpasses = &subPassCreateInfo;
renderPassCreateInfo.dependencyCount = 0;
renderPassCreateInfo.pDependencies = nullptr;

result = vkCreateRenderPass( dev, &renderPassCreateInfo, nullptr, &outFramebufferDesc.renderPass );
assert( result == VK_SUCCESS );

VkImageView attachments[ 2 ] = { outFramebufferDesc.imageView, outFramebufferDesc.depthStencilImageView };
VkFramebufferCreateInfo framebufferCreateInfo = {};
framebufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferCreateInfo.pNext = nullptr;
framebufferCreateInfo.renderPass = outFramebufferDesc.renderPass;
framebufferCreateInfo.attachmentCount = 2;
framebufferCreateInfo.pAttachments = &attachments[ 0 ];
framebufferCreateInfo.width = width;
framebufferCreateInfo.height = height;
framebufferCreateInfo.layers = 1;
result = vkCreateFramebuffer( dev, &framebufferCreateInfo, nullptr, &outFramebufferDesc.framebuffer );

...

// After rendering the left eye:
VkImageCopy region = {};
region.extent.width = device.width;
region.extent.height = device.height;
region.extent.depth = 1;
region.srcSubresource.baseArrayLayer = 1;
region.srcSubresource.layerCount = 1;
region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.dstSubresource.layerCount = 1;
region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;

vkCmdCopyImage( gCurrentDrawCommandBuffer, device.fbDesc.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, device.fbDesc.imageCopy, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region );

Вот мой VkPipelineVertexInputStateCreateInfo, я использую программируемое вытягивание вершин:

VkPipelineVertexInputStateCreateInfo inputState = {};
inputState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;

Как я могу исправить ошибку и заставить работать правый глаз? Я использую HTC Vive, OpenVR 1.7.15, AMD R9 Nano, Vulkan 1.1 на Vulkan SDK 1.1.126.0, Windows 10. У меня включено расширение устройства VK_KHR_MULTIVIEW_EXTENSION_NAME.

...