Subversion Repository Public Repository

Divide-Framework

This repository has no backups
This repository's network speed is throttled to 100KB/sec

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
#include "stdafx.h"

#include "Headers/GLWrapper.h"
#include "Headers/glHardwareQuery.h"

#include "GUI/Headers/GUI.h"
#include "Core/Headers/Kernel.h"
#include "Core/Headers/Console.h"
#include "Core/Headers/Application.h"
#include "Core/Headers/Configuration.h"
#include "Core/Headers/PlatformContext.h"

#include "Utility/Headers/Localization.h"


#include "Platform/Headers/PlatformRuntime.h"
#include "Platform/Video/Headers/GFXDevice.h"
#include "Platform/Video/OpenGL/Buffers/Headers/glMemoryManager.h"
#include "Platform/Video/OpenGL/Buffers/ShaderBuffer/Headers/glUniformBuffer.h"
#include "Platform/Video/OpenGL/Buffers/VertexBuffer/Headers/glVertexArray.h"

#ifndef CEGUI_STATIC
#define CEGUI_STATIC
#endif //CEGUI_STATIC

#include <CEGUI/CEGUI.h>
#include <CEGUI/RendererModules/OpenGL/GL3Renderer.h>

#include <AntTweakBar/include/AntTweakBar.h>

#include <GLIM/glim.h>
#include <chrono>
#include <thread>

#define HAVE_M_PI
#include <SDL.h>

namespace Divide {
namespace {
    const U32 g_maxVAOS = 512u;
    const U32 g_maxQueryRings = 64;

    class ContextPool {
    public:
        ContextPool()
        {
            _contexts.reserve(HARDWARE_THREAD_COUNT() * 2);
        }

        ~ContextPool() 
        {
            assert(_contexts.empty());
        }

        bool init(U32 size, const DisplayWindow& window) {
            SDL_Window* raw = window.getRawWindow();
            WriteLock w_lock(_glContextLock);
            _contexts.resize(size, std::make_pair(nullptr, false));
            for (std::pair<SDL_GLContext, bool>& ctx : _contexts) {
                ctx.first = SDL_GL_CreateContext(raw);
            }
            return true;
        }

        bool destroy() {
            WriteLock w_lock(_glContextLock);
            for (std::pair<SDL_GLContext, bool>& ctx : _contexts) {
                SDL_GL_DeleteContext(ctx.first);
            }
            _contexts.clear();
            return true;
        }

        bool getAvailableContext(SDL_GLContext& ctx) {
            UpgradableReadLock ur_lock(_glContextLock);
            for (std::pair<SDL_GLContext, bool>& ctxIt : _contexts) {
                if (!ctxIt.second) {
                    UpgradeToWriteLock w_lock(ur_lock);
                    ctx = ctxIt.first;
                    ctxIt.second = true;
                    return true;
                }
            }

            return false;
        }

