video_core: Fix build issues on macos
This commit is contained in:
@@ -121,12 +121,14 @@ void TextureRuntime::FormatConvert(const Surface& surface, bool upload, std::spa
|
|||||||
OGLTexture TextureRuntime::Allocate(u32 width, u32 height, VideoCore::PixelFormat format,
|
OGLTexture TextureRuntime::Allocate(u32 width, u32 height, VideoCore::PixelFormat format,
|
||||||
VideoCore::TextureType type) {
|
VideoCore::TextureType type) {
|
||||||
const u32 layers = type == VideoCore::TextureType::CubeMap ? 6 : 1;
|
const u32 layers = type == VideoCore::TextureType::CubeMap ? 6 : 1;
|
||||||
|
const u32 levels = std::log2(std::max(width, height)) + 1;
|
||||||
const GLenum target =
|
const GLenum target =
|
||||||
type == VideoCore::TextureType::CubeMap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
|
type == VideoCore::TextureType::CubeMap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
|
||||||
|
|
||||||
|
// Attempt to recycle an unused texture
|
||||||
const VideoCore::HostTextureTag key = {
|
const VideoCore::HostTextureTag key = {
|
||||||
.format = format, .width = width, .height = height, .layers = layers};
|
.format = format, .width = width, .height = height, .layers = layers};
|
||||||
|
|
||||||
// Attempt to recycle an unused texture
|
|
||||||
if (auto it = texture_recycler.find(key); it != texture_recycler.end()) {
|
if (auto it = texture_recycler.find(key); it != texture_recycler.end()) {
|
||||||
OGLTexture texture = std::move(it->second);
|
OGLTexture texture = std::move(it->second);
|
||||||
texture_recycler.erase(it);
|
texture_recycler.erase(it);
|
||||||
@@ -144,8 +146,7 @@ OGLTexture TextureRuntime::Allocate(u32 width, u32 height, VideoCore::PixelForma
|
|||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(target, texture.handle);
|
glBindTexture(target, texture.handle);
|
||||||
|
|
||||||
glTexStorage2D(target, std::bit_width(std::max(width, height)), tuple.internal_format, width,
|
glTexStorage2D(target, levels, tuple.internal_format, width, height);
|
||||||
height);
|
|
||||||
|
|
||||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
@@ -16,7 +16,7 @@ void Scheduler::CommandChunk::ExecuteAll(vk::CommandBuffer render_cmdbuf, vk::Co
|
|||||||
while (command != nullptr) {
|
while (command != nullptr) {
|
||||||
auto next = command->GetNext();
|
auto next = command->GetNext();
|
||||||
command->Execute(render_cmdbuf, upload_cmdbuf);
|
command->Execute(render_cmdbuf, upload_cmdbuf);
|
||||||
std::destroy_at(command);
|
command->~Command();
|
||||||
command = next;
|
command = next;
|
||||||
}
|
}
|
||||||
submit = false;
|
submit = false;
|
||||||
@@ -27,15 +27,27 @@ void Scheduler::CommandChunk::ExecuteAll(vk::CommandBuffer render_cmdbuf, vk::Co
|
|||||||
|
|
||||||
Scheduler::Scheduler(const Instance& instance, RenderpassCache& renderpass_cache, RendererVulkan& renderer)
|
Scheduler::Scheduler(const Instance& instance, RenderpassCache& renderpass_cache, RendererVulkan& renderer)
|
||||||
: instance{instance}, renderpass_cache{renderpass_cache}, renderer{renderer}, master_semaphore{instance},
|
: instance{instance}, renderpass_cache{renderpass_cache}, renderer{renderer}, master_semaphore{instance},
|
||||||
command_pool{instance, master_semaphore}, use_worker_thread{Settings::values.async_command_recording} {
|
command_pool{instance, master_semaphore}, stop_requested{false},
|
||||||
|
use_worker_thread{Settings::values.async_command_recording} {
|
||||||
AllocateWorkerCommandBuffers();
|
AllocateWorkerCommandBuffers();
|
||||||
if (use_worker_thread) {
|
if (use_worker_thread) {
|
||||||
AcquireNewChunk();
|
AcquireNewChunk();
|
||||||
worker_thread = std::jthread([this](std::stop_token token) { WorkerThread(token); });
|
worker_thread = std::thread([this]() { WorkerThread(); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Scheduler::~Scheduler() = default;
|
Scheduler::~Scheduler() {
|
||||||
|
stop_requested = true;
|
||||||
|
|
||||||
|
// Push a dummy chunk to unblock the thread
|
||||||
|
{
|
||||||
|
std::scoped_lock lock{work_mutex};
|
||||||
|
work_queue.push(std::move(chunk));
|
||||||
|
}
|
||||||
|
|
||||||
|
work_cv.notify_one();
|
||||||
|
worker_thread.join();
|
||||||
|
}
|
||||||
|
|
||||||
void Scheduler::Flush(vk::Semaphore signal, vk::Semaphore wait) {
|
void Scheduler::Flush(vk::Semaphore signal, vk::Semaphore wait) {
|
||||||
SubmitExecution(signal, wait);
|
SubmitExecution(signal, wait);
|
||||||
@@ -75,7 +87,7 @@ void Scheduler::DispatchWork() {
|
|||||||
AcquireNewChunk();
|
AcquireNewChunk();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scheduler::WorkerThread(std::stop_token stop_token) {
|
void Scheduler::WorkerThread() {
|
||||||
do {
|
do {
|
||||||
std::unique_ptr<CommandChunk> work;
|
std::unique_ptr<CommandChunk> work;
|
||||||
bool has_submit{false};
|
bool has_submit{false};
|
||||||
@@ -84,8 +96,8 @@ void Scheduler::WorkerThread(std::stop_token stop_token) {
|
|||||||
if (work_queue.empty()) {
|
if (work_queue.empty()) {
|
||||||
wait_cv.notify_all();
|
wait_cv.notify_all();
|
||||||
}
|
}
|
||||||
work_cv.wait(lock, stop_token, [this] { return !work_queue.empty(); });
|
work_cv.wait(lock, [this] { return !work_queue.empty() || stop_requested; });
|
||||||
if (stop_token.stop_requested()) {
|
if (stop_requested) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
work = std::move(work_queue.front());
|
work = std::move(work_queue.front());
|
||||||
@@ -99,7 +111,7 @@ void Scheduler::WorkerThread(std::stop_token stop_token) {
|
|||||||
}
|
}
|
||||||
std::scoped_lock reserve_lock{reserve_mutex};
|
std::scoped_lock reserve_lock{reserve_mutex};
|
||||||
chunk_reserve.push_back(std::move(work));
|
chunk_reserve.push_back(std::move(work));
|
||||||
} while (!stop_token.stop_requested());
|
} while (!stop_requested);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scheduler::AllocateWorkerCommandBuffers() {
|
void Scheduler::AllocateWorkerCommandBuffers() {
|
||||||
|
@@ -151,7 +151,7 @@ private:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Command* const current_last = last;
|
Command* const current_last = last;
|
||||||
last = std::construct_at(reinterpret_cast<FuncType*>(data.data() + command_offset), std::move(command));
|
last = new (data.data() + command_offset) FuncType(std::move(command));
|
||||||
|
|
||||||
if (current_last) {
|
if (current_last) {
|
||||||
current_last->SetNext(last);
|
current_last->SetNext(last);
|
||||||
@@ -185,7 +185,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void WorkerThread(std::stop_token stop_token);
|
void WorkerThread();
|
||||||
|
|
||||||
void AllocateWorkerCommandBuffers();
|
void AllocateWorkerCommandBuffers();
|
||||||
|
|
||||||
@@ -209,7 +209,8 @@ private:
|
|||||||
std::mutex work_mutex;
|
std::mutex work_mutex;
|
||||||
std::condition_variable_any work_cv;
|
std::condition_variable_any work_cv;
|
||||||
std::condition_variable wait_cv;
|
std::condition_variable wait_cv;
|
||||||
std::jthread worker_thread;
|
std::thread worker_thread;
|
||||||
|
std::atomic_bool stop_requested;
|
||||||
bool use_worker_thread;
|
bool use_worker_thread;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -150,7 +150,7 @@ ImageAlloc TextureRuntime::Allocate(u32 width, u32 height, VideoCore::PixelForma
|
|||||||
|
|
||||||
ImageAlloc alloc{};
|
ImageAlloc alloc{};
|
||||||
alloc.format = format;
|
alloc.format = format;
|
||||||
alloc.levels = std::bit_width(std::max(width, height));
|
alloc.levels = std::log2(std::max(width, height)) + 1;
|
||||||
alloc.layers = type == VideoCore::TextureType::CubeMap ? 6 : 1;
|
alloc.layers = type == VideoCore::TextureType::CubeMap ? 6 : 1;
|
||||||
alloc.aspect = GetImageAspect(format);
|
alloc.aspect = GetImageAspect(format);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user