More vulkan in thin3d

This commit is contained in:
Henrik Rydgard 2015-12-31 01:07:06 +01:00
parent 2a71e164f5
commit 73d6d2dc72
8 changed files with 74 additions and 63 deletions

View File

@ -83,7 +83,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>../common;..;../ext/native;../ext/native/ext/glew;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../common;..;../ext;../ext/native;../ext/native/ext/glew;</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;_M_IX86=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
@ -105,7 +105,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>../common;..;../ext/native;../ext/native/ext/glew;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../common;..;../ext;../ext/native;../ext/native/ext/glew;</AdditionalIncludeDirectories>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<OmitFramePointers>false</OmitFramePointers>
@ -131,7 +131,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>../common;..;../ext/native;../ext/native/ext/glew;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../common;..;../ext;../ext/native;../ext/native/ext/glew;</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
@ -157,7 +157,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>../common;..;../ext/native;../ext/native/ext/glew;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../common;..;../ext;../ext/native;../ext/native/ext/glew;</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>

View File

@ -135,6 +135,8 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m
return false;
}
init_glslang();
g_Vulkan = new VulkanContext("PPSSPP", VULKAN_FLAG_VALIDATE);
g_Vulkan->CreateDevice(0);
g_Vulkan->InitDebugMsgCallback(Vulkan_Dbg);
@ -157,6 +159,8 @@ void WindowsVulkanContext::Shutdown() {
g_Vulkan->DestroyDevice();
delete g_Vulkan;
g_Vulkan = nullptr;
finalize_glslang();
}
Thin3DContext *WindowsVulkanContext::CreateThin3DContext() {

View File

@ -1134,10 +1134,10 @@ void VulkanTexture::Create(VulkanContext *vulkan, int w, int h) {
/* Create a mappable image. It will be the texture if linear images are ok to be textures */
/* or it will be the staging image if they are not. */
VkResult res = vkCreateImage(vulkan->Device(), &image_create_info, NULL, &mappableImage);
VkResult res = vkCreateImage(vulkan->GetDevice(), &image_create_info, NULL, &mappableImage);
assert(res == VK_SUCCESS);
vkGetImageMemoryRequirements(vulkan->Device(), mappableImage, &mem_reqs);
vkGetImageMemoryRequirements(vulkan->GetDevice(), mappableImage, &mem_reqs);
assert(res == VK_SUCCESS);
mem_alloc.allocationSize = mem_reqs.size;
@ -1146,10 +1146,10 @@ void VulkanTexture::Create(VulkanContext *vulkan, int w, int h) {
pass = vulkan->MemoryTypeFromProperties(mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &mem_alloc.memoryTypeIndex);
assert(pass);
res = vkAllocateMemory(vulkan->Device(), &mem_alloc, NULL, &(mappableMemory));
res = vkAllocateMemory(vulkan->GetDevice(), &mem_alloc, NULL, &(mappableMemory));
assert(res == VK_SUCCESS);
res = vkBindImageMemory(vulkan->Device(), mappableImage, mappableMemory, 0);
res = vkBindImageMemory(vulkan->GetDevice(), mappableImage, mappableMemory, 0);
assert(res == VK_SUCCESS);
}
@ -1628,3 +1628,36 @@ void init_glslang() {
void finalize_glslang() {
glslang::FinalizeProcess();
}
const char *VulkanResultToString(VkResult res) {
switch (res) {
case VK_NOT_READY: return "VK_NOT_READY";
case VK_TIMEOUT: return "VK_TIMEOUT";
case VK_EVENT_SET: return "VK_EVENT_SET";
case VK_EVENT_RESET: return "VK_EVENT_RESET";
case VK_INCOMPLETE: return "VK_INCOMPLETE";
case VK_ERROR_OUT_OF_HOST_MEMORY: return "VK_ERROR_OUT_OF_HOST_MEMORY";
case VK_ERROR_OUT_OF_DEVICE_MEMORY: return "VK_ERROR_OUT_OF_DEVICE_MEMORY";
case VK_ERROR_INITIALIZATION_FAILED: return "VK_ERROR_INITIALIZATION_FAILED";
case VK_ERROR_DEVICE_LOST: return "VK_ERROR_DEVICE_LOST";
case VK_ERROR_MEMORY_MAP_FAILED: return "VK_ERROR_MEMORY_MAP_FAILED";
case VK_ERROR_LAYER_NOT_PRESENT: return "VK_ERROR_LAYER_NOT_PRESENT";
case VK_ERROR_EXTENSION_NOT_PRESENT: return "VK_ERROR_EXTENSION_NOT_PRESENT";
case VK_ERROR_FEATURE_NOT_PRESENT: return "VK_ERROR_FEATURE_NOT_PRESENT";
case VK_ERROR_INCOMPATIBLE_DRIVER: return "VK_ERROR_INCOMPATIBLE_DRIVER";
case VK_ERROR_TOO_MANY_OBJECTS: return "VK_ERROR_TOO_MANY_OBJECTS";
case VK_ERROR_FORMAT_NOT_SUPPORTED: return "VK_ERROR_FORMAT_NOT_SUPPORTED";
case VK_ERROR_SURFACE_LOST_KHR: return "VK_ERROR_SURFACE_LOST_KHR";
case VK_SUBOPTIMAL_KHR: return "VK_SUBOPTIMAL_KHR";
case VK_ERROR_OUT_OF_DATE_KHR: return "VK_ERROR_OUT_OF_DATE_KHR";
case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR";
case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR";
default:
return "Unknown";
}
}
void VulkanAssertImpl(VkResult check, const char *function, const char *file, int line) {
const char *error = "(none)";
}

View File

@ -71,7 +71,7 @@ public:
VkResult CreateDevice(int physical_device);
VkDevice Device() {
VkDevice GetDevice() {
return device_;
}
@ -274,5 +274,10 @@ void TransitionImageLayout(
VkImageLayout old_image_layout,
VkImageLayout new_image_layout);
void VulkanAssertImpl(VkResult check, const char *function, const char *file, int line);
// DO NOT call vulkan functions within this! Instead, store the result in a variable and check that.
#define VulkanAssert(x) if ((x) != VK_SUCCESS) VulkanAssertImpl((x), __FUNCTION__, __FILE__, __LINE__);
#endif // UTIL_INIT

View File

@ -114,7 +114,7 @@ static inline void Uint8x4ToFloat4(uint32_t u, float f[4]) {
// their own similar buffer solutions.
class VulkanPushBuffer {
public:
VulkanPushBuffer(VkDevice device, VulkanDeviceMemoryManager *memMan, size_t size) : offset_(0), size_(size), writePtr_(nullptr) {
VulkanPushBuffer(VkDevice device, VulkanContext *vulkan, size_t size) : offset_(0), size_(size), writePtr_(nullptr) {
VkBufferCreateInfo b;
b.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
b.pNext = nullptr;
@ -131,7 +131,7 @@ public:
VkMemoryAllocateInfo alloc;
alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
alloc.pNext = nullptr;
memMan->memory_type_from_properties(0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &alloc.memoryTypeIndex);
vulkan->MemoryTypeFromProperties(0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &alloc.memoryTypeIndex);
alloc.allocationSize = size;
res = vkAllocateMemory(device, &alloc, nullptr, &deviceMemory_);
@ -511,8 +511,6 @@ private:
VulkanContext *vulkan_;
VulkanDeviceMemoryManager vulkanMem_;
// These are used to compose the pipeline cache key.
Thin3DVKBlendState *curBlendState_;
Thin3DVKDepthStencilState *curDepthStencilState_;
@ -633,10 +631,10 @@ enum class TextureState {
class Thin3DVKTexture : public Thin3DTexture {
public:
Thin3DVKTexture(VkDevice device, VulkanDeviceMemoryManager *memMan) : device_(device), memMan_(memMan), state_(TextureState::UNINITIALIZED) {
Thin3DVKTexture(VulkanContext *vulkan) : vulkan_(vulkan), state_(TextureState::UNINITIALIZED) {
}
Thin3DVKTexture(VkDevice device, VulkanDeviceMemoryManager *memMan, T3DTextureType type, T3DImageFormat format, int width, int height, int depth, int mipLevels)
: device_(device), memMan_(memMan), format_(format), mipLevels_(mipLevels) {
Thin3DVKTexture(VulkanContext *vulkan, T3DTextureType type, T3DImageFormat format, int width, int height, int depth, int mipLevels)
: vulkan_(vulkan), format_(format), mipLevels_(mipLevels) {
Create(type, format, width, height, depth, mipLevels);
}
@ -671,7 +669,7 @@ public:
VkImageView GetImageView() { return view_; }
private:
VulkanDeviceMemoryManager *memMan_;
VulkanContext *vulkan_;
VkDevice device_;
VulkanImage image_;
VulkanImage staging_;
@ -685,8 +683,8 @@ private:
};
Thin3DVKContext::Thin3DVKContext(VulkanContext *vulkan)
: viewportDirty_(false), scissorDirty_(false) {
device_ = vulkan->Device();
: viewportDirty_(false), scissorDirty_(false), vulkan_(vulkan) {
device_ = vulkan->GetDevice();
noScissor_.offset.x = 0;
noScissor_.offset.y = 0;
@ -723,8 +721,8 @@ Thin3DVKContext::Thin3DVKContext(VulkanContext *vulkan)
dp.poolSizeCount = ARRAY_SIZE(dpTypes);
res = vkCreateDescriptorPool(device_, &dp, nullptr, &descriptorPool_);
assert(VK_SUCCESS == res);
pushBuffer_[0] = new VulkanPushBuffer(device_, &vulkanMem_, 1024 * 1024);
pushBuffer_[1] = new VulkanPushBuffer(device_, &vulkanMem_, 1024 * 1024);
pushBuffer_[0] = new VulkanPushBuffer(device_, vulkan_, 1024 * 1024);
pushBuffer_[1] = new VulkanPushBuffer(device_, vulkan_, 1024 * 1024);
// binding 0 - vertex data
// binding 1 - uniform data
@ -1120,11 +1118,11 @@ Thin3DVertexFormat *Thin3DVKContext::CreateVertexFormat(const std::vector<Thin3D
}
Thin3DTexture *Thin3DVKContext::CreateTexture() {
return new Thin3DVKTexture(device_, &vulkanMem_);
return new Thin3DVKTexture(vulkan_);
}
Thin3DTexture *Thin3DVKContext::CreateTexture(T3DTextureType type, T3DImageFormat format, int width, int height, int depth, int mipLevels) {
return new Thin3DVKTexture(device_, &vulkanMem_, type, format, width, height, depth, mipLevels);
return new Thin3DVKTexture(vulkan_, type, format, width, height, depth, mipLevels);
}
void Thin3DVKTexture::SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) {
@ -1134,8 +1132,8 @@ void Thin3DVKTexture::SetImageData(int x, int y, int z, int width, int height, i
// So we need to do a staging copy. We upload the data to the staging buffer immediately, then we actually do the final copy once it's used the first time
// as we need a command buffer and the architecture of Thin3D doesn't really work the way we want..
if (!image_.IsValid()) {
staging_.Create2D(device_, memMan_, vulkanFormat, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, width, height);
image_.Create2D(device_, memMan_, vulkanFormat, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, (VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT), width, height);
staging_.Create2D(device_, vulkan_, vulkanFormat, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, width, height);
image_.Create2D(device_, vulkan_, vulkanFormat, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, (VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT), width, height);
}
VkImageViewCreateInfo iv;

View File

@ -40,28 +40,7 @@
#include "thin3d/vulkan_utils.h"
void VulkanDeviceMemoryManager::Init(VkPhysicalDevice gpu) {
// Get Memory information and properties
vkGetPhysicalDeviceMemoryProperties(gpu, &memory_properties_);
}
VkResult VulkanDeviceMemoryManager::memory_type_from_properties(uint32_t typeBits, VkFlags requirements_mask, uint32_t *typeIndex) {
// Search memtypes to find first index with those properties
for (uint32_t i = 0; i < 32; i++) {
if ((typeBits & 1) == 1) {
// Type is available, does it match user properties?
if ((memory_properties_.memoryTypes[i].propertyFlags & requirements_mask) == requirements_mask) {
*typeIndex = i;
return VK_SUCCESS;
}
}
typeBits >>= 1;
}
// No memory types matched, return failure
return VK_ERROR_FORMAT_NOT_SUPPORTED;
}
void VulkanImage::Create2D(VkDevice device, VulkanDeviceMemoryManager *memMan, VkFormat format, VkFlags required_props, VkImageUsageFlags usage, int width, int height) {
void VulkanImage::Create2D(VkDevice device, VulkanContext *vulkan, VkFormat format, VkFlags required_props, VkImageUsageFlags usage, int width, int height) {
width_ = width;
height_ = height;
@ -94,8 +73,8 @@ void VulkanImage::Create2D(VkDevice device, VulkanDeviceMemoryManager *memMan, V
mem_alloc_.allocationSize = mem_reqs.size;
mem_alloc_.memoryTypeIndex = 0;
err = memMan->memory_type_from_properties(mem_reqs.memoryTypeBits, required_props, &mem_alloc_.memoryTypeIndex);
assert(!err);
bool res = vulkan->MemoryTypeFromProperties(mem_reqs.memoryTypeBits, required_props, &mem_alloc_.memoryTypeIndex);
assert(res);
err = vkAllocateMemory(device, &mem_alloc_, nullptr, &memory_);
assert(!err);

View File

@ -21,18 +21,7 @@
#define VK_PROTOTYPES
#include "ext/vulkan/vulkan.h"
//
class VulkanDeviceMemoryManager {
public:
VulkanDeviceMemoryManager() {}
void Init(VkPhysicalDevice gpu);
VkResult memory_type_from_properties(uint32_t typeBits, VkFlags requirements_mask, uint32_t *typeIndex);
private:
VkPhysicalDeviceMemoryProperties memory_properties_;
};
#include "VulkanContext.h"
// Utility class to handle images without going insane.
@ -43,7 +32,7 @@ public:
bool IsValid() const { return image_ != nullptr; }
// This can be done completely unsynchronized.
void Create2D(VkDevice device, VulkanDeviceMemoryManager *memMan, VkFormat format, VkFlags required_props, VkImageUsageFlags usage, int width, int height);
void Create2D(VkDevice device, VulkanContext *vulkan, VkFormat format, VkFlags required_props, VkImageUsageFlags usage, int width, int height);
// This can only be used if you pass in VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT in required_props in Create2D.
void SetImageData2D(VkDevice device, const uint8_t *data, int width, int height, int pitch);

View File

@ -246,6 +246,9 @@
<ProjectReference Include="..\Core\Core.vcxproj">
<Project>{533f1d30-d04d-47cc-ad71-20f658907e36}</Project>
</ProjectReference>
<ProjectReference Include="..\ext\glslang.vcxproj">
<Project>{edfa2e87-8ac1-4853-95d4-d7594ff81947}</Project>
</ProjectReference>
<ProjectReference Include="..\ext\libkirk\libkirk.vcxproj">
<Project>{3baae095-e0ab-4b0e-b5df-ce39c8ae31de}</Project>
</ProjectReference>
@ -269,4 +272,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>