Remove MAP_UNSYNCHRONIZED_BIT from GL persistent maps

* This is required because we add MAP_READ_BIT and the spec doesn't allow maps
  that are both unsynchronized and reading.
* Also add a test for unsynchronised persistent maps, and update the
  GL_Buffer_Updates test to not require a reference image but check each quad
  individually for the expected colour.
This commit is contained in:
baldurk
2019-05-22 12:04:33 +01:00
parent 09d7387db2
commit 2573dffde7
4 changed files with 111 additions and 29 deletions
@@ -2033,6 +2033,9 @@ void *WrappedOpenGL::glMapNamedBufferRangeEXT(GLuint buffer, GLintptr offset, GL
// it.
access &= ~(GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_INVALIDATE_RANGE_BIT);
// also can't be unsynchronized for some reason
access &= ~GL_MAP_UNSYNCHRONIZED_BIT;
directMap = true;
persistent = true;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

+66 -27
View File
@@ -74,32 +74,34 @@ void main()
Vec4f green(0.0f, 1.0f, 0.0f, 1.0f);
// clang-format explodes on these for some reason
#define TEST_CASES() \
BUFFER_TEST(BufferDataImmutable) \
BUFFER_TEST(BufferStorageImmutable) \
BUFFER_TEST(BufferDataOrphanedOnce) \
BUFFER_TEST(BufferDataOrphanedMany) \
BUFFER_TEST(BufferDataOrphanedPerFrame) \
BUFFER_TEST(BufferDataUpdatedOnce) \
BUFFER_TEST(BufferDataUpdatedMany) \
BUFFER_TEST(BufferDataUpdatedPerFrame) \
BUFFER_TEST(BufferStorageUpdatedOnce) \
BUFFER_TEST(BufferStorageUpdatedMany) \
BUFFER_TEST(BufferStorageUpdatedPerFrame) \
BUFFER_TEST(SingleMapBufferReadback) \
BUFFER_TEST(SingleMapBufferRangeReadback) \
BUFFER_TEST(CoherentMapBufferRangeReadback) \
BUFFER_TEST(CleanBufferMapWriteInvalidate) \
BUFFER_TEST(CleanBufferMapWriteNonInvalidate) \
BUFFER_TEST(DirtyBufferMapWriteInvalidate) \
BUFFER_TEST(DirtyBufferMapWriteNonInvalidate) \
BUFFER_TEST(CleanBufferMapFlushExplicit) \
BUFFER_TEST(DirtyBufferMapFlushExplicit) \
BUFFER_TEST(CoherentMapWrite) \
BUFFER_TEST(CoherentMapWriteInvalidateRange) \
BUFFER_TEST(CoherentMapWriteInvalidateBuffer) \
BUFFER_TEST(NonCoherentMapFlush) \
BUFFER_TEST(OffsetMapWrite) \
#define TEST_CASES() \
BUFFER_TEST(BufferDataImmutable) \
BUFFER_TEST(BufferStorageImmutable) \
BUFFER_TEST(BufferDataOrphanedOnce) \
BUFFER_TEST(BufferDataOrphanedMany) \
BUFFER_TEST(BufferDataOrphanedPerFrame) \
BUFFER_TEST(BufferDataUpdatedOnce) \
BUFFER_TEST(BufferDataUpdatedMany) \
BUFFER_TEST(BufferDataUpdatedPerFrame) \
BUFFER_TEST(BufferStorageUpdatedOnce) \
BUFFER_TEST(BufferStorageUpdatedMany) \
BUFFER_TEST(BufferStorageUpdatedPerFrame) \
BUFFER_TEST(SingleMapBufferReadback) \
BUFFER_TEST(SingleMapBufferRangeReadback) \
BUFFER_TEST(CoherentMapBufferRangeReadback) \
BUFFER_TEST(CleanBufferMapWriteInvalidate) \
BUFFER_TEST(CleanBufferMapWriteNonInvalidate) \
BUFFER_TEST(DirtyBufferMapWriteInvalidate) \
BUFFER_TEST(DirtyBufferMapWriteNonInvalidate) \
BUFFER_TEST(CleanBufferMapFlushExplicit) \
BUFFER_TEST(DirtyBufferMapFlushExplicit) \
BUFFER_TEST(CoherentMapWrite) \
BUFFER_TEST(CoherentMapWriteInvalidateRange) \
BUFFER_TEST(CoherentMapWriteInvalidateBuffer) \
BUFFER_TEST(CoherentMapWriteUnsynchronised) \
BUFFER_TEST(NonCoherentMapFlush) \
BUFFER_TEST(NonCoherentMapFlushUnsynchronised) \
BUFFER_TEST(OffsetMapWrite) \
BUFFER_TEST(OffsetMapFlush)
#undef BUFFER_TEST
@@ -226,6 +228,14 @@ void main()
GL_UNIFORM_BUFFER, 0, sizeof(Vec4f), GL_MAP_COHERENT_BIT | GL_MAP_PERSISTENT_BIT |
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
glBindBuffer(GL_UNIFORM_BUFFER, buffers[CoherentMapWriteUnsynchronised]);
glBufferStorage(GL_UNIFORM_BUFFER, sizeof(Vec4f), &red,
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
ptrs[CoherentMapWriteUnsynchronised] = (Vec4f *)glMapBufferRange(
GL_UNIFORM_BUFFER, 0, sizeof(Vec4f),
GL_MAP_COHERENT_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
glBindBuffer(GL_UNIFORM_BUFFER, buffers[NonCoherentMapFlush]);
glBufferStorage(GL_UNIFORM_BUFFER, sizeof(Vec4f), &red, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
@@ -233,6 +243,14 @@ void main()
GL_UNIFORM_BUFFER, 0, sizeof(Vec4f),
GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
glBindBuffer(GL_UNIFORM_BUFFER, buffers[NonCoherentMapFlushUnsynchronised]);
glBufferStorage(GL_UNIFORM_BUFFER, sizeof(Vec4f), &red, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
ptrs[NonCoherentMapFlushUnsynchronised] =
(Vec4f *)glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(Vec4f),
GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT |
GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
glBindBuffer(GL_UNIFORM_BUFFER, buffers[OffsetMapWrite]);
glBufferStorage(GL_UNIFORM_BUFFER, sizeof(Vec4f), &cyan,
GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT);
@@ -362,12 +380,21 @@ void main()
memcpy(ptrs[CoherentMapWriteInvalidateRange], &red, sizeof(Vec4f));
if(ptrs[CoherentMapWriteInvalidateBuffer])
memcpy(ptrs[CoherentMapWriteInvalidateBuffer], &red, sizeof(Vec4f));
if(ptrs[CoherentMapWriteUnsynchronised])
memcpy(ptrs[CoherentMapWriteUnsynchronised], &red, sizeof(Vec4f));
glBindBuffer(GL_UNIFORM_BUFFER, buffers[NonCoherentMapFlush]);
if(ptrs[NonCoherentMapFlush])
memcpy(ptrs[NonCoherentMapFlush], &red, sizeof(Vec4f));
glFlushMappedBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(float) * 4);
glBindBuffer(GL_UNIFORM_BUFFER, buffers[NonCoherentMapFlushUnsynchronised]);
if(ptrs[NonCoherentMapFlushUnsynchronised])
memcpy(ptrs[NonCoherentMapFlushUnsynchronised], &red, sizeof(Vec4f));
glFlushMappedBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(float) * 4);
glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
glBindBuffer(GL_UNIFORM_BUFFER, buffers[OffsetMapWrite]);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(Vec4f), &cyan);
@@ -401,10 +428,13 @@ void main()
GL_DEBUG_SEVERITY_HIGH, -1, TestNames[buf]);
if(buf == CoherentMapWrite || buf == CoherentMapWriteInvalidateRange ||
buf == CoherentMapWriteInvalidateBuffer)
buf == CoherentMapWriteInvalidateBuffer || buf == CoherentMapWriteUnsynchronised)
{
if(ptrs[buf])
memcpy(ptrs[buf], &green, sizeof(Vec4f));
if(buf == CoherentMapWriteUnsynchronised)
glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
}
if(buf == NonCoherentMapFlush)
@@ -415,6 +445,15 @@ void main()
glFlushMappedBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(float) * 4);
}
if(buf == NonCoherentMapFlushUnsynchronised)
{
glBindBuffer(GL_UNIFORM_BUFFER, buffers[NonCoherentMapFlushUnsynchronised]);
if(ptrs[NonCoherentMapFlushUnsynchronised])
memcpy(ptrs[NonCoherentMapFlushUnsynchronised], &green, sizeof(Vec4f));
glFlushMappedBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(float) * 4);
glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
}
if(buf == SingleMapBufferReadback)
{
glBindBuffer(GL_COPY_READ_BUFFER, buffers[buf]);
+42 -2
View File
@@ -7,7 +7,46 @@ class GL_Buffer_Updates(rdtest.TestCase):
return rdtest.run_and_capture("demos_x64", "GL_Buffer_Updates", 5)
def check_capture(self):
self.check_final_backbuffer()
# Make an output so we can pick pixels
out: rd.ReplayOutput = self.controller.CreateOutput(rd.CreateHeadlessWindowingData(100, 100), rd.ReplayOutputType.Texture)
self.check(out is not None)
tex = rd.TextureDisplay()
# At each draw, the centre pixel of the viewport should be green
draw = self.get_first_draw()
while draw is not None:
self.controller.SetFrameEvent(draw.eventId, False)
if draw.flags & rd.DrawFlags.Drawcall:
tex.resourceId = self.controller.GetPipelineState().GetOutputTargets()[0].resourceId
out.SetTextureDisplay(tex)
view: rd.Viewport = self.controller.GetPipelineState().GetViewport(0)
x,y = int(view.x + view.width / 2), int(view.y + view.height / 2)
# convert to top-left co-ordinates for use with PickPixel
y = self.get_texture(tex.resourceId).height - y
picked: rd.PixelValue = out.PickPixel(tex.resourceId, False, x, y, 0, 0, 0)
if not rdtest.value_compare(picked.floatValue, [0.0, 1.0, 0.0, 1.0]):
raise rdtest.TestFailureException("Picked value {} at {} doesn't match expected green".format(picked.floatValue, (x,y)))
draw = draw.next
rdtest.log.success("Draws are all green")
# Now save the backbuffer to disk
ref_path = rdtest.get_tmp_path('backbuffer.png')
save_data = rd.TextureSave()
save_data.resourceId = tex.resourceId
save_data.destType = rd.FileType.PNG
self.controller.SaveTexture(save_data, ref_path)
# Open the capture and grab the thumbnail, check that it is all green too (dirty way of verifying we didn't
# break in-app updates but somehow end up with the right data)
@@ -29,10 +68,11 @@ class GL_Buffer_Updates(rdtest.TestCase):
f.write(thumb.data)
# The original thumbnail should also be identical, since we have the uncompressed extended thumbnail.
ref_path = self.get_ref_path('backbuffer.png')
if not rdtest.png_compare(tmp_path, ref_path):
raise rdtest.TestFailureException("Reference backbuffer and thumbnail image differ", tmp_path, ref_path)
rdtest.log.success("Thumbnail is identical to reference")
out.Shutdown()