mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-10-09 03:53:55 +00:00
More vulkan in thin3d
This commit is contained in:
parent
2a71e164f5
commit
73d6d2dc72
@ -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>
|
||||
|
@ -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() {
|
||||
|
@ -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)";
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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>
|
Loading…
Reference in New Issue
Block a user