    private:
        SharedLock _glContextLock;
        vectorImpl<std::pair<SDL_GLContext, bool /*in use*/>> _contexts;
    } g_ContextPool;
};

ErrorCode GL_API::createGLContext(const DisplayWindow& window) {
    g_ContextPool.init(HARDWARE_THREAD_COUNT() * 2, window);
    GLUtil::_glRenderContext = SDL_GL_CreateContext(window.getRawWindow());
    if (GLUtil::_glRenderContext == nullptr)
    {
        Console::errorfn(Locale::get(_ID("ERROR_GFX_DEVICE")),
                         Locale::get(_ID("ERROR_GL_OLD_VERSION")));
        Console::printfn(Locale::get(_ID("WARN_SWITCH_D3D")));
        Console::printfn(Locale::get(_ID("WARN_APPLICATION_CLOSE")));
        return ErrorCode::OGL_OLD_HARDWARE;
    }

    return ErrorCode::NO_ERR;
}

ErrorCode GL_API::destroyGLContext() {
    SDL_GL_DeleteContext(GLUtil::_glRenderContext);
    g_ContextPool.destroy();

    return ErrorCode::NO_ERR;
}


/// Try and create a valid OpenGL context taking in account the specified resolution and command line arguments
ErrorCode GL_API::initRenderingAPI(GLint argc, char** argv, Configuration& config) {
    // Fill our (abstract API <-> openGL) enum translation tables with proper values
    GLUtil::fillEnumTables();

    const DisplayWindow& window = _context.parent().platformContext().app().windowManager().getActiveWindow();
    ErrorCode errorState = createGLContext(window);
    if (errorState != ErrorCode::NO_ERR) {
        return errorState;
    }

    SDL_GL_MakeCurrent(window.getRawWindow(), GLUtil::_glRenderContext);
    glbinding::Binding::initialize();
    if (glbinding::getCurrentContext() == 0) {
        return ErrorCode::GLBINGING_INIT_ERROR;
    }

    glbinding::Binding::useCurrentContext();

    if (s_hardwareQueryPool == nullptr) {
        s_hardwareQueryPool = MemoryManager_NEW glHardwareQueryPool(_context);
    }

    // OpenGL has a nifty error callback system, available in every build
    // configuration if required
    if (Config::ENABLE_GPU_VALIDATION) {
        // GL_DEBUG_OUTPUT_SYNCHRONOUS is essential for debugging gl commands in the IDE
        glEnable(GL_DEBUG_OUTPUT);
        glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
        // hardwire our debug callback function with OpenGL's implementation
        glDebugMessageCallback((GLDEBUGPROC)GLUtil::DebugCallback, nullptr);
        // nVidia flushes a lot of useful info about buffer allocations and shader
        // recompiles due to state and what now, but those aren't needed until that's
        // what's actually causing the bottlenecks
        /*U32 nvidiaBufferErrors[] = { 131185, 131218 };
        // Disable shader compiler errors (shader class handles that)
        glDebugMessageControl(GL_DEBUG_SOURCE_SHADER_COMPILER, GL_DEBUG_TYPE_ERROR,
            GL_DONT_CARE, 0, nullptr, GL_FALSE);
        // Disable nVidia buffer allocation info (an easy enable is to change the
        // count param to 0)
        glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_OTHER,
            GL_DONT_CARE, 2, nvidiaBufferErrors, GL_FALSE);
        // Shader will be recompiled nVidia error
        glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_PERFORMANCE,
            GL_DONT_CARE, 2, nvidiaBufferErrors, GL_FALSE);*/
    }

    // Vsync is toggled on or off via the external config file
    SDL_GL_SetSwapInterval(config.runtime.enableVSync ? 1 : 0);
        
    // If we got here, let's figure out what capabilities we have available
    // Maximum addressable texture image units in the fragment shader
    s_maxTextureUnits = GLUtil::getIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS);
    s_maxAttribBindings = GLUtil::getIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS);
    s_vaoBufferData.init(s_maxAttribBindings);

    assert(to_base(ShaderProgram::TextureUsage::COUNT) < to_U32(s_maxTextureUnits) &&
           "GL Wrapper: insufficient number of texture image units available on current hardware!");

    assert(to_base(AttribLocation::COUNT) < to_U32(s_maxAttribBindings) &&
           "GL Wrapper: insufficient number of attribute binding locations available on current hardware!");

    Console::printfn(Locale::get(_ID("GL_MAX_TEX_UNITS_FRAG")), s_maxTextureUnits);
    
    // Maximum number of colour attachments per framebuffer
    s_maxFBOAttachments = GLUtil::getIntegerv(GL_MAX_COLOR_ATTACHMENTS);
    GL_API::s_blendProperties.resize(s_maxFBOAttachments);

    // Query GPU vendor to enable/disable vendor specific features
    GPUVendor vendor = GPUVendor::COUNT;
    const char* gpuVendorStr = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
    if (gpuVendorStr != nullptr) {
        if (strstr(gpuVendorStr, "Intel") != nullptr) {
            vendor = GPUVendor::INTEL;
        } else if (strstr(gpuVendorStr, "NVIDIA") != nullptr) {
            vendor = GPUVendor::NVIDIA;
        } else if (strstr(gpuVendorStr, "ATI") != nullptr || strstr(gpuVendorStr, "AMD") != nullptr) {
            vendor = GPUVendor::AMD;
        } else if(strstr(gpuVendorStr, "Microsoft") != nullptr) {
            vendor = GPUVendor::MICROSOFT;
        } else {
            vendor = GPUVendor::OTHER;
        }
    } else {
        gpuVendorStr = "Unknown GPU Vendor";
        vendor = GPUVendor::OTHER;
    }
    GPURenderer renderer = GPURenderer::COUNT;
    const char* gpuRendererStr = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
    if (gpuRendererStr != nullptr) {
        if (strstr(gpuRendererStr,"Tegra") || strstr(gpuRendererStr, "GeForce") || strstr(gpuRendererStr, "NV")) {
            renderer = GPURenderer::GEFORCE;
        } else if(strstr(gpuRendererStr, "PowerVR") || strstr(gpuRendererStr, "Apple")) {
            renderer = GPURenderer::POWERVR;
            vendor = GPUVendor::IMAGINATION_TECH;
        } else if(strstr(gpuRendererStr, "Mali")) {
            renderer = GPURenderer::MALI;
            vendor = GPUVendor::ARM;
        } else if (strstr(gpuRendererStr, "Adreno")) {
            renderer = GPURenderer::ADRENO;
            vendor = GPUVendor::QUALCOMM;
        } else if(strstr(gpuRendererStr, "AMD") || strstr(gpuRendererStr, "ATI")) {
            renderer = GPURenderer::RADEON;
        } else if (strstr(gpuRendererStr, "Intel")) {
            renderer = GPURenderer::INTEL;
        } else if(strstr(gpuRendererStr, "Vivante")) {
            renderer = GPURenderer::VIVANTE;
            vendor = GPUVendor::VIVANTE;
        } else if(strstr(gpuRendererStr, "VideoCore")) {
            renderer = GPURenderer::VIDEOCORE;
            vendor = GPUVendor::ALPHAMOSAIC;
        } else if(strstr(gpuRendererStr, "WebKit") || strstr(gpuRendererStr, "Mozilla") || strstr(gpuRendererStr, "ANGLE")) {
            renderer = GPURenderer::WEBGL;
            vendor = GPUVendor::WEBGL;
        } else {
            renderer = GPURenderer::UNKNOWN;
        }
    } else {
        gpuRendererStr = "Unknown GPU Renderer";
        renderer = GPURenderer::UNKNOWN;
    }

    _context.setGPURenderer(renderer);
    _context.setGPUVendor(vendor);
    // Cap max anisotropic level to what the hardware supports
    CLAMP(config.rendering.anisotropicFilteringLevel, to_U8(1), to_U8(GLUtil::getIntegerv(gl::GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT)));
    GL_API::s_anisoLevel = config.rendering.anisotropicFilteringLevel;

    Console::printfn(Locale::get(_ID("GL_MAX_VERSION")),
                     GLUtil::getIntegerv(GL_MAJOR_VERSION),
                     GLUtil::getIntegerv(GL_MINOR_VERSION));

    // Number of sample buffers associated with the framebuffer & MSAA sample
    // count
    GLint samplerBuffers = GLUtil::getIntegerv(GL_SAMPLES);
    GLint sampleCount = GLUtil::getIntegerv(GL_SAMPLE_BUFFERS);
    Console::printfn(Locale::get(_ID("GL_MULTI_SAMPLE_INFO")), sampleCount, samplerBuffers);
    // If we do not support MSAA on a hardware level for whatever reason, override user set MSAA levels
    if (samplerBuffers == 0 || sampleCount == 0) {
        config.rendering.msaaSamples = 0;
    }
    // Print all of the OpenGL functionality info to the console and log
    // How many uniforms can we send to fragment shaders
    Console::printfn(Locale::get(_ID("GL_MAX_UNIFORM")),
                     GLUtil::getIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS));
    // How many uniforms can we send to vertex shaders
    Console::printfn(Locale::get(_ID("GL_MAX_VERT_UNIFORM")),
                     GLUtil::getIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS));
    // How many attributes can we send to a vertex shader
    Console::printfn(Locale::get(_ID("GL_MAX_VERT_ATTRIB")),
                     GLUtil::getIntegerv(GL_MAX_VERTEX_ATTRIBS));
    // Maximum number of texture units we can address in shaders
    Console::printfn(Locale::get(_ID("GL_MAX_TEX_UNITS")),
                     GLUtil::getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS),
                     GL_API::s_maxTextureUnits);
    // Query shading language version support
    Console::printfn(Locale::get(_ID("GL_GLSL_SUPPORT")),
                     glGetString(GL_SHADING_LANGUAGE_VERSION));
    // GPU info, including vendor, gpu and driver
    Console::printfn(Locale::get(_ID("GL_VENDOR_STRING")),
                     gpuVendorStr, gpuRendererStr, glGetString(GL_VERSION));
    // In order: Maximum number of uniform buffer binding points,
    //           maximum size in basic machine units of a uniform block and
    //           minimum required alignment for uniform buffer sizes and offset
    GL_API::s_UBOffsetAlignment = GLUtil::getIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
    GL_API::s_UBMaxSize = GLUtil::getIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE);
    Console::printfn(Locale::get(_ID("GL_UBO_INFO")),
                     GLUtil::getIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS),
                     GL_API::s_UBMaxSize / 1024,
                     GL_API::s_UBOffsetAlignment);

    // In order: Maximum number of shader storage buffer binding points,
    //           maximum size in basic machine units of a shader storage block,
    //           maximum total number of active shader storage blocks that may
    //           be accessed by all active shaders and
    //           minimum required alignment for shader storage buffer sizes and
    //           offset.
    GL_API::s_SSBOffsetAlignment = GLUtil::getIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT);
    GL_API::s_SSBMaxSize = GLUtil::getIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE);
    Console::printfn(
        Locale::get(_ID("GL_SSBO_INFO")),
        GLUtil::getIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS),
        (GLUtil::getIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE) / 1024) / 1024,
        GLUtil::getIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS),
        GL_API::s_SSBOffsetAlignment);

    // Maximum number of subroutines and maximum number of subroutine uniform
    // locations usable in a shader
    Console::printfn(Locale::get(_ID("GL_SUBROUTINE_INFO")),
                     GLUtil::getIntegerv(GL_MAX_SUBROUTINES),
                     GLUtil::getIntegerv(GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS));

    // Seamless cubemaps are a nice feature to have enabled (core since 3.2)
    glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
    //glEnable(GL_FRAMEBUFFER_SRGB);
    // Enable multisampling if we actually support and request it
    config.rendering.msaaSamples > 0 ? glEnable(GL_MULTISAMPLE)
                                     :  glDisable(GL_MULTISAMPLE);

    // Line smoothing should almost always be used
    if (Config::USE_HARDWARE_AA_LINES) {
        glEnable(GL_LINE_SMOOTH);
        glGetIntegerv(GL_SMOOTH_LINE_WIDTH_RANGE, &s_lineWidthLimit);
    } else {
        glGetIntegerv(GL_ALIASED_LINE_WIDTH_RANGE, &s_lineWidthLimit);
    }

    // Culling is enabled by default, but RenderStateBlocks can toggle it on a per-draw call basis
    glEnable(GL_CULL_FACE);

    // Prepare font rendering subsystem
    if (!createFonsContext()) {
        Console::errorfn(Locale::get(_ID("ERROR_FONT_INIT")));
        return ErrorCode::FONT_INIT_ERROR;
    }

    // Prepare immediate mode emulation rendering
    NS_GLIM::glim.SetVertexAttribLocation(to_base(AttribLocation::VERTEX_POSITION));
    // Initialize our VAO pool
    GL_API::s_vaoPool.init(g_maxVAOS);
    // Initialize our query pool
    GL_API::s_hardwareQueryPool->init(g_maxQueryRings);
    // Initialize shader buffers
    glUniformBuffer::onGLInit();
    // We need a dummy VAO object for point rendering
    s_dummyVAO = GL_API::s_vaoPool.allocate();

    // In debug, we also have various performance counters to profile GPU rendering
    // operations
    if (Config::ENABLE_GPU_VALIDATION) {
        // We have multiple counter buffers, and each can be multi-buffered
        // (currently, only double-buffered, front and back)
        // to avoid pipeline stalls
        for (std::shared_ptr<glHardwareQueryRing>& queryRing : _hardwareQueries) {
            queryRing->initQueries();
        }
    }
    
    // Once OpenGL is ready for rendering, init CEGUI
    _GUIGLrenderer = &CEGUI::OpenGL3Renderer::create();
    _GUIGLrenderer->enableExtraStateSettings(config.gui.cegui.extraStates);
    CEGUI::System::create(*_GUIGLrenderer);

    if (Config::USE_ANT_TWEAK_BAR) {
        TwInit(TW_OPENGL_CORE, NULL);
    }

    static const vec4<F32> clearColour = DefaultColours::DIVIDE_BLUE();
    glClearColor(clearColour.r, clearColour.g, clearColour.b, clearColour.a);

    // Prepare shader headers and various shader related states
    if (initShaders()) {
        // That's it. Everything should be ready for draw calls
        Console::printfn(Locale::get(_ID("START_OGL_API_OK")));

        return ErrorCode::NO_ERR;
    }

    return ErrorCode::GLSL_INIT_ERROR;
}

/// Clear everything that was setup in initRenderingAPI()
void GL_API::closeRenderingAPI() {
    if (!deInitShaders()) {
        DIVIDE_UNEXPECTED_CALL("GLSL failed to shutdown!");
    }

    CEGUI::OpenGL3Renderer::destroy(*_GUIGLrenderer);
    _GUIGLrenderer = nullptr;
    // Destroy sampler objects
    {
        WriteLock w_lock(s_samplerMapLock);
        MemoryManager::DELETE_HASHMAP(s_samplerMap);
    }
    // Destroy the text rendering system
    deleteFonsContext();
    _fonts.clear();
    // If we have an indirect draw buffer, delete it
    if (s_indirectDrawBuffer > 0) {
        glDeleteBuffers(1, &s_indirectDrawBuffer);
        s_indirectDrawBuffer = 0;
    }
    if (s_dummyVAO > 0) {
        glDeleteVertexArrays(1, &s_dummyVAO);
        s_dummyVAO = 0;
    }
    glVertexArray::cleanup();
    GLUtil::clearVBOs();
    GL_API::s_vaoPool.destroy();
    GL_API::s_hardwareQueryPool->destroy();
    MemoryManager::DELETE(s_hardwareQueryPool);

    destroyGLContext();
}

void GL_API::createOrValidateContextForCurrentThread(GFXDevice& context) {
    if (Runtime::isMainThread() || glbinding::getCurrentContext() != 0) {
        return;
    }

    // Double check so that we don't run into a race condition!
    UpgradableReadLock r_lock(GLUtil::_glSecondaryContextMutex);
    if (glbinding::getCurrentContext() == 0) {
        UpgradeToWriteLock w_lock(r_lock);
        // This also makes the context current
        assert(GLUtil::_glSecondaryContext == nullptr && "GL_API::syncToThread: double init context for current thread!");
        bool ctxFound = g_ContextPool.getAvailableContext(GLUtil::_glSecondaryContext);
        assert(ctxFound && "GL_API::syncToThread: context not found for current thread!");
        ACKNOWLEDGE_UNUSED(ctxFound);
        const DisplayWindow& window = context.parent().platformContext().app().windowManager().getActiveWindow();
        SDL_GL_MakeCurrent(window.getRawWindow(), GLUtil::_glSecondaryContext);
        glbinding::Binding::initialize(false);
        // Enable OpenGL debug callbacks for this context as well
        if (Config::ENABLE_GPU_VALIDATION) {
            glEnable(GL_DEBUG_OUTPUT);
            glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
            // Debug callback in a separate thread requires a flag to distinguish it
            // from the main thread's callbacks
            glDebugMessageCallback((GLDEBUGPROC)GLUtil::DebugCallback, GLUtil::_glSecondaryContext);
        }
    }
}

};

Commits for Divide-Framework/trunk/Source Code/Platform/Video/OpenGL/SDLWindowWrapper.cpp

Diff revisions: vs.
Revision Author Commited Message
912 Diff Diff IonutCava picture IonutCava Sun 02 Jul, 2017 23:42:39 +0000

[Ionut]
- Add experimental Weighted Blended Order Independed Transparency (ref: http://casual-effects.blogspot.co.uk/2015/03/implemented-weighted-blended-order.html)
— Add per drawbuffer blend
— All translucent renderbin items go via the new OIT 2-step rendering: accumulation and composition
- Make sure we have proper blend enabled for text rendering
- Add a primitive form of PushConstants (unused yet. Emulated via Uniform calls)
- Fix bug with XMLParser not using case insensitive key lookups

909 Diff Diff IonutCava picture IonutCava Thu 29 Jun, 2017 23:57:18 +0000

[Ionut]
- Rework RenderTarget class
— RTAttachment now deal with textures directly
— RT size needs to be specified upfront
- Application class is no longer a Singleton but passed around in the PlatformContext

908 Diff Diff IonutCava picture IonutCava Thu 29 Jun, 2017 15:56:53 +0000

[Ionut]
- Texture’s MSAA sample count is now a property of the TextureDescriptor
- Add extra SDL validation as well as fallback for too high MSAA sample count specified

907 Diff Diff IonutCava picture IonutCava Wed 28 Jun, 2017 23:16:40 +0000

[Ionut]
- Rework texture loading, mip map generation, sampler usage, etc
- ResourceDescriptor for textures now ONLY takes a TextureDescriptor as a property descriptor. Sampler must be assigned to the tex descriptor:
— ToDo: Separate samplers completely from textures and assign them from a pool to textures at bind time

904 Diff Diff IonutCava picture IonutCava Sun 25 Jun, 2017 21:38:57 +0000

[Ionut]
- Rework the way GPU queries are handled via GenericDrawCommand rendering options.

900 Diff Diff IonutCava picture IonutCava Fri 23 Jun, 2017 16:00:28 +0000

[Ionut]
- Add AntTweakBar support for easier debugging

897 Diff Diff IonutCava picture IonutCava Thu 22 Jun, 2017 18:26:20 +0000

[IonutCava]
- Fix multi-context GL object creation
- Add missing file

896 Diff Diff IonutCava picture IonutCava Thu 22 Jun, 2017 16:13:10 +0000

[Ionut]
- Add vs140 platform support
- Remove GPU sync options for tasks. This should be an API-level capability.

895 Diff Diff IonutCava picture IonutCava Wed 21 Jun, 2017 21:10:26 +0000

[IonutCava]
- Reorder and cleanup OpenGL backend a bit.
- Small code cleanup
- Some small profile-guided optimizations

890 IonutCava picture IonutCava Sun 14 May, 2017 20:54:59 +0000

[Ionut]
- Add pre-compiled header support
- Initial code for per-stage tessellation computation