Add support for texture units

This commit is contained in:
Attila Uygun 2023-10-23 23:07:32 +02:00
parent 3125bb9c95
commit 010c6b097c
13 changed files with 50 additions and 45 deletions

View File

@ -56,7 +56,7 @@ void ImageQuad::Draw(float frame_frac) {
if (!texture_ || !texture_->IsValid()) if (!texture_ || !texture_->IsValid())
return; return;
texture_->Activate(); texture_->Activate(0);
Vector2f tex_scale = {GetFrameWidth() / texture_->GetWidth(), Vector2f tex_scale = {GetFrameWidth() / texture_->GetWidth(),
GetFrameHeight() / texture_->GetHeight()}; GetFrameHeight() / texture_->GetHeight()};

View File

@ -131,7 +131,7 @@ void ImguiBackend::Render() {
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
reinterpret_cast<Texture*>(pcmd->GetTexID())->Activate(); reinterpret_cast<Texture*>(pcmd->GetTexID())->Activate(0);
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) {

View File

@ -7,9 +7,6 @@ class InputEvent;
class PlatformObserver { class PlatformObserver {
public: public:
PlatformObserver() = default;
virtual ~PlatformObserver() = default;
virtual void OnWindowCreated() = 0; virtual void OnWindowCreated() = 0;
virtual void OnWindowDestroyed() = 0; virtual void OnWindowDestroyed() = 0;
virtual void OnWindowResized(int width, int height) = 0; virtual void OnWindowResized(int width, int height) = 0;

View File

@ -199,8 +199,7 @@ void RendererOpenGL::Draw(uint64_t resource_id,
uint64_t RendererOpenGL::CreateTexture() { uint64_t RendererOpenGL::CreateTexture() {
GLuint gl_id = 0; GLuint gl_id = 0;
glGenTextures(1, &gl_id); glGenTextures(1, &gl_id);
glBindTexture(GL_TEXTURE_2D, gl_id);
BindTexture(gl_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@ -218,7 +217,7 @@ void RendererOpenGL::UpdateTexture(uint64_t resource_id,
if (it == textures_.end()) if (it == textures_.end())
return; return;
BindTexture(it->second); glBindTexture(GL_TEXTURE_2D, it->second);
if (image->IsCompressed()) { if (image->IsCompressed()) {
GLenum format = 0; GLenum format = 0;
switch (image->GetFormat()) { switch (image->GetFormat()) {
@ -275,13 +274,23 @@ void RendererOpenGL::DestroyTexture(uint64_t resource_id) {
textures_.erase(it); textures_.erase(it);
} }
void RendererOpenGL::ActivateTexture(uint64_t resource_id) { void RendererOpenGL::ActivateTexture(uint64_t resource_id,
uint64_t texture_unit) {
if (texture_unit >= kMaxTextureUnits) {
DLOG(0) << "Invalid texture unit " << texture_unit;
return;
}
auto it = textures_.find(resource_id); auto it = textures_.find(resource_id);
if (it == textures_.end()) { if (it == textures_.end()) {
return; return;
} }
BindTexture(it->second); if (it->second != active_texture_id_[texture_unit]) {
glActiveTexture(GL_TEXTURE0 + texture_unit);
glBindTexture(GL_TEXTURE_2D, it->second);
active_texture_id_[texture_unit] = it->second;
}
} }
uint64_t RendererOpenGL::CreateShader( uint64_t RendererOpenGL::CreateShader(
@ -550,13 +559,6 @@ void RendererOpenGL::DestroyAllResources() {
DCHECK(textures_.size() == 0); DCHECK(textures_.size() == 0);
} }
void RendererOpenGL::BindTexture(GLuint id) {
if (id != active_texture_id_) {
glBindTexture(GL_TEXTURE_2D, id);
active_texture_id_ = id;
}
}
bool RendererOpenGL::SetupVertexLayout( bool RendererOpenGL::SetupVertexLayout(
const VertexDescription& vd, const VertexDescription& vd,
GLuint vertex_size, GLuint vertex_size,

View File

@ -1,6 +1,7 @@
#ifndef ENGINE_RENDERER_OPENGL_RENDERER_OPENGL_H #ifndef ENGINE_RENDERER_OPENGL_RENDERER_OPENGL_H
#define ENGINE_RENDERER_OPENGL_RENDERER_OPENGL_H #define ENGINE_RENDERER_OPENGL_RENDERER_OPENGL_H
#include <array>
#include <memory> #include <memory>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
@ -43,7 +44,7 @@ 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 DestroyTexture(uint64_t resource_id) final; void DestroyTexture(uint64_t resource_id) final;
void ActivateTexture(uint64_t resource_id) final; void ActivateTexture(uint64_t resource_id, uint64_t texture_unit) final;
uint64_t CreateShader(std::unique_ptr<ShaderSource> source, uint64_t CreateShader(std::unique_ptr<ShaderSource> source,
const VertexDescription& vertex_description, const VertexDescription& vertex_description,
@ -113,7 +114,7 @@ class RendererOpenGL final : public Renderer {
uint64_t last_resource_id_ = 0; uint64_t last_resource_id_ = 0;
GLuint active_shader_id_ = 0; GLuint active_shader_id_ = 0;
GLuint active_texture_id_ = 0; std::array<GLuint, kMaxTextureUnits> active_texture_id_ = {};
bool vertex_array_objects_ = false; bool vertex_array_objects_ = false;
bool npot_ = false; bool npot_ = false;
@ -144,7 +145,6 @@ class RendererOpenGL final : public Renderer {
void ContextLost(); void ContextLost();
void DestroyAllResources(); void DestroyAllResources();
void BindTexture(GLuint id);
bool SetupVertexLayout(const VertexDescription& vd, bool SetupVertexLayout(const VertexDescription& vd,
GLuint vertex_size, GLuint vertex_size,
bool use_vao, bool use_vao,

View File

@ -57,7 +57,7 @@ void RendererOpenGL::Present() {
} }
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
active_shader_id_ = 0; active_shader_id_ = 0;
active_texture_id_ = 0; active_texture_id_ = {};
fps_++; fps_++;
} }

View File

@ -50,7 +50,7 @@ void RendererOpenGL::Present() {
glXSwapBuffers(display_, window_); glXSwapBuffers(display_, window_);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
active_shader_id_ = 0; active_shader_id_ = 0;
active_texture_id_ = 0; active_texture_id_ = {};
fps_++; fps_++;
} }

View File

@ -72,7 +72,7 @@ void RendererOpenGL::Present() {
SwapBuffers(dc_); SwapBuffers(dc_);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
active_shader_id_ = 0; active_shader_id_ = 0;
active_texture_id_ = 0; active_texture_id_ = {};
fps_++; fps_++;
} }

View File

@ -19,7 +19,8 @@ enum class RendererType { kUnknown, kVulkan, kOpenGL };
class Renderer { class Renderer {
public: public:
const unsigned kInvalidId = 0; static const unsigned kInvalidId = 0;
static const unsigned kMaxTextureUnits = 8;
static std::unique_ptr<Renderer> Create(RendererType type, static std::unique_ptr<Renderer> Create(RendererType type,
base::Closure context_lost_cb); base::Closure context_lost_cb);
@ -51,7 +52,7 @@ class Renderer {
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 DestroyTexture(uint64_t resource_id) = 0; virtual void DestroyTexture(uint64_t resource_id) = 0;
virtual void ActivateTexture(uint64_t resource_id) = 0; virtual void ActivateTexture(uint64_t resource_id, uint64_t texture_unit) = 0;
virtual uint64_t CreateShader(std::unique_ptr<ShaderSource> source, virtual uint64_t CreateShader(std::unique_ptr<ShaderSource> source,
const VertexDescription& vertex_description, const VertexDescription& vertex_description,

View File

@ -28,9 +28,9 @@ void Texture::Destroy() {
} }
} }
void Texture::Activate() { void Texture::Activate(uint64_t texture_unit) {
if (IsValid()) if (IsValid())
renderer_->ActivateTexture(resource_id_); renderer_->ActivateTexture(resource_id_, texture_unit);
} }
} // namespace eng } // namespace eng

View File

@ -20,7 +20,7 @@ class Texture : public RenderResource {
void Destroy(); void Destroy();
void Activate(); void Activate(uint64_t texture_unit);
int GetWidth() const { return width_; } int GetWidth() const { return width_; }
int GetHeight() const { return height_; } int GetHeight() const { return height_; }

View File

@ -559,21 +559,24 @@ void RendererVulkan::DestroyTexture(uint64_t resource_id) {
textures_.erase(it); textures_.erase(it);
} }
void RendererVulkan::ActivateTexture(uint64_t resource_id) { void RendererVulkan::ActivateTexture(uint64_t resource_id,
uint64_t texture_unit) {
auto it = textures_.find(resource_id); auto it = textures_.find(resource_id);
if (it == textures_.end()) if (it == textures_.end())
return; return;
if (active_descriptor_sets_[/*TODO*/ 0] != std::get<0>(it->second.desc_set)) { if (active_descriptor_sets_[texture_unit] !=
active_descriptor_sets_[/*TODO*/ 0] = std::get<0>(it->second.desc_set); std::get<0>(it->second.desc_set)) {
if (active_shader_id_ != 0) { active_descriptor_sets_[texture_unit] = std::get<0>(it->second.desc_set);
if (active_shader_id_ != kInvalidId) {
auto active_shader = shaders_.find(active_shader_id_); auto active_shader = shaders_.find(active_shader_id_);
if (active_shader != shaders_.end() && if (active_shader != shaders_.end() &&
active_shader->second.desc_set_count > 0) { active_shader->second.desc_set_count > texture_unit) {
vkCmdBindDescriptorSets(frames_[current_frame_].draw_command_buffer, vkCmdBindDescriptorSets(
frames_[current_frame_].draw_command_buffer,
VK_PIPELINE_BIND_POINT_GRAPHICS, VK_PIPELINE_BIND_POINT_GRAPHICS,
active_shader->second.pipeline_layout, 0, 1, active_shader->second.pipeline_layout, texture_unit, 1,
&active_descriptor_sets_[0], 0, nullptr); &active_descriptor_sets_[texture_unit], 0, nullptr);
} }
} }
} }
@ -788,12 +791,14 @@ void RendererVulkan::ActivateShader(uint64_t resource_id) {
active_shader_id_ = resource_id; active_shader_id_ = resource_id;
vkCmdBindPipeline(frames_[current_frame_].draw_command_buffer, vkCmdBindPipeline(frames_[current_frame_].draw_command_buffer,
VK_PIPELINE_BIND_POINT_GRAPHICS, it->second.pipeline); VK_PIPELINE_BIND_POINT_GRAPHICS, it->second.pipeline);
if (it->second.desc_set_count > 0 &&
active_descriptor_sets_[/*TODO*/ 0] != VK_NULL_HANDLE) { for (size_t i = 0; i < it->second.desc_set_count; ++i) {
if (active_descriptor_sets_[i] != VK_NULL_HANDLE) {
vkCmdBindDescriptorSets(frames_[current_frame_].draw_command_buffer, vkCmdBindDescriptorSets(frames_[current_frame_].draw_command_buffer,
VK_PIPELINE_BIND_POINT_GRAPHICS, VK_PIPELINE_BIND_POINT_GRAPHICS,
it->second.pipeline_layout, 0, 1, it->second.pipeline_layout, i, 1,
&active_descriptor_sets_[0], 0, nullptr); &active_descriptor_sets_[i], 0, nullptr);
}
} }
} }
} }
@ -2053,7 +2058,7 @@ void RendererVulkan::SwapBuffers() {
context_.SwapBuffers(); context_.SwapBuffers();
current_frame_ = (current_frame_ + 1) % frames_.size(); current_frame_ = (current_frame_ + 1) % frames_.size();
active_shader_id_ = 0; active_shader_id_ = kInvalidId;
for (auto& ds : active_descriptor_sets_) for (auto& ds : active_descriptor_sets_)
ds = VK_NULL_HANDLE; ds = VK_NULL_HANDLE;

View File

@ -45,7 +45,7 @@ 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 DestroyTexture(uint64_t resource_id) final; void DestroyTexture(uint64_t resource_id) final;
void ActivateTexture(uint64_t resource_id) final; void ActivateTexture(uint64_t resource_id, uint64_t texture_unit) final;
uint64_t CreateShader(std::unique_ptr<ShaderSource> source, uint64_t CreateShader(std::unique_ptr<ShaderSource> source,
const VertexDescription& vertex_description, const VertexDescription& vertex_description,