mirror of
https://github.com/izzy2lost/ppsspp.git
synced 2026-03-10 12:43:04 -07:00
Merge pull request #15727 from hrydgard/texture-3d
Implement the PSP's equal-size mips "3D texturing"
This commit is contained in:
@@ -31,7 +31,7 @@ static bool IsDepthStencilFormat(VkFormat format) {
|
||||
}
|
||||
}
|
||||
|
||||
bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips, VkFormat format, VkImageLayout initialLayout, VkImageUsageFlags usage, const VkComponentMapping *mapping) {
|
||||
bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int depth, int numMips, VkFormat format, VkImageLayout initialLayout, VkImageUsageFlags usage, const VkComponentMapping *mapping) {
|
||||
if (w == 0 || h == 0 || numMips == 0) {
|
||||
ERROR_LOG(G3D, "Can't create a zero-size VulkanTexture");
|
||||
return false;
|
||||
@@ -41,17 +41,18 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips,
|
||||
|
||||
width_ = w;
|
||||
height_ = h;
|
||||
depth_ = depth;
|
||||
numMips_ = numMips;
|
||||
format_ = format;
|
||||
|
||||
VkImageAspectFlags aspect = IsDepthStencilFormat(format) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
||||
VkImageCreateInfo image_create_info{ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
|
||||
image_create_info.imageType = VK_IMAGE_TYPE_2D;
|
||||
image_create_info.imageType = depth > 1 ? VK_IMAGE_TYPE_3D : VK_IMAGE_TYPE_2D;
|
||||
image_create_info.format = format_;
|
||||
image_create_info.extent.width = width_;
|
||||
image_create_info.extent.height = height_;
|
||||
image_create_info.extent.depth = 1;
|
||||
image_create_info.extent.depth = depth;
|
||||
image_create_info.mipLevels = numMips;
|
||||
image_create_info.arrayLayers = 1;
|
||||
image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
@@ -98,7 +99,7 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips,
|
||||
// Create the view while we're at it.
|
||||
VkImageViewCreateInfo view_info{ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO };
|
||||
view_info.image = image_;
|
||||
view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
view_info.viewType = depth > 1 ? VK_IMAGE_VIEW_TYPE_3D : VK_IMAGE_VIEW_TYPE_2D;
|
||||
view_info.format = format_;
|
||||
if (mapping) {
|
||||
view_info.components = *mapping;
|
||||
@@ -122,11 +123,12 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips,
|
||||
}
|
||||
|
||||
// TODO: Batch these.
|
||||
void VulkanTexture::UploadMip(VkCommandBuffer cmd, int mip, int mipWidth, int mipHeight, VkBuffer buffer, uint32_t offset, size_t rowLength) {
|
||||
void VulkanTexture::UploadMip(VkCommandBuffer cmd, int mip, int mipWidth, int mipHeight, int depthLayer, VkBuffer buffer, uint32_t offset, size_t rowLength) {
|
||||
VkBufferImageCopy copy_region{};
|
||||
copy_region.bufferOffset = offset;
|
||||
copy_region.bufferRowLength = (uint32_t)rowLength;
|
||||
copy_region.bufferImageHeight = 0; // 2D
|
||||
copy_region.imageOffset.z = depthLayer;
|
||||
copy_region.imageExtent.width = mipWidth;
|
||||
copy_region.imageExtent.height = mipHeight;
|
||||
copy_region.imageExtent.depth = 1;
|
||||
|
||||
@@ -22,9 +22,11 @@ public:
|
||||
// Fast uploads from buffer. Mipmaps supported.
|
||||
// Usage must at least include VK_IMAGE_USAGE_TRANSFER_DST_BIT in order to use UploadMip.
|
||||
// When using UploadMip, initialLayout should be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL.
|
||||
bool CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips, VkFormat format, VkImageLayout initialLayout, VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, const VkComponentMapping *mapping = nullptr);
|
||||
bool CreateDirect(VkCommandBuffer cmd, int w, int h, int depth, int numMips, VkFormat format, VkImageLayout initialLayout, VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, const VkComponentMapping *mapping = nullptr);
|
||||
void ClearMip(VkCommandBuffer cmd, int mip, uint32_t value);
|
||||
void UploadMip(VkCommandBuffer cmd, int mip, int mipWidth, int mipHeight, VkBuffer buffer, uint32_t offset, size_t rowLength); // rowLength is in pixels
|
||||
|
||||
// Can also be used to copy individual levels of a 3D texture.
|
||||
void UploadMip(VkCommandBuffer cmd, int mip, int mipWidth, int mipHeight, int depthLayer, VkBuffer buffer, uint32_t offset, size_t rowLength); // rowLength is in pixels
|
||||
|
||||
void GenerateMips(VkCommandBuffer cmd, int firstMipToGenerate, bool fromCompute);
|
||||
void EndCreate(VkCommandBuffer cmd, bool vertexTexture, VkPipelineStageFlags prevStage, VkImageLayout layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
@@ -62,10 +64,11 @@ private:
|
||||
VkImageView view_ = VK_NULL_HANDLE;
|
||||
VmaAllocation allocation_ = VK_NULL_HANDLE;
|
||||
|
||||
int32_t width_ = 0;
|
||||
int32_t height_ = 0;
|
||||
int32_t numMips_ = 1;
|
||||
int16_t width_ = 0;
|
||||
int16_t height_ = 0;
|
||||
int16_t numMips_ = 1;
|
||||
int16_t depth_ = 1;
|
||||
|
||||
VkFormat format_ = VK_FORMAT_UNDEFINED;
|
||||
size_t offset_ = 0;
|
||||
std::string tag_;
|
||||
};
|
||||
|
||||
@@ -640,7 +640,7 @@ VulkanTexture *VKContext::GetNullTexture() {
|
||||
nullTexture_->SetTag("Null");
|
||||
int w = 8;
|
||||
int h = 8;
|
||||
nullTexture_->CreateDirect(cmdInit, w, h, 1, VK_FORMAT_A8B8G8R8_UNORM_PACK32, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
nullTexture_->CreateDirect(cmdInit, w, h, 1, 1, VK_FORMAT_A8B8G8R8_UNORM_PACK32, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||
uint32_t bindOffset;
|
||||
VkBuffer bindBuf;
|
||||
@@ -651,7 +651,7 @@ VulkanTexture *VKContext::GetNullTexture() {
|
||||
data[y*w + x] = 0; // black
|
||||
}
|
||||
}
|
||||
nullTexture_->UploadMip(cmdInit, 0, w, h, bindBuf, bindOffset, w);
|
||||
nullTexture_->UploadMip(cmdInit, 0, w, h, 0, bindBuf, bindOffset, w);
|
||||
nullTexture_->EndCreate(cmdInit, false, VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
} else {
|
||||
nullTexture_->Touch();
|
||||
@@ -733,7 +733,7 @@ bool VKTexture::Create(VkCommandBuffer cmd, VulkanPushBuffer *push, const Textur
|
||||
usageBits |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
}
|
||||
|
||||
if (!vkTex_->CreateDirect(cmd, width_, height_, mipLevels_, vulkanFormat, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, usageBits)) {
|
||||
if (!vkTex_->CreateDirect(cmd, width_, height_, 1, mipLevels_, vulkanFormat, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, usageBits)) {
|
||||
ERROR_LOG(G3D, "Failed to create VulkanTexture: %dx%dx%d fmt %d, %d levels", width_, height_, depth_, (int)vulkanFormat, mipLevels_);
|
||||
return false;
|
||||
}
|
||||
@@ -755,7 +755,7 @@ bool VKTexture::Create(VkCommandBuffer cmd, VulkanPushBuffer *push, const Textur
|
||||
} else {
|
||||
offset = push->PushAligned((const void *)desc.initData[i], size, 16, &buf);
|
||||
}
|
||||
vkTex_->UploadMip(cmd, i, w, h, buf, offset, w);
|
||||
vkTex_->UploadMip(cmd, i, w, h, 0, buf, offset, w);
|
||||
w = (w + 1) / 2;
|
||||
h = (h + 1) / 2;
|
||||
d = (d + 1) / 2;
|
||||
@@ -787,6 +787,7 @@ VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit)
|
||||
caps_.framebufferDepthBlitSupported = false; // Can be checked for.
|
||||
caps_.framebufferDepthCopySupported = true; // Will pretty much always be the case.
|
||||
caps_.preferredDepthBufferFormat = DataFormat::D24_S8; // TODO: Ask vulkan.
|
||||
caps_.texture3DSupported = true;
|
||||
|
||||
auto deviceProps = vulkan->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDeviceIndex()).properties;
|
||||
switch (deviceProps.vendorID) {
|
||||
|
||||
Reference in New Issue
Block a user