Update src/RenderDevice.cpp

This commit is contained in:
2025-10-18 01:56:46 +00:00
parent 78f1b2d7a9
commit e5c501272b

View File

@@ -1,13 +1,23 @@
/*
RenderDevice — Inverse Interactive
Homepage: https://dock-it.dev/Inverse-Interactive/RenderDevice
License: Creative Commons Attribution-ShareAlike 4.0 International
SPDX-License-Identifier: CC-BY-SA-4.0
Full License Text: https://dock-it.dev/Inverse-Interactive/RenderDevice/raw/branch/main/LICENSE
Copyright (c) Inverse Interactive
You are free to share and adapt this work under the terms of CC BY-SA 4.0.
Provide appropriate credit and distribute derivatives under the same license.
*/
#include "RenderDevice.h" #include "RenderDevice.h"
#include <GL/glew.h> #include <GL/glew.h>
#include <cstring> #include <cstring>
namespace PF
{
static GLenum ToGL(RenderDevice::Compare f) static GLenum ToGL(RenderDevice::Compare f)
{ {
switch (f) switch (f) {
{
case RenderDevice::Compare::Never: case RenderDevice::Compare::Never:
return GL_NEVER; return GL_NEVER;
case RenderDevice::Compare::Less: case RenderDevice::Compare::Less:
@@ -30,8 +40,7 @@ namespace PF
static GLenum ToGL(RenderDevice::CullFace c) static GLenum ToGL(RenderDevice::CullFace c)
{ {
switch (c) switch (c) {
{
case RenderDevice::CullFace::Back: case RenderDevice::CullFace::Back:
return GL_BACK; return GL_BACK;
case RenderDevice::CullFace::Front: case RenderDevice::CullFace::Front:
@@ -46,7 +55,7 @@ namespace PF
static GLenum ToGL(RenderDevice::IndexType t) static GLenum ToGL(RenderDevice::IndexType t)
{ {
using PF::RenderDevice; using CX::RenderDevice;
return (t == RenderDevice::IndexType::U16) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT; return (t == RenderDevice::IndexType::U16) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
} }
@@ -54,8 +63,7 @@ namespace PF
static GLenum ToGL(RenderDevice::BlendFactor f) static GLenum ToGL(RenderDevice::BlendFactor f)
{ {
switch (f) switch (f) {
{
case RenderDevice::BlendFactor::Zero: case RenderDevice::BlendFactor::Zero:
return GL_ZERO; return GL_ZERO;
case RenderDevice::BlendFactor::One: case RenderDevice::BlendFactor::One:
@@ -82,8 +90,7 @@ namespace PF
static GLenum ToGL(RenderDevice::DrawMode m) static GLenum ToGL(RenderDevice::DrawMode m)
{ {
switch (m) switch (m) {
{
case RenderDevice::DrawMode::Triangles: case RenderDevice::DrawMode::Triangles:
return GL_TRIANGLES; return GL_TRIANGLES;
case RenderDevice::DrawMode::Lines: case RenderDevice::DrawMode::Lines:
@@ -105,8 +112,7 @@ namespace PF
static GLenum ToGL(RenderDevice::Usage u) static GLenum ToGL(RenderDevice::Usage u)
{ {
switch (u) switch (u) {
{
case RenderDevice::Usage::StreamDraw: case RenderDevice::Usage::StreamDraw:
return GL_STREAM_DRAW; return GL_STREAM_DRAW;
case RenderDevice::Usage::StaticDraw: case RenderDevice::Usage::StaticDraw:
@@ -119,7 +125,6 @@ namespace PF
void RenderDevice::_refreshGPUInfo() void RenderDevice::_refreshGPUInfo()
{ {
const char *v = reinterpret_cast<const char *>(glGetString(GL_VENDOR)); const char *v = reinterpret_cast<const char *>(glGetString(GL_VENDOR));
const char *r = reinterpret_cast<const char *>(glGetString(GL_RENDERER)); const char *r = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
const char *ver = reinterpret_cast<const char *>(glGetString(GL_VERSION)); const char *ver = reinterpret_cast<const char *>(glGetString(GL_VERSION));
@@ -133,12 +138,10 @@ namespace PF
GLint major = 0, minor = 0; GLint major = 0, minor = 0;
m_activeDevice->GetIntegerv(PName::MajorVersion, &major); m_activeDevice->GetIntegerv(PName::MajorVersion, &major);
m_activeDevice->GetIntegerv(PName::MinorVersion, &minor); m_activeDevice->GetIntegerv(PName::MinorVersion, &minor);
if (major == 0 && !m_gpu.version.empty()) if (major == 0 && !m_gpu.version.empty()) {
{
// naive parse: "3.3.0 XXX" // naive parse: "3.3.0 XXX"
int M = 0, m = 0; int M = 0, m = 0;
if (std::sscanf(m_gpu.version.c_str(), "%d.%d", &M, &m) == 2) if (std::sscanf(m_gpu.version.c_str(), "%d.%d", &M, &m) == 2) {
{
major = M; major = M;
minor = m; minor = m;
} }
@@ -149,9 +152,7 @@ namespace PF
void RenderDevice::Init() void RenderDevice::Init()
{ {
if (m_activeDevice) {
if (m_activeDevice)
{
m_lastError = DeviceErrors::DeviceAlreadyCreated; m_lastError = DeviceErrors::DeviceAlreadyCreated;
return; return;
} }
@@ -161,10 +162,9 @@ namespace PF
glewExperimental = true; glewExperimental = true;
GLenum err = glewInit(); GLenum err = glewInit();
glGetError(); glGetError();
if (err != GLEW_OK) if (err != GLEW_OK) {
{
m_lastError = DeviceErrors::glewInitFailed; m_lastError = DeviceErrors::glewInitFailed;
return 1; return;
} }
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
@@ -195,8 +195,7 @@ namespace PF
static bool s_hasTimer = false; static bool s_hasTimer = false;
static bool s_hasTimer64 = false; static bool s_hasTimer64 = false;
if (!s_checked) if (!s_checked) {
{
s_hasTimer = (GLEW_VERSION_3_3 || GLEW_ARB_timer_query || GLEW_EXT_timer_query); s_hasTimer = (GLEW_VERSION_3_3 || GLEW_ARB_timer_query || GLEW_EXT_timer_query);
s_hasTimer64 = (GLEW_VERSION_3_3 || GLEW_ARB_timer_query); s_hasTimer64 = (GLEW_VERSION_3_3 || GLEW_ARB_timer_query);
s_checked = true; s_checked = true;
@@ -204,15 +203,13 @@ namespace PF
if (!s_hasTimer) if (!s_hasTimer)
return; return;
if (m_frameTimerQuery == 0) if (m_frameTimerQuery == 0) {
{
glGenQueries(1, &m_frameTimerQuery); glGenQueries(1, &m_frameTimerQuery);
if (m_frameTimerQuery == 0) if (m_frameTimerQuery == 0)
return; return;
} }
if (!m_frameTimerActive) if (!m_frameTimerActive) {
{
glBeginQuery(GL_TIME_ELAPSED, m_frameTimerQuery); glBeginQuery(GL_TIME_ELAPSED, m_frameTimerQuery);
m_frameTimerActive = true; m_frameTimerActive = true;
GetStats().gpuTimersIssued++; GetStats().gpuTimersIssued++;
@@ -226,8 +223,7 @@ namespace PF
static bool s_checked = false; static bool s_checked = false;
static bool s_hasTimer = false; static bool s_hasTimer = false;
static bool s_hasTimer64 = false; static bool s_hasTimer64 = false;
if (!s_checked) if (!s_checked) {
{
s_hasTimer = (GLEW_VERSION_3_3 || GLEW_ARB_timer_query || GLEW_EXT_timer_query); s_hasTimer = (GLEW_VERSION_3_3 || GLEW_ARB_timer_query || GLEW_EXT_timer_query);
s_hasTimer64 = (GLEW_VERSION_3_3 || GLEW_ARB_timer_query); s_hasTimer64 = (GLEW_VERSION_3_3 || GLEW_ARB_timer_query);
s_checked = true; s_checked = true;
@@ -244,16 +240,13 @@ namespace PF
GLint available = 0; GLint available = 0;
glGetQueryObjectiv(m_frameTimerQuery, GL_QUERY_RESULT_AVAILABLE, &available); glGetQueryObjectiv(m_frameTimerQuery, GL_QUERY_RESULT_AVAILABLE, &available);
if (s_hasTimer64 && glGetQueryObjectui64v) if (s_hasTimer64 && glGetQueryObjectui64v) {
{
GLuint64 ns = 0; GLuint64 ns = 0;
glGetQueryObjectui64v(m_frameTimerQuery, glGetQueryObjectui64v(m_frameTimerQuery,
available ? GL_QUERY_RESULT : GL_QUERY_RESULT, available ? GL_QUERY_RESULT : GL_QUERY_RESULT,
&ns); &ns);
GetStats().gpuTimeNsLastFrame = ns; GetStats().gpuTimeNsLastFrame = ns;
} } else {
else
{
GLuint ns32 = 0; GLuint ns32 = 0;
glGetQueryObjectuiv(m_frameTimerQuery, glGetQueryObjectuiv(m_frameTimerQuery,
available ? GL_QUERY_RESULT : GL_QUERY_RESULT, available ? GL_QUERY_RESULT : GL_QUERY_RESULT,
@@ -273,10 +266,8 @@ namespace PF
slot.active = false; slot.active = false;
// reuse free slots if any // reuse free slots if any
for (size_t i = 0; i < m_timerPool.size(); ++i) for (size_t i = 0; i < m_timerPool.size(); ++i) {
{ if (m_timerPool[i].id == 0) {
if (m_timerPool[i].id == 0)
{
m_timerPool[i] = slot; m_timerPool[i] = slot;
return static_cast<GpuTimer>(i + 1); // handle 1-based return static_cast<GpuTimer>(i + 1); // handle 1-based
} }
@@ -292,8 +283,7 @@ namespace PF
size_t idx = static_cast<size_t>(h - 1); size_t idx = static_cast<size_t>(h - 1);
if (idx >= m_timerPool.size()) if (idx >= m_timerPool.size())
return; return;
if (m_timerPool[idx].id) if (m_timerPool[idx].id) {
{
glDeleteQueries(1, &m_timerPool[idx].id); glDeleteQueries(1, &m_timerPool[idx].id);
} }
m_timerPool[idx] = {}; // mark free m_timerPool[idx] = {}; // mark free
@@ -307,8 +297,7 @@ namespace PF
if (idx >= m_timerPool.size()) if (idx >= m_timerPool.size())
return; return;
auto &ts = m_timerPool[idx]; auto &ts = m_timerPool[idx];
if (ts.id && !ts.active) if (ts.id && !ts.active) {
{
glBeginQuery(GL_TIME_ELAPSED, ts.id); glBeginQuery(GL_TIME_ELAPSED, ts.id);
ts.active = true; ts.active = true;
GetStats().gpuTimersIssued++; GetStats().gpuTimersIssued++;
@@ -331,8 +320,7 @@ namespace PF
ts.active = false; ts.active = false;
GLint available = 0; GLint available = 0;
if (!wait) if (!wait) {
{
glGetQueryObjectiv(ts.id, GL_QUERY_RESULT_AVAILABLE, &available); glGetQueryObjectiv(ts.id, GL_QUERY_RESULT_AVAILABLE, &available);
if (!available) if (!available)
return false; // not ready yet return false; // not ready yet
@@ -352,8 +340,7 @@ namespace PF
// ==== Existing API ==== // ==== Existing API ====
void RenderDevice::Viewport(int x, int y, int w, int h) void RenderDevice::Viewport(int x, int y, int w, int h)
{ {
if (m_viewport[0] != x || m_viewport[1] != y || m_viewport[2] != w || m_viewport[3] != h) if (m_viewport[0] != x || m_viewport[1] != y || m_viewport[2] != w || m_viewport[3] != h) {
{
glViewport(x, y, w, h); glViewport(x, y, w, h);
m_viewport[0] = x; m_viewport[0] = x;
m_viewport[1] = y; m_viewport[1] = y;
@@ -365,8 +352,7 @@ namespace PF
void RenderDevice::SetClearColor(float r, float g, float b, float a) void RenderDevice::SetClearColor(float r, float g, float b, float a)
{ {
if (m_clear[0] != r || m_clear[1] != g || m_clear[2] != b || m_clear[3] != a) if (m_clear[0] != r || m_clear[1] != g || m_clear[2] != b || m_clear[3] != a) {
{
glClearColor(r, g, b, a); glClearColor(r, g, b, a);
m_clear[0] = r; m_clear[0] = r;
m_clear[1] = g; m_clear[1] = g;
@@ -391,8 +377,7 @@ namespace PF
void RenderDevice::SetDepthTest(const bool enabled) void RenderDevice::SetDepthTest(const bool enabled)
{ {
if (m_depthTest != enabled) if (m_depthTest != enabled) {
{
enabled ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST); enabled ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
m_depthTest = enabled; m_depthTest = enabled;
GetStats().stateChanges++; GetStats().stateChanges++;
@@ -402,8 +387,7 @@ namespace PF
void RenderDevice::SetDepthFunc(const Compare f) void RenderDevice::SetDepthFunc(const Compare f)
{ {
const auto glf = ToGL(f); const auto glf = ToGL(f);
if (m_depthFunc != static_cast<int>(glf)) if (m_depthFunc != static_cast<int>(glf)) {
{
glDepthFunc(glf); glDepthFunc(glf);
m_depthFunc = static_cast<int>(glf); m_depthFunc = static_cast<int>(glf);
GetStats().stateChanges++; GetStats().stateChanges++;
@@ -412,8 +396,7 @@ namespace PF
void RenderDevice::SetDepthMask(const bool enableWrite) void RenderDevice::SetDepthMask(const bool enableWrite)
{ {
if (m_depthMask != enableWrite) if (m_depthMask != enableWrite) {
{
glDepthMask(enableWrite ? GL_TRUE : GL_FALSE); glDepthMask(enableWrite ? GL_TRUE : GL_FALSE);
m_depthMask = enableWrite; m_depthMask = enableWrite;
GetStats().stateChanges++; GetStats().stateChanges++;
@@ -422,8 +405,7 @@ namespace PF
void RenderDevice::SetColorMask(const bool r, const bool g, const bool b, const bool a) void RenderDevice::SetColorMask(const bool r, const bool g, const bool b, const bool a)
{ {
if (m_colorMask[0] != r || m_colorMask[1] != g || m_colorMask[2] != b || m_colorMask[3] != a) if (m_colorMask[0] != r || m_colorMask[1] != g || m_colorMask[2] != b || m_colorMask[3] != a) {
{
glColorMask(r, g, b, a); glColorMask(r, g, b, a);
m_colorMask[0] = r; m_colorMask[0] = r;
m_colorMask[1] = g; m_colorMask[1] = g;
@@ -437,23 +419,19 @@ namespace PF
void RenderDevice::SetCull(const CullFace c) void RenderDevice::SetCull(const CullFace c)
{ {
const auto glc = ToGL(c); const auto glc = ToGL(c);
if (c == CullFace::None) if (c == CullFace::None) {
{ if (m_cullFace != 0) {
if (m_cullFace != 0)
{
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
m_cullFace = 0; m_cullFace = 0;
GetStats().stateChanges++; GetStats().stateChanges++;
} }
return; return;
} }
if (m_cullFace == 0) if (m_cullFace == 0) {
{
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
GetStats().stateChanges++; GetStats().stateChanges++;
} }
if (m_cullFace != (int)glc) if (m_cullFace != (int) glc) {
{
glCullFace(glc); glCullFace(glc);
m_cullFace = (int) glc; m_cullFace = (int) glc;
GetStats().stateChanges++; GetStats().stateChanges++;
@@ -463,8 +441,7 @@ namespace PF
void RenderDevice::SetFrontFace(const Winding w) void RenderDevice::SetFrontFace(const Winding w)
{ {
const auto glw = ToGL(w); const auto glw = ToGL(w);
if (m_frontFace != (int)glw) if (m_frontFace != (int) glw) {
{
glFrontFace(glw); glFrontFace(glw);
m_frontFace = (int) glw; m_frontFace = (int) glw;
GetStats().stateChanges++; GetStats().stateChanges++;
@@ -473,8 +450,7 @@ namespace PF
void RenderDevice::SetBlend(const bool enabled) void RenderDevice::SetBlend(const bool enabled)
{ {
if (m_blend != enabled) if (m_blend != enabled) {
{
enabled ? glEnable(GL_BLEND) : glDisable(GL_BLEND); enabled ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
m_blend = enabled; m_blend = enabled;
GetStats().stateChanges++; GetStats().stateChanges++;
@@ -484,8 +460,7 @@ namespace PF
void RenderDevice::SetBlendFunc(const BlendFactor src, const BlendFactor dst) void RenderDevice::SetBlendFunc(const BlendFactor src, const BlendFactor dst)
{ {
const auto gls = ToGL(src), gld = ToGL(dst); const auto gls = ToGL(src), gld = ToGL(dst);
if (m_blendSrc != (int)gls || m_blendDst != (int)gld) if (m_blendSrc != (int) gls || m_blendDst != (int) gld) {
{
glBlendFunc(gls, gld); glBlendFunc(gls, gld);
m_blendSrc = (int) gls; m_blendSrc = (int) gls;
m_blendDst = (int) gld; m_blendDst = (int) gld;
@@ -505,8 +480,7 @@ namespace PF
{ {
const unsigned newRGB = (unsigned) rgb; const unsigned newRGB = (unsigned) rgb;
const unsigned newA = (unsigned) a; const unsigned newA = (unsigned) a;
if (m_blendEqRGB != newRGB || m_blendEqA != newA) if (m_blendEqRGB != newRGB || m_blendEqA != newA) {
{
if (newRGB == newA) if (newRGB == newA)
glBlendEquation((GLenum) newRGB); glBlendEquation((GLenum) newRGB);
else else
@@ -520,8 +494,7 @@ namespace PF
void RenderDevice::SetStencil(bool enabled) void RenderDevice::SetStencil(bool enabled)
{ {
if (m_stencilEnabled != enabled) if (m_stencilEnabled != enabled) {
{
enabled ? glEnable(GL_STENCIL_TEST) : glDisable(GL_STENCIL_TEST); enabled ? glEnable(GL_STENCIL_TEST) : glDisable(GL_STENCIL_TEST);
m_stencilEnabled = enabled; m_stencilEnabled = enabled;
GetStats().stencilStateChanges++; GetStats().stencilStateChanges++;
@@ -536,17 +509,16 @@ namespace PF
GetStats().stateChanges++; GetStats().stateChanges++;
} }
void RenderDevice::SetStencilOp(unsigned sfail, unsigned dpfail, unsigned dppass) void RenderDevice::SetStencilOp(unsigned sfail, unsigned dCXail, unsigned dppass)
{ {
glStencilOp((GLenum)sfail, (GLenum)dpfail, (GLenum)dppass); glStencilOp((GLenum) sfail, (GLenum) dCXail, (GLenum) dppass);
GetStats().stencilStateChanges++; GetStats().stencilStateChanges++;
GetStats().stateChanges++; GetStats().stateChanges++;
} }
void RenderDevice::SetStencilMask(unsigned mask) void RenderDevice::SetStencilMask(unsigned mask)
{ {
if (m_stencilMask != mask) if (m_stencilMask != mask) {
{
glStencilMask(mask); glStencilMask(mask);
m_stencilMask = mask; m_stencilMask = mask;
GetStats().stencilStateChanges++; GetStats().stencilStateChanges++;
@@ -556,17 +528,14 @@ namespace PF
void RenderDevice::SetScissor(bool enabled, int x, int y, int w, int h) void RenderDevice::SetScissor(bool enabled, int x, int y, int w, int h)
{ {
if (m_scissorEnabled != enabled) if (m_scissorEnabled != enabled) {
{
enabled ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST); enabled ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST);
m_scissorEnabled = enabled; m_scissorEnabled = enabled;
GetStats().scissorChanges++; GetStats().scissorChanges++;
GetStats().stateChanges++; GetStats().stateChanges++;
} }
if (enabled) if (enabled) {
{ if (m_scissorBox[0] != x || m_scissorBox[1] != y || m_scissorBox[2] != w || m_scissorBox[3] != h) {
if (m_scissorBox[0] != x || m_scissorBox[1] != y || m_scissorBox[2] != w || m_scissorBox[3] != h)
{
glScissor(x, y, w, h); glScissor(x, y, w, h);
m_scissorBox[0] = x; m_scissorBox[0] = x;
m_scissorBox[1] = y; m_scissorBox[1] = y;
@@ -586,8 +555,7 @@ namespace PF
void RenderDevice::BindVAO(const VAO &v) void RenderDevice::BindVAO(const VAO &v)
{ {
if (m_boundVAO != v.id) if (m_boundVAO != v.id) {
{
glBindVertexArray(v.id); glBindVertexArray(v.id);
m_boundVAO = v.id; m_boundVAO = v.id;
GetStats().vaoBinds++; GetStats().vaoBinds++;
@@ -603,7 +571,8 @@ namespace PF
v = {}; v = {};
} }
RenderDevice::Buffer RenderDevice::CreateBuffer(BufferTarget target, size_t sizeBytes, const void *data, Usage usage) RenderDevice::Buffer RenderDevice::CreateBuffer(BufferTarget target, size_t sizeBytes, const void *data,
Usage usage)
{ {
Buffer b{}; Buffer b{};
b.target = target; b.target = target;
@@ -618,19 +587,14 @@ namespace PF
void RenderDevice::BindBuffer(const Buffer &b) void RenderDevice::BindBuffer(const Buffer &b)
{ {
const GLenum tgt = ToGL(b.target); const GLenum tgt = ToGL(b.target);
if (b.target == BufferTarget::Array) if (b.target == BufferTarget::Array) {
{ if (m_boundArrayBuffer != b.id) {
if (m_boundArrayBuffer != b.id)
{
glBindBuffer(tgt, b.id); glBindBuffer(tgt, b.id);
m_boundArrayBuffer = b.id; m_boundArrayBuffer = b.id;
GetStats().bufferBinds++; GetStats().bufferBinds++;
} }
} } else {
else if (m_boundElementBuffer != b.id) {
{
if (m_boundElementBuffer != b.id)
{
glBindBuffer(tgt, b.id); glBindBuffer(tgt, b.id);
m_boundElementBuffer = b.id; m_boundElementBuffer = b.id;
GetStats().bufferBinds++; GetStats().bufferBinds++;
@@ -753,38 +717,27 @@ namespace PF
void RenderDevice::BindTextureUnit(unsigned unit, const Texture &t) void RenderDevice::BindTextureUnit(unsigned unit, const Texture &t)
{ {
if (glBindTextureUnit) if (glBindTextureUnit) {
{
// DSA // DSA
if (unit < 32) if (unit < 32) {
{ if (m_boundTexUnits[unit] != t.id) {
if (m_boundTexUnits[unit] != t.id)
{
glBindTextureUnit(unit, t.id); glBindTextureUnit(unit, t.id);
m_boundTexUnits[unit] = t.id; m_boundTexUnits[unit] = t.id;
GetStats().textureBinds++; GetStats().textureBinds++;
} }
} } else {
else
{
glBindTextureUnit(unit, t.id); glBindTextureUnit(unit, t.id);
GetStats().textureBinds++; GetStats().textureBinds++;
} }
} } else {
else if (unit < 32) {
{ if (m_boundTexUnits[unit] != t.id) {
if (unit < 32)
{
if (m_boundTexUnits[unit] != t.id)
{
glActiveTexture(GL_TEXTURE0 + unit); glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(t.target, t.id); glBindTexture(t.target, t.id);
m_boundTexUnits[unit] = t.id; m_boundTexUnits[unit] = t.id;
GetStats().textureBinds++; GetStats().textureBinds++;
} }
} } else {
else
{
glActiveTexture(GL_TEXTURE0 + unit); glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(t.target, t.id); glBindTexture(t.target, t.id);
GetStats().textureBinds++; GetStats().textureBinds++;
@@ -807,14 +760,14 @@ namespace PF
GetStats().stateChanges++; GetStats().stateChanges++;
} }
PF::RenderDevice::Sampler PF::RenderDevice::CreateSampler() CX::RenderDevice::Sampler CX::RenderDevice::CreateSampler()
{ {
Sampler s{}; Sampler s{};
glGenSamplers(1, &s.id); glGenSamplers(1, &s.id);
return s; return s;
} }
void PF::RenderDevice::SetSamplerParams(Sampler s, TexFilter minFilter, TexFilter magFilter, TexWrap wrapS, void CX::RenderDevice::SetSamplerParams(Sampler s, TexFilter minFilter, TexFilter magFilter, TexWrap wrapS,
TexWrap wrapT) TexWrap wrapT)
{ {
if (!s.id) if (!s.id)
@@ -831,8 +784,7 @@ namespace PF
return; return;
#ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
GLfloat maxAniso = 1.0f; GLfloat maxAniso = 1.0f;
if (glewIsSupported("GL_EXT_texture_filter_anisotropic")) if (glewIsSupported("GL_EXT_texture_filter_anisotropic")) {
{
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAniso); glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAniso);
if (aniso < 1.0f) if (aniso < 1.0f)
aniso = 1.0f; aniso = 1.0f;
@@ -845,17 +797,13 @@ namespace PF
void RenderDevice::BindSampler(unsigned unit, Sampler s) void RenderDevice::BindSampler(unsigned unit, Sampler s)
{ {
if (unit < 32) if (unit < 32) {
{ if (m_boundSamplers[unit] != s.id) {
if (m_boundSamplers[unit] != s.id)
{
glBindSampler(unit, s.id); glBindSampler(unit, s.id);
m_boundSamplers[unit] = s.id; m_boundSamplers[unit] = s.id;
GetStats().samplerBinds++; GetStats().samplerBinds++;
} }
} } else {
else
{
glBindSampler(unit, s.id); glBindSampler(unit, s.id);
GetStats().samplerBinds++; GetStats().samplerBinds++;
} }
@@ -863,8 +811,7 @@ namespace PF
void RenderDevice::Destroy(Sampler &s) void RenderDevice::Destroy(Sampler &s)
{ {
if (s.id) if (s.id) {
{
for (unsigned i = 0; i < 32; ++i) for (unsigned i = 0; i < 32; ++i)
if (m_boundSamplers[i] == s.id) if (m_boundSamplers[i] == s.id)
m_boundSamplers[i] = 0; m_boundSamplers[i] = 0;
@@ -890,8 +837,7 @@ namespace PF
void RenderDevice::BindFramebuffer(const Framebuffer &fb) void RenderDevice::BindFramebuffer(const Framebuffer &fb)
{ {
if (m_boundFramebuffer != fb.id) if (m_boundFramebuffer != fb.id) {
{
glBindFramebuffer(GL_FRAMEBUFFER, fb.id); glBindFramebuffer(GL_FRAMEBUFFER, fb.id);
m_boundFramebuffer = fb.id; m_boundFramebuffer = fb.id;
GetStats().framebufferBinds++; GetStats().framebufferBinds++;
@@ -900,8 +846,7 @@ namespace PF
void RenderDevice::BindDefaultFramebuffer() void RenderDevice::BindDefaultFramebuffer()
{ {
if (m_boundFramebuffer != 0) if (m_boundFramebuffer != 0) {
{
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
m_boundFramebuffer = 0; m_boundFramebuffer = 0;
GetStats().framebufferBinds++; GetStats().framebufferBinds++;
@@ -1006,7 +951,8 @@ namespace PF
GetStats().instancesDrawn += instanceCount; GetStats().instancesDrawn += instanceCount;
} }
void RenderDevice::DrawElementsBaseVertex(DrawMode mode, int count, IndexType type, const void *offset, int baseVertex) void RenderDevice::DrawElementsBaseVertex(DrawMode mode, int count, IndexType type, const void *offset,
int baseVertex)
{ {
glDrawElementsBaseVertex(ToGL(mode), count, ToGL(type), offset, baseVertex); glDrawElementsBaseVertex(ToGL(mode), count, ToGL(type), offset, baseVertex);
GetStats().indexedDrawCalls++; GetStats().indexedDrawCalls++;
@@ -1016,8 +962,7 @@ namespace PF
void RenderDevice::SetObjectLabel(unsigned glType, unsigned id, const std::string &name) void RenderDevice::SetObjectLabel(unsigned glType, unsigned id, const std::string &name)
{ {
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
if (id && !name.empty() && glObjectLabel) if (id && !name.empty() && glObjectLabel) {
{
glObjectLabel(glType, id, (GLsizei) name.size(), name.c_str()); glObjectLabel(glType, id, (GLsizei) name.size(), name.c_str());
} }
#endif #endif
@@ -1035,10 +980,8 @@ namespace PF
glBindTexture(GL_TEXTURE_2D, t.id); glBindTexture(GL_TEXTURE_2D, t.id);
GetStats().textureBinds++; GetStats().textureBinds++;
// allocate immutable storage
glTexStorage2D(GL_TEXTURE_2D, t.levels, static_cast<GLenum>(internalFmt), w, h); glTexStorage2D(GL_TEXTURE_2D, t.levels, static_cast<GLenum>(internalFmt), w, h);
// sensible defaults
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (t.levels > 1) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (t.levels > 1) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@@ -1077,4 +1020,3 @@ namespace PF
m_boundTexUnits[unit] = 0; m_boundTexUnits[unit] = 0;
GetStats().textureBinds++; GetStats().textureBinds++;
} }
}