mirror of https://github.com/auygun/kaliber.git
Add support for texture update without extra copy
This commit is contained in:
parent
0da56dd552
commit
3c54bc474c
|
@ -102,6 +102,8 @@ void Engine::Initialize() {
|
||||||
|
|
||||||
thread_pool_.Initialize();
|
thread_pool_.Initialize();
|
||||||
|
|
||||||
|
imgui_backend_.Initialize(IsMobile(), GetRootPath());
|
||||||
|
|
||||||
platform_->CreateMainWindow();
|
platform_->CreateMainWindow();
|
||||||
|
|
||||||
CreateRendererInternal(RendererType::kVulkan);
|
CreateRendererInternal(RendererType::kVulkan);
|
||||||
|
@ -119,8 +121,6 @@ void Engine::Initialize() {
|
||||||
CreateRenderResources();
|
CreateRenderResources();
|
||||||
WaitForAsyncWork();
|
WaitForAsyncWork();
|
||||||
|
|
||||||
imgui_backend_.Initialize();
|
|
||||||
|
|
||||||
CHECK(game_->Initialize()) << "Failed to initialize the game.";
|
CHECK(game_->Initialize()) << "Failed to initialize the game.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
#include "engine/imgui_backend.h"
|
#include "engine/imgui_backend.h"
|
||||||
|
|
||||||
#include "base/log.h"
|
#include "base/log.h"
|
||||||
#include "engine/asset/image.h"
|
|
||||||
#include "engine/asset/shader_source.h"
|
#include "engine/asset/shader_source.h"
|
||||||
#include "engine/engine.h"
|
|
||||||
#include "engine/input_event.h"
|
#include "engine/input_event.h"
|
||||||
#include "engine/platform/asset_file.h"
|
#include "engine/platform/asset_file.h"
|
||||||
#include "engine/renderer/renderer.h"
|
#include "engine/renderer/renderer.h"
|
||||||
#include "engine/renderer/shader.h"
|
|
||||||
#include "engine/renderer/texture.h"
|
|
||||||
#include "third_party/imgui/imgui.h"
|
#include "third_party/imgui/imgui.h"
|
||||||
|
|
||||||
using namespace base;
|
using namespace base;
|
||||||
|
@ -19,11 +15,11 @@ namespace {
|
||||||
const char vertex_description[] = "p2f;t2f;c4b";
|
const char vertex_description[] = "p2f;t2f;c4b";
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ImguiBackend::ImguiBackend() : shader_{std::make_unique<Shader>(nullptr)} {}
|
ImguiBackend::ImguiBackend() = default;
|
||||||
|
|
||||||
ImguiBackend::~ImguiBackend() = default;
|
ImguiBackend::~ImguiBackend() = default;
|
||||||
|
|
||||||
void ImguiBackend::Initialize() {
|
void ImguiBackend::Initialize(bool is_mobile, std::string root_path) {
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
ImGui::GetIO().IniFilename = nullptr;
|
ImGui::GetIO().IniFilename = nullptr;
|
||||||
|
@ -33,12 +29,11 @@ void ImguiBackend::Initialize() {
|
||||||
|
|
||||||
size_t buffer_size = 0;
|
size_t buffer_size = 0;
|
||||||
auto buffer = AssetFile::ReadWholeFile("engine/RobotoMono-Regular.ttf",
|
auto buffer = AssetFile::ReadWholeFile("engine/RobotoMono-Regular.ttf",
|
||||||
Engine::Get().GetRootPath().c_str(),
|
root_path.c_str(), &buffer_size);
|
||||||
&buffer_size);
|
|
||||||
if (buffer) {
|
if (buffer) {
|
||||||
ImFontConfig font_cfg = ImFontConfig();
|
ImFontConfig font_cfg = ImFontConfig();
|
||||||
font_cfg.FontDataOwnedByAtlas = false;
|
font_cfg.FontDataOwnedByAtlas = false;
|
||||||
float size_pixels = Engine::Get().IsMobile() ? 64 : 32;
|
float size_pixels = is_mobile ? 64 : 32;
|
||||||
ImGui::GetIO().Fonts->AddFontFromMemoryTTF(buffer.get(), (int)buffer_size,
|
ImGui::GetIO().Fonts->AddFontFromMemoryTTF(buffer.get(), (int)buffer_size,
|
||||||
size_pixels, &font_cfg);
|
size_pixels, &font_cfg);
|
||||||
ImGui::GetIO().Fonts->Build();
|
ImGui::GetIO().Fonts->Build();
|
||||||
|
@ -48,54 +43,45 @@ void ImguiBackend::Initialize() {
|
||||||
|
|
||||||
// Arbitrary scale-up for mobile devices.
|
// Arbitrary scale-up for mobile devices.
|
||||||
// TODO: Put some effort into DPI awareness.
|
// TODO: Put some effort into DPI awareness.
|
||||||
if (Engine::Get().IsMobile())
|
if (is_mobile)
|
||||||
ImGui::GetStyle().ScaleAllSizes(2.0f);
|
ImGui::GetStyle().ScaleAllSizes(2.0f);
|
||||||
|
|
||||||
Engine::Get().SetImageSource(
|
|
||||||
"imgui_atlas",
|
|
||||||
[]() -> std::unique_ptr<Image> {
|
|
||||||
unsigned char* pixels;
|
|
||||||
int width, height;
|
|
||||||
ImGui::GetIO().Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
|
||||||
LOG(0) << "Font atlas size: " << width << ", " << height;
|
|
||||||
auto image = std::make_unique<Image>();
|
|
||||||
image->Create(width, height);
|
|
||||||
memcpy(image->GetBuffer(), pixels, width * height * 4);
|
|
||||||
return image;
|
|
||||||
},
|
|
||||||
true);
|
|
||||||
Engine::Get().RefreshImage("imgui_atlas");
|
|
||||||
ImGui::GetIO().Fonts->SetTexID(
|
|
||||||
(ImTextureID)(intptr_t)Engine::Get().AcquireTexture("imgui_atlas"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImguiBackend::Shutdown() {
|
void ImguiBackend::Shutdown() {
|
||||||
|
ImGui::DestroyContext();
|
||||||
for (auto& id : geometries_)
|
for (auto& id : geometries_)
|
||||||
renderer_->DestroyGeometry(id);
|
renderer_->DestroyGeometry(id);
|
||||||
geometries_.clear();
|
geometries_.clear();
|
||||||
ImGui::DestroyContext();
|
renderer_->DestroyTexture(font_atlas_);
|
||||||
shader_.reset();
|
renderer_->DestroyShader(shader_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImguiBackend::CreateRenderResources(Renderer* renderer) {
|
void ImguiBackend::CreateRenderResources(Renderer* renderer) {
|
||||||
renderer_ = renderer;
|
renderer_ = renderer;
|
||||||
shader_->SetRenderer(renderer);
|
|
||||||
|
|
||||||
geometries_.clear();
|
geometries_.clear();
|
||||||
|
|
||||||
|
// Avoid flickering by using the geometries form the last frame if available.
|
||||||
if (ImGui::GetCurrentContext() && ImGui::GetDrawData())
|
if (ImGui::GetCurrentContext() && ImGui::GetDrawData())
|
||||||
Render();
|
Render();
|
||||||
|
|
||||||
|
// Create the shader.
|
||||||
auto source = std::make_unique<ShaderSource>();
|
auto source = std::make_unique<ShaderSource>();
|
||||||
if (source->Load("engine/imgui.glsl")) {
|
if (source->Load("engine/imgui.glsl")) {
|
||||||
VertexDescription vd;
|
shader_ = renderer_->CreateShader(std::move(source), vertex_description_,
|
||||||
if (!ParseVertexDescription(vertex_description, vd)) {
|
kPrimitive_Triangles, false);
|
||||||
DLOG(0) << "Failed to parse vertex description.";
|
|
||||||
} else {
|
|
||||||
shader_->Create(std::move(source), vd, kPrimitive_Triangles, false);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
LOG(0) << "Could not create imgui shader.";
|
LOG(0) << "Could not create imgui shader.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a texture for the font atlas.
|
||||||
|
unsigned char* pixels;
|
||||||
|
int width, height;
|
||||||
|
ImGui::GetIO().Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||||
|
LOG(0) << "Font atlas size: " << width << ", " << height;
|
||||||
|
font_atlas_ = renderer_->CreateTexture();
|
||||||
|
renderer_->UpdateTexture(font_atlas_, width, height, ImageFormat::kRGBA32,
|
||||||
|
width * height * 4, pixels);
|
||||||
|
ImGui::GetIO().Fonts->SetTexID((ImTextureID)(intptr_t)font_atlas_);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<InputEvent> ImguiBackend::OnInputEvent(
|
std::unique_ptr<InputEvent> ImguiBackend::OnInputEvent(
|
||||||
|
@ -133,6 +119,7 @@ void ImguiBackend::NewFrame(float delta_time) {
|
||||||
|
|
||||||
void ImguiBackend::Render() {
|
void ImguiBackend::Render() {
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
|
// Create a geometry for each draw list and upload the vertex data.
|
||||||
ImDrawData* draw_data = ImGui::GetDrawData();
|
ImDrawData* draw_data = ImGui::GetDrawData();
|
||||||
if ((int)geometries_.size() < draw_data->CmdListsCount)
|
if ((int)geometries_.size() < draw_data->CmdListsCount)
|
||||||
geometries_.resize(draw_data->CmdListsCount, 0);
|
geometries_.resize(draw_data->CmdListsCount, 0);
|
||||||
|
@ -160,9 +147,9 @@ void ImguiBackend::Draw() {
|
||||||
draw_data->DisplayPos.x + draw_data->DisplaySize.x,
|
draw_data->DisplayPos.x + draw_data->DisplaySize.x,
|
||||||
draw_data->DisplayPos.y + draw_data->DisplaySize.y,
|
draw_data->DisplayPos.y + draw_data->DisplaySize.y,
|
||||||
draw_data->DisplayPos.y);
|
draw_data->DisplayPos.y);
|
||||||
shader_->Activate();
|
renderer_->ActivateShader(shader_);
|
||||||
shader_->SetUniform("projection", proj);
|
renderer_->SetUniform(shader_, "projection", proj);
|
||||||
shader_->UploadUniforms();
|
renderer_->UploadUniforms(shader_);
|
||||||
|
|
||||||
for (int n = 0; n < draw_data->CmdListsCount; n++) {
|
for (int n = 0; n < draw_data->CmdListsCount; n++) {
|
||||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||||
|
@ -171,7 +158,8 @@ void ImguiBackend::Draw() {
|
||||||
if (pcmd->ClipRect.z <= pcmd->ClipRect.x ||
|
if (pcmd->ClipRect.z <= pcmd->ClipRect.x ||
|
||||||
pcmd->ClipRect.w <= pcmd->ClipRect.y)
|
pcmd->ClipRect.w <= pcmd->ClipRect.y)
|
||||||
continue;
|
continue;
|
||||||
reinterpret_cast<Texture*>(pcmd->GetTexID())->Activate(0);
|
auto texture_id = reinterpret_cast<uint64_t>(pcmd->GetTexID());
|
||||||
|
renderer_->ActivateTexture(texture_id, 0);
|
||||||
renderer_->SetScissor(int(pcmd->ClipRect.x), int(pcmd->ClipRect.y),
|
renderer_->SetScissor(int(pcmd->ClipRect.x), int(pcmd->ClipRect.y),
|
||||||
int(pcmd->ClipRect.z - pcmd->ClipRect.x),
|
int(pcmd->ClipRect.z - pcmd->ClipRect.x),
|
||||||
int(pcmd->ClipRect.w - pcmd->ClipRect.y));
|
int(pcmd->ClipRect.w - pcmd->ClipRect.y));
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
namespace eng {
|
namespace eng {
|
||||||
|
|
||||||
class InputEvent;
|
class InputEvent;
|
||||||
class Shader;
|
|
||||||
class Renderer;
|
class Renderer;
|
||||||
|
|
||||||
class ImguiBackend {
|
class ImguiBackend {
|
||||||
|
@ -17,7 +16,7 @@ class ImguiBackend {
|
||||||
ImguiBackend();
|
ImguiBackend();
|
||||||
~ImguiBackend();
|
~ImguiBackend();
|
||||||
|
|
||||||
void Initialize();
|
void Initialize(bool is_mobile, std::string root_path);
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
void CreateRenderResources(Renderer* renderer);
|
void CreateRenderResources(Renderer* renderer);
|
||||||
|
@ -31,7 +30,8 @@ class ImguiBackend {
|
||||||
private:
|
private:
|
||||||
VertexDescription vertex_description_;
|
VertexDescription vertex_description_;
|
||||||
std::vector<uint64_t> geometries_;
|
std::vector<uint64_t> geometries_;
|
||||||
std::unique_ptr<Shader> shader_;
|
uint64_t shader_ = 0;
|
||||||
|
uint64_t font_atlas_ = 0;
|
||||||
Renderer* renderer_ = nullptr;
|
Renderer* renderer_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -251,56 +251,63 @@ uint64_t RendererOpenGL::CreateTexture() {
|
||||||
|
|
||||||
void RendererOpenGL::UpdateTexture(uint64_t resource_id,
|
void RendererOpenGL::UpdateTexture(uint64_t resource_id,
|
||||||
std::unique_ptr<Image> image) {
|
std::unique_ptr<Image> image) {
|
||||||
|
UpdateTexture(resource_id, image->GetWidth(), image->GetHeight(),
|
||||||
|
image->GetFormat(), image->GetSize(), image->GetBuffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RendererOpenGL::UpdateTexture(uint64_t resource_id,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
ImageFormat format,
|
||||||
|
size_t data_size,
|
||||||
|
uint8_t* image_data) {
|
||||||
auto it = textures_.find(resource_id);
|
auto it = textures_.find(resource_id);
|
||||||
if (it == textures_.end())
|
if (it == textures_.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, it->second);
|
glBindTexture(GL_TEXTURE_2D, it->second);
|
||||||
if (image->IsCompressed()) {
|
if (IsCompressedFormat(format)) {
|
||||||
GLenum format = 0;
|
GLenum gl_format = 0;
|
||||||
switch (image->GetFormat()) {
|
switch (format) {
|
||||||
case ImageFormat::kDXT1:
|
case ImageFormat::kDXT1:
|
||||||
format = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
|
gl_format = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
|
||||||
break;
|
break;
|
||||||
case ImageFormat::kDXT5:
|
case ImageFormat::kDXT5:
|
||||||
format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
gl_format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||||
break;
|
break;
|
||||||
case ImageFormat::kETC1:
|
case ImageFormat::kETC1:
|
||||||
format = GL_ETC1_RGB8_OES;
|
gl_format = GL_ETC1_RGB8_OES;
|
||||||
break;
|
break;
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
case ImageFormat::kATC:
|
case ImageFormat::kATC:
|
||||||
format = GL_ATC_RGB_AMD;
|
gl_format = GL_ATC_RGB_AMD;
|
||||||
break;
|
break;
|
||||||
case ImageFormat::kATCIA:
|
case ImageFormat::kATCIA:
|
||||||
format = GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD;
|
gl_format = GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
NOTREACHED() << "- Unhandled texure format: "
|
NOTREACHED() << "- Unhandled texture format: "
|
||||||
<< ImageFormatToString(image->GetFormat());
|
<< ImageFormatToString(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, image->GetWidth(),
|
glCompressedTexImage2D(GL_TEXTURE_2D, 0, gl_format, width, height, 0,
|
||||||
image->GetHeight(), 0, image->GetSize(),
|
data_size, image_data);
|
||||||
image->GetBuffer());
|
|
||||||
|
|
||||||
// On some devices the first glCompressedTexImage2D call after context-lost
|
// On some devices the first glCompressedTexImage2D call after context-lost
|
||||||
// returns GL_INVALID_VALUE for some reason.
|
// returns GL_INVALID_VALUE for some reason.
|
||||||
GLenum err = glGetError();
|
GLenum err = glGetError();
|
||||||
if (err == GL_INVALID_VALUE) {
|
if (err == GL_INVALID_VALUE) {
|
||||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, image->GetWidth(),
|
glCompressedTexImage2D(GL_TEXTURE_2D, 0, gl_format, width, height, 0,
|
||||||
image->GetHeight(), 0, image->GetSize(),
|
data_size, image_data);
|
||||||
image->GetBuffer());
|
|
||||||
err = glGetError();
|
err = glGetError();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err != GL_NO_ERROR)
|
if (err != GL_NO_ERROR)
|
||||||
LOG(0) << "GL ERROR after glCompressedTexImage2D: " << (int)err;
|
LOG(0) << "GL ERROR after glCompressedTexImage2D: " << (int)err;
|
||||||
} else {
|
} else {
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image->GetWidth(),
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
|
||||||
image->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
GL_UNSIGNED_BYTE, image_data);
|
||||||
image->GetBuffer());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,12 @@ class RendererOpenGL final : public Renderer {
|
||||||
|
|
||||||
uint64_t CreateTexture() final;
|
uint64_t CreateTexture() final;
|
||||||
void UpdateTexture(uint64_t resource_id, std::unique_ptr<Image> image) final;
|
void UpdateTexture(uint64_t resource_id, std::unique_ptr<Image> image) final;
|
||||||
|
void UpdateTexture(uint64_t resource_id,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
ImageFormat format,
|
||||||
|
size_t data_size,
|
||||||
|
uint8_t* image_data) final;
|
||||||
void DestroyTexture(uint64_t resource_id) final;
|
void DestroyTexture(uint64_t resource_id) final;
|
||||||
void ActivateTexture(uint64_t resource_id, uint64_t texture_unit) final;
|
void ActivateTexture(uint64_t resource_id, uint64_t texture_unit) final;
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,12 @@ class Renderer {
|
||||||
virtual uint64_t CreateTexture() = 0;
|
virtual uint64_t CreateTexture() = 0;
|
||||||
virtual void UpdateTexture(uint64_t resource_id,
|
virtual void UpdateTexture(uint64_t resource_id,
|
||||||
std::unique_ptr<Image> image) = 0;
|
std::unique_ptr<Image> image) = 0;
|
||||||
|
virtual void UpdateTexture(uint64_t resource_id,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
ImageFormat format,
|
||||||
|
size_t data_size,
|
||||||
|
uint8_t* image_data) = 0;
|
||||||
virtual void DestroyTexture(uint64_t resource_id) = 0;
|
virtual void DestroyTexture(uint64_t resource_id) = 0;
|
||||||
virtual void ActivateTexture(uint64_t resource_id, uint64_t texture_unit) = 0;
|
virtual void ActivateTexture(uint64_t resource_id, uint64_t texture_unit) = 0;
|
||||||
|
|
||||||
|
|
|
@ -558,16 +558,27 @@ uint64_t RendererVulkan::CreateTexture() {
|
||||||
|
|
||||||
void RendererVulkan::UpdateTexture(uint64_t resource_id,
|
void RendererVulkan::UpdateTexture(uint64_t resource_id,
|
||||||
std::unique_ptr<Image> image) {
|
std::unique_ptr<Image> image) {
|
||||||
|
UpdateTexture(resource_id, image->GetWidth(), image->GetHeight(),
|
||||||
|
image->GetFormat(), image->GetSize(), image->GetBuffer());
|
||||||
|
task_runner_.Delete(HERE, std::move(image));
|
||||||
|
semaphore_.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RendererVulkan::UpdateTexture(uint64_t resource_id,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
ImageFormat format,
|
||||||
|
size_t data_size,
|
||||||
|
uint8_t* image_data) {
|
||||||
auto it = textures_.find(resource_id);
|
auto it = textures_.find(resource_id);
|
||||||
if (it == textures_.end())
|
if (it == textures_.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
VkImageLayout old_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
VkImageLayout old_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
VkFormat format = GetImageFormat(image->GetFormat());
|
VkFormat vk_format = GetImageFormat(format);
|
||||||
|
|
||||||
if (it->second.view != VK_NULL_HANDLE &&
|
if (it->second.view != VK_NULL_HANDLE &&
|
||||||
(it->second.width != image->GetWidth() ||
|
(it->second.width != width || it->second.height != height)) {
|
||||||
it->second.height != image->GetHeight())) {
|
|
||||||
// Size mismatch. Recreate the texture.
|
// Size mismatch. Recreate the texture.
|
||||||
FreeImage(std::move(it->second.image), it->second.view,
|
FreeImage(std::move(it->second.image), it->second.view,
|
||||||
std::move(it->second.desc_set));
|
std::move(it->second.desc_set));
|
||||||
|
@ -576,12 +587,12 @@ void RendererVulkan::UpdateTexture(uint64_t resource_id,
|
||||||
|
|
||||||
if (it->second.view == VK_NULL_HANDLE) {
|
if (it->second.view == VK_NULL_HANDLE) {
|
||||||
AllocateImage(it->second.image, it->second.view, it->second.desc_set,
|
AllocateImage(it->second.image, it->second.view, it->second.desc_set,
|
||||||
format, image->GetWidth(), image->GetHeight(),
|
vk_format, width, height,
|
||||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
VMA_MEMORY_USAGE_GPU_ONLY);
|
VMA_MEMORY_USAGE_GPU_ONLY);
|
||||||
old_layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
old_layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
it->second.width = image->GetWidth();
|
it->second.width = width;
|
||||||
it->second.height = image->GetHeight();
|
it->second.height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
task_runner_.PostTask(
|
task_runner_.PostTask(
|
||||||
|
@ -591,10 +602,9 @@ void RendererVulkan::UpdateTexture(uint64_t resource_id,
|
||||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, VK_ACCESS_TRANSFER_WRITE_BIT,
|
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||||
old_layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL));
|
old_layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL));
|
||||||
task_runner_.PostTask(
|
task_runner_.PostTask(HERE, std::bind(&RendererVulkan::UpdateImage, this,
|
||||||
HERE, std::bind(&RendererVulkan::UpdateImage, this,
|
std::get<0>(it->second.image),
|
||||||
std::get<0>(it->second.image), format, image->GetBuffer(),
|
vk_format, image_data, width, height));
|
||||||
image->GetWidth(), image->GetHeight()));
|
|
||||||
task_runner_.PostTask(
|
task_runner_.PostTask(
|
||||||
HERE,
|
HERE,
|
||||||
std::bind(&RendererVulkan::ImageMemoryBarrier, this,
|
std::bind(&RendererVulkan::ImageMemoryBarrier, this,
|
||||||
|
@ -605,7 +615,6 @@ void RendererVulkan::UpdateTexture(uint64_t resource_id,
|
||||||
0, VK_ACCESS_SHADER_READ_BIT,
|
0, VK_ACCESS_SHADER_READ_BIT,
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
|
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
|
||||||
task_runner_.Delete(HERE, std::move(image));
|
|
||||||
semaphore_.release();
|
semaphore_.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,12 @@ class RendererVulkan final : public Renderer {
|
||||||
|
|
||||||
uint64_t CreateTexture() final;
|
uint64_t CreateTexture() final;
|
||||||
void UpdateTexture(uint64_t resource_id, std::unique_ptr<Image> image) final;
|
void UpdateTexture(uint64_t resource_id, std::unique_ptr<Image> image) final;
|
||||||
|
void UpdateTexture(uint64_t resource_id,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
ImageFormat format,
|
||||||
|
size_t data_size,
|
||||||
|
uint8_t* image_data) final;
|
||||||
void DestroyTexture(uint64_t resource_id) final;
|
void DestroyTexture(uint64_t resource_id) final;
|
||||||
void ActivateTexture(uint64_t resource_id, uint64_t texture_unit) final;
|
void ActivateTexture(uint64_t resource_id, uint64_t texture_unit) final;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue