WIP OpenXR layout transitions;

This commit is contained in:
bjorn 2022-08-05 18:36:51 -07:00
parent 7ceefcf4c2
commit a23f0351cc
5 changed files with 85 additions and 10 deletions

View File

@ -143,6 +143,8 @@ bool gpu_texture_init(gpu_texture* texture, gpu_texture_info* info);
bool gpu_texture_init_view(gpu_texture* texture, gpu_texture_view_info* info);
void gpu_texture_destroy(gpu_texture* texture);
gpu_texture* gpu_surface_acquire(void);
void gpu_xr_acquire(gpu_stream* stream, gpu_texture* texture);
void gpu_xr_release(gpu_stream* stream, gpu_texture* texture);
// Sampler

View File

@ -706,6 +706,56 @@ gpu_texture* gpu_surface_acquire(void) {
return &state.surfaceTextures[state.currentSurfaceTexture];
}
void gpu_xr_acquire(gpu_stream* stream, gpu_texture* texture) {
if (texture->layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { // TODO depth
return;
}
VkImageMemoryBarrier transition = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.srcAccessMask = 0,
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.newLayout = texture->layout,
.image = texture->handle,
.subresourceRange.aspectMask = texture->aspect,
.subresourceRange.baseMipLevel = 0,
.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS,
.subresourceRange.baseArrayLayer = 0,
.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS
};
VkPipelineStageFlags prev = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
VkPipelineStageFlags next = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
vkCmdPipelineBarrier(stream->commands, prev, next, 0, 0, NULL, 0, NULL, 1, &transition);
}
void gpu_xr_release(gpu_stream* stream, gpu_texture* texture) {
if (texture->layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { // TODO depth
return;
}
VkImageMemoryBarrier transition = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
.dstAccessMask = 0,
.oldLayout = texture->layout,
.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
.image = texture->handle,
.subresourceRange.aspectMask = texture->aspect,
.subresourceRange.baseMipLevel = 0,
.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS,
.subresourceRange.baseArrayLayer = 0,
.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS
};
VkPipelineStageFlags prev = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
VkPipelineStageFlags next = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
vkCmdPipelineBarrier(stream->commands, prev, next, 0, 0, NULL, 0, NULL, 1, &transition);
}
// Sampler
bool gpu_sampler_init(gpu_sampler* sampler, gpu_sampler_info* info) {

View File

@ -62,6 +62,7 @@ struct Buffer {
struct Texture {
uint32_t ref;
uint32_t xrTick;
gpu_texture* gpu;
gpu_texture* renderView;
Material* material;
@ -872,8 +873,7 @@ void lovrGraphicsSubmit(Pass** passes, uint32_t count) {
// finish. In between, the 'flush' cache is flushed and the 'clear' cache is cleared.
gpu_barrier* barrier = &barriers[sync->lastWriteIndex];
// Only the first write in a pass is considered, because each pass can only perform one type
// of write to a resource, and there is not currently any intra-pass synchronization.
// Only the first write in a pass is considered for a barrier (and there's no intra-pass sync)
if (sync->lastWriteIndex == i + 1) {
continue;
}
@ -939,6 +939,16 @@ void lovrGraphicsSubmit(Pass** passes, uint32_t count) {
for (uint32_t i = 0; i < count; i++) {
for (uint32_t j = 0; j < passes[i]->access.length; j++) {
passes[i]->access.data[j].sync->lastWriteIndex = 0;
// OpenXR swapchain texture layout transitions >__>
Texture* texture = passes[i]->access.data[j].texture;
if (texture && texture->info.xr && texture->xrTick != state.tick) {
gpu_xr_acquire(streams[0], texture->gpu);
gpu_xr_release(streams[total - 1], texture->gpu);
texture->xrTick = state.tick;
}
}
}

View File

@ -212,6 +212,7 @@ typedef struct {
uint32_t samples;
uint32_t usage;
bool srgb;
bool xr;
uintptr_t handle;
uint32_t imageCount;
struct Image** images;

View File

@ -918,7 +918,8 @@ static void openxr_start(void) {
.mipmaps = 1,
.samples = 1,
.usage = TEXTURE_RENDER | TEXTURE_SAMPLE,
.handle = (uintptr_t) images[i].image
.handle = (uintptr_t) images[i].image,
.xr = true
});
}
@ -986,7 +987,7 @@ static void openxr_destroy(void) {
if (state.actionSet) xrDestroyActionSet(state.actionSet);
if (state.swapchain) xrDestroySwapchain(state.swapchain);
if (state.referenceSpace) xrDestroySpace(state.referenceSpace);
if (state.session) xrEndSession(state.session);
if (state.session) xrDestroySession(state.session);
if (state.instance) xrDestroyInstance(state.instance);
memset(&state, 0, sizeof(state));
}
@ -1666,12 +1667,8 @@ static bool openxr_animate(Device device, Model* model) {
}
static Texture* openxr_getTexture(void) {
return state.began && state.frameState.shouldRender ? state.textures[state.textureIndex] : NULL;
}
static Pass* openxr_getPass(void) {
if (state.began) {
return state.frameState.shouldRender ? state.pass : NULL;
return state.frameState.shouldRender ? state.textures[state.textureIndex] : NULL;
}
XrFrameBeginInfo beginfo = { .type = XR_TYPE_FRAME_BEGIN_INFO };
@ -1685,7 +1682,22 @@ static Pass* openxr_getPass(void) {
XrSwapchainImageWaitInfo waitInfo = { XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO, .timeout = XR_INFINITE_DURATION };
XR(xrAcquireSwapchainImage(state.swapchain, NULL, &state.textureIndex));
XR(xrWaitSwapchainImage(state.swapchain, &waitInfo));
lovrPassSetTarget(state.pass, &state.textures[state.textureIndex], NULL);
return state.textures[state.textureIndex];
}
static Pass* openxr_getPass(void) {
if (state.began) {
return state.frameState.shouldRender ? state.pass : NULL;
}
Texture* texture = openxr_getTexture();
if (!texture) {
return NULL;
}
lovrPassSetTarget(state.pass, &texture, NULL);
lovrPassReset(state.pass);
uint32_t count;