Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/doitsujin/dxvk.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Ashton <joshua@froggi.es>2021-08-11 12:39:19 +0300
committerJoshua Ashton <joshua@froggi.es>2021-08-11 12:48:28 +0300
commite325c9eae77340cbc885777902943a6f7ecc4c92 (patch)
tree31d7a85d70d3ccadbd8854eb49d9f4b6a88f408c
parent2c8099adf1842bc4caff31f605bfb023b2c087be (diff)
[d3d9] Fix upload race with default image mappingd3d9-fix-default-image-mapping
Fixes a Wine test
-rw-r--r--src/d3d9/d3d9_device.cpp132
1 files changed, 67 insertions, 65 deletions
diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp
index 3fae30c0..69b4aa4c 100644
--- a/src/d3d9/d3d9_device.cpp
+++ b/src/d3d9/d3d9_device.cpp
@@ -4183,79 +4183,81 @@ namespace dxvk {
else {
physSlice = mappedBuffer->getSliceHandle();
- if (unlikely(wasWrittenByGPU)) {
- Rc<DxvkImage> resourceImage = pResource->GetImage();
-
- Rc<DxvkImage> mappedImage = resourceImage->info().sampleCount != 1
- ? pResource->GetResolveImage()
- : std::move(resourceImage);
-
- // When using any map mode which requires the image contents
- // to be preserved, and if the GPU has write access to the
- // image, copy the current image contents into the buffer.
- auto subresourceLayers = vk::makeSubresourceLayers(subresource);
-
- // We need to resolve this, some games
- // lock MSAA render targets even though
- // that's entirely illegal and they explicitly
- // tell us that they do NOT want to lock them...
- if (resourceImage != nullptr) {
+ if (!alloced) {
+ if (unlikely(wasWrittenByGPU)) {
+ Rc<DxvkImage> resourceImage = pResource->GetImage();
+
+ Rc<DxvkImage> mappedImage = resourceImage->info().sampleCount != 1
+ ? pResource->GetResolveImage()
+ : std::move(resourceImage);
+
+ // When using any map mode which requires the image contents
+ // to be preserved, and if the GPU has write access to the
+ // image, copy the current image contents into the buffer.
+ auto subresourceLayers = vk::makeSubresourceLayers(subresource);
+
+ // We need to resolve this, some games
+ // lock MSAA render targets even though
+ // that's entirely illegal and they explicitly
+ // tell us that they do NOT want to lock them...
+ if (resourceImage != nullptr) {
+ EmitCs([
+ cMainImage = resourceImage,
+ cResolveImage = mappedImage,
+ cSubresource = subresourceLayers
+ ] (DxvkContext* ctx) {
+ VkImageResolve region;
+ region.srcSubresource = cSubresource;
+ region.srcOffset = VkOffset3D { 0, 0, 0 };
+ region.dstSubresource = cSubresource;
+ region.dstOffset = VkOffset3D { 0, 0, 0 };
+ region.extent = cMainImage->mipLevelExtent(cSubresource.mipLevel);
+
+ if (cSubresource.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
+ ctx->resolveImage(
+ cResolveImage, cMainImage, region,
+ cMainImage->info().format);
+ }
+ else {
+ ctx->resolveDepthStencilImage(
+ cResolveImage, cMainImage, region,
+ VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR,
+ VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR);
+ }
+ });
+ }
+
+ VkFormat packedFormat = GetPackedDepthStencilFormat(desc.Format);
+
EmitCs([
- cMainImage = resourceImage,
- cResolveImage = mappedImage,
- cSubresource = subresourceLayers
+ cImageBuffer = mappedBuffer,
+ cImage = std::move(mappedImage),
+ cSubresources = subresourceLayers,
+ cLevelExtent = levelExtent,
+ cPackedFormat = packedFormat
] (DxvkContext* ctx) {
- VkImageResolve region;
- region.srcSubresource = cSubresource;
- region.srcOffset = VkOffset3D { 0, 0, 0 };
- region.dstSubresource = cSubresource;
- region.dstOffset = VkOffset3D { 0, 0, 0 };
- region.extent = cMainImage->mipLevelExtent(cSubresource.mipLevel);
-
- if (cSubresource.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
- ctx->resolveImage(
- cResolveImage, cMainImage, region,
- cMainImage->info().format);
- }
- else {
- ctx->resolveDepthStencilImage(
- cResolveImage, cMainImage, region,
- VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR,
- VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR);
+ if (cSubresources.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
+ ctx->copyImageToBuffer(cImageBuffer, 0, 4, 0,
+ cImage, cSubresources, VkOffset3D { 0, 0, 0 },
+ cLevelExtent);
+ } else {
+ // Copying DS to a packed buffer is only supported for D24S8 and D32S8
+ // right now so the 4 byte row alignment is guaranteed by the format size
+ ctx->copyDepthStencilImageToPackedBuffer(
+ cImageBuffer, 0,
+ VkOffset2D { 0, 0 },
+ VkExtent2D { cLevelExtent.width, cLevelExtent.height },
+ cImage, cSubresources,
+ VkOffset2D { 0, 0 },
+ VkExtent2D { cLevelExtent.width, cLevelExtent.height },
+ cPackedFormat);
}
});
}
- VkFormat packedFormat = GetPackedDepthStencilFormat(desc.Format);
-
- EmitCs([
- cImageBuffer = mappedBuffer,
- cImage = std::move(mappedImage),
- cSubresources = subresourceLayers,
- cLevelExtent = levelExtent,
- cPackedFormat = packedFormat
- ] (DxvkContext* ctx) {
- if (cSubresources.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
- ctx->copyImageToBuffer(cImageBuffer, 0, 4, 0,
- cImage, cSubresources, VkOffset3D { 0, 0, 0 },
- cLevelExtent);
- } else {
- // Copying DS to a packed buffer is only supported for D24S8 and D32S8
- // right now so the 4 byte row alignment is guaranteed by the format size
- ctx->copyDepthStencilImageToPackedBuffer(
- cImageBuffer, 0,
- VkOffset2D { 0, 0 },
- VkExtent2D { cLevelExtent.width, cLevelExtent.height },
- cImage, cSubresources,
- VkOffset2D { 0, 0 },
- VkExtent2D { cLevelExtent.width, cLevelExtent.height },
- cPackedFormat);
- }
- });
-
if (!WaitForResource(mappedBuffer, Flags))
return D3DERR_WASSTILLDRAWING;
- } else if (alloced) {
+ } else {
// If we are a new alloc, and we weren't written by the GPU
// that means that we are a newly initialized
// texture, and hence can just memset -> 0 and