| // Copyright 2016 The SwiftShader Authors. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #ifndef sw_Surface_hpp |
| #define sw_Surface_hpp |
| |
| #include "Color.hpp" |
| #include "Device/Config.hpp" |
| #include "System/Resource.hpp" |
| #include <vulkan/vulkan.h> |
| |
| namespace sw |
| { |
| class Resource; |
| |
| template <typename T> struct RectT |
| { |
| RectT() {} |
| RectT(T x0i, T y0i, T x1i, T y1i) : x0(x0i), y0(y0i), x1(x1i), y1(y1i) {} |
| |
| void clip(T minX, T minY, T maxX, T maxY) |
| { |
| x0 = clamp(x0, minX, maxX); |
| y0 = clamp(y0, minY, maxY); |
| x1 = clamp(x1, minX, maxX); |
| y1 = clamp(y1, minY, maxY); |
| } |
| |
| T width() const { return x1 - x0; } |
| T height() const { return y1 - y0; } |
| |
| T x0; // Inclusive |
| T y0; // Inclusive |
| T x1; // Exclusive |
| T y1; // Exclusive |
| }; |
| |
| typedef RectT<int> Rect; |
| typedef RectT<float> RectF; |
| |
| template<typename T> struct SliceRectT : public RectT<T> |
| { |
| SliceRectT() : slice(0) {} |
| SliceRectT(const RectT<T>& rect) : RectT<T>(rect), slice(0) {} |
| SliceRectT(const RectT<T>& rect, int s) : RectT<T>(rect), slice(s) {} |
| SliceRectT(T x0, T y0, T x1, T y1, int s) : RectT<T>(x0, y0, x1, y1), slice(s) {} |
| int slice; |
| }; |
| |
| typedef SliceRectT<int> SliceRect; |
| typedef SliceRectT<float> SliceRectF; |
| |
| enum Format : unsigned char |
| { |
| FORMAT_NULL = VK_FORMAT_UNDEFINED, |
| // VK_FORMAT_R4G4_UNORM_PACK8, |
| // VK_FORMAT_R4G4B4A4_UNORM_PACK16, |
| FORMAT_R4G4B4A4 = VK_FORMAT_B4G4R4A4_UNORM_PACK16, // Mandatory |
| FORMAT_R5G6B5 = VK_FORMAT_R5G6B5_UNORM_PACK16, // Mandatory |
| // VK_FORMAT_B5G6R5_UNORM_PACK16, |
| FORMAT_R5G5B5A1 = VK_FORMAT_R5G5B5A1_UNORM_PACK16, |
| // VK_FORMAT_B5G5R5A1_UNORM_PACK16, |
| FORMAT_A1R5G5B5 = VK_FORMAT_A1R5G5B5_UNORM_PACK16, // Mandatory |
| FORMAT_R8 = VK_FORMAT_R8_UNORM, // Mandatory |
| FORMAT_R8_SNORM = VK_FORMAT_R8_SNORM, // Mandatory |
| // VK_FORMAT_R8_USCALED, |
| // VK_FORMAT_R8_SSCALED, |
| FORMAT_R8UI = VK_FORMAT_R8_UINT, // Mandatory |
| FORMAT_R8I = VK_FORMAT_R8_SINT, // Mandatory |
| // VK_FORMAT_R8_SRGB, |
| FORMAT_G8R8 = VK_FORMAT_R8G8_UNORM, // Mandatory |
| FORMAT_G8R8_SNORM = VK_FORMAT_R8G8_SNORM, // Mandatory |
| // VK_FORMAT_R8G8_USCALED, |
| // VK_FORMAT_R8G8_SSCALED, |
| FORMAT_G8R8UI = VK_FORMAT_R8G8_UINT, // Mandatory |
| FORMAT_G8R8I = VK_FORMAT_R8G8_SINT, // Mandatory |
| // VK_FORMAT_R8G8_SRGB, |
| // VK_FORMAT_R8G8B8_UNORM, |
| // VK_FORMAT_R8G8B8_SNORM, |
| // VK_FORMAT_R8G8B8_USCALED, |
| // VK_FORMAT_R8G8B8_SSCALED, |
| // VK_FORMAT_R8G8B8_UINT, |
| // VK_FORMAT_R8G8B8_SINT, |
| // VK_FORMAT_R8G8B8_SRGB, |
| // VK_FORMAT_B8G8R8_UNORM, |
| // VK_FORMAT_B8G8R8_SNORM, |
| // VK_FORMAT_B8G8R8_USCALED, |
| // VK_FORMAT_B8G8R8_SSCALED, |
| // VK_FORMAT_B8G8R8_UINT, |
| // VK_FORMAT_B8G8R8_SINT, |
| // VK_FORMAT_B8G8R8_SRGB, |
| FORMAT_A8B8G8R8 = VK_FORMAT_R8G8B8A8_UNORM, // Mandatory |
| FORMAT_A8B8G8R8_SNORM = VK_FORMAT_R8G8B8A8_SNORM, // Mandatory |
| // VK_FORMAT_R8G8B8A8_USCALED, |
| // VK_FORMAT_R8G8B8A8_SSCALED, |
| FORMAT_A8B8G8R8UI = VK_FORMAT_R8G8B8A8_UINT, // Mandatory |
| FORMAT_A8B8G8R8I = VK_FORMAT_R8G8B8A8_SINT, // Mandatory |
| FORMAT_SRGB8_A8 = VK_FORMAT_R8G8B8A8_SRGB, // Mandatory |
| FORMAT_A8R8G8B8 = VK_FORMAT_B8G8R8A8_UNORM, // Mandatory |
| // VK_FORMAT_B8G8R8A8_SNORM, |
| // VK_FORMAT_B8G8R8A8_USCALED, |
| // VK_FORMAT_B8G8R8A8_SSCALED, |
| // VK_FORMAT_B8G8R8A8_UINT, |
| // VK_FORMAT_B8G8R8A8_SINT, |
| // VK_FORMAT_B8G8R8A8_SRGB, // TODO: Mandatory |
| // VK_FORMAT_A8B8G8R8_UNORM_PACK32, // TODO: Mandatory |
| // VK_FORMAT_A8B8G8R8_SNORM_PACK32, // TODO: Mandatory |
| // VK_FORMAT_A8B8G8R8_USCALED_PACK32, |
| // VK_FORMAT_A8B8G8R8_SSCALED_PACK32, |
| // VK_FORMAT_A8B8G8R8_UINT_PACK32, // TODO: Mandatory |
| // VK_FORMAT_A8B8G8R8_SINT_PACK32, // TODO: Mandatory |
| // VK_FORMAT_A8B8G8R8_SRGB_PACK32, // TODO: Mandatory |
| FORMAT_A2R10G10B10 = VK_FORMAT_A2R10G10B10_UNORM_PACK32, |
| // VK_FORMAT_A2R10G10B10_SNORM_PACK32, |
| // VK_FORMAT_A2R10G10B10_USCALED_PACK32, |
| // VK_FORMAT_A2R10G10B10_SSCALED_PACK32, |
| // VK_FORMAT_A2R10G10B10_UINT_PACK32, |
| // VK_FORMAT_A2R10G10B10_SINT_PACK32, |
| FORMAT_A2B10G10R10 = VK_FORMAT_A2B10G10R10_UNORM_PACK32, // Mandatory |
| // VK_FORMAT_A2B10G10R10_SNORM_PACK32, |
| // VK_FORMAT_A2B10G10R10_USCALED_PACK32, |
| // VK_FORMAT_A2B10G10R10_SSCALED_PACK32, |
| FORMAT_A2B10G10R10UI = VK_FORMAT_A2B10G10R10_UINT_PACK32, // Mandatory |
| // VK_FORMAT_A2B10G10R10_SINT_PACK32, |
| // VK_FORMAT_R16_UNORM, // Mandatory (Vertex buffer only) |
| // VK_FORMAT_R16_SNORM, // Mandatory (Vertex buffer only) |
| // VK_FORMAT_R16_USCALED, |
| // VK_FORMAT_R16_SSCALED, |
| FORMAT_R16UI = VK_FORMAT_R16_UINT, // Mandatory |
| FORMAT_R16I = VK_FORMAT_R16_SINT, // Mandatory |
| FORMAT_R16F = VK_FORMAT_R16_SFLOAT, // Mandatory |
| FORMAT_G16R16 = VK_FORMAT_R16G16_UNORM, // Mandatory (Vertex buffer only) |
| // VK_FORMAT_R16G16_SNORM, // Mandatory (Vertex buffer only) |
| // VK_FORMAT_R16G16_USCALED, |
| // VK_FORMAT_R16G16_SSCALED, |
| FORMAT_G16R16UI = VK_FORMAT_R16G16_UINT, // Mandatory |
| FORMAT_G16R16I = VK_FORMAT_R16G16_SINT, // Mandatory |
| FORMAT_G16R16F = VK_FORMAT_R16G16_SFLOAT, // Mandatory |
| // VK_FORMAT_R16G16B16_UNORM, |
| // VK_FORMAT_R16G16B16_SNORM, |
| // VK_FORMAT_R16G16B16_USCALED, |
| // VK_FORMAT_R16G16B16_SSCALED, |
| // VK_FORMAT_R16G16B16_UINT, |
| // VK_FORMAT_R16G16B16_SINT, |
| // VK_FORMAT_R16G16B16_SFLOAT, |
| FORMAT_A16B16G16R16 = VK_FORMAT_R16G16B16A16_UNORM, // Mandatory (Vertex buffer only) |
| // VK_FORMAT_R16G16B16A16_SNORM, // Mandatory (Vertex buffer only) |
| // VK_FORMAT_R16G16B16A16_USCALED, |
| // VK_FORMAT_R16G16B16A16_SSCALED, |
| FORMAT_A16B16G16R16UI = VK_FORMAT_R16G16B16A16_UINT, // Mandatory |
| FORMAT_A16B16G16R16I = VK_FORMAT_R16G16B16A16_SINT, // Mandatory |
| FORMAT_A16B16G16R16F = VK_FORMAT_R16G16B16A16_SFLOAT, // Mandatory |
| FORMAT_R32UI = VK_FORMAT_R32_UINT, // Mandatory |
| FORMAT_R32I = VK_FORMAT_R32_SINT, // Mandatory |
| FORMAT_R32F = VK_FORMAT_R32_SFLOAT, // Mandatory |
| FORMAT_G32R32UI = VK_FORMAT_R32G32_UINT, // Mandatory |
| FORMAT_G32R32I = VK_FORMAT_R32G32_SINT, // Mandatory |
| FORMAT_G32R32F = VK_FORMAT_R32G32_SFLOAT, // Mandatory |
| // VK_FORMAT_R32G32B32_UINT, // Mandatory (Vertex buffer only) |
| // VK_FORMAT_R32G32B32_SINT, // Mandatory (Vertex buffer only) |
| // VK_FORMAT_R32G32B32_SFLOAT, // Mandatory (Vertex buffer only) |
| FORMAT_A32B32G32R32UI = VK_FORMAT_R32G32B32A32_UINT, // Mandatory |
| FORMAT_A32B32G32R32I = VK_FORMAT_R32G32B32A32_SINT, // Mandatory |
| FORMAT_A32B32G32R32F = VK_FORMAT_R32G32B32A32_SFLOAT, // Mandatory |
| // VK_FORMAT_R64_UINT, |
| // VK_FORMAT_R64_SINT, |
| // VK_FORMAT_R64_SFLOAT, |
| // VK_FORMAT_R64G64_UINT, |
| // VK_FORMAT_R64G64_SINT, |
| // VK_FORMAT_R64G64_SFLOAT, |
| // VK_FORMAT_R64G64B64_UINT, |
| // VK_FORMAT_R64G64B64_SINT, |
| // VK_FORMAT_R64G64B64_SFLOAT, |
| // VK_FORMAT_R64G64B64A64_UINT, |
| // VK_FORMAT_R64G64B64A64_SINT, |
| // VK_FORMAT_R64G64B64A64_SFLOAT, |
| // VK_FORMAT_B10G11R11_UFLOAT_PACK32, // TODO: Mandatory |
| // VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, // TODO: Mandatory |
| FORMAT_D16 = VK_FORMAT_D16_UNORM, // Mandatory |
| FORMAT_D24X8 = VK_FORMAT_X8_D24_UNORM_PACK32, // Feature specific |
| FORMAT_D32F = VK_FORMAT_D32_SFLOAT, // Mandatory |
| FORMAT_S8 = VK_FORMAT_S8_UINT, |
| // VK_FORMAT_D16_UNORM_S8_UINT, |
| FORMAT_D24S8 = VK_FORMAT_D24_UNORM_S8_UINT, // Feature specific |
| FORMAT_D32FS8 = VK_FORMAT_D32_SFLOAT_S8_UINT, // Feature specific |
| // VK_FORMAT_BC1_RGB_UNORM_BLOCK, // Feature specific |
| // VK_FORMAT_BC1_RGB_SRGB_BLOCK, // Feature specific |
| // VK_FORMAT_BC1_RGBA_UNORM_BLOCK, // Feature specific |
| // VK_FORMAT_BC1_RGBA_SRGB_BLOCK, // Feature specific |
| // VK_FORMAT_BC2_UNORM_BLOCK, // Feature specific |
| // VK_FORMAT_BC2_SRGB_BLOCK, // Feature specific |
| // VK_FORMAT_BC3_UNORM_BLOCK, // Feature specific |
| // VK_FORMAT_BC3_SRGB_BLOCK, // Feature specific |
| // VK_FORMAT_BC4_UNORM_BLOCK, // Feature specific |
| // VK_FORMAT_BC4_SNORM_BLOCK, // Feature specific |
| // VK_FORMAT_BC5_UNORM_BLOCK, // Feature specific |
| // VK_FORMAT_BC5_SNORM_BLOCK, // Feature specific |
| // VK_FORMAT_BC6H_UFLOAT_BLOCK, // Feature specific |
| // VK_FORMAT_BC6H_SFLOAT_BLOCK, // Feature specific |
| // VK_FORMAT_BC7_UNORM_BLOCK, // Feature specific |
| // VK_FORMAT_BC7_SRGB_BLOCK, // Feature specific |
| FORMAT_RGB8_ETC2 = VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, // Feature specific |
| FORMAT_SRGB8_ETC2 = VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, // Feature specific |
| FORMAT_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, // Feature specific |
| FORMAT_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, // Feature specific |
| FORMAT_RGBA8_ETC2_EAC = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, // Feature specific |
| FORMAT_SRGB8_ALPHA8_ETC2_EAC = VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, // Feature specific |
| FORMAT_R11_EAC = VK_FORMAT_EAC_R11_UNORM_BLOCK, // Feature specific |
| FORMAT_SIGNED_R11_EAC = VK_FORMAT_EAC_R11_SNORM_BLOCK, // Feature specific |
| FORMAT_RG11_EAC = VK_FORMAT_EAC_R11G11_UNORM_BLOCK, // Feature specific |
| FORMAT_SIGNED_RG11_EAC = VK_FORMAT_EAC_R11G11_SNORM_BLOCK, // Feature specific |
| FORMAT_RGBA_ASTC_4x4_KHR = VK_FORMAT_ASTC_4x4_UNORM_BLOCK, // Feature specific |
| FORMAT_SRGB8_ALPHA8_ASTC_4x4_KHR = VK_FORMAT_ASTC_4x4_SRGB_BLOCK, // Feature specific |
| FORMAT_RGBA_ASTC_5x4_KHR = VK_FORMAT_ASTC_5x4_UNORM_BLOCK, // Feature specific |
| FORMAT_SRGB8_ALPHA8_ASTC_5x4_KHR = VK_FORMAT_ASTC_5x4_SRGB_BLOCK, // Feature specific |
| FORMAT_RGBA_ASTC_5x5_KHR = VK_FORMAT_ASTC_5x5_UNORM_BLOCK, // Feature specific |
| FORMAT_SRGB8_ALPHA8_ASTC_5x5_KHR = VK_FORMAT_ASTC_5x5_SRGB_BLOCK, // Feature specific |
| FORMAT_RGBA_ASTC_6x5_KHR = VK_FORMAT_ASTC_6x5_UNORM_BLOCK, // Feature specific |
| FORMAT_SRGB8_ALPHA8_ASTC_6x5_KHR = VK_FORMAT_ASTC_6x5_SRGB_BLOCK, // Feature specific |
| FORMAT_RGBA_ASTC_6x6_KHR = VK_FORMAT_ASTC_6x6_UNORM_BLOCK, // Feature specific |
| FORMAT_SRGB8_ALPHA8_ASTC_6x6_KHR = VK_FORMAT_ASTC_6x6_SRGB_BLOCK, // Feature specific |
| FORMAT_RGBA_ASTC_8x5_KHR = VK_FORMAT_ASTC_8x5_UNORM_BLOCK, // Feature specific |
| FORMAT_SRGB8_ALPHA8_ASTC_8x5_KHR = VK_FORMAT_ASTC_8x5_SRGB_BLOCK, // Feature specific |
| FORMAT_RGBA_ASTC_8x6_KHR = VK_FORMAT_ASTC_8x6_UNORM_BLOCK, // Feature specific |
| FORMAT_SRGB8_ALPHA8_ASTC_8x6_KHR = VK_FORMAT_ASTC_8x6_SRGB_BLOCK, // Feature specific |
| FORMAT_RGBA_ASTC_8x8_KHR = VK_FORMAT_ASTC_8x8_UNORM_BLOCK, // Feature specific |
| FORMAT_SRGB8_ALPHA8_ASTC_8x8_KHR = VK_FORMAT_ASTC_8x8_SRGB_BLOCK, // Feature specific |
| FORMAT_RGBA_ASTC_10x5_KHR = VK_FORMAT_ASTC_10x5_UNORM_BLOCK, // Feature specific |
| FORMAT_SRGB8_ALPHA8_ASTC_10x5_KHR = VK_FORMAT_ASTC_10x5_SRGB_BLOCK, // Feature specific |
| FORMAT_RGBA_ASTC_10x6_KHR = VK_FORMAT_ASTC_10x6_UNORM_BLOCK, // Feature specific |
| FORMAT_SRGB8_ALPHA8_ASTC_10x6_KHR = VK_FORMAT_ASTC_10x6_SRGB_BLOCK, // Feature specific |
| FORMAT_RGBA_ASTC_10x8_KHR = VK_FORMAT_ASTC_10x8_UNORM_BLOCK, // Feature specific |
| FORMAT_SRGB8_ALPHA8_ASTC_10x8_KHR = VK_FORMAT_ASTC_10x8_SRGB_BLOCK, // Feature specific |
| FORMAT_RGBA_ASTC_10x10_KHR = VK_FORMAT_ASTC_10x10_UNORM_BLOCK, // Feature specific |
| FORMAT_SRGB8_ALPHA8_ASTC_10x10_KHR = VK_FORMAT_ASTC_10x10_SRGB_BLOCK, // Feature specific |
| FORMAT_RGBA_ASTC_12x10_KHR = VK_FORMAT_ASTC_12x10_UNORM_BLOCK, // Feature specific |
| FORMAT_SRGB8_ALPHA8_ASTC_12x10_KHR = VK_FORMAT_ASTC_12x10_SRGB_BLOCK, // Feature specific |
| FORMAT_RGBA_ASTC_12x12_KHR = VK_FORMAT_ASTC_12x12_UNORM_BLOCK, // Feature specific |
| FORMAT_SRGB8_ALPHA8_ASTC_12x12_KHR = VK_FORMAT_ASTC_12x12_SRGB_BLOCK, // Feature specific |
| |
| // EXTENSION FORMATS: |
| // IMPORTANT: if any of these formats are added, this enum needs |
| // to go from "unsigned char" to "unsigned int" and FORMAT_LAST |
| // below needs to be updated to take extensions into account. |
| |
| // VK_FORMAT_G8B8G8R8_422_UNORM, |
| // VK_FORMAT_B8G8R8G8_422_UNORM, |
| // VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, // TODO: Mandatory |
| // VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, // TODO: Mandatory |
| // VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM, |
| // VK_FORMAT_G8_B8R8_2PLANE_422_UNORM, |
| // VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM, |
| // VK_FORMAT_R10X6_UNORM_PACK16, |
| // VK_FORMAT_R10X6G10X6_UNORM_2PACK16, |
| // VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16, |
| // VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16, |
| // VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16, |
| // VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16, |
| // VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16, |
| // VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16, |
| // VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16, |
| // VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16, |
| // VK_FORMAT_R12X4_UNORM_PACK16, |
| // VK_FORMAT_R12X4G12X4_UNORM_2PACK16, |
| // VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16, |
| // VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16, |
| // VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16, |
| // VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16, |
| // VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16, |
| // VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16, |
| // VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16, |
| // VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16, |
| // VK_FORMAT_G16B16G16R16_422_UNORM, |
| // VK_FORMAT_B16G16R16G16_422_UNORM, |
| // VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM, |
| // VK_FORMAT_G16_B16R16_2PLANE_420_UNORM, |
| // VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM, |
| // VK_FORMAT_G16_B16R16_2PLANE_422_UNORM, |
| // VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM, |
| // VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG, |
| // VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG, |
| // VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG, |
| // VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG, |
| // VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG, |
| // VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG, |
| // VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG, |
| // VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG, |
| |
| // YUV formats |
| FORMAT_YV12_BT601 = VK_FORMAT_END_RANGE + 1, // TODO: VK_FORMAT_G8_B8R8_2PLANE_420_UNORM + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601 |
| FORMAT_YV12_BT709, // TODO: VK_FORMAT_G8_B8R8_2PLANE_420_UNORM + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709 |
| FORMAT_YV12_JFIF, // TODO: VK_FORMAT_G8_B8R8_2PLANE_420_UNORM + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020 |
| |
| FORMAT_LAST = FORMAT_YV12_JFIF |
| }; |
| |
| enum Lock |
| { |
| LOCK_UNLOCKED, |
| LOCK_READONLY, |
| LOCK_WRITEONLY, |
| LOCK_READWRITE, |
| LOCK_DISCARD, |
| LOCK_UPDATE // Write access which doesn't dirty the buffer, because it's being updated with the sibling's data. |
| }; |
| |
| class [[clang::lto_visibility_public]] Surface |
| { |
| private: |
| struct Buffer |
| { |
| friend Surface; |
| |
| private: |
| void write(int x, int y, int z, const Color<float> &color); |
| void write(int x, int y, const Color<float> &color); |
| void write(void *element, const Color<float> &color); |
| Color<float> read(int x, int y, int z) const; |
| Color<float> read(int x, int y) const; |
| Color<float> read(void *element) const; |
| Color<float> sample(float x, float y, float z) const; |
| Color<float> sample(float x, float y, int layer) const; |
| |
| void *lockRect(int x, int y, int z, Lock lock); |
| void unlockRect(); |
| |
| void *buffer; |
| int width; |
| int height; |
| int depth; |
| short border; |
| short samples; |
| |
| int bytes; |
| int pitchB; |
| int pitchP; |
| int sliceB; |
| int sliceP; |
| |
| Format format; |
| AtomicInt lock; |
| |
| bool dirty; // Sibling internal/external buffer doesn't match. |
| }; |
| |
| protected: |
| Surface(int width, int height, int depth, Format format, void *pixels, int pitch, int slice); |
| Surface(Resource *texture, int width, int height, int depth, int border, int samples, Format format, bool lockable, bool renderTarget, int pitchP = 0); |
| |
| public: |
| static Surface *create(int width, int height, int depth, Format format, void *pixels, int pitch, int slice); |
| static Surface *create(Resource *texture, int width, int height, int depth, int border, int samples, Format format, bool lockable, bool renderTarget, int pitchP = 0); |
| |
| virtual ~Surface() = 0; |
| |
| inline void *lock(int x, int y, int z, Lock lock, Accessor client, bool internal = false); |
| inline void unlock(bool internal = false); |
| inline int getWidth() const; |
| inline int getHeight() const; |
| inline int getDepth() const; |
| inline int getBorder() const; |
| inline Format getFormat(bool internal = false) const; |
| inline int getPitchB(bool internal = false) const; |
| inline int getPitchP(bool internal = false) const; |
| inline int getSliceB(bool internal = false) const; |
| inline int getSliceP(bool internal = false) const; |
| |
| void *lockExternal(int x, int y, int z, Lock lock, Accessor client); |
| void unlockExternal(); |
| inline Format getExternalFormat() const; |
| inline int getExternalPitchB() const; |
| inline int getExternalPitchP() const; |
| inline int getExternalSliceB() const; |
| inline int getExternalSliceP() const; |
| |
| virtual void *lockInternal(int x, int y, int z, Lock lock, Accessor client) = 0; |
| virtual void unlockInternal() = 0; |
| inline Format getInternalFormat() const; |
| inline int getInternalPitchB() const; |
| inline int getInternalPitchP() const; |
| inline int getInternalSliceB() const; |
| inline int getInternalSliceP() const; |
| |
| void *lockStencil(int x, int y, int front, Accessor client); |
| void unlockStencil(); |
| inline Format getStencilFormat() const; |
| inline int getStencilPitchB() const; |
| inline int getStencilSliceB() const; |
| |
| void sync(); // Wait for lock(s) to be released. |
| virtual bool requiresSync() const { return false; } |
| inline bool isUnlocked() const; // Only reliable after sync(). |
| |
| inline int getSamples() const; |
| inline int getMultiSampleCount() const; |
| inline int getSuperSampleCount() const; |
| |
| bool isEntire(const Rect& rect) const; |
| Rect getRect() const; |
| void clearDepth(float depth, int x0, int y0, int width, int height); |
| void clearStencil(unsigned char stencil, unsigned char mask, int x0, int y0, int width, int height); |
| void fill(const Color<float> &color, int x0, int y0, int width, int height); |
| |
| Color<float> readExternal(int x, int y, int z) const; |
| Color<float> readExternal(int x, int y) const; |
| Color<float> sampleExternal(float x, float y, float z) const; |
| Color<float> sampleExternal(float x, float y) const; |
| void writeExternal(int x, int y, int z, const Color<float> &color); |
| void writeExternal(int x, int y, const Color<float> &color); |
| |
| void copyInternal(const Surface* src, int x, int y, float srcX, float srcY, bool filter); |
| void copyInternal(const Surface* src, int x, int y, int z, float srcX, float srcY, float srcZ, bool filter); |
| |
| enum Edge { TOP, BOTTOM, RIGHT, LEFT }; |
| void copyCubeEdge(Edge dstEdge, Surface *src, Edge srcEdge); |
| void computeCubeCorner(int x0, int y0, int x1, int y1); |
| |
| bool hasStencil() const; |
| bool hasDepth() const; |
| bool isRenderTarget() const; |
| |
| bool hasDirtyContents() const; |
| void markContentsClean(); |
| inline bool isExternalDirty() const; |
| Resource *getResource(); |
| |
| static int bytes(Format format); |
| static int pitchB(int width, int border, Format format, bool target); |
| static int pitchP(int width, int border, Format format, bool target); |
| static int sliceB(int width, int height, int border, Format format, bool target); |
| static int sliceP(int width, int height, int border, Format format, bool target); |
| static size_t size(int width, int height, int depth, int border, int samples, Format format); |
| |
| static bool isStencil(Format format); |
| static bool isDepth(Format format); |
| static bool hasQuadLayout(Format format); |
| |
| static bool isFloatFormat(Format format); |
| static bool isUnsignedComponent(Format format, int component); |
| static bool isSRGBreadable(Format format); |
| static bool isSRGBwritable(Format format); |
| static bool isSRGBformat(Format format); |
| static bool isCompressed(Format format); |
| static bool isSignedNonNormalizedInteger(Format format); |
| static bool isUnsignedNonNormalizedInteger(Format format); |
| static bool isNonNormalizedInteger(Format format); |
| static bool isNormalizedInteger(Format format); |
| static int componentCount(Format format); |
| |
| private: |
| sw::Resource *resource; |
| |
| typedef unsigned char byte; |
| typedef unsigned short word; |
| typedef unsigned int dword; |
| typedef uint64_t qword; |
| |
| struct DXT1 |
| { |
| word c0; |
| word c1; |
| dword lut; |
| }; |
| |
| struct DXT3 |
| { |
| qword a; |
| |
| word c0; |
| word c1; |
| dword lut; |
| }; |
| |
| struct DXT5 |
| { |
| union |
| { |
| struct |
| { |
| byte a0; |
| byte a1; |
| }; |
| |
| qword alut; // Skip first 16 bit |
| }; |
| |
| word c0; |
| word c1; |
| dword clut; |
| }; |
| |
| struct ATI2 |
| { |
| union |
| { |
| struct |
| { |
| byte y0; |
| byte y1; |
| }; |
| |
| qword ylut; // Skip first 16 bit |
| }; |
| |
| union |
| { |
| struct |
| { |
| byte x0; |
| byte x1; |
| }; |
| |
| qword xlut; // Skip first 16 bit |
| }; |
| }; |
| |
| struct ATI1 |
| { |
| union |
| { |
| struct |
| { |
| byte r0; |
| byte r1; |
| }; |
| |
| qword rlut; // Skip first 16 bit |
| }; |
| }; |
| |
| static void decodeDXT1(Buffer &internal, Buffer &external); |
| static void decodeDXT3(Buffer &internal, Buffer &external); |
| static void decodeDXT5(Buffer &internal, Buffer &external); |
| static void decodeATI1(Buffer &internal, Buffer &external); |
| static void decodeATI2(Buffer &internal, Buffer &external); |
| static void decodeEAC(Buffer &internal, Buffer &external, int nbChannels, bool isSigned); |
| static void decodeETC2(Buffer &internal, Buffer &external, int nbAlphaBits, bool isSRGB); |
| static void decodeASTC(Buffer &internal, Buffer &external, int xSize, int ySize, int zSize, bool isSRGB); |
| |
| static void update(Buffer &destination, Buffer &source); |
| static void genericUpdate(Buffer &destination, Buffer &source); |
| static void *allocateBuffer(int width, int height, int depth, int border, int samples, Format format); |
| static void memfill4(void *buffer, int pattern, int bytes); |
| |
| bool identicalBuffers() const; |
| Format selectInternalFormat(Format format) const; |
| |
| void resolve(); |
| |
| Buffer external; |
| Buffer internal; |
| Buffer stencil; |
| |
| const bool lockable; |
| const bool renderTarget; |
| |
| bool dirtyContents; // Sibling surfaces need updating (mipmaps / cube borders). |
| |
| bool hasParent; |
| bool ownExternal; |
| }; |
| } |
| |
| #undef min |
| #undef max |
| |
| namespace sw |
| { |
| void *Surface::lock(int x, int y, int z, Lock lock, Accessor client, bool internal) |
| { |
| return internal ? lockInternal(x, y, z, lock, client) : lockExternal(x, y, z, lock, client); |
| } |
| |
| void Surface::unlock(bool internal) |
| { |
| return internal ? unlockInternal() : unlockExternal(); |
| } |
| |
| int Surface::getWidth() const |
| { |
| return external.width; |
| } |
| |
| int Surface::getHeight() const |
| { |
| return external.height; |
| } |
| |
| int Surface::getDepth() const |
| { |
| return external.depth; |
| } |
| |
| int Surface::getBorder() const |
| { |
| return internal.border; |
| } |
| |
| Format Surface::getFormat(bool internal) const |
| { |
| return internal ? getInternalFormat() : getExternalFormat(); |
| } |
| |
| int Surface::getPitchB(bool internal) const |
| { |
| return internal ? getInternalPitchB() : getExternalPitchB(); |
| } |
| |
| int Surface::getPitchP(bool internal) const |
| { |
| return internal ? getInternalPitchP() : getExternalPitchP(); |
| } |
| |
| int Surface::getSliceB(bool internal) const |
| { |
| return internal ? getInternalSliceB() : getExternalSliceB(); |
| } |
| |
| int Surface::getSliceP(bool internal) const |
| { |
| return internal ? getInternalSliceP() : getExternalSliceP(); |
| } |
| |
| Format Surface::getExternalFormat() const |
| { |
| return external.format; |
| } |
| |
| int Surface::getExternalPitchB() const |
| { |
| return external.pitchB; |
| } |
| |
| int Surface::getExternalPitchP() const |
| { |
| return external.pitchP; |
| } |
| |
| int Surface::getExternalSliceB() const |
| { |
| return external.sliceB; |
| } |
| |
| int Surface::getExternalSliceP() const |
| { |
| return external.sliceP; |
| } |
| |
| Format Surface::getInternalFormat() const |
| { |
| return internal.format; |
| } |
| |
| int Surface::getInternalPitchB() const |
| { |
| return internal.pitchB; |
| } |
| |
| int Surface::getInternalPitchP() const |
| { |
| return internal.pitchP; |
| } |
| |
| int Surface::getInternalSliceB() const |
| { |
| return internal.sliceB; |
| } |
| |
| int Surface::getInternalSliceP() const |
| { |
| return internal.sliceP; |
| } |
| |
| Format Surface::getStencilFormat() const |
| { |
| return stencil.format; |
| } |
| |
| int Surface::getStencilPitchB() const |
| { |
| return stencil.pitchB; |
| } |
| |
| int Surface::getStencilSliceB() const |
| { |
| return stencil.sliceB; |
| } |
| |
| int Surface::getSamples() const |
| { |
| return internal.samples; |
| } |
| |
| int Surface::getMultiSampleCount() const |
| { |
| return sw::min((int)internal.samples, 4); |
| } |
| |
| int Surface::getSuperSampleCount() const |
| { |
| return internal.samples > 4 ? internal.samples / 4 : 1; |
| } |
| |
| bool Surface::isUnlocked() const |
| { |
| return external.lock == LOCK_UNLOCKED && |
| internal.lock == LOCK_UNLOCKED && |
| stencil.lock == LOCK_UNLOCKED; |
| } |
| |
| bool Surface::isExternalDirty() const |
| { |
| return external.buffer && external.buffer != internal.buffer && external.dirty; |
| } |
| } |
| |
| #endif // sw_Surface_hpp |