Commit 45c697aa by Ben Clayton

clang-format the src/WSI directory

Bug: b/144825072 Change-Id: Iabb4e1b2f4bb3da842fdeaa3ad2c6c3816810ae6 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/39659 Presubmit-Ready: Ben Clayton <bclayton@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Tested-by: 's avatarBen Clayton <bclayton@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 2ed93ab1
...@@ -18,17 +18,14 @@ ...@@ -18,17 +18,14 @@
#include <algorithm> #include <algorithm>
namespace namespace {
{
static const VkSurfaceFormatKHR surfaceFormats[] = static const VkSurfaceFormatKHR surfaceFormats[] = {
{ { VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR },
{VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR}, { VK_FORMAT_B8G8R8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR },
{VK_FORMAT_B8G8R8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
}; };
static const VkPresentModeKHR presentModes[] = static const VkPresentModeKHR presentModes[] = {
{
// FIXME(b/124265819): Make present modes behave correctly. Currently we use XPutImage // FIXME(b/124265819): Make present modes behave correctly. Currently we use XPutImage
// with no synchronization, which behaves more like VK_PRESENT_MODE_IMMEDIATE_KHR. We // with no synchronization, which behaves more like VK_PRESENT_MODE_IMMEDIATE_KHR. We
// should convert to using the Present extension, which allows us to request presentation // should convert to using the Present extension, which allows us to request presentation
...@@ -38,13 +35,13 @@ static const VkPresentModeKHR presentModes[] = ...@@ -38,13 +35,13 @@ static const VkPresentModeKHR presentModes[] =
VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_MAILBOX_KHR,
}; };
} } // namespace
namespace vk { namespace vk {
VkResult PresentImage::allocateImage(VkDevice device, const VkImageCreateInfo& createInfo) VkResult PresentImage::allocateImage(VkDevice device, const VkImageCreateInfo &createInfo)
{ {
VkImage* vkImagePtr = reinterpret_cast<VkImage*>(allocate(sizeof(VkImage), REQUIRED_MEMORY_ALIGNMENT, DEVICE_MEMORY)); VkImage *vkImagePtr = reinterpret_cast<VkImage *>(allocate(sizeof(VkImage), REQUIRED_MEMORY_ALIGNMENT, DEVICE_MEMORY));
if(!vkImagePtr) if(!vkImagePtr)
{ {
return VK_ERROR_OUT_OF_DEVICE_MEMORY; return VK_ERROR_OUT_OF_DEVICE_MEMORY;
...@@ -63,11 +60,11 @@ VkResult PresentImage::allocateImage(VkDevice device, const VkImageCreateInfo& c ...@@ -63,11 +60,11 @@ VkResult PresentImage::allocateImage(VkDevice device, const VkImageCreateInfo& c
return status; return status;
} }
VkResult PresentImage::allocateAndBindImageMemory(VkDevice device, const VkMemoryAllocateInfo& allocateInfo) VkResult PresentImage::allocateAndBindImageMemory(VkDevice device, const VkMemoryAllocateInfo &allocateInfo)
{ {
ASSERT(image); ASSERT(image);
VkDeviceMemory* vkDeviceMemoryPtr = reinterpret_cast<VkDeviceMemory*>( VkDeviceMemory *vkDeviceMemoryPtr = reinterpret_cast<VkDeviceMemory *>(
allocate(sizeof(VkDeviceMemory), REQUIRED_MEMORY_ALIGNMENT, DEVICE_MEMORY)); allocate(sizeof(VkDeviceMemory), REQUIRED_MEMORY_ALIGNMENT, DEVICE_MEMORY));
if(!vkDeviceMemoryPtr) if(!vkDeviceMemoryPtr)
{ {
...@@ -179,7 +176,7 @@ VkResult SurfaceKHR::getPresentModes(uint32_t *pPresentModeCount, VkPresentModeK ...@@ -179,7 +176,7 @@ VkResult SurfaceKHR::getPresentModes(uint32_t *pPresentModeCount, VkPresentModeK
return VK_SUCCESS; return VK_SUCCESS;
} }
void SurfaceKHR::associateSwapchain(SwapchainKHR* swapchain) void SurfaceKHR::associateSwapchain(SwapchainKHR *swapchain)
{ {
associatedSwapchain = swapchain; associatedSwapchain = swapchain;
} }
...@@ -210,7 +207,7 @@ VkResult SurfaceKHR::getPresentRectangles(uint32_t *pRectCount, VkRect2D *pRects ...@@ -210,7 +207,7 @@ VkResult SurfaceKHR::getPresentRectangles(uint32_t *pRectCount, VkRect2D *pRects
VkSurfaceCapabilitiesKHR capabilities; VkSurfaceCapabilitiesKHR capabilities;
getSurfaceCapabilities(&capabilities); getSurfaceCapabilities(&capabilities);
pRects[0].offset = {0,0}; pRects[0].offset = { 0, 0 };
pRects[0].extent = capabilities.currentExtent; pRects[0].extent = capabilities.currentExtent;
*pRectCount = 1; *pRectCount = 1;
......
...@@ -15,8 +15,8 @@ ...@@ -15,8 +15,8 @@
#ifndef SWIFTSHADER_VKSURFACEKHR_HPP_ #ifndef SWIFTSHADER_VKSURFACEKHR_HPP_
#define SWIFTSHADER_VKSURFACEKHR_HPP_ #define SWIFTSHADER_VKSURFACEKHR_HPP_
#include "Vulkan/VkObject.hpp"
#include "Vulkan/VkImage.hpp" #include "Vulkan/VkImage.hpp"
#include "Vulkan/VkObject.hpp"
#include <Vulkan/VulkanPlatform.h> #include <Vulkan/VulkanPlatform.h>
#include <vector> #include <vector>
...@@ -38,20 +38,20 @@ class SwapchainKHR; ...@@ -38,20 +38,20 @@ class SwapchainKHR;
class PresentImage class PresentImage
{ {
public: public:
VkResult allocateImage(VkDevice device, const VkImageCreateInfo& createInfo); VkResult allocateImage(VkDevice device, const VkImageCreateInfo &createInfo);
VkResult allocateAndBindImageMemory(VkDevice device, const VkMemoryAllocateInfo& allocateInfo); VkResult allocateAndBindImageMemory(VkDevice device, const VkMemoryAllocateInfo &allocateInfo);
void clear(); void clear();
VkImage asVkImage() const; VkImage asVkImage() const;
const Image* getImage() const { return image; } const Image *getImage() const { return image; }
DeviceMemory* getImageMemory() const { return imageMemory; } DeviceMemory *getImageMemory() const { return imageMemory; }
bool isAvailable() const { return (imageStatus == AVAILABLE); } bool isAvailable() const { return (imageStatus == AVAILABLE); }
bool exists() const { return (imageStatus != NONEXISTENT); } bool exists() const { return (imageStatus != NONEXISTENT); }
void setStatus(PresentImageStatus status) { imageStatus = status; } void setStatus(PresentImageStatus status) { imageStatus = status; }
private: private:
Image* image = nullptr; Image *image = nullptr;
DeviceMemory* imageMemory = nullptr; DeviceMemory *imageMemory = nullptr;
PresentImageStatus imageStatus = NONEXISTENT; PresentImageStatus imageStatus = NONEXISTENT;
}; };
...@@ -65,41 +65,41 @@ public: ...@@ -65,41 +65,41 @@ public:
return vk::TtoVkT<SurfaceKHR, VkSurfaceKHR>(this); return vk::TtoVkT<SurfaceKHR, VkSurfaceKHR>(this);
} }
static inline SurfaceKHR* Cast(VkSurfaceKHR object) static inline SurfaceKHR *Cast(VkSurfaceKHR object)
{ {
return vk::VkTtoT<SurfaceKHR, VkSurfaceKHR>(object); return vk::VkTtoT<SurfaceKHR, VkSurfaceKHR>(object);
} }
void destroy(const VkAllocationCallbacks* pAllocator) void destroy(const VkAllocationCallbacks *pAllocator)
{ {
destroySurface(pAllocator); destroySurface(pAllocator);
} }
virtual void destroySurface(const VkAllocationCallbacks* pAllocator) = 0; virtual void destroySurface(const VkAllocationCallbacks *pAllocator) = 0;
virtual void getSurfaceCapabilities(VkSurfaceCapabilitiesKHR* pSurfaceCapabilities) const; virtual void getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const;
uint32_t getSurfaceFormatsCount() const; uint32_t getSurfaceFormatsCount() const;
VkResult getSurfaceFormats(uint32_t* pSurfaceFormatCount, VkSurfaceFormatKHR* pSurfaceFormats) const; VkResult getSurfaceFormats(uint32_t *pSurfaceFormatCount, VkSurfaceFormatKHR *pSurfaceFormats) const;
uint32_t getPresentModeCount() const; uint32_t getPresentModeCount() const;
VkResult getPresentModes(uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes) const; VkResult getPresentModes(uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes) const;
VkResult getPresentRectangles(uint32_t *pRectCount, VkRect2D *pRects) const; VkResult getPresentRectangles(uint32_t *pRectCount, VkRect2D *pRects) const;
virtual void attachImage(PresentImage* image) = 0; virtual void attachImage(PresentImage *image) = 0;
virtual void detachImage(PresentImage* image) = 0; virtual void detachImage(PresentImage *image) = 0;
virtual VkResult present(PresentImage* image) = 0; virtual VkResult present(PresentImage *image) = 0;
void associateSwapchain(SwapchainKHR* swapchain); void associateSwapchain(SwapchainKHR *swapchain);
void disassociateSwapchain(); void disassociateSwapchain();
bool hasAssociatedSwapchain(); bool hasAssociatedSwapchain();
private: private:
SwapchainKHR* associatedSwapchain = nullptr; SwapchainKHR *associatedSwapchain = nullptr;
}; };
static inline SurfaceKHR* Cast(VkSurfaceKHR object) static inline SurfaceKHR *Cast(VkSurfaceKHR object)
{ {
return SurfaceKHR::Cast(object); return SurfaceKHR::Cast(object);
} }
......
...@@ -24,20 +24,20 @@ ...@@ -24,20 +24,20 @@
namespace vk { namespace vk {
SwapchainKHR::SwapchainKHR(const VkSwapchainCreateInfoKHR *pCreateInfo, void *mem) : SwapchainKHR::SwapchainKHR(const VkSwapchainCreateInfoKHR *pCreateInfo, void *mem)
surface(vk::Cast(pCreateInfo->surface)), : surface(vk::Cast(pCreateInfo->surface))
images(reinterpret_cast<PresentImage*>(mem)), , images(reinterpret_cast<PresentImage *>(mem))
imageCount(pCreateInfo->minImageCount), , imageCount(pCreateInfo->minImageCount)
retired(false) , retired(false)
{ {
memset(reinterpret_cast<void*>(images), 0, imageCount * sizeof(PresentImage)); memset(reinterpret_cast<void *>(images), 0, imageCount * sizeof(PresentImage));
} }
void SwapchainKHR::destroy(const VkAllocationCallbacks *pAllocator) void SwapchainKHR::destroy(const VkAllocationCallbacks *pAllocator)
{ {
for(uint32_t i = 0; i < imageCount; i++) for(uint32_t i = 0; i < imageCount; i++)
{ {
PresentImage& currentImage = images[i]; PresentImage &currentImage = images[i];
if(currentImage.exists()) if(currentImage.exists())
{ {
surface->detachImage(&currentImage); surface->detachImage(&currentImage);
...@@ -67,7 +67,7 @@ void SwapchainKHR::retire() ...@@ -67,7 +67,7 @@ void SwapchainKHR::retire()
for(uint32_t i = 0; i < imageCount; i++) for(uint32_t i = 0; i < imageCount; i++)
{ {
PresentImage& currentImage = images[i]; PresentImage &currentImage = images[i];
if(currentImage.isAvailable()) if(currentImage.isAvailable())
{ {
surface->detachImage(&currentImage); surface->detachImage(&currentImage);
...@@ -125,7 +125,7 @@ VkResult SwapchainKHR::createImages(VkDevice device, const VkSwapchainCreateInfo ...@@ -125,7 +125,7 @@ VkResult SwapchainKHR::createImages(VkDevice device, const VkSwapchainCreateInfo
VkResult status; VkResult status;
for(uint32_t i = 0; i < imageCount; i++) for(uint32_t i = 0; i < imageCount; i++)
{ {
PresentImage& currentImage = images[i]; PresentImage &currentImage = images[i];
status = currentImage.allocateImage(device, imageInfo); status = currentImage.allocateImage(device, imageInfo);
if(status != VK_SUCCESS) if(status != VK_SUCCESS)
...@@ -170,11 +170,11 @@ VkResult SwapchainKHR::getImages(uint32_t *pSwapchainImageCount, VkImage *pSwapc ...@@ -170,11 +170,11 @@ VkResult SwapchainKHR::getImages(uint32_t *pSwapchainImageCount, VkImage *pSwapc
return VK_SUCCESS; return VK_SUCCESS;
} }
VkResult SwapchainKHR::getNextImage(uint64_t timeout, Semaphore* semaphore, Fence* fence, uint32_t *pImageIndex) VkResult SwapchainKHR::getNextImage(uint64_t timeout, Semaphore *semaphore, Fence *fence, uint32_t *pImageIndex)
{ {
for(uint32_t i = 0; i < imageCount; i++) for(uint32_t i = 0; i < imageCount; i++)
{ {
PresentImage& currentImage = images[i]; PresentImage &currentImage = images[i];
if(currentImage.isAvailable()) if(currentImage.isAvailable())
{ {
currentImage.setStatus(DRAWING); currentImage.setStatus(DRAWING);
...@@ -199,7 +199,7 @@ VkResult SwapchainKHR::getNextImage(uint64_t timeout, Semaphore* semaphore, Fenc ...@@ -199,7 +199,7 @@ VkResult SwapchainKHR::getNextImage(uint64_t timeout, Semaphore* semaphore, Fenc
VkResult SwapchainKHR::present(uint32_t index) VkResult SwapchainKHR::present(uint32_t index)
{ {
auto& image = images[index]; auto &image = images[index];
image.setStatus(PRESENTING); image.setStatus(PRESENTING);
VkResult result = surface->present(&image); VkResult result = surface->present(&image);
image.setStatus(AVAILABLE); image.setStatus(AVAILABLE);
......
...@@ -15,10 +15,9 @@ ...@@ -15,10 +15,9 @@
#ifndef SWIFTSHADER_VKSWAPCHAINKHR_HPP #ifndef SWIFTSHADER_VKSWAPCHAINKHR_HPP
#define SWIFTSHADER_VKSWAPCHAINKHR_HPP #define SWIFTSHADER_VKSWAPCHAINKHR_HPP
#include "Vulkan/VkObject.hpp"
#include "Vulkan/VkImage.hpp"
#include "VkSurfaceKHR.hpp" #include "VkSurfaceKHR.hpp"
#include "Vulkan/VkImage.hpp"
#include "Vulkan/VkObject.hpp"
#include <vector> #include <vector>
...@@ -30,34 +29,34 @@ class Semaphore; ...@@ -30,34 +29,34 @@ class Semaphore;
class SwapchainKHR : public Object<SwapchainKHR, VkSwapchainKHR> class SwapchainKHR : public Object<SwapchainKHR, VkSwapchainKHR>
{ {
public: public:
SwapchainKHR(const VkSwapchainCreateInfoKHR* pCreateInfo, void* mem); SwapchainKHR(const VkSwapchainCreateInfoKHR *pCreateInfo, void *mem);
void destroy(const VkAllocationCallbacks* pAllocator); void destroy(const VkAllocationCallbacks *pAllocator);
static size_t ComputeRequiredAllocationSize(const VkSwapchainCreateInfoKHR* pCreateInfo); static size_t ComputeRequiredAllocationSize(const VkSwapchainCreateInfoKHR *pCreateInfo);
void retire(); void retire();
VkResult createImages(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo); VkResult createImages(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo);
uint32_t getImageCount() const; uint32_t getImageCount() const;
VkResult getImages(uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) const; VkResult getImages(uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) const;
VkResult getNextImage(uint64_t timeout, Semaphore* semaphore, Fence* fence, uint32_t* pImageIndex); VkResult getNextImage(uint64_t timeout, Semaphore *semaphore, Fence *fence, uint32_t *pImageIndex);
VkResult present(uint32_t index); VkResult present(uint32_t index);
PresentImage const &getImage(uint32_t imageIndex) { return images[imageIndex]; } PresentImage const &getImage(uint32_t imageIndex) { return images[imageIndex]; }
private: private:
SurfaceKHR* surface = nullptr; SurfaceKHR *surface = nullptr;
PresentImage* images = nullptr; PresentImage *images = nullptr;
uint32_t imageCount = 0; uint32_t imageCount = 0;
bool retired = false; bool retired = false;
void resetImages(); void resetImages();
}; };
static inline SwapchainKHR* Cast(VkSwapchainKHR object) static inline SwapchainKHR *Cast(VkSwapchainKHR object)
{ {
return SwapchainKHR::Cast(object); return SwapchainKHR::Cast(object);
} }
......
...@@ -14,15 +14,14 @@ ...@@ -14,15 +14,14 @@
#include "Win32SurfaceKHR.hpp" #include "Win32SurfaceKHR.hpp"
#include "Vulkan/VkDeviceMemory.hpp"
#include "Vulkan/VkDebug.hpp" #include "Vulkan/VkDebug.hpp"
#include "Vulkan/VkDeviceMemory.hpp"
#include <string.h> #include <string.h>
namespace namespace {
VkExtent2D getWindowSize(HWND hwnd)
{ {
VkExtent2D getWindowSize(HWND hwnd)
{
RECT clientRect = {}; RECT clientRect = {};
BOOL status = GetClientRect(hwnd, &clientRect); BOOL status = GetClientRect(hwnd, &clientRect);
ASSERT(status != 0); ASSERT(status != 0);
...@@ -31,13 +30,13 @@ namespace ...@@ -31,13 +30,13 @@ namespace
int windowHeight = clientRect.bottom - clientRect.top; int windowHeight = clientRect.bottom - clientRect.top;
return { static_cast<uint32_t>(windowWidth), static_cast<uint32_t>(windowHeight) }; return { static_cast<uint32_t>(windowWidth), static_cast<uint32_t>(windowHeight) };
}
} }
} // namespace
namespace vk { namespace vk {
Win32SurfaceKHR::Win32SurfaceKHR(const VkWin32SurfaceCreateInfoKHR *pCreateInfo, void *mem) : Win32SurfaceKHR::Win32SurfaceKHR(const VkWin32SurfaceCreateInfoKHR *pCreateInfo, void *mem)
hwnd(pCreateInfo->hwnd) : hwnd(pCreateInfo->hwnd)
{ {
ASSERT(IsWindow(hwnd) == TRUE); ASSERT(IsWindow(hwnd) == TRUE);
windowContext = GetDC(hwnd); windowContext = GetDC(hwnd);
...@@ -66,19 +65,19 @@ void Win32SurfaceKHR::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceC ...@@ -66,19 +65,19 @@ void Win32SurfaceKHR::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceC
pSurfaceCapabilities->maxImageExtent = extent; pSurfaceCapabilities->maxImageExtent = extent;
} }
void Win32SurfaceKHR::attachImage(PresentImage* image) void Win32SurfaceKHR::attachImage(PresentImage *image)
{ {
// Nothing to do here, the current implementation based on GDI blits on // Nothing to do here, the current implementation based on GDI blits on
// present instead of associating the image with the surface. // present instead of associating the image with the surface.
} }
void Win32SurfaceKHR::detachImage(PresentImage* image) void Win32SurfaceKHR::detachImage(PresentImage *image)
{ {
// Nothing to do here, the current implementation based on GDI blits on // Nothing to do here, the current implementation based on GDI blits on
// present instead of associating the image with the surface. // present instead of associating the image with the surface.
} }
VkResult Win32SurfaceKHR::present(PresentImage* image) VkResult Win32SurfaceKHR::present(PresentImage *image)
{ {
// Recreate frame buffer in case window size has changed // Recreate frame buffer in case window size has changed
lazyCreateFrameBuffer(); lazyCreateFrameBuffer();
...@@ -100,7 +99,7 @@ VkResult Win32SurfaceKHR::present(PresentImage* image) ...@@ -100,7 +99,7 @@ VkResult Win32SurfaceKHR::present(PresentImage* image)
subresourceLayers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; subresourceLayers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
subresourceLayers.layerCount = 1; subresourceLayers.layerCount = 1;
image->getImage()->blitToBuffer(subresourceLayers, VkOffset3D{}, extent, reinterpret_cast<uint8_t*>(framebuffer), bitmapRowPitch, 0); image->getImage()->blitToBuffer(subresourceLayers, VkOffset3D{}, extent, reinterpret_cast<uint8_t *>(framebuffer), bitmapRowPitch, 0);
StretchBlt(windowContext, 0, 0, extent.width, extent.height, bitmapContext, 0, 0, extent.width, extent.height, SRCCOPY); StretchBlt(windowContext, 0, 0, extent.width, extent.height, bitmapContext, 0, 0, extent.width, extent.height, SRCCOPY);
...@@ -154,4 +153,4 @@ void Win32SurfaceKHR::destroyFrameBuffer() ...@@ -154,4 +153,4 @@ void Win32SurfaceKHR::destroyFrameBuffer()
framebuffer = nullptr; framebuffer = nullptr;
} }
} } // namespace vk
\ No newline at end of file \ No newline at end of file
...@@ -15,21 +15,22 @@ ...@@ -15,21 +15,22 @@
#ifndef SWIFTSHADER_WIN32SURFACEKHR_HPP #ifndef SWIFTSHADER_WIN32SURFACEKHR_HPP
#define SWIFTSHADER_WIN32SURFACEKHR_HPP #define SWIFTSHADER_WIN32SURFACEKHR_HPP
#include "Vulkan/VkObject.hpp"
#include "Vulkan/VkImage.hpp"
#include "VkSurfaceKHR.hpp" #include "VkSurfaceKHR.hpp"
#include "Vulkan/VkImage.hpp"
#include "Vulkan/VkObject.hpp"
#if !defined(WIN32_LEAN_AND_MEAN) #if !defined(WIN32_LEAN_AND_MEAN)
#define WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN
#endif // !defined(WIN32_LEAN_AND_MEAN) #endif // !defined(WIN32_LEAN_AND_MEAN)
#include <Windows.h>
#include "vulkan/vulkan_win32.h" #include "vulkan/vulkan_win32.h"
#include <Windows.h>
#include <map> #include <map>
namespace vk { namespace vk {
class Win32SurfaceKHR : public SurfaceKHR, public ObjectBase<Win32SurfaceKHR, VkSurfaceKHR> { class Win32SurfaceKHR : public SurfaceKHR, public ObjectBase<Win32SurfaceKHR, VkSurfaceKHR>
{
public: public:
Win32SurfaceKHR(const VkWin32SurfaceCreateInfoKHR *pCreateInfo, void *mem); Win32SurfaceKHR(const VkWin32SurfaceCreateInfoKHR *pCreateInfo, void *mem);
...@@ -39,9 +40,9 @@ public: ...@@ -39,9 +40,9 @@ public:
void getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const override; void getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const override;
virtual void attachImage(PresentImage* image) override; virtual void attachImage(PresentImage *image) override;
virtual void detachImage(PresentImage* image) override; virtual void detachImage(PresentImage *image) override;
VkResult present(PresentImage* image) override; VkResult present(PresentImage *image) override;
private: private:
void lazyCreateFrameBuffer(); void lazyCreateFrameBuffer();
...@@ -58,5 +59,5 @@ private: ...@@ -58,5 +59,5 @@ private:
void *framebuffer = nullptr; void *framebuffer = nullptr;
}; };
} } // namespace vk
#endif //SWIFTSHADER_WIN32SURFACEKHR_HPP #endif //SWIFTSHADER_WIN32SURFACEKHR_HPP
...@@ -18,10 +18,9 @@ ...@@ -18,10 +18,9 @@
#include <memory> #include <memory>
namespace namespace {
{
template <typename FPTR> template<typename FPTR>
void getFuncAddress(void *lib, const char *name, FPTR *out) void getFuncAddress(void *lib, const char *name, FPTR *out)
{ {
*out = reinterpret_cast<FPTR>(getProcAddress(lib, name)); *out = reinterpret_cast<FPTR>(getProcAddress(lib, name));
...@@ -45,8 +44,8 @@ struct LibXcbExports ...@@ -45,8 +44,8 @@ struct LibXcbExports
xcb_void_cookie_t (*xcb_free_gc)(xcb_connection_t *c, xcb_gcontext_t gc); xcb_void_cookie_t (*xcb_free_gc)(xcb_connection_t *c, xcb_gcontext_t gc);
uint32_t (*xcb_generate_id)(xcb_connection_t *c); uint32_t (*xcb_generate_id)(xcb_connection_t *c);
xcb_get_geometry_cookie_t (*xcb_get_geometry)(xcb_connection_t *c, xcb_drawable_t drawable); xcb_get_geometry_cookie_t (*xcb_get_geometry)(xcb_connection_t *c, xcb_drawable_t drawable);
xcb_get_geometry_reply_t* (*xcb_get_geometry_reply)(xcb_connection_t *c, xcb_get_geometry_cookie_t cookie, xcb_generic_error_t **e); xcb_get_geometry_reply_t *(*xcb_get_geometry_reply)(xcb_connection_t *c, xcb_get_geometry_cookie_t cookie, xcb_generic_error_t **e);
xcb_void_cookie_t (*xcb_put_image)(xcb_connection_t *c, uint8_t format, xcb_drawable_t drawable, xcb_gcontext_t gc, uint16_t width,uint16_t height, int16_t dst_x, int16_t dst_y, uint8_t left_pad, uint8_t depth, uint32_t data_len, const uint8_t* data); xcb_void_cookie_t (*xcb_put_image)(xcb_connection_t *c, uint8_t format, xcb_drawable_t drawable, xcb_gcontext_t gc, uint16_t width, uint16_t height, int16_t dst_x, int16_t dst_y, uint8_t left_pad, uint8_t depth, uint32_t data_len, const uint8_t *data);
}; };
class LibXcb class LibXcb
...@@ -65,8 +64,7 @@ public: ...@@ -65,8 +64,7 @@ public:
private: private:
LibXcbExports *loadExports() LibXcbExports *loadExports()
{ {
static auto exports = [] static auto exports = [] {
{
if(getProcAddress(RTLD_DEFAULT, "xcb_create_gc")) if(getProcAddress(RTLD_DEFAULT, "xcb_create_gc"))
{ {
return std::unique_ptr<LibXcbExports>(new LibXcbExports(RTLD_DEFAULT)); return std::unique_ptr<LibXcbExports>(new LibXcbExports(RTLD_DEFAULT));
...@@ -90,15 +88,14 @@ LibXcb libXcb; ...@@ -90,15 +88,14 @@ LibXcb libXcb;
namespace vk { namespace vk {
XcbSurfaceKHR::XcbSurfaceKHR(const VkXcbSurfaceCreateInfoKHR *pCreateInfo, void *mem) : XcbSurfaceKHR::XcbSurfaceKHR(const VkXcbSurfaceCreateInfoKHR *pCreateInfo, void *mem)
connection(pCreateInfo->connection), : connection(pCreateInfo->connection)
window(pCreateInfo->window) , window(pCreateInfo->window)
{ {
} }
void XcbSurfaceKHR::destroySurface(const VkAllocationCallbacks *pAllocator) void XcbSurfaceKHR::destroySurface(const VkAllocationCallbacks *pAllocator)
{ {
} }
size_t XcbSurfaceKHR::ComputeRequiredAllocationSize(const VkXcbSurfaceCreateInfoKHR *pCreateInfo) size_t XcbSurfaceKHR::ComputeRequiredAllocationSize(const VkXcbSurfaceCreateInfoKHR *pCreateInfo)
...@@ -111,7 +108,7 @@ void XcbSurfaceKHR::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCap ...@@ -111,7 +108,7 @@ void XcbSurfaceKHR::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCap
SurfaceKHR::getSurfaceCapabilities(pSurfaceCapabilities); SurfaceKHR::getSurfaceCapabilities(pSurfaceCapabilities);
auto geom = libXcb->xcb_get_geometry_reply(connection, libXcb->xcb_get_geometry(connection, window), nullptr); auto geom = libXcb->xcb_get_geometry_reply(connection, libXcb->xcb_get_geometry(connection, window), nullptr);
VkExtent2D extent = {static_cast<uint32_t>(geom->width), static_cast<uint32_t>(geom->height)}; VkExtent2D extent = { static_cast<uint32_t>(geom->width), static_cast<uint32_t>(geom->height) };
free(geom); free(geom);
pSurfaceCapabilities->currentExtent = extent; pSurfaceCapabilities->currentExtent = extent;
...@@ -119,17 +116,17 @@ void XcbSurfaceKHR::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCap ...@@ -119,17 +116,17 @@ void XcbSurfaceKHR::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCap
pSurfaceCapabilities->maxImageExtent = extent; pSurfaceCapabilities->maxImageExtent = extent;
} }
void XcbSurfaceKHR::attachImage(PresentImage* image) void XcbSurfaceKHR::attachImage(PresentImage *image)
{ {
auto gc = libXcb->xcb_generate_id(connection); auto gc = libXcb->xcb_generate_id(connection);
uint32_t values[2] = {0, 0xffffffff}; uint32_t values[2] = { 0, 0xffffffff };
libXcb->xcb_create_gc(connection, gc, window, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND, values); libXcb->xcb_create_gc(connection, gc, window, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND, values);
graphicsContexts[image] = gc; graphicsContexts[image] = gc;
} }
void XcbSurfaceKHR::detachImage(PresentImage* image) void XcbSurfaceKHR::detachImage(PresentImage *image)
{ {
auto it = graphicsContexts.find(image); auto it = graphicsContexts.find(image);
if(it != graphicsContexts.end()) if(it != graphicsContexts.end())
...@@ -139,13 +136,13 @@ void XcbSurfaceKHR::detachImage(PresentImage* image) ...@@ -139,13 +136,13 @@ void XcbSurfaceKHR::detachImage(PresentImage* image)
} }
} }
VkResult XcbSurfaceKHR::present(PresentImage* image) VkResult XcbSurfaceKHR::present(PresentImage *image)
{ {
auto it = graphicsContexts.find(image); auto it = graphicsContexts.find(image);
if(it != graphicsContexts.end()) if(it != graphicsContexts.end())
{ {
auto geom = libXcb->xcb_get_geometry_reply(connection, libXcb->xcb_get_geometry(connection, window), nullptr); auto geom = libXcb->xcb_get_geometry_reply(connection, libXcb->xcb_get_geometry(connection, window), nullptr);
VkExtent2D windowExtent = {static_cast<uint32_t>(geom->width), static_cast<uint32_t>(geom->height)}; VkExtent2D windowExtent = { static_cast<uint32_t>(geom->width), static_cast<uint32_t>(geom->height) };
free(geom); free(geom);
VkExtent3D extent = image->getImage()->getMipLevelExtent(VK_IMAGE_ASPECT_COLOR_BIT, 0); VkExtent3D extent = image->getImage()->getMipLevelExtent(VK_IMAGE_ASPECT_COLOR_BIT, 0);
...@@ -156,7 +153,7 @@ VkResult XcbSurfaceKHR::present(PresentImage* image) ...@@ -156,7 +153,7 @@ VkResult XcbSurfaceKHR::present(PresentImage* image)
// TODO: Convert image if not RGB888. // TODO: Convert image if not RGB888.
int stride = image->getImage()->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0); int stride = image->getImage()->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
auto buffer = reinterpret_cast<uint8_t*>(image->getImageMemory()->getOffsetPointer(0)); auto buffer = reinterpret_cast<uint8_t *>(image->getImageMemory()->getOffsetPointer(0));
size_t bufferSize = extent.height * stride; size_t bufferSize = extent.height * stride;
constexpr int depth = 24; // TODO: Actually use window display depth. constexpr int depth = 24; // TODO: Actually use window display depth.
...@@ -180,4 +177,4 @@ VkResult XcbSurfaceKHR::present(PresentImage* image) ...@@ -180,4 +177,4 @@ VkResult XcbSurfaceKHR::present(PresentImage* image)
return VK_SUCCESS; return VK_SUCCESS;
} }
} } // namespace vk
\ No newline at end of file \ No newline at end of file
...@@ -15,16 +15,17 @@ ...@@ -15,16 +15,17 @@
#ifndef SWIFTSHADER_XCBSURFACEKHR_HPP #ifndef SWIFTSHADER_XCBSURFACEKHR_HPP
#define SWIFTSHADER_XCBSURFACEKHR_HPP #define SWIFTSHADER_XCBSURFACEKHR_HPP
#include "Vulkan/VkObject.hpp"
#include "VkSurfaceKHR.hpp" #include "VkSurfaceKHR.hpp"
#include <xcb/xcb.h> #include "Vulkan/VkObject.hpp"
#include "vulkan/vulkan_xcb.h" #include "vulkan/vulkan_xcb.h"
#include <xcb/xcb.h>
#include <unordered_map> #include <unordered_map>
namespace vk { namespace vk {
class XcbSurfaceKHR : public SurfaceKHR, public ObjectBase<XcbSurfaceKHR, VkSurfaceKHR> { class XcbSurfaceKHR : public SurfaceKHR, public ObjectBase<XcbSurfaceKHR, VkSurfaceKHR>
{
public: public:
XcbSurfaceKHR(const VkXcbSurfaceCreateInfoKHR *pCreateInfo, void *mem); XcbSurfaceKHR(const VkXcbSurfaceCreateInfoKHR *pCreateInfo, void *mem);
...@@ -34,15 +35,15 @@ public: ...@@ -34,15 +35,15 @@ public:
void getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const override; void getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const override;
virtual void attachImage(PresentImage* image) override; virtual void attachImage(PresentImage *image) override;
virtual void detachImage(PresentImage* image) override; virtual void detachImage(PresentImage *image) override;
VkResult present(PresentImage* image) override; VkResult present(PresentImage *image) override;
private: private:
xcb_connection_t* connection; xcb_connection_t *connection;
xcb_window_t window; xcb_window_t window;
std::unordered_map<PresentImage*, uint32_t> graphicsContexts; std::unordered_map<PresentImage *, uint32_t> graphicsContexts;
}; };
} } // namespace vk
#endif //SWIFTSHADER_XCBSURFACEKHR_HPP #endif //SWIFTSHADER_XCBSURFACEKHR_HPP
...@@ -19,22 +19,21 @@ ...@@ -19,22 +19,21 @@
namespace vk { namespace vk {
XlibSurfaceKHR::XlibSurfaceKHR(const VkXlibSurfaceCreateInfoKHR *pCreateInfo, void *mem) : XlibSurfaceKHR::XlibSurfaceKHR(const VkXlibSurfaceCreateInfoKHR *pCreateInfo, void *mem)
pDisplay(pCreateInfo->dpy), : pDisplay(pCreateInfo->dpy)
window(pCreateInfo->window) , window(pCreateInfo->window)
{ {
int screen = DefaultScreen(pDisplay); int screen = DefaultScreen(pDisplay);
gc = libX11->XDefaultGC(pDisplay, screen); gc = libX11->XDefaultGC(pDisplay, screen);
XVisualInfo xVisual; XVisualInfo xVisual;
Status status = libX11->XMatchVisualInfo(pDisplay, screen, 32, TrueColor, &xVisual); Status status = libX11->XMatchVisualInfo(pDisplay, screen, 32, TrueColor, &xVisual);
bool match = (status != 0 && xVisual.blue_mask ==0xFF); bool match = (status != 0 && xVisual.blue_mask == 0xFF);
visual = match ? xVisual.visual : libX11->XDefaultVisual(pDisplay, screen); visual = match ? xVisual.visual : libX11->XDefaultVisual(pDisplay, screen);
} }
void XlibSurfaceKHR::destroySurface(const VkAllocationCallbacks *pAllocator) void XlibSurfaceKHR::destroySurface(const VkAllocationCallbacks *pAllocator)
{ {
} }
size_t XlibSurfaceKHR::ComputeRequiredAllocationSize(const VkXlibSurfaceCreateInfoKHR *pCreateInfo) size_t XlibSurfaceKHR::ComputeRequiredAllocationSize(const VkXlibSurfaceCreateInfoKHR *pCreateInfo)
...@@ -48,14 +47,14 @@ void XlibSurfaceKHR::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCa ...@@ -48,14 +47,14 @@ void XlibSurfaceKHR::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCa
XWindowAttributes attr; XWindowAttributes attr;
libX11->XGetWindowAttributes(pDisplay, window, &attr); libX11->XGetWindowAttributes(pDisplay, window, &attr);
VkExtent2D extent = {static_cast<uint32_t>(attr.width), static_cast<uint32_t>(attr.height)}; VkExtent2D extent = { static_cast<uint32_t>(attr.width), static_cast<uint32_t>(attr.height) };
pSurfaceCapabilities->currentExtent = extent; pSurfaceCapabilities->currentExtent = extent;
pSurfaceCapabilities->minImageExtent = extent; pSurfaceCapabilities->minImageExtent = extent;
pSurfaceCapabilities->maxImageExtent = extent; pSurfaceCapabilities->maxImageExtent = extent;
} }
void XlibSurfaceKHR::attachImage(PresentImage* image) void XlibSurfaceKHR::attachImage(PresentImage *image)
{ {
XWindowAttributes attr; XWindowAttributes attr;
libX11->XGetWindowAttributes(pDisplay, window, &attr); libX11->XGetWindowAttributes(pDisplay, window, &attr);
...@@ -63,37 +62,37 @@ void XlibSurfaceKHR::attachImage(PresentImage* image) ...@@ -63,37 +62,37 @@ void XlibSurfaceKHR::attachImage(PresentImage* image)
VkExtent3D extent = image->getImage()->getMipLevelExtent(VK_IMAGE_ASPECT_COLOR_BIT, 0); VkExtent3D extent = image->getImage()->getMipLevelExtent(VK_IMAGE_ASPECT_COLOR_BIT, 0);
int bytes_per_line = image->getImage()->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0); int bytes_per_line = image->getImage()->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
char* buffer = static_cast<char*>(image->getImageMemory()->getOffsetPointer(0)); char *buffer = static_cast<char *>(image->getImageMemory()->getOffsetPointer(0));
XImage* xImage = libX11->XCreateImage(pDisplay, visual, attr.depth, ZPixmap, 0, buffer, extent.width, extent.height, 32, bytes_per_line); XImage *xImage = libX11->XCreateImage(pDisplay, visual, attr.depth, ZPixmap, 0, buffer, extent.width, extent.height, 32, bytes_per_line);
imageMap[image] = xImage; imageMap[image] = xImage;
} }
void XlibSurfaceKHR::detachImage(PresentImage* image) void XlibSurfaceKHR::detachImage(PresentImage *image)
{ {
auto it = imageMap.find(image); auto it = imageMap.find(image);
if(it != imageMap.end()) if(it != imageMap.end())
{ {
XImage* xImage = it->second; XImage *xImage = it->second;
xImage->data = nullptr; // the XImage does not actually own the buffer xImage->data = nullptr; // the XImage does not actually own the buffer
XDestroyImage(xImage); XDestroyImage(xImage);
imageMap.erase(image); imageMap.erase(image);
} }
} }
VkResult XlibSurfaceKHR::present(PresentImage* image) VkResult XlibSurfaceKHR::present(PresentImage *image)
{ {
auto it = imageMap.find(image); auto it = imageMap.find(image);
if(it != imageMap.end()) if(it != imageMap.end())
{ {
XImage* xImage = it->second; XImage *xImage = it->second;
if(xImage->data) if(xImage->data)
{ {
XWindowAttributes attr; XWindowAttributes attr;
libX11->XGetWindowAttributes(pDisplay, window, &attr); libX11->XGetWindowAttributes(pDisplay, window, &attr);
VkExtent2D windowExtent = {static_cast<uint32_t>(attr.width), static_cast<uint32_t>(attr.height)}; VkExtent2D windowExtent = { static_cast<uint32_t>(attr.width), static_cast<uint32_t>(attr.height) };
VkExtent3D extent = image->getImage()->getMipLevelExtent(VK_IMAGE_ASPECT_COLOR_BIT, 0); VkExtent3D extent = image->getImage()->getMipLevelExtent(VK_IMAGE_ASPECT_COLOR_BIT, 0);
if(windowExtent.width != extent.width || windowExtent.height != extent.height) if(windowExtent.width != extent.width || windowExtent.height != extent.height)
...@@ -108,4 +107,4 @@ VkResult XlibSurfaceKHR::present(PresentImage* image) ...@@ -108,4 +107,4 @@ VkResult XlibSurfaceKHR::present(PresentImage* image)
return VK_SUCCESS; return VK_SUCCESS;
} }
} } // namespace vk
\ No newline at end of file \ No newline at end of file
...@@ -15,16 +15,17 @@ ...@@ -15,16 +15,17 @@
#ifndef SWIFTSHADER_XLIBSURFACEKHR_HPP #ifndef SWIFTSHADER_XLIBSURFACEKHR_HPP
#define SWIFTSHADER_XLIBSURFACEKHR_HPP #define SWIFTSHADER_XLIBSURFACEKHR_HPP
#include "Vulkan/VkObject.hpp"
#include "libX11.hpp"
#include "VkSurfaceKHR.hpp" #include "VkSurfaceKHR.hpp"
#include "libX11.hpp"
#include "Vulkan/VkObject.hpp"
#include "vulkan/vulkan_xlib.h" #include "vulkan/vulkan_xlib.h"
#include <unordered_map> #include <unordered_map>
namespace vk { namespace vk {
class XlibSurfaceKHR : public SurfaceKHR, public ObjectBase<XlibSurfaceKHR, VkSurfaceKHR> { class XlibSurfaceKHR : public SurfaceKHR, public ObjectBase<XlibSurfaceKHR, VkSurfaceKHR>
{
public: public:
XlibSurfaceKHR(const VkXlibSurfaceCreateInfoKHR *pCreateInfo, void *mem); XlibSurfaceKHR(const VkXlibSurfaceCreateInfoKHR *pCreateInfo, void *mem);
...@@ -34,17 +35,17 @@ public: ...@@ -34,17 +35,17 @@ public:
void getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const override; void getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const override;
virtual void attachImage(PresentImage* image) override; virtual void attachImage(PresentImage *image) override;
virtual void detachImage(PresentImage* image) override; virtual void detachImage(PresentImage *image) override;
VkResult present(PresentImage* image) override; VkResult present(PresentImage *image) override;
private: private:
Display *const pDisplay; Display *const pDisplay;
const Window window; const Window window;
GC gc; GC gc;
Visual *visual = nullptr; Visual *visual = nullptr;
std::unordered_map<PresentImage*, XImage*> imageMap; std::unordered_map<PresentImage *, XImage *> imageMap;
}; };
} } // namespace vk
#endif //SWIFTSHADER_XLIBSURFACEKHR_HPP #endif //SWIFTSHADER_XLIBSURFACEKHR_HPP
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
namespace { namespace {
template <typename FPTR> template<typename FPTR>
void getFuncAddress(void *lib, const char *name, FPTR *out) void getFuncAddress(void *lib, const char *name, FPTR *out)
{ {
*out = reinterpret_cast<FPTR>(getProcAddress(lib, name)); *out = reinterpret_cast<FPTR>(getProcAddress(lib, name));
...@@ -70,7 +70,7 @@ LibX11exports *LibX11::loadExports() ...@@ -70,7 +70,7 @@ LibX11exports *LibX11::loadExports()
if(getProcAddress(RTLD_DEFAULT, "XOpenDisplay")) // Search the global scope for pre-loaded X11 library. if(getProcAddress(RTLD_DEFAULT, "XOpenDisplay")) // Search the global scope for pre-loaded X11 library.
{ {
libX11exports = new LibX11exports(RTLD_DEFAULT, RTLD_DEFAULT); libX11exports = new LibX11exports(RTLD_DEFAULT, RTLD_DEFAULT);
libX11 = (void*)-1; // No need to load it. libX11 = (void *)-1; // No need to load it.
} }
else else
{ {
...@@ -83,7 +83,7 @@ LibX11exports *LibX11::loadExports() ...@@ -83,7 +83,7 @@ LibX11exports *LibX11::loadExports()
} }
else else
{ {
libX11 = (void*)-1; // Don't attempt loading more than once. libX11 = (void *)-1; // Don't attempt loading more than once.
} }
} }
} }
......
...@@ -30,11 +30,12 @@ struct LibX11exports ...@@ -30,11 +30,12 @@ struct LibX11exports
int (*XWidthOfScreen)(Screen *screen); int (*XWidthOfScreen)(Screen *screen);
int (*XHeightOfScreen)(Screen *screen); int (*XHeightOfScreen)(Screen *screen);
int (*XPlanesOfScreen)(Screen *screen); int (*XPlanesOfScreen)(Screen *screen);
GC (*XDefaultGC)(Display *display, int screen_number); GC(*XDefaultGC)
(Display *display, int screen_number);
int (*XDefaultDepth)(Display *display, int screen_number); int (*XDefaultDepth)(Display *display, int screen_number);
Status (*XMatchVisualInfo)(Display *display, int screen, int depth, int screen_class, XVisualInfo *vinfo_return); Status (*XMatchVisualInfo)(Display *display, int screen, int depth, int screen_class, XVisualInfo *vinfo_return);
Visual *(*XDefaultVisual)(Display *display, int screen_number); Visual *(*XDefaultVisual)(Display *display, int screen_number);
int (*(*XSetErrorHandler)(int (*handler)(Display*, XErrorEvent*)))(Display*, XErrorEvent*); int (*(*XSetErrorHandler)(int (*handler)(Display *, XErrorEvent *)))(Display *, XErrorEvent *);
int (*XSync)(Display *display, Bool discard); int (*XSync)(Display *display, Bool discard);
XImage *(*XCreateImage)(Display *display, Visual *visual, unsigned int depth, int format, int offset, char *data, unsigned int width, unsigned int height, int bitmap_pad, int bytes_per_line); XImage *(*XCreateImage)(Display *display, Visual *visual, unsigned int depth, int format, int offset, char *data, unsigned int width, unsigned int height, int bitmap_pad, int bytes_per_line);
int (*XCloseDisplay)(Display *display); int (*XCloseDisplay)(Display *display);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment