OSDN Git Service

Set render targets correctly when drawing
authorChris Forbes <chrisforbes@google.com>
Thu, 21 Feb 2019 22:58:28 +0000 (14:58 -0800)
committerChris Forbes <chrisforbes@google.com>
Sat, 23 Feb 2019 02:27:50 +0000 (02:27 +0000)
There are some horrible hacks in here -- the draw command should not be
doing anywhere near this much work -- but this gets us to first
triangle.

Passes: dEQP-VK.api.smoke.triangle

Bug: b/124177079
Change-Id: I4240cb8cdce2f4bbb804e88e66d1695ab0b0e41e
Reviewed-on: https://swiftshader-review.googlesource.com/c/25212
Tested-by: Chris Forbes <chrisforbes@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>

src/Device/PixelProcessor.cpp
src/Device/PixelProcessor.hpp
src/Vulkan/VkCommandBuffer.cpp
src/Vulkan/VkFramebuffer.cpp
src/Vulkan/VkFramebuffer.hpp
src/Vulkan/VkImage.hpp
src/Vulkan/VkImageView.cpp
src/Vulkan/VkImageView.hpp

index cc86873..1996bb6 100644 (file)
@@ -97,6 +97,11 @@ namespace sw
                context->renderTargetLayer[index] = layer;
        }
 
+       Surface *PixelProcessor::getRenderTarget(int index)
+       {
+               return context->renderTarget[index];
+       }
+
        void PixelProcessor::setDepthBuffer(Surface *depthBuffer, unsigned int layer)
        {
                context->depthBuffer = depthBuffer;
index 536f324..e51fa18 100644 (file)
@@ -153,6 +153,7 @@ namespace sw
                void lockUniformBuffers(byte** u, sw::Resource* uniformBuffers[]);
 
                void setRenderTarget(int index, Surface *renderTarget, unsigned int layer = 0);
+               Surface *getRenderTarget(int index);
                void setDepthBuffer(Surface *depthBuffer, unsigned int layer = 0);
                void setStencilBuffer(Surface *stencilBuffer, unsigned int layer = 0);
 
index f659a01..4578fe5 100644 (file)
@@ -17,6 +17,7 @@
 #include "VkEvent.hpp"
 #include "VkFramebuffer.hpp"
 #include "VkImage.hpp"
+#include "VkImageView.hpp"
 #include "VkPipeline.hpp"
 #include "VkRenderPass.hpp"
 #include "Device/Renderer.hpp"
@@ -164,6 +165,16 @@ struct Draw : public CommandBuffer::Command
                executionState.renderer->setViewport(pipeline->getViewport());
                executionState.renderer->setBlendConstant(pipeline->getBlendConstants());
 
+               for (auto i = 0u; i < executionState.renderPass->getCurrentSubpass().colorAttachmentCount; i++)
+               {
+                       auto attachmentReference = executionState.renderPass->getCurrentSubpass().pColorAttachments[i];
+                       if (attachmentReference.attachment != VK_ATTACHMENT_UNUSED)
+                       {
+                               auto attachment = executionState.renderPassFramebuffer->getAttachment(attachmentReference.attachment);
+                               executionState.renderer->setRenderTarget(i, attachment->asSurface(), 0);
+                       }
+               }
+
                const uint32_t primitiveCount = pipeline->computePrimitiveCount(vertexCount);
                const uint32_t lastInstance = firstInstance + instanceCount - 1;
                for(uint32_t instance = firstInstance; instance <= lastInstance; instance++)
@@ -171,6 +182,22 @@ struct Draw : public CommandBuffer::Command
                        executionState.renderer->setInstanceID(instance);
                        executionState.renderer->draw(context.drawType, 0, primitiveCount);
                }
+
+               // Wait for completion. We should be able to get rid of this eventually.
+               executionState.renderer->synchronize();
+
+               // Renderer has finished touching the color attachments; destroy the temporary Surface objects.
+               // We shouldn't need to do any of this at draw time.
+               for (auto i = 0u; i < executionState.renderPass->getCurrentSubpass().colorAttachmentCount; i++)
+               {
+                       auto attachmentReference = executionState.renderPass->getCurrentSubpass().pColorAttachments[i];
+                       if (attachmentReference.attachment != VK_ATTACHMENT_UNUSED)
+                       {
+                               auto surface = executionState.renderer->getRenderTarget(i);
+                               executionState.renderer->setRenderTarget(i, nullptr, 0);
+                               delete surface;
+                       }
+               }
        }
 
        uint32_t vertexCount;
index 1adadce..1d0f81d 100644 (file)
@@ -94,6 +94,11 @@ void Framebuffer::clear(const VkClearAttachment& attachment, const VkClearRect&
        }
 }
 
+ImageView *Framebuffer::getAttachment(uint32_t index) const
+{
+       return attachments[index];
+}
+
 size_t Framebuffer::ComputeRequiredAllocationSize(const VkFramebufferCreateInfo* pCreateInfo)
 {
        return pCreateInfo->attachmentCount * sizeof(void*);
index 2e16e99..c615763 100644 (file)
@@ -34,6 +34,7 @@ public:
        void clear(const VkClearAttachment& attachment, const VkClearRect& rect);
 
        static size_t ComputeRequiredAllocationSize(const VkFramebufferCreateInfo* pCreateInfo);
+       ImageView *getAttachment(uint32_t index) const;
 
 private:
        RenderPass* renderPass;
index eb8cc94..68ca016 100644 (file)
@@ -48,6 +48,7 @@ public:
        void clear(const VkClearValue& clearValue, const VkRect2D& renderArea, const VkImageSubresourceRange& subresourceRange);
        void clear(const VkClearColorValue& color, const VkImageSubresourceRange& subresourceRange);
        void clear(const VkClearDepthStencilValue& color, const VkImageSubresourceRange& subresourceRange);
+       sw::Surface* asSurface(const VkImageAspectFlags& flags, uint32_t mipLevel, uint32_t layer) const;
 
        VkImageType              getImageType() const { return imageType; }
        VkFormat                 getFormat() const { return format; }
@@ -74,7 +75,6 @@ private:
        VkFormat getClearFormat() const;
        void clear(void* pixelData, VkFormat format, const VkImageSubresourceRange& subresourceRange, VkImageAspectFlags aspectMask);
        void clear(void* pixelData, VkFormat format, const VkRect2D& renderArea, const VkImageSubresourceRange& subresourceRange, VkImageAspectFlags aspectMask);
-       sw::Surface* asSurface(const VkImageAspectFlags& flags, uint32_t mipLevel, uint32_t layer) const;
 
        DeviceMemory*            deviceMemory = nullptr;
        VkDeviceSize             memoryOffset = 0;
index 630ad49..c0ac795 100644 (file)
@@ -119,4 +119,9 @@ void ImageView::clear(const VkClearValue& clearValue, const VkImageAspectFlags a
        image->clear(clearValue, renderArea.rect, sr);
 }
 
+sw::Surface *ImageView::asSurface()
+{
+       return image->asSurface(subresourceRange.aspectMask, subresourceRange.baseArrayLayer, subresourceRange.baseMipLevel);
+}
+
 }
\ No newline at end of file
index 26be628..8eb3ee5 100644 (file)
@@ -34,6 +34,8 @@ public:
        void clear(const VkClearValue& clearValues, const VkImageAspectFlags aspectMask, const VkRect2D& renderArea);
        void clear(const VkClearValue& clearValue, const VkImageAspectFlags aspectMask, const VkClearRect& renderArea);
 
+       sw::Surface *asSurface();
+
 private:
        bool                       imageTypesMatch(VkImageType imageType) const;