| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrVkGpu.h" | 8 #include "GrVkGpu.h" |
| 9 | 9 |
| 10 #include "GrContextOptions.h" | 10 #include "GrContextOptions.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 #include "GrVkRenderPass.h" | 27 #include "GrVkRenderPass.h" |
| 28 #include "GrVkResourceProvider.h" | 28 #include "GrVkResourceProvider.h" |
| 29 #include "GrVkTexture.h" | 29 #include "GrVkTexture.h" |
| 30 #include "GrVkTextureRenderTarget.h" | 30 #include "GrVkTextureRenderTarget.h" |
| 31 #include "GrVkTransferBuffer.h" | 31 #include "GrVkTransferBuffer.h" |
| 32 #include "GrVkVertexBuffer.h" | 32 #include "GrVkVertexBuffer.h" |
| 33 | 33 |
| 34 #include "SkConfig8888.h" | 34 #include "SkConfig8888.h" |
| 35 | 35 |
| 36 #include "vk/GrVkInterface.h" | 36 #include "vk/GrVkInterface.h" |
| 37 #include "vk/GrVkTypes.h" |
| 37 | 38 |
| 38 #define VK_CALL(X) GR_VK_CALL(this->vkInterface(), X) | 39 #define VK_CALL(X) GR_VK_CALL(this->vkInterface(), X) |
| 39 #define VK_CALL_RET(RET, X) GR_VK_CALL_RET(this->vkInterface(), RET, X) | 40 #define VK_CALL_RET(RET, X) GR_VK_CALL_RET(this->vkInterface(), RET, X) |
| 40 #define VK_CALL_ERRCHECK(X) GR_VK_CALL_ERRCHECK(this->vkInterface(), X) | 41 #define VK_CALL_ERRCHECK(X) GR_VK_CALL_ERRCHECK(this->vkInterface(), X) |
| 41 | 42 |
| 42 //////////////////////////////////////////////////////////////////////////////// | 43 //////////////////////////////////////////////////////////////////////////////// |
| 43 // Stuff used to set up a GrVkGpu secrectly for now. | 44 // Stuff used to set up a GrVkGpu secrectly for now. |
| 44 | 45 |
| 45 // For now the VkGpuCreate is using the same signature as GL. This is mostly for
ease of | 46 // For now the VkGpuCreate is using the same signature as GL. This is mostly for
ease of |
| 46 // hiding this code from offical skia. In the end the VkGpuCreate will not take
a GrBackendContext | 47 // hiding this code from offical skia. In the end the VkGpuCreate will not take
a GrBackendContext |
| (...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 | 576 |
| 576 if (0 == desc.fTextureHandle) { | 577 if (0 == desc.fTextureHandle) { |
| 577 return nullptr; | 578 return nullptr; |
| 578 } | 579 } |
| 579 | 580 |
| 580 int maxSize = this->caps()->maxTextureSize(); | 581 int maxSize = this->caps()->maxTextureSize(); |
| 581 if (desc.fWidth > maxSize || desc.fHeight > maxSize) { | 582 if (desc.fWidth > maxSize || desc.fHeight > maxSize) { |
| 582 return nullptr; | 583 return nullptr; |
| 583 } | 584 } |
| 584 | 585 |
| 585 // TODO: determine what format Chrome will actually send us and turn it into
a Resource | 586 const GrVkTextureInfo* info = reinterpret_cast<const GrVkTextureInfo*>(desc.
fTextureHandle); |
| 586 GrVkImage::Resource* imageRsrc = reinterpret_cast<GrVkImage::Resource*>(desc
.fTextureHandle); | |
| 587 | 587 |
| 588 GrGpuResource::LifeCycle lifeCycle = (kAdopt_GrWrapOwnership == ownership) | 588 GrGpuResource::LifeCycle lifeCycle = (kAdopt_GrWrapOwnership == ownership) |
| 589 ? GrGpuResource::kAdopted_LifeCycle | 589 ? GrGpuResource::kAdopted_LifeCycle |
| 590 : GrGpuResource::kBorrowed_LifeCycle; | 590 : GrGpuResource::kBorrowed_LifeCycle; |
| 591 | 591 |
| 592 GrSurfaceDesc surfDesc; | 592 GrSurfaceDesc surfDesc; |
| 593 // next line relies on GrBackendTextureDesc's flags matching GrTexture's | 593 // next line relies on GrBackendTextureDesc's flags matching GrTexture's |
| 594 surfDesc.fFlags = (GrSurfaceFlags)desc.fFlags; | 594 surfDesc.fFlags = (GrSurfaceFlags)desc.fFlags; |
| 595 surfDesc.fWidth = desc.fWidth; | 595 surfDesc.fWidth = desc.fWidth; |
| 596 surfDesc.fHeight = desc.fHeight; | 596 surfDesc.fHeight = desc.fHeight; |
| 597 surfDesc.fConfig = desc.fConfig; | 597 surfDesc.fConfig = desc.fConfig; |
| 598 surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount()
); | 598 surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount()
); |
| 599 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFla
g); | 599 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFla
g); |
| 600 // In GL, Chrome assumes all textures are BottomLeft | 600 // In GL, Chrome assumes all textures are BottomLeft |
| 601 // In VK, we don't have this restriction | 601 // In VK, we don't have this restriction |
| 602 surfDesc.fOrigin = resolve_origin(desc.fOrigin); | 602 surfDesc.fOrigin = resolve_origin(desc.fOrigin); |
| 603 | 603 |
| 604 GrVkTexture* texture = nullptr; | 604 GrVkTexture* texture = nullptr; |
| 605 if (renderTarget) { | 605 if (renderTarget) { |
| 606 texture = GrVkTextureRenderTarget::CreateWrappedTextureRenderTarget(this
, surfDesc, | 606 texture = GrVkTextureRenderTarget::CreateWrappedTextureRenderTarget(this
, surfDesc, |
| 607 life
Cycle, format, | 607 life
Cycle, format, |
| 608 imag
eRsrc); | 608 info
); |
| 609 } else { | 609 } else { |
| 610 texture = GrVkTexture::CreateWrappedTexture(this, surfDesc, lifeCycle, f
ormat, imageRsrc); | 610 texture = GrVkTexture::CreateWrappedTexture(this, surfDesc, lifeCycle, f
ormat, |
| 611 info); |
| 611 } | 612 } |
| 612 if (!texture) { | 613 if (!texture) { |
| 613 return nullptr; | 614 return nullptr; |
| 614 } | 615 } |
| 615 | 616 |
| 616 return texture; | 617 return texture; |
| 617 } | 618 } |
| 618 | 619 |
| 619 GrRenderTarget* GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDe
sc& wrapDesc, | 620 GrRenderTarget* GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDe
sc& wrapDesc, |
| 620 GrWrapOwnership ownership) { | 621 GrWrapOwnership ownership) { |
| 621 | 622 |
| 622 // TODO: determine what format Chrome will actually send us and turn it into
a Resource | 623 const GrVkTextureInfo* info = |
| 623 GrVkImage::Resource* imageRsrc = | 624 reinterpret_cast<const GrVkTextureInfo*>(wrapDesc.fRenderTargetHandle); |
| 624 reinterpret_cast<GrVkImage::Resource*>(wrapDesc.fRenderTargetHandle); | |
| 625 | 625 |
| 626 GrGpuResource::LifeCycle lifeCycle = (kAdopt_GrWrapOwnership == ownership) | 626 GrGpuResource::LifeCycle lifeCycle = (kAdopt_GrWrapOwnership == ownership) |
| 627 ? GrGpuResource::kAdopted_LifeCycle | 627 ? GrGpuResource::kAdopted_LifeCycle |
| 628 : GrGpuResource::kBorrowed_LifeCycle; | 628 : GrGpuResource::kBorrowed_LifeCycle; |
| 629 | 629 |
| 630 GrSurfaceDesc desc; | 630 GrSurfaceDesc desc; |
| 631 desc.fConfig = wrapDesc.fConfig; | 631 desc.fConfig = wrapDesc.fConfig; |
| 632 desc.fFlags = kCheckAllocation_GrSurfaceFlag; | 632 desc.fFlags = kCheckAllocation_GrSurfaceFlag; |
| 633 desc.fWidth = wrapDesc.fWidth; | 633 desc.fWidth = wrapDesc.fWidth; |
| 634 desc.fHeight = wrapDesc.fHeight; | 634 desc.fHeight = wrapDesc.fHeight; |
| 635 desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount()
); | 635 desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount()
); |
| 636 | 636 |
| 637 desc.fOrigin = resolve_origin(wrapDesc.fOrigin); | 637 desc.fOrigin = resolve_origin(wrapDesc.fOrigin); |
| 638 | 638 |
| 639 GrVkRenderTarget* tgt = GrVkRenderTarget::CreateWrappedRenderTarget(this, de
sc, | 639 GrVkRenderTarget* tgt = GrVkRenderTarget::CreateWrappedRenderTarget(this, de
sc, |
| 640 lifeCycl
e, imageRsrc); | 640 lifeCycl
e, |
| 641 info); |
| 641 if (tgt && wrapDesc.fStencilBits) { | 642 if (tgt && wrapDesc.fStencilBits) { |
| 642 if (!createStencilAttachmentForRenderTarget(tgt, desc.fWidth, desc.fHeig
ht)) { | 643 if (!createStencilAttachmentForRenderTarget(tgt, desc.fWidth, desc.fHeig
ht)) { |
| 643 tgt->unref(); | 644 tgt->unref(); |
| 644 return nullptr; | 645 return nullptr; |
| 645 } | 646 } |
| 646 } | 647 } |
| 647 return tgt; | 648 return tgt; |
| 648 } | 649 } |
| 649 | 650 |
| 650 //////////////////////////////////////////////////////////////////////////////// | 651 //////////////////////////////////////////////////////////////////////////////// |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 737 return 0; | 738 return 0; |
| 738 } | 739 } |
| 739 | 740 |
| 740 VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT; | 741 VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT; |
| 741 usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; | 742 usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; |
| 742 usageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; | 743 usageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; |
| 743 | 744 |
| 744 VkFlags memProps = (srcData && linearTiling) ? VK_MEMORY_PROPERTY_HOST_VISIB
LE_BIT : | 745 VkFlags memProps = (srcData && linearTiling) ? VK_MEMORY_PROPERTY_HOST_VISIB
LE_BIT : |
| 745 VK_MEMORY_PROPERTY_DEVICE_LOC
AL_BIT; | 746 VK_MEMORY_PROPERTY_DEVICE_LOC
AL_BIT; |
| 746 | 747 |
| 747 // This ImageDesc refers to the texture that will be read by the client. Thu
s even if msaa is | 748 VkImage image = 0; |
| 748 // requested, this ImageDesc describes the resolved texutre. Therefore we al
ways have samples set | 749 VkDeviceMemory alloc; |
| 749 // to 1. | |
| 750 GrVkImage::ImageDesc imageDesc; | |
| 751 imageDesc.fImageType = VK_IMAGE_TYPE_2D; | |
| 752 imageDesc.fFormat = pixelFormat; | |
| 753 imageDesc.fWidth = w; | |
| 754 imageDesc.fHeight = h; | |
| 755 imageDesc.fLevels = 1; | |
| 756 imageDesc.fSamples = 1; | |
| 757 imageDesc.fImageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TI
LING_OPTIMAL; | |
| 758 imageDesc.fUsageFlags = usageFlags; | |
| 759 imageDesc.fMemProps = memProps; | |
| 760 | 750 |
| 761 const GrVkImage::Resource* imageRsrc = GrVkImage::CreateResource(this, image
Desc); | 751 VkImageTiling imageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE
_TILING_OPTIMAL; |
| 762 if (!imageRsrc) { | 752 VkImageLayout initialLayout = (VK_IMAGE_TILING_LINEAR == imageTiling) |
| 753 ? VK_IMAGE_LAYOUT_PREINITIALIZED |
| 754 : VK_IMAGE_LAYOUT_UNDEFINED; |
| 755 |
| 756 // Create Image |
| 757 VkSampleCountFlagBits vkSamples; |
| 758 if (!GrSampleCountToVkSampleCount(1, &vkSamples)) { |
| 763 return 0; | 759 return 0; |
| 764 } | 760 } |
| 765 | 761 |
| 762 const VkImageCreateInfo imageCreateInfo = { |
| 763 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // sType |
| 764 NULL, // pNext |
| 765 0, // VkImageCreateFlags |
| 766 VK_IMAGE_TYPE_2D, // VkImageType |
| 767 pixelFormat, // VkFormat |
| 768 { w, h, 1 }, // VkExtent3D |
| 769 1, // mipLevels |
| 770 1, // arrayLayers |
| 771 vkSamples, // samples |
| 772 imageTiling, // VkImageTiling |
| 773 usageFlags, // VkImageUsageFlags |
| 774 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode |
| 775 0, // queueFamilyCount |
| 776 0, // pQueueFamilyIndices |
| 777 initialLayout // initialLayout |
| 778 }; |
| 779 |
| 780 GR_VK_CALL_ERRCHECK(this->vkInterface(), CreateImage(this->device(), &imageC
reateInfo, nullptr, &image)); |
| 781 |
| 782 if (!GrVkMemory::AllocAndBindImageMemory(this, image, memProps, &alloc)) { |
| 783 VK_CALL(DestroyImage(this->device(), image, nullptr)); |
| 784 return 0; |
| 785 } |
| 786 |
| 766 if (srcData) { | 787 if (srcData) { |
| 767 if (linearTiling) { | 788 if (linearTiling) { |
| 768 const VkImageSubresource subres = { | 789 const VkImageSubresource subres = { |
| 769 VK_IMAGE_ASPECT_COLOR_BIT, | 790 VK_IMAGE_ASPECT_COLOR_BIT, |
| 770 0, // mipLevel | 791 0, // mipLevel |
| 771 0, // arraySlice | 792 0, // arraySlice |
| 772 }; | 793 }; |
| 773 VkSubresourceLayout layout; | 794 VkSubresourceLayout layout; |
| 774 VkResult err; | 795 VkResult err; |
| 775 | 796 |
| 776 const GrVkInterface* interface = this->vkInterface(); | 797 VK_CALL(GetImageSubresourceLayout(fDevice, image, &subres, &layout))
; |
| 777 | |
| 778 GR_VK_CALL(interface, GetImageSubresourceLayout(fDevice, | |
| 779 imageRsrc->fImage, | |
| 780 &subres, | |
| 781 &layout)); | |
| 782 | 798 |
| 783 void* mapPtr; | 799 void* mapPtr; |
| 784 err = GR_VK_CALL(interface, MapMemory(fDevice, | 800 err = VK_CALL(MapMemory(fDevice, alloc, 0, layout.rowPitch * h, 0, &
mapPtr)); |
| 785 imageRsrc->fAlloc, | |
| 786 0, | |
| 787 layout.rowPitch * h, | |
| 788 0, | |
| 789 &mapPtr)); | |
| 790 if (err) { | 801 if (err) { |
| 791 imageRsrc->unref(this); | 802 VK_CALL(FreeMemory(this->device(), alloc, nullptr)); |
| 803 VK_CALL(DestroyImage(this->device(), image, nullptr)); |
| 792 return 0; | 804 return 0; |
| 793 } | 805 } |
| 794 | 806 |
| 795 size_t bpp = GrBytesPerPixel(config); | 807 size_t bpp = GrBytesPerPixel(config); |
| 796 size_t rowCopyBytes = bpp * w; | 808 size_t rowCopyBytes = bpp * w; |
| 797 // If there is no padding on dst (layout.rowPitch) we can do a singl
e memcopy. | 809 // If there is no padding on dst (layout.rowPitch) we can do a singl
e memcopy. |
| 798 // This assumes the srcData comes in with no padding. | 810 // This assumes the srcData comes in with no padding. |
| 799 if (rowCopyBytes == layout.rowPitch) { | 811 if (rowCopyBytes == layout.rowPitch) { |
| 800 memcpy(mapPtr, srcData, rowCopyBytes * h); | 812 memcpy(mapPtr, srcData, rowCopyBytes * h); |
| 801 } else { | 813 } else { |
| 802 SkRectMemcpy(mapPtr, static_cast<size_t>(layout.rowPitch), srcDa
ta, w, rowCopyBytes, | 814 SkRectMemcpy(mapPtr, static_cast<size_t>(layout.rowPitch), srcDa
ta, w, rowCopyBytes, |
| 803 h); | 815 h); |
| 804 } | 816 } |
| 805 GR_VK_CALL(interface, UnmapMemory(fDevice, imageRsrc->fAlloc)); | 817 VK_CALL(UnmapMemory(fDevice, alloc)); |
| 806 } else { | 818 } else { |
| 807 // TODO: Add support for copying to optimal tiling | 819 // TODO: Add support for copying to optimal tiling |
| 808 SkASSERT(false); | 820 SkASSERT(false); |
| 809 } | 821 } |
| 810 } | 822 } |
| 811 | 823 |
| 812 return (GrBackendObject)imageRsrc; | 824 GrVkTextureInfo* info = new GrVkTextureInfo; |
| 825 info->fImage = image; |
| 826 info->fAlloc = alloc; |
| 827 info->fImageTiling = imageTiling; |
| 828 |
| 829 return (GrBackendObject)info; |
| 813 } | 830 } |
| 814 | 831 |
| 815 bool GrVkGpu::isTestingOnlyBackendTexture(GrBackendObject id) const { | 832 bool GrVkGpu::isTestingOnlyBackendTexture(GrBackendObject id) const { |
| 816 GrVkImage::Resource* backend = reinterpret_cast<GrVkImage::Resource*>(id); | 833 const GrVkTextureInfo* backend = reinterpret_cast<const GrVkTextureInfo*>(id
); |
| 817 | 834 |
| 818 if (backend && backend->fImage && backend->fAlloc) { | 835 if (backend && backend->fImage && backend->fAlloc) { |
| 819 VkMemoryRequirements req; | 836 VkMemoryRequirements req; |
| 820 memset(&req, 0, sizeof(req)); | 837 memset(&req, 0, sizeof(req)); |
| 821 GR_VK_CALL(this->vkInterface(), GetImageMemoryRequirements(fDevice, | 838 GR_VK_CALL(this->vkInterface(), GetImageMemoryRequirements(fDevice, |
| 822 backend->fIma
ge, | 839 backend->fIma
ge, |
| 823 &req)); | 840 &req)); |
| 824 // TODO: find a better check | 841 // TODO: find a better check |
| 825 // This will probably fail with a different driver | 842 // This will probably fail with a different driver |
| 826 return (req.size > 0) && (req.size <= 8192 * 8192); | 843 return (req.size > 0) && (req.size <= 8192 * 8192); |
| 827 } | 844 } |
| 828 | 845 |
| 829 return false; | 846 return false; |
| 830 } | 847 } |
| 831 | 848 |
| 832 void GrVkGpu::deleteTestingOnlyBackendTexture(GrBackendObject id, bool abandon)
{ | 849 void GrVkGpu::deleteTestingOnlyBackendTexture(GrBackendObject id, bool abandon)
{ |
| 833 GrVkImage::Resource* backend = reinterpret_cast<GrVkImage::Resource*>(id); | 850 const GrVkTextureInfo* backend = reinterpret_cast<const GrVkTextureInfo*>(id
); |
| 834 | 851 |
| 835 if (backend) { | 852 if (backend) { |
| 836 if (!abandon) { | 853 if (!abandon) { |
| 837 backend->unref(this); | 854 VK_CALL(FreeMemory(this->device(), backend->fAlloc, nullptr)); |
| 838 } else { | 855 VK_CALL(DestroyImage(this->device(), backend->fImage, nullptr)); |
| 839 backend->unrefAndAbandon(); | |
| 840 } | 856 } |
| 857 delete backend; |
| 841 } | 858 } |
| 842 } | 859 } |
| 843 | 860 |
| 844 //////////////////////////////////////////////////////////////////////////////// | 861 //////////////////////////////////////////////////////////////////////////////// |
| 845 | 862 |
| 846 void GrVkGpu::addMemoryBarrier(VkPipelineStageFlags srcStageMask, | 863 void GrVkGpu::addMemoryBarrier(VkPipelineStageFlags srcStageMask, |
| 847 VkPipelineStageFlags dstStageMask, | 864 VkPipelineStageFlags dstStageMask, |
| 848 bool byRegion, | 865 bool byRegion, |
| 849 VkMemoryBarrier* barrier) const { | 866 VkMemoryBarrier* barrier) const { |
| 850 SkASSERT(fCurrentCmdBuffer); | 867 SkASSERT(fCurrentCmdBuffer); |
| (...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1410 int set_a_break_pt_here = 9; | 1427 int set_a_break_pt_here = 9; |
| 1411 aglSwapBuffers(aglGetCurrentContext()); | 1428 aglSwapBuffers(aglGetCurrentContext()); |
| 1412 #elif defined(SK_BUILD_FOR_WIN32) | 1429 #elif defined(SK_BUILD_FOR_WIN32) |
| 1413 SwapBuf(); | 1430 SwapBuf(); |
| 1414 int set_a_break_pt_here = 9; | 1431 int set_a_break_pt_here = 9; |
| 1415 SwapBuf(); | 1432 SwapBuf(); |
| 1416 #endif | 1433 #endif |
| 1417 #endif | 1434 #endif |
| 1418 } | 1435 } |
| 1419 | 1436 |
| OLD | NEW |