mirror of https://github.com/bjornbytes/lovr.git
Fix automipmap synchronization;
This commit is contained in:
parent
e4024d82c4
commit
1c48578e95
|
@ -547,7 +547,8 @@ typedef enum {
|
|||
GPU_PHASE_DEPTH_EARLY = (1 << 6),
|
||||
GPU_PHASE_DEPTH_LATE = (1 << 7),
|
||||
GPU_PHASE_COLOR = (1 << 8),
|
||||
GPU_PHASE_TRANSFER = (1 << 9)
|
||||
GPU_PHASE_TRANSFER = (1 << 9),
|
||||
GPU_PHASE_ALL = (1 << 10)
|
||||
} gpu_phase;
|
||||
|
||||
typedef enum {
|
||||
|
@ -564,8 +565,8 @@ typedef enum {
|
|||
GPU_CACHE_COLOR_WRITE = (1 << 10),
|
||||
GPU_CACHE_TRANSFER_READ = (1 << 11),
|
||||
GPU_CACHE_TRANSFER_WRITE = (1 << 12),
|
||||
GPU_CACHE_WRITE = GPU_CACHE_STORAGE_WRITE | GPU_CACHE_DEPTH_WRITE | GPU_CACHE_COLOR_WRITE | GPU_CACHE_TRANSFER_WRITE,
|
||||
GPU_CACHE_READ = ~GPU_CACHE_WRITE
|
||||
GPU_CACHE_WRITE_MASK = GPU_CACHE_STORAGE_WRITE | GPU_CACHE_DEPTH_WRITE | GPU_CACHE_COLOR_WRITE | GPU_CACHE_TRANSFER_WRITE,
|
||||
GPU_CACHE_READ_MASK = ~GPU_CACHE_WRITE_MASK
|
||||
} gpu_cache;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -194,7 +194,7 @@ static void expunge(void);
|
|||
static VkFramebuffer getCachedFramebuffer(VkRenderPass pass, VkImageView images[9], uint32_t imageCount, uint32_t size[2]);
|
||||
static VkImageLayout getNaturalLayout(uint32_t usage, VkImageAspectFlags aspect);
|
||||
static VkFormat convertFormat(gpu_texture_format format, int colorspace);
|
||||
static VkPipelineStageFlags convertPhase(gpu_phase phase);
|
||||
static VkPipelineStageFlags convertPhase(gpu_phase phase, bool dst);
|
||||
static VkAccessFlags convertCache(gpu_cache cache);
|
||||
static VkBool32 relay(VkDebugUtilsMessageSeverityFlagBitsEXT severity, VkDebugUtilsMessageTypeFlagsEXT flags, const VkDebugUtilsMessengerCallbackDataEXT* data, void* userdata);
|
||||
static void nickname(void* object, VkObjectType type, const char* name);
|
||||
|
@ -1796,8 +1796,8 @@ void gpu_sync(gpu_stream* stream, gpu_barrier* barriers, uint32_t count) {
|
|||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
gpu_barrier* barrier = &barriers[i];
|
||||
src |= convertPhase(barrier->prev);
|
||||
dst |= convertPhase(barrier->next);
|
||||
src |= convertPhase(barrier->prev, false);
|
||||
dst |= convertPhase(barrier->next, true);
|
||||
memoryBarrier.srcAccessMask |= convertCache(barrier->flush);
|
||||
memoryBarrier.dstAccessMask |= convertCache(barrier->clear);
|
||||
}
|
||||
|
@ -2704,7 +2704,7 @@ static VkFormat convertFormat(gpu_texture_format format, int colorspace) {
|
|||
return formats[format][colorspace];
|
||||
}
|
||||
|
||||
static VkPipelineStageFlags convertPhase(gpu_phase phase) {
|
||||
static VkPipelineStageFlags convertPhase(gpu_phase phase, bool dst) {
|
||||
VkPipelineStageFlags flags = 0;
|
||||
if (phase & GPU_PHASE_INDIRECT) flags |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT;
|
||||
if (phase & GPU_PHASE_INPUT_INDEX) flags |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
|
||||
|
@ -2716,6 +2716,7 @@ static VkPipelineStageFlags convertPhase(gpu_phase phase) {
|
|||
if (phase & GPU_PHASE_DEPTH_LATE) flags |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
||||
if (phase & GPU_PHASE_COLOR) flags |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
if (phase & GPU_PHASE_TRANSFER) flags |= VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
if (phase & GPU_PHASE_ALL) flags |= dst ? VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT : VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
|
|
@ -877,26 +877,24 @@ void lovrGraphicsSubmit(Pass** passes, uint32_t count) {
|
|||
if (canvas->mipmap) {
|
||||
bool depth = pass->depth && pass->depth->info.mipmaps > 1;
|
||||
|
||||
// Waits for the external subpass dependency layout transition to finish before mipmapping
|
||||
gpu_barrier barrier = {
|
||||
.prev = GPU_PHASE_COLOR | (depth ? GPU_PHASE_DEPTH_LATE : 0),
|
||||
.prev = GPU_PHASE_ALL,
|
||||
.next = GPU_PHASE_TRANSFER,
|
||||
.flush = GPU_CACHE_COLOR_WRITE | (depth ? GPU_CACHE_DEPTH_WRITE : 0),
|
||||
.flush = 0,
|
||||
.clear = GPU_CACHE_TRANSFER_READ
|
||||
};
|
||||
|
||||
// Wait for rendering to finish before mipmapping
|
||||
gpu_sync(pass->stream, &barrier, 1);
|
||||
|
||||
for (uint32_t t = 0; t < canvas->count; t++) {
|
||||
if (pass->color[t]->info.mipmaps > 1) {
|
||||
mipmapTexture(pass->stream, pass->color[t], 0, ~0u);
|
||||
trackTexture(pass, pass->color[t], GPU_PHASE_TRANSFER, GPU_CACHE_TRANSFER_WRITE);
|
||||
}
|
||||
}
|
||||
|
||||
if (depth) {
|
||||
mipmapTexture(pass->stream, pass->depth, 0, ~0u);
|
||||
trackTexture(pass, pass->depth, GPU_PHASE_TRANSFER, GPU_CACHE_TRANSFER_WRITE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -963,8 +961,8 @@ void lovrGraphicsSubmit(Pass** passes, uint32_t count) {
|
|||
// - does clear the write cache
|
||||
// - resets the 'last write' and clears pendingReads
|
||||
|
||||
uint32_t read = access->cache & GPU_CACHE_READ;
|
||||
uint32_t write = access->cache & GPU_CACHE_WRITE;
|
||||
uint32_t read = access->cache & GPU_CACHE_READ_MASK;
|
||||
uint32_t write = access->cache & GPU_CACHE_WRITE_MASK;
|
||||
uint32_t newReads = read & ~sync->pendingReads;
|
||||
bool hasNewReads = newReads || (access->phase & ~sync->readPhase);
|
||||
bool readAfterWrite = read && sync->pendingWrite && hasNewReads;
|
||||
|
@ -1000,6 +998,21 @@ void lovrGraphicsSubmit(Pass** passes, uint32_t count) {
|
|||
sync->lastWriteIndex = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// For automipmapping, the final write to the target is a transfer, not an attachment write
|
||||
if (pass->info.type == PASS_RENDER && pass->info.canvas.mipmap) {
|
||||
for (uint32_t t = 0; t < pass->info.canvas.count; t++) {
|
||||
if (pass->color[t]->info.mipmaps > 1) {
|
||||
pass->color[t]->sync.writePhase = GPU_PHASE_TRANSFER;
|
||||
pass->color[t]->sync.pendingWrite = GPU_CACHE_TRANSFER_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
if (pass->depth && pass->depth->info.mipmaps > 1) {
|
||||
pass->depth->sync.writePhase = GPU_PHASE_TRANSFER;
|
||||
pass->depth->sync.pendingWrite = GPU_CACHE_TRANSFER_WRITE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
|
|
Loading…
Reference in New Issue