mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-30 01:01:21 +00:00
graphics: refactoring #2
This commit is contained in:
1 parent
b51d4322cc
commit
0a5f78c727
137 files changed
+10230
-10893
No files matched your search
@@ -4,6 +4,7 @@
|
||||
#include "common/threads.h"
|
||||
#include "graphics/host_gpu/graphicContext.h"
|
||||
#include "graphics/host_gpu/renderer/render.h"
|
||||
#include "graphics/host_gpu/renderer/renderContext.h"
|
||||
#include "graphics/host_gpu/vulkanCommon.h"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -58,17 +59,16 @@ public:
|
||||
~LabelManager() { KYTY_NOT_IMPLEMENTED; }
|
||||
KYTY_CLASS_NO_COPY(LabelManager);
|
||||
|
||||
Label* Create(GraphicContext* ctx, LabelCallback callback_1, LabelCallback callback_2,
|
||||
const uint64_t* args);
|
||||
void Delete(Label* label);
|
||||
void Set(CommandBuffer* buffer, Label* label);
|
||||
Label* Create(LabelCallback callback_1, LabelCallback callback_2, const uint64_t* args);
|
||||
void Delete(Label& label);
|
||||
void Set(CommandBuffer& buffer, Label& label);
|
||||
void Drain();
|
||||
|
||||
private:
|
||||
static void ThreadRun(void* data);
|
||||
|
||||
bool Remove(Label* label);
|
||||
static void Destroy(Label* label);
|
||||
bool Remove(Label& label);
|
||||
static void Destroy(Label& label);
|
||||
|
||||
Common::Mutex m_mutex;
|
||||
Common::CondVar m_cond_var;
|
||||
@@ -146,7 +146,7 @@ void LabelManager::ThreadRun(void* data) {
|
||||
manager->m_callbacks_in_flight += fired_labels.size();
|
||||
|
||||
for (auto& label: deleted_labels) {
|
||||
bool removed = manager->Remove(label);
|
||||
bool removed = manager->Remove(*label);
|
||||
EXIT_NOT_IMPLEMENTED(!removed);
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ void LabelManager::ThreadRun(void* data) {
|
||||
(void)finished_submissions;
|
||||
|
||||
for (auto& label: deleted_labels) {
|
||||
Destroy(label);
|
||||
Destroy(*label);
|
||||
}
|
||||
|
||||
for (auto& label: fired_labels) {
|
||||
@@ -186,16 +186,14 @@ void LabelManager::ThreadRun(void* data) {
|
||||
}
|
||||
}
|
||||
|
||||
Label* LabelManager::Create(GraphicContext* ctx, LabelCallback callback_1, LabelCallback callback_2,
|
||||
Label* LabelManager::Create(LabelCallback callback_1, LabelCallback callback_2,
|
||||
const uint64_t* args) {
|
||||
EXIT_IF(ctx == nullptr);
|
||||
|
||||
Common::LockGuard lock(m_mutex);
|
||||
|
||||
auto* label = new Label;
|
||||
|
||||
label->status = LabelStatus::New;
|
||||
label->device = ctx->device;
|
||||
label->device = GetRenderContext().GetGraphics().device;
|
||||
label->callbacks.callback_1 = callback_1;
|
||||
label->callbacks.callback_2 = callback_2;
|
||||
|
||||
@@ -210,21 +208,20 @@ Label* LabelManager::Create(GraphicContext* ctx, LabelCallback callback_1, Label
|
||||
return label;
|
||||
}
|
||||
|
||||
bool LabelManager::Remove(Label* label) {
|
||||
EXIT_IF(label == nullptr);
|
||||
EXIT_IF(label->device == nullptr);
|
||||
bool LabelManager::Remove(Label& label) {
|
||||
EXIT_IF(label.device == nullptr);
|
||||
|
||||
Common::LockGuard lock(m_mutex);
|
||||
|
||||
const auto it = std::find(m_labels.begin(), m_labels.end(), label);
|
||||
const auto it = std::find(m_labels.begin(), m_labels.end(), &label);
|
||||
EXIT_NOT_IMPLEMENTED(it == m_labels.end());
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(label->status != LabelStatus::NotActive &&
|
||||
label->status != LabelStatus::Active &&
|
||||
label->status != LabelStatus::ActiveDeleted);
|
||||
EXIT_NOT_IMPLEMENTED(label.status != LabelStatus::NotActive &&
|
||||
label.status != LabelStatus::Active &&
|
||||
label.status != LabelStatus::ActiveDeleted);
|
||||
|
||||
if (!label->submissions.empty()) {
|
||||
label->status = LabelStatus::ActiveDeleted;
|
||||
if (!label.submissions.empty()) {
|
||||
label.status = LabelStatus::ActiveDeleted;
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -234,44 +231,41 @@ bool LabelManager::Remove(Label* label) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void LabelManager::Destroy(Label* label) {
|
||||
EXIT_IF(label == nullptr);
|
||||
EXIT_IF(label->device == nullptr);
|
||||
void LabelManager::Destroy(Label& label) {
|
||||
EXIT_IF(label.device == nullptr);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(!label->submissions.empty());
|
||||
EXIT_NOT_IMPLEMENTED(!label.submissions.empty());
|
||||
|
||||
delete label;
|
||||
delete &label;
|
||||
}
|
||||
|
||||
void LabelManager::Delete(Label* label) {
|
||||
void LabelManager::Delete(Label& label) {
|
||||
if (Remove(label)) {
|
||||
Destroy(label);
|
||||
}
|
||||
}
|
||||
|
||||
void LabelManager::Set(CommandBuffer* buffer, Label* label) {
|
||||
EXIT_IF(label == nullptr);
|
||||
EXIT_IF(buffer == nullptr);
|
||||
EXIT_IF(buffer->IsInvalid());
|
||||
EXIT_IF(label->device == nullptr);
|
||||
void LabelManager::Set(CommandBuffer& buffer, Label& label) {
|
||||
EXIT_IF(buffer.IsInvalid());
|
||||
EXIT_IF(label.device == nullptr);
|
||||
|
||||
Common::LockGuard lock(m_mutex);
|
||||
|
||||
const auto it = std::find(m_labels.begin(), m_labels.end(), label);
|
||||
const auto it = std::find(m_labels.begin(), m_labels.end(), &label);
|
||||
EXIT_NOT_IMPLEMENTED(it == m_labels.end());
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(label->status != LabelStatus::New &&
|
||||
label->status != LabelStatus::NotActive &&
|
||||
label->status != LabelStatus::Active);
|
||||
EXIT_NOT_IMPLEMENTED(label.status != LabelStatus::New &&
|
||||
label.status != LabelStatus::NotActive &&
|
||||
label.status != LabelStatus::Active);
|
||||
|
||||
label->status = LabelStatus::Active;
|
||||
label.status = LabelStatus::Active;
|
||||
|
||||
LabelSubmission submission {};
|
||||
submission.callbacks = label->callbacks;
|
||||
submission.callbacks = label.callbacks;
|
||||
submission.completion = std::make_shared<LabelEvent>();
|
||||
submission.completion->device = label->device;
|
||||
submission.completion->device = label.device;
|
||||
|
||||
auto vk_buffer = buffer->Handle();
|
||||
auto vk_buffer = buffer.Handle();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(vk_buffer == nullptr);
|
||||
|
||||
@@ -281,24 +275,24 @@ void LabelManager::Set(CommandBuffer* buffer, Label* label) {
|
||||
create_info.flags = {};
|
||||
|
||||
const auto create_result =
|
||||
label->device.createEvent(&create_info, nullptr, &submission.completion->event);
|
||||
label.device.createEvent(&create_info, nullptr, &submission.completion->event);
|
||||
if (create_result != vk::Result::eSuccess || submission.completion->event == nullptr) {
|
||||
EXIT("failed to create label event: %s (%d)\n", VulkanToString(create_result).c_str(),
|
||||
static_cast<int>(create_result));
|
||||
}
|
||||
buffer->RetainResourceUntilFence(submission.completion);
|
||||
buffer.RetainResourceUntilFence(submission.completion);
|
||||
|
||||
// Labels can be reused before an earlier end-of-pipe event has been
|
||||
// observed by the polling thread. Capture a separate Vulkan event and
|
||||
// callback snapshot for each set so older writes are not lost.
|
||||
const auto reset_result = label->device.resetEvent(submission.completion->event);
|
||||
const auto reset_result = label.device.resetEvent(submission.completion->event);
|
||||
if (reset_result != vk::Result::eSuccess) {
|
||||
EXIT("failed to reset label event: %s (%d)\n", VulkanToString(reset_result).c_str(),
|
||||
static_cast<int>(reset_result));
|
||||
}
|
||||
vk_buffer.setEvent(submission.completion->event, vk::PipelineStageFlagBits::eBottomOfPipe);
|
||||
|
||||
label->submissions.push_back(submission);
|
||||
label.submissions.push_back(submission);
|
||||
|
||||
m_cond_var.SignalAll();
|
||||
}
|
||||
@@ -324,20 +318,19 @@ void LabelInit() {
|
||||
g_label_manager = new LabelManager;
|
||||
}
|
||||
|
||||
Label* LabelCreate(GraphicContext* ctx, LabelCallback callback_1, LabelCallback callback_2,
|
||||
const uint64_t* args) {
|
||||
Label* LabelCreate(LabelCallback callback_1, LabelCallback callback_2, const uint64_t* args) {
|
||||
EXIT_IF(g_label_manager == nullptr);
|
||||
|
||||
return g_label_manager->Create(ctx, callback_1, callback_2, args);
|
||||
return g_label_manager->Create(callback_1, callback_2, args);
|
||||
}
|
||||
|
||||
void LabelDelete(Label* label) {
|
||||
void LabelDelete(Label& label) {
|
||||
EXIT_IF(g_label_manager == nullptr);
|
||||
|
||||
g_label_manager->Delete(label);
|
||||
}
|
||||
|
||||
void LabelSet(CommandBuffer* buffer, Label* label) {
|
||||
void LabelSet(CommandBuffer& buffer, Label& label) {
|
||||
EXIT_IF(g_label_manager == nullptr);
|
||||
|
||||
g_label_manager->Set(buffer, label);
|
||||
|
||||
@@ -15,10 +15,9 @@ void LabelInit();
|
||||
constexpr int LABEL_ARGS_MAX = 5;
|
||||
using LabelCallback = bool (*)(const uint64_t* args);
|
||||
|
||||
Label* LabelCreate(GraphicContext* ctx, LabelCallback callback_1, LabelCallback callback_2,
|
||||
const uint64_t* args);
|
||||
void LabelDelete(Label* label);
|
||||
void LabelSet(CommandBuffer* buffer, Label* label);
|
||||
Label* LabelCreate(LabelCallback callback_1, LabelCallback callback_2, const uint64_t* args);
|
||||
void LabelDelete(Label& label);
|
||||
void LabelSet(CommandBuffer& buffer, Label& label);
|
||||
void LabelDrain();
|
||||
[[nodiscard]] bool LabelInCallback() noexcept;
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "graphics/guest_gpu/gpu_defs.h"
|
||||
#include "graphics/guest_gpu/gpu_format.h"
|
||||
#include "graphics/host_gpu/graphicContext.h"
|
||||
#include "graphics/host_gpu/renderer/renderContext.h"
|
||||
#include "graphics/host_gpu/transfer.h"
|
||||
#include "graphics/host_gpu/vma.h"
|
||||
#include "graphics/host_gpu/vulkanCommon.h"
|
||||
@@ -240,25 +241,26 @@ vk::ComponentMapping TextureGetComponentMapping(uint32_t swizzle) {
|
||||
return components;
|
||||
}
|
||||
|
||||
bool TextureCheckFormat(GraphicContext* ctx, vk::ImageCreateInfo* image_info) {
|
||||
bool TextureCheckFormat(vk::ImageCreateInfo& image_info) {
|
||||
auto& graphics = GetRenderContext().GetGraphics();
|
||||
vk::ImageFormatProperties props {};
|
||||
if (ctx->GetImageFormatProperties(image_info->format, image_info->imageType, image_info->tiling,
|
||||
image_info->usage, image_info->flags,
|
||||
&props) == vk::Result::eErrorFormatNotSupported) {
|
||||
if (graphics.GetImageFormatProperties(image_info.format, image_info.imageType,
|
||||
image_info.tiling, image_info.usage, image_info.flags,
|
||||
&props) == vk::Result::eErrorFormatNotSupported) {
|
||||
auto apply_fallback = [&](vk::Format replacement, const char* message) {
|
||||
image_info->format = replacement;
|
||||
const bool result = TextureCheckFormat(ctx, image_info);
|
||||
image_info.format = replacement;
|
||||
const bool result = TextureCheckFormat(image_info);
|
||||
LOGF("%s [%s]\n", message, (!result ? "FAIL" : "SUCCESS"));
|
||||
return result;
|
||||
};
|
||||
|
||||
if (image_info->format == vk::Format::eR8G8B8A8Srgb) {
|
||||
if (image_info.format == vk::Format::eR8G8B8A8Srgb) {
|
||||
// TODO() convert SRGB -> LINEAR in shader
|
||||
return apply_fallback(
|
||||
vk::Format::eR8G8B8A8Unorm,
|
||||
"replace vk::Format::eR8G8B8A8Srgb => vk::Format::eR8G8B8A8Unorm");
|
||||
}
|
||||
if (image_info->format == vk::Format::eB8G8R8A8Srgb) {
|
||||
if (image_info.format == vk::Format::eB8G8R8A8Srgb) {
|
||||
// TODO() convert SRGB -> LINEAR in shader
|
||||
return apply_fallback(
|
||||
vk::Format::eB8G8R8A8Unorm,
|
||||
@@ -269,34 +271,31 @@ bool TextureCheckFormat(GraphicContext* ctx, vk::ImageCreateInfo* image_info) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TextureCheckFormatExact(GraphicContext* ctx, const vk::ImageCreateInfo& image_info) {
|
||||
static bool TextureCheckFormatExact(const vk::ImageCreateInfo& image_info) {
|
||||
auto& graphics = GetRenderContext().GetGraphics();
|
||||
vk::ImageFormatProperties props {};
|
||||
return ctx->GetImageFormatProperties(image_info.format, image_info.imageType, image_info.tiling,
|
||||
image_info.usage, image_info.flags,
|
||||
&props) != vk::Result::eErrorFormatNotSupported;
|
||||
return graphics.GetImageFormatProperties(image_info.format, image_info.imageType,
|
||||
image_info.tiling, image_info.usage, image_info.flags,
|
||||
&props) != vk::Result::eErrorFormatNotSupported;
|
||||
}
|
||||
|
||||
bool TextureCheckStorageSwizzle(vk::ImageCreateInfo* image_info, vk::ComponentMapping* components) {
|
||||
if (image_info->usage & vk::ImageUsageFlagBits::eStorage) {
|
||||
if (components->r == vk::ComponentSwizzle::eR &&
|
||||
components->g == vk::ComponentSwizzle::eG &&
|
||||
components->b == vk::ComponentSwizzle::eB &&
|
||||
components->a == vk::ComponentSwizzle::eA) {
|
||||
bool TextureCheckStorageSwizzle(vk::ImageCreateInfo& image_info, vk::ComponentMapping& components) {
|
||||
if (image_info.usage & vk::ImageUsageFlagBits::eStorage) {
|
||||
if (components.r == vk::ComponentSwizzle::eR && components.g == vk::ComponentSwizzle::eG &&
|
||||
components.b == vk::ComponentSwizzle::eB && components.a == vk::ComponentSwizzle::eA) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (components->r == vk::ComponentSwizzle::eB &&
|
||||
components->g == vk::ComponentSwizzle::eG &&
|
||||
components->b == vk::ComponentSwizzle::eR &&
|
||||
components->a == vk::ComponentSwizzle::eA &&
|
||||
image_info->format == vk::Format::eR8G8B8A8Srgb) {
|
||||
if (components.r == vk::ComponentSwizzle::eB && components.g == vk::ComponentSwizzle::eG &&
|
||||
components.b == vk::ComponentSwizzle::eR && components.a == vk::ComponentSwizzle::eA &&
|
||||
image_info.format == vk::Format::eR8G8B8A8Srgb) {
|
||||
LOGF("replace vk::Format::eR8G8B8A8Srgb => vk::Format::eB8G8R8A8Srgb\n");
|
||||
|
||||
components->r = vk::ComponentSwizzle::eR;
|
||||
components->g = vk::ComponentSwizzle::eG;
|
||||
components->b = vk::ComponentSwizzle::eB;
|
||||
components->a = vk::ComponentSwizzle::eA;
|
||||
image_info->format = vk::Format::eB8G8R8A8Srgb;
|
||||
components.r = vk::ComponentSwizzle::eR;
|
||||
components.g = vk::ComponentSwizzle::eG;
|
||||
components.b = vk::ComponentSwizzle::eB;
|
||||
components.a = vk::ComponentSwizzle::eA;
|
||||
image_info.format = vk::Format::eB8G8R8A8Srgb;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -413,10 +412,9 @@ bool TextureCanCreateCubeView(uint64_t type, uint32_t base_array, uint32_t layer
|
||||
layer_count % 6u == 0;
|
||||
}
|
||||
|
||||
vk::ComponentMapping TextureCreateImage(GraphicContext* ctx, VulkanImage* vk_obj,
|
||||
vk::ComponentMapping TextureCreateImage(VulkanImage& vk_obj,
|
||||
const TextureImageCreateParams& params) {
|
||||
EXIT_IF(ctx == nullptr);
|
||||
EXIT_IF(vk_obj == nullptr);
|
||||
auto& graphics = GetRenderContext().GetGraphics();
|
||||
EXIT_IF(params.owner == nullptr);
|
||||
|
||||
const bool array_texture = TextureIsLayeredTexture(params.type);
|
||||
@@ -474,7 +472,7 @@ vk::ComponentMapping TextureCreateImage(GraphicContext* ctx, VulkanImage* vk_obj
|
||||
image_info.samples = vk::SampleCountFlagBits::e1;
|
||||
|
||||
const bool storage_view = TextureHasFormatUsage(params.view_usage, TextureFormatUsage::Storage);
|
||||
if (storage_view && !TextureCheckStorageSwizzle(&image_info, &components)) {
|
||||
if (storage_view && !TextureCheckStorageSwizzle(image_info, components)) {
|
||||
if (!params.storage_swizzle_fallback) {
|
||||
EXIT("swizzle is not supported");
|
||||
}
|
||||
@@ -494,11 +492,11 @@ vk::ComponentMapping TextureCreateImage(GraphicContext* ctx, VulkanImage* vk_obj
|
||||
const auto requested_usage = params.format_usage;
|
||||
const auto required_usage = params.required_format_usage;
|
||||
const bool has_optional_usage = static_cast<uint32_t>(requested_usage & ~required_usage) != 0;
|
||||
if (!TextureCheckFormatExact(ctx, image_info) && has_optional_usage) {
|
||||
if (!TextureCheckFormatExact(image_info) && has_optional_usage) {
|
||||
auto required_info = image_info;
|
||||
required_info.usage = TextureGetUsage(required_usage);
|
||||
required_info.format = view_checked_format;
|
||||
if (TextureCheckFormatExact(ctx, required_info)) {
|
||||
if (TextureCheckFormatExact(required_info)) {
|
||||
static std::atomic_uint log_count {0};
|
||||
if (log_count.fetch_add(1, std::memory_order_relaxed) < 16) {
|
||||
LOGF("\t %s usage 0x%08x is not supported for format %d, using required "
|
||||
@@ -511,39 +509,38 @@ vk::ComponentMapping TextureCreateImage(GraphicContext* ctx, VulkanImage* vk_obj
|
||||
}
|
||||
}
|
||||
|
||||
if (!TextureCheckFormat(ctx, &image_info)) {
|
||||
if (!TextureCheckFormat(image_info)) {
|
||||
if (has_optional_usage) {
|
||||
image_info.format = view_checked_format;
|
||||
image_info.usage = TextureGetUsage(required_usage);
|
||||
}
|
||||
if (!has_optional_usage || !TextureCheckFormat(ctx, &image_info)) {
|
||||
if (!has_optional_usage || !TextureCheckFormat(image_info)) {
|
||||
EXIT("format is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
vk_obj->extent.width = image_info.extent.width;
|
||||
vk_obj->extent.height = image_info.extent.height;
|
||||
vk_obj->layers = image_info.arrayLayers;
|
||||
vk_obj->mip_levels = image_info.mipLevels;
|
||||
vk_obj->format = image_info.format;
|
||||
vk_obj->image = nullptr;
|
||||
vk_obj->layout = image_info.initialLayout;
|
||||
vk_obj.extent.width = image_info.extent.width;
|
||||
vk_obj.extent.height = image_info.extent.height;
|
||||
vk_obj.layers = image_info.arrayLayers;
|
||||
vk_obj.mip_levels = image_info.mipLevels;
|
||||
vk_obj.format = image_info.format;
|
||||
vk_obj.image = nullptr;
|
||||
vk_obj.layout = image_info.initialLayout;
|
||||
|
||||
vk_obj->memory.property = vk::MemoryPropertyFlagBits::eDeviceLocal;
|
||||
vk_obj.memory.property = vk::MemoryPropertyFlagBits::eDeviceLocal;
|
||||
|
||||
bool created = VulkanCreateImage(ctx, image_info, vk_obj);
|
||||
bool created = graphics.CreateImage(image_info, vk_obj);
|
||||
EXIT_NOT_IMPLEMENTED(!created);
|
||||
|
||||
return components;
|
||||
}
|
||||
|
||||
void TextureCreateImageViews(GraphicContext* ctx, VulkanImage* vk_obj,
|
||||
void TextureCreateImageViews(VulkanImage& vk_obj,
|
||||
vk::ComponentMapping components, uint64_t type, uint32_t base_array,
|
||||
uint32_t base_level, uint32_t level_count, uint32_t depth,
|
||||
bool allow_cube_view, TextureFormatUsage view_usage) {
|
||||
EXIT_IF(ctx == nullptr);
|
||||
EXIT_IF(vk_obj == nullptr);
|
||||
EXIT_IF(level_count == 0 || base_level + level_count > vk_obj->mip_levels);
|
||||
auto& graphics = GetRenderContext().GetGraphics();
|
||||
EXIT_IF(level_count == 0 || base_level + level_count > vk_obj.mip_levels);
|
||||
|
||||
const bool layered_texture = TextureIsLayeredTexture(type);
|
||||
const bool volume_texture = TextureIs3DTexture(type);
|
||||
@@ -559,9 +556,9 @@ void TextureCreateImageViews(GraphicContext* ctx, VulkanImage* vk_obj,
|
||||
create_info.sType = vk::StructureType::eImageViewCreateInfo;
|
||||
create_info.pNext = (usage_info.usage ? &usage_info : nullptr);
|
||||
create_info.flags = {};
|
||||
create_info.image = vk_obj->image;
|
||||
create_info.image = vk_obj.image;
|
||||
create_info.viewType = vk::ImageViewType::e2D;
|
||||
create_info.format = vk_obj->format;
|
||||
create_info.format = vk_obj.format;
|
||||
create_info.components = components;
|
||||
create_info.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor;
|
||||
create_info.subresourceRange.baseArrayLayer = (layered_texture ? base_array : 0);
|
||||
@@ -581,8 +578,8 @@ void TextureCreateImageViews(GraphicContext* ctx, VulkanImage* vk_obj,
|
||||
|
||||
auto create_view = [&](int index) {
|
||||
const auto result =
|
||||
ctx->device.createImageView(&create_info, nullptr, &vk_obj->image_view[index]);
|
||||
if (result != vk::Result::eSuccess || vk_obj->image_view[index] == nullptr) {
|
||||
graphics.device.createImageView(&create_info, nullptr, &vk_obj.image_view[index]);
|
||||
if (result != vk::Result::eSuccess || vk_obj.image_view[index] == nullptr) {
|
||||
EXIT("failed to create texture image view: result=%d format=%d index=%d\n",
|
||||
static_cast<int>(result), static_cast<int>(create_info.format), index);
|
||||
}
|
||||
@@ -854,7 +851,7 @@ static uint64_t FmaskRegionCopySize(const BufferImageCopy& region) {
|
||||
sizeof(uint32_t);
|
||||
}
|
||||
|
||||
static void UploadFmaskIdentity(GraphicContext* ctx, VulkanImage* vk_obj,
|
||||
static void UploadFmaskIdentity(VulkanImage& vk_obj,
|
||||
const std::vector<BufferImageCopy>& regions,
|
||||
vk::ImageLayout dst_layout, const char* owner) {
|
||||
constexpr uint32_t kIdentityFmaskPattern = 0x76543210u;
|
||||
@@ -878,7 +875,8 @@ static void UploadFmaskIdentity(GraphicContext* ctx, VulkanImage* vk_obj,
|
||||
words[i] = kIdentityFmaskPattern;
|
||||
}
|
||||
|
||||
Transfer::UploadImage(ctx, vk_obj, temp_buf.Data(), upload_size, upload_regions, dst_layout);
|
||||
Transfer::UploadImage(vk_obj, temp_buf.Data(), upload_size, upload_regions,
|
||||
dst_layout);
|
||||
}
|
||||
|
||||
struct GpuTileElementLayout {
|
||||
@@ -887,31 +885,30 @@ struct GpuTileElementLayout {
|
||||
uint32_t tall = 1;
|
||||
};
|
||||
|
||||
static bool GetGpuTileElementLayout(uint32_t fmt, GpuTileElementLayout* out) {
|
||||
EXIT_IF(out == nullptr);
|
||||
static bool GetGpuTileElementLayout(uint32_t fmt, GpuTileElementLayout& out) {
|
||||
if (const auto bytes = Prospero::NumBytesPerElement(fmt); bytes != 0) {
|
||||
*out = {bytes, 1, 1};
|
||||
out = {bytes, 1, 1};
|
||||
return true;
|
||||
}
|
||||
if (const auto bytes = Prospero::BlockCompressedBytesPerBlock(fmt); bytes != 0) {
|
||||
*out = {bytes, 4, 4};
|
||||
out = {bytes, 4, 4};
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool SetGpuTileSize(uint64_t offset, uint64_t length, uint64_t capacity, uint64_t* size) {
|
||||
if (size == nullptr || offset > capacity || length > capacity - offset) {
|
||||
static bool SetGpuTileSize(uint64_t offset, uint64_t length, uint64_t capacity, uint64_t& size) {
|
||||
if (offset > capacity || length > capacity - offset) {
|
||||
return false;
|
||||
}
|
||||
*size = length;
|
||||
size = length;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TextureBuildGpuTileInfos(uint64_t size, const std::vector<BufferImageCopy>& regions,
|
||||
const TextureUploadLayout& layout, uint32_t fmt, uint32_t depth,
|
||||
uint64_t levels, std::vector<GpuTileInfo>* out_infos) {
|
||||
if (out_infos == nullptr || size == 0 || levels == 0 || levels > 16 || depth == 0 ||
|
||||
uint64_t levels, std::vector<GpuTileInfo>& out_infos) {
|
||||
if (size == 0 || levels == 0 || levels > 16 || depth == 0 ||
|
||||
regions.size() != GetTextureRegionCount(depth, levels, layout.volume_texture) ||
|
||||
Prospero::IsFmaskTextureFormat(fmt)) {
|
||||
return false;
|
||||
@@ -921,7 +918,7 @@ bool TextureBuildGpuTileInfos(uint64_t size, const std::vector<BufferImageCopy>&
|
||||
if (layout.tile_family == TileBlockFamily::RenderTarget64KB ||
|
||||
layout.tile_family == TileBlockFamily::Depth64KB) {
|
||||
element.bytes = Prospero::RenderTargetBytesPerElement(fmt);
|
||||
} else if (!GetGpuTileElementLayout(fmt, &element)) {
|
||||
} else if (!GetGpuTileElementLayout(fmt, element)) {
|
||||
return false;
|
||||
}
|
||||
if (element.bytes == 0) {
|
||||
@@ -933,12 +930,12 @@ bool TextureBuildGpuTileInfos(uint64_t size, const std::vector<BufferImageCopy>&
|
||||
if (layout.volume_texture) {
|
||||
TileVolumeLayout volume {};
|
||||
if (!TileGetTextureVolumeLayout(fmt, regions[0].width, regions[0].height, depth,
|
||||
static_cast<uint32_t>(levels), layout.tile, &volume)) {
|
||||
static_cast<uint32_t>(levels), layout.tile, volume)) {
|
||||
return false;
|
||||
}
|
||||
element = {volume.bytes_per_element, volume.texel_width, volume.texel_height};
|
||||
TileBlockLayout block {};
|
||||
if (!TileGetBlockLayout(volume.family, element.bytes, &block)) return false;
|
||||
if (!TileGetBlockLayout(volume.family, element.bytes, block)) return false;
|
||||
|
||||
size_t region_base = 0;
|
||||
for (uint32_t level = 0; level < levels; ++level) {
|
||||
@@ -958,9 +955,9 @@ bool TextureBuildGpuTileInfos(uint64_t size, const std::vector<BufferImageCopy>&
|
||||
const uint64_t linear_span =
|
||||
static_cast<uint64_t>(copy_depth - 1u) * linear_stride +
|
||||
layout.level_sizes[level].size;
|
||||
if (!SetGpuTileSize(info.linear_offset, linear_span, size, &info.linear_size) ||
|
||||
if (!SetGpuTileSize(info.linear_offset, linear_span, size, info.linear_size) ||
|
||||
!SetGpuTileSize(info.tiled_offset, volume.level_sizes[level], size,
|
||||
&info.tiled_size)) {
|
||||
info.tiled_size)) {
|
||||
return false;
|
||||
}
|
||||
info.linear_slice_stride = linear_stride;
|
||||
@@ -990,7 +987,7 @@ bool TextureBuildGpuTileInfos(uint64_t size, const std::vector<BufferImageCopy>&
|
||||
const bool tail = level >= layout.first_tail_level;
|
||||
const auto family = base_family;
|
||||
TileBlockLayout block {};
|
||||
if (!TileGetBlockLayout(family, element.bytes, &block)) {
|
||||
if (!TileGetBlockLayout(family, element.bytes, block)) {
|
||||
return false;
|
||||
}
|
||||
const auto level_depth = GetTextureLevelDepth(depth, level, layout.volume_texture);
|
||||
@@ -1001,9 +998,9 @@ bool TextureBuildGpuTileInfos(uint64_t size, const std::vector<BufferImageCopy>&
|
||||
info.bytes_per_element = block.bytes_per_element;
|
||||
info.linear_offset = region.offset;
|
||||
info.tiled_offset = TextureUploadSliceSourceOffset(layout, level, z);
|
||||
if (!SetGpuTileSize(info.linear_offset, level_size.size, size, &info.linear_size) ||
|
||||
if (!SetGpuTileSize(info.linear_offset, level_size.size, size, info.linear_size) ||
|
||||
!SetGpuTileSize(info.tiled_offset, GetLevelSrcSize(level_size), size,
|
||||
&info.tiled_size)) {
|
||||
info.tiled_size)) {
|
||||
return false;
|
||||
}
|
||||
info.width = std::max((region.width + element.wide - 1u) / element.wide, 1u);
|
||||
@@ -1036,11 +1033,11 @@ bool TextureBuildGpuTileInfos(uint64_t size, const std::vector<BufferImageCopy>&
|
||||
if (infos.empty()) {
|
||||
return false;
|
||||
}
|
||||
*out_infos = std::move(infos);
|
||||
out_infos = std::move(infos);
|
||||
return true;
|
||||
}
|
||||
|
||||
void TextureUploadGuestImage(GraphicContext* ctx, VulkanImage* vk_obj, const void* src_data,
|
||||
void TextureUploadGuestImage(VulkanImage& vk_obj, const void* src_data,
|
||||
uint64_t size, const std::vector<BufferImageCopy>& regions,
|
||||
const TextureUploadLayout& layout, uint32_t fmt, uint64_t width,
|
||||
uint64_t height, uint32_t depth, uint64_t levels, const char* owner,
|
||||
@@ -1051,21 +1048,21 @@ void TextureUploadGuestImage(GraphicContext* ctx, VulkanImage* vk_obj, const voi
|
||||
owner, layout.tile, size, width, height, depth, layout.pitch, levels);
|
||||
}
|
||||
if (static_cast<Prospero::TileMode>(layout.tile) == Prospero::TileMode::kLinear) {
|
||||
Transfer::UploadImage(ctx, vk_obj, src_data, size, regions, dst_layout);
|
||||
Transfer::UploadImage(vk_obj, src_data, size, regions, dst_layout);
|
||||
return;
|
||||
}
|
||||
if (layout.tile_family == TileBlockFamily::Depth64KB && Prospero::IsFmaskTextureFormat(fmt)) {
|
||||
UploadFmaskIdentity(ctx, vk_obj, regions, dst_layout, owner);
|
||||
UploadFmaskIdentity(vk_obj, regions, dst_layout, owner);
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<GpuTileInfo> infos;
|
||||
if (!TextureBuildGpuTileInfos(size, regions, layout, fmt, depth, levels, &infos)) {
|
||||
if (!TextureBuildGpuTileInfos(size, regions, layout, fmt, depth, levels, infos)) {
|
||||
EXIT("%s: GPU tiled upload unsupported: fmt=%u tile=%u size=%" PRIu64 " extent=%" PRIu64
|
||||
"x%" PRIu64 " depth=%u pitch=%u levels=%" PRIu64 "\n",
|
||||
owner, fmt, layout.tile, size, width, height, depth, layout.pitch, levels);
|
||||
}
|
||||
Transfer::UploadTiledImage(ctx, vk_obj, src_data, size, size, infos, regions, dst_layout);
|
||||
Transfer::UploadTiledImage(vk_obj, src_data, size, size, infos, regions, dst_layout);
|
||||
}
|
||||
|
||||
} // namespace Libs::Graphics
|
||||
@@ -83,8 +83,8 @@ struct TextureImageCreateParams {
|
||||
|
||||
vk::ComponentSwizzle TextureGetComponentSwizzle(uint8_t s);
|
||||
vk::ComponentMapping TextureGetComponentMapping(uint32_t swizzle);
|
||||
bool TextureCheckFormat(GraphicContext* ctx, vk::ImageCreateInfo* image_info);
|
||||
bool TextureCheckStorageSwizzle(vk::ImageCreateInfo* image_info, vk::ComponentMapping* components);
|
||||
bool TextureCheckFormat(vk::ImageCreateInfo& image_info);
|
||||
bool TextureCheckStorageSwizzle(vk::ImageCreateInfo& image_info, vk::ComponentMapping& components);
|
||||
vk::ImageUsageFlags TextureGetUsage(TextureFormatUsage usage);
|
||||
vk::ImageUsageFlags TextureGetViewUsage(TextureFormatUsage usage);
|
||||
vk::Format TextureGetFormat(uint32_t fmt);
|
||||
@@ -99,9 +99,9 @@ bool TextureIs3DTexture(uint64_t type);
|
||||
bool TextureIsCubeTexture(uint64_t type);
|
||||
bool TextureIsLayeredTexture(uint64_t type);
|
||||
bool TextureCanCreateCubeView(uint64_t type, uint32_t base_array, uint32_t layer_count);
|
||||
vk::ComponentMapping TextureCreateImage(GraphicContext* ctx, VulkanImage* image,
|
||||
vk::ComponentMapping TextureCreateImage(VulkanImage& image,
|
||||
const TextureImageCreateParams& params);
|
||||
void TextureCreateImageViews(GraphicContext* ctx, VulkanImage* vk_obj,
|
||||
void TextureCreateImageViews(VulkanImage& vk_obj,
|
||||
vk::ComponentMapping components, uint64_t type, uint32_t base_array,
|
||||
uint32_t base_level, uint32_t level_count, uint32_t depth,
|
||||
bool allow_cube_view, TextureFormatUsage view_usage);
|
||||
@@ -125,8 +125,8 @@ std::vector<ImageBufferCopy>
|
||||
TextureBuildDownloadRegions(const std::vector<BufferImageCopy>& upload_regions);
|
||||
bool TextureBuildGpuTileInfos(uint64_t size, const std::vector<BufferImageCopy>& regions,
|
||||
const TextureUploadLayout& layout, uint32_t fmt, uint32_t depth,
|
||||
uint64_t levels, std::vector<GpuTileInfo>* infos);
|
||||
void TextureUploadGuestImage(GraphicContext* ctx, VulkanImage* vk_obj, const void* src_data,
|
||||
uint64_t levels, std::vector<GpuTileInfo>& infos);
|
||||
void TextureUploadGuestImage(VulkanImage& vk_obj, const void* src_data,
|
||||
uint64_t size, const std::vector<BufferImageCopy>& regions,
|
||||
const TextureUploadLayout& layout, uint32_t fmt, uint64_t width,
|
||||
uint64_t height, uint32_t depth, uint64_t levels, const char* owner,
|
||||
|
||||
Reference in new issue
Block a user