mirror of https://github.com/bjornbytes/lovr.git
WIP OpenXR layout transitions;
This commit is contained in:
parent
7ceefcf4c2
commit
a23f0351cc
|
@ -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);
|
bool gpu_texture_init_view(gpu_texture* texture, gpu_texture_view_info* info);
|
||||||
void gpu_texture_destroy(gpu_texture* texture);
|
void gpu_texture_destroy(gpu_texture* texture);
|
||||||
gpu_texture* gpu_surface_acquire(void);
|
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
|
// Sampler
|
||||||
|
|
||||||
|
|
|
@ -706,6 +706,56 @@ gpu_texture* gpu_surface_acquire(void) {
|
||||||
return &state.surfaceTextures[state.currentSurfaceTexture];
|
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
|
// Sampler
|
||||||
|
|
||||||
bool gpu_sampler_init(gpu_sampler* sampler, gpu_sampler_info* info) {
|
bool gpu_sampler_init(gpu_sampler* sampler, gpu_sampler_info* info) {
|
||||||
|
|
|
@ -62,6 +62,7 @@ struct Buffer {
|
||||||
|
|
||||||
struct Texture {
|
struct Texture {
|
||||||
uint32_t ref;
|
uint32_t ref;
|
||||||
|
uint32_t xrTick;
|
||||||
gpu_texture* gpu;
|
gpu_texture* gpu;
|
||||||
gpu_texture* renderView;
|
gpu_texture* renderView;
|
||||||
Material* material;
|
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.
|
// finish. In between, the 'flush' cache is flushed and the 'clear' cache is cleared.
|
||||||
gpu_barrier* barrier = &barriers[sync->lastWriteIndex];
|
gpu_barrier* barrier = &barriers[sync->lastWriteIndex];
|
||||||
|
|
||||||
// Only the first write in a pass is considered, because each pass can only perform one type
|
// Only the first write in a pass is considered for a barrier (and there's no intra-pass sync)
|
||||||
// of write to a resource, and there is not currently any intra-pass synchronization.
|
|
||||||
if (sync->lastWriteIndex == i + 1) {
|
if (sync->lastWriteIndex == i + 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -939,6 +939,16 @@ void lovrGraphicsSubmit(Pass** passes, uint32_t count) {
|
||||||
for (uint32_t i = 0; i < count; i++) {
|
for (uint32_t i = 0; i < count; i++) {
|
||||||
for (uint32_t j = 0; j < passes[i]->access.length; j++) {
|
for (uint32_t j = 0; j < passes[i]->access.length; j++) {
|
||||||
passes[i]->access.data[j].sync->lastWriteIndex = 0;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -212,6 +212,7 @@ typedef struct {
|
||||||
uint32_t samples;
|
uint32_t samples;
|
||||||
uint32_t usage;
|
uint32_t usage;
|
||||||
bool srgb;
|
bool srgb;
|
||||||
|
bool xr;
|
||||||
uintptr_t handle;
|
uintptr_t handle;
|
||||||
uint32_t imageCount;
|
uint32_t imageCount;
|
||||||
struct Image** images;
|
struct Image** images;
|
||||||
|
|
|
@ -918,7 +918,8 @@ static void openxr_start(void) {
|
||||||
.mipmaps = 1,
|
.mipmaps = 1,
|
||||||
.samples = 1,
|
.samples = 1,
|
||||||
.usage = TEXTURE_RENDER | TEXTURE_SAMPLE,
|
.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.actionSet) xrDestroyActionSet(state.actionSet);
|
||||||
if (state.swapchain) xrDestroySwapchain(state.swapchain);
|
if (state.swapchain) xrDestroySwapchain(state.swapchain);
|
||||||
if (state.referenceSpace) xrDestroySpace(state.referenceSpace);
|
if (state.referenceSpace) xrDestroySpace(state.referenceSpace);
|
||||||
if (state.session) xrEndSession(state.session);
|
if (state.session) xrDestroySession(state.session);
|
||||||
if (state.instance) xrDestroyInstance(state.instance);
|
if (state.instance) xrDestroyInstance(state.instance);
|
||||||
memset(&state, 0, sizeof(state));
|
memset(&state, 0, sizeof(state));
|
||||||
}
|
}
|
||||||
|
@ -1666,12 +1667,8 @@ static bool openxr_animate(Device device, Model* model) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static Texture* openxr_getTexture(void) {
|
static Texture* openxr_getTexture(void) {
|
||||||
return state.began && state.frameState.shouldRender ? state.textures[state.textureIndex] : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Pass* openxr_getPass(void) {
|
|
||||||
if (state.began) {
|
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 };
|
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 };
|
XrSwapchainImageWaitInfo waitInfo = { XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO, .timeout = XR_INFINITE_DURATION };
|
||||||
XR(xrAcquireSwapchainImage(state.swapchain, NULL, &state.textureIndex));
|
XR(xrAcquireSwapchainImage(state.swapchain, NULL, &state.textureIndex));
|
||||||
XR(xrWaitSwapchainImage(state.swapchain, &waitInfo));
|
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);
|
lovrPassReset(state.pass);
|
||||||
|
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
|
|
Loading…
Reference in New Issue