GithubHelp home page GithubHelp logo

juandiegomontoya / fwog Goto Github PK

View Code? Open in Web Editor NEW
127.0 127.0 11.0 15.96 MB

Froggy OpenGL Engoodener

Home Page: https://fwog.readthedocs.io

License: MIT License

CMake 1.10% C++ 65.36% C 22.12% GLSL 11.41%
api graphics opengl

fwog's Introduction

I frogor ๐Ÿธ

fwog's People

Contributors

anonn10 avatar clementineaccount avatar deccer avatar juandiegomontoya avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

fwog's Issues

Expose asynchronous pixel transfers

For uploads, this could take the form of a vkCmdCopyBufferToImage-like function. For downloads, vkCmdCopyImageToBuffer (to a mapped/mappable buffer) is the form that can be taken. Actual PBOs won't have to be exposed.

Simplify textures

Using textures is currently rather annoying as it requires creating a Texture (memory) and then a TextureView to actually use it, adding to the boilerplate needed to use textures. Take this code, for example:

  auto gcolorTex = Fwog::CreateTexture2D({ gWindowWidth, gWindowHeight }, Fwog::Format::R8G8B8A8_UNORM);
  auto gnormalTex = Fwog::CreateTexture2D({ gWindowWidth, gWindowHeight }, Fwog::Format::R16G16B16_SNORM);
  auto gdepthTex = Fwog::CreateTexture2D({ gWindowWidth, gWindowHeight }, Fwog::Format::D32_FLOAT);
  auto gbufferColorView = gcolorTex->View();
  auto gbufferNormalView = gnormalTex->View();
  auto gbufferDepthView = gdepthTex->View();

Half of this could be removed if Textures were allowed where TextureViews currently are.

  • TextureView should inherit from Texture as they can share a common API
  • Functions that currently take a TextureView& should take a Texture&
  • Rename TextureSampler to Sampler

Make MemoryBarrier not a command

There are uses of memory barriers that don't require them to be inside of a render/compute pass. The current system is limiting and encourages the user to call glMemoryBarrier themselves.

Buffer views

Might be pretty cool to be able to slice up buffers.

Internally, this would be implemented by adding an implicit offset when binding buffers. However, the API would have to change to make buffer views be the default way to use buffers. Idea: buffer views can be implicitly constructed from buffers. That way, the user is not forced to explicitly create buffer views.

Deduplicate pipeline state

Currently, every single bit of graphics pipeline state is set (over 30 gl calls) when a new pipeline is bound.

Solution: track the previously bound pipeline and compare each state prior to calling the relevant OpenGL function. Note: when a pipeline is deleted, set the tracked pipeline pointer to null if its ID is the same as the pipeline being deleted.

Way to query device features and capabilities

This could come in the form of a big struct that can be asked for at any time. Fwog would, in theory, acquire this information at initialization time (which doesn't yet exist) with a bunch of glGet calls.

This information could also be used by Fwog itself to assert correct API usage (e.g., binding limits, dispatch limits, etc.).

BindImage should assert format

Problem: glBindImageUnit has a format parameter, Fwog potentially passes all valid InternalFormat values to glBindImageUnit which are not valid according to gl registry.

Solution: Add assertion to allow only specified formats to be passed to glBindImageUnit Source

Facility for asynchronously compiling pipelines

This would be to allow the driver's worker threads to link programs asynchronously without being forced to immediately link them when glGetProgramiv is called.

The API would require a way to send a pipeline to be compiled, a way to query its completion, and a way to get the pipeline (waiting for its completion if it hasn't already). This could take the form of a simple Future type for pipelines. Query operations would simply wrap {ARB, KHR}_parallel_shader_compile's way of querying the completion status.

TODO: investigate performance of this

Typed textures

This one is potentially complicated, but it can be broken down into two levels:

  1. Separate types for color textures and depth/stencil textures. Could be useful for improving safety in a number of places. This level comes with a few tricky design considerations (namely the question of runtime vs compile-time format checking via new enums). Mostly likely to implement this.
  2. Templated texture type by format. More complicated to implement (maybe?), but offers improved safety when uploading pixels. I'm doubtful that the effort is worth the payoff here.

Framebuffer cache does not account for deleted textures

Currently experiencing a bug with window resizing (which causes textures to be deleted and remade) related to this.

Solution: ~Texture should access the global Fwog state (which doesn't yet exist) and call something in the framebuffer cache to remove all cached framebuffers referencing that texture.

Remove `Create` methods and use constructors

Optional spam is annoying and writing error checking code everywhere is too. API objects should use plain old constructors. Errors in constructors should be propagated via exceptions.

Debug API mode

Add a runtime or compile-time way to set the API debug mode. Enabling debug mode would enable features such as:

  • Extra runtime error checking
  • Zeroing resource bindings at the start of rendering/compute
  • Inserting timers at the start of rendering/compute
  • Inserting debug markers at the start of rendering/compute (added in 364ec0c)

Suggestion: app_hello_square.cpp should show InputAssemblyState

Currently, 01_hello_triangle is intended as a 'tutorial' project for a beginner and is documented as such. The knowledge of setting primitives coming from OpenGL, however, is not documented and requires the user to have had experience with Vulkan in order to infer the usage of an InputAssemblyState.

The file of 01_hello_triangle could allow a soft introduction to the concept for someone coming from OpenGL through specifying the InputAssemblyState, even though the default is already TRIANGLE_LIST

image

Dynamic graphics pipeline state

Add the ability to set certain graphics pipeline state in a render pass without having to bind a new pipeline. This might seem antithetical to the design of Fwog, but sometimes it is useful to be able to cheaply change some minimal state between draws without having to bind an entire pipeline.

In drivers for modern desktop hardware, some state is practically free to change. The goal is to identify those states and add the common ones to Fwog.

Secondary goal: make a benchmark to test if dynamic state has the intended performance impact of zero.

Remove fake stencil support or actually support it

Currently the user can create stencil attachments but do nothing with them. They should either be fully supported or removed altogether in any case. I am leaning towards the latter as they do not offer much benefit these days.

Add command for clearing textures

Currently, the only way to clear a texture is to begin a render pass with the texture. This is annoying in compute because it requires beginning and ending an empty render pass.

Refactor examples

The examples should use a better common framework and be structured in a way that lends itself to readability. The code should also be well-documented (at least with comments) as this is how most will learn the API.

This checklist records my progress in the examples-refactor branch.

  • Application
  • 01_hello_triangle
  • 02_deferred
  • 03_gltf_viewer
  • 04_volumetric
  • 05_gpu_driven

Expose glTextureBarrier

If I can't find a fancy abstraction for this (which is likely), then all that needs to be decided is a suitable name. I don't know if I like the name "TextureBarrier", but I may stick with it for familiarity.

Mechanism to safely allow mixed raw GL calls and Fwog calls

Currently, raw GL calls with Fwog is a gamble because it can change some state that is cached by the Fwog context without it knowing. This can lead to state being omitted from a draw.

Proposal: add a function which dirties the relevant caches in Fwog. The user can call this when raw GL calls were made before issuing the next call to Fwog. This function should be forbidden inside render passes.

Refactor compile options

The current generator expression is confusing, plus the scope of the command is wrong and leaks into projects that depend on Fwog.

Beginning rendering with integer render target causes warnings on Nvidia

If the previously bound pipeline enabled blending, binding a framebuffer with an integer RT will cause a warning. The same thing happens when dithering is enabled.

  • Disable dithering at initialization time
  • Delay binding framebuffers until a pipeline is actually bound. Then, BeginRendering only performs the work of clearing render targets.

Invalid Integer Constant Expression

Following Warnings are Treated as Errors (Release Mode cannot compile) #69

Sorry Jaker! I didn't test the project in Debug mode after the pull and it turns out whatever fixed Release mode broke Debug mode. I only just found out. I already attempted to clean and rebuild the solution.

image

Fancy fragment shader debugging feature

It would be convenient for the sake of debugging to be able to visualize any variable in a fragment shader without having to go through the standard hassle of doing so. Typically, one would have to do one of the following for debug visualizing a variable:

  • Temporarily write to one of the existing render targets (e.g., albedo) while debugging. First, you would have to ensure the data fits in the render target's range. For example, visualizing the UV gradient at close distances would require multiplying by some arbitrarily large number to make a visible gradient, or visualizing object IDs would require dividing by an arbitrarily large number (or mapping to color) to make them visible.
  • Make a render target (e.g., RGBA32_FLOAT) whose sole purpose is for writing debug data to. This works, but requires extra setup on both the API and shader side of things. It may also require fitting the data to be in some viewable range that can be displayed on the screen.

Ideally, these things could be automated to a degree. In the shader, the user shouldn't have to do more than call some intrinsic (e.g., debugVisualizeFWG(someScalar)). This intrinsic would write to a hidden render target (whose type could ideally be inferred, but a simple implementation could get away with RGBA32_FLOAT).

From the API side, the user would be given the ability to get the debug image for the render pass. The user could draw this themselves, or pass it to another function provided by the API to automatically process it into color image. The scope of the processing is not clear. Alternatively, the image could be viewed in a debugger such as RenderDoc, which provides its own facilities for visualize images in different ways.

TODO: investigate data visualization algorithms

Implementation-wise, this feature would require at least some way to inject code into the shader. Ideas:

  • Make a fake extension (that's enabled with the standard extension syntax) and inject the fragment output and potential function definitions there. Downside: this "extension" would have to be declared last to be legal GLSL once processed.
  • Make a fake include (e.g., #include "DebugFWG" and inject code the same way as above. This makes it clearer that it's implemented in the preprocessor and involves actual textual code.
  • Search for instances where the intrinsic is called, then inject the code at the top of the file (after all extension directives). This requires the least effort from the user, but makes it unclear to the reader where these intrinsics are coming from.

A render target would need to exist for this feature to work. The working concept is to reserve the last render target for this. Other ideas:

  • RenderInfo could contain a flag that can enable the debug render target for that pass. Downside: pipelines that don't draw to it would make it texels become undefined after drawing. The FBO could be swapped on-the-fly to prevent this at the expense of some overhead.
  • Pipelines could internally contain a flag indicating whether the shader intrinsic is used, which would enable on-the-fly FBO swapping as previously described. This reduces work from the user's perspective.

Lastly, the user needs a way to query this image in order to use it themselves. Ideas:

  • Some global function that returns the current debug texture for the render pass. This feels icky and bug-prone, but would work at least
  • EndRendering could return a reference to the debug image. This feels weird, but I don't know why

Optionally, the API would provide some functions to process the debug image into something that can be visualized. These could invoke a compute shader to perform some image processing algorithm or invoke CPU readback if we aren't concerned with performance. Such algorithms could color a scalar image, or compress the range to fit within [0, 1] and highlight outliers (think RenderDoc overlays). I'm labeling this subfeature as optional because it feels outside the scope of Fwog and is something that can be done by a proper debugger.

Handle resource binding leakage

At the moment, a resource bound via any of the Cmd::Bind* functions will stay bound until another resource is bound to that slot. This means the bindings will escape rendering and compute scopes, which is against one of the core tenets of Fwog (preventing the possibility of state leakage).

Possible solutions:

  1. In debug mode, zero all resource bindings when a rendering or compute scope begins. This should make it fairly obvious if leaked bindings are being relied on by the pass.
  2. Using introspection, determine what resources need to be bound to a program before drawing or dispatching compute with it, then, in debug mode only, assert that a resource has been bound to each of the required bindings since the beginning of the rendering/compute scope. This would be more robust, but also more annoying to implement.

Remove stdlib includes from headers where possible

Replace them with forward declarations. We only want to pay the include cost once per TU.

Also need to decide if it would be better to use a header with STL forward declarations, or to redeclare them in each header they are needed.

UploadFormat Reversed format not correctly named

    UBYTE_3_3_2,
    UBYTE_2_3_3,
    USHORT_5_5_5_1,
    USHORT_5_5_5_1_REV,
    UINT_10_10_10_2,
    UINT_10_10_10_2_REV,

should be

    UBYTE_3_3_2,
    UBYTE_2_3_3_REV,
    USHORT_5_5_5_1,
    USHORT_1_5_5_5_REV,
    UINT_10_10_10_2,
    UINT_2_10_10_2_REV,

Assign it to me, ill prepare a PR when I'm back from travels.

Add stencil buffer example

Create a minimal example showing how to use stencil buffering in Fwog.

The technique used in the example should not be trivial to achieve without using the stencil buffer.

Fix buffer mapping

It's really jank right now, but OpenGL's way is also really jank.

TODO: think of a good way to do this.

Reconsider buffer mapping... again

The only compelling use case for mapping a buffer (that I can think of) is for persistent mapping. Maybe that should be the only way?

Following that, I cannot think of a reason to allow the user to explicitly unmap a persistently-mapped pointer. In that case, implicitly unmapping the pointer on buffer destruction would be better.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.