Skip to content

Conversation

@wh1t3lord
Copy link
Contributor

Introduction

So it is a new backend from me and it's DirectX 12 for Microsoft NT platforms (>=Windows10).

The library comes to a stage that it is needed to provide more user friendly interaction between end user and library, what relates to rendering backend is a simple and naive integration like in the popular library ImGui by Ocornut where user already has an integrated backend and they need to pass an initialization structure with all required parameters.

Well I will describe more detailed this chapter but for now I just leave this message in a such poor state, because for now it is a reminder for me to finish this work and move to Vulkan implementation.

Backend architecture

I set a straight aim to provide an efficient and optimized resource management and provide to user the low level settings of resource allocation. I mean that backend strives for being simple from user's side (in terms of how to set things up) and from another side it optimizes in all ways possible.

Buffer management aka geometry

About buffer management the library allocates one buffer and utilizes all its space the offset calculation is based on this offset allocator implementation by sebbbi (see sources, MIT license).

But if buffer is out of memory or offset allocator can't allocate the required space it will allocate a new buffer.

And rendering system tries to deallocate the buffer if it is not used. (in optimized way of course)

For now I tested with a really small sized buffers like less 1Kb and it was stable, of course it is not optimal settings due to high allocation of buffers and defragmentation of GPU's memory. By default I picked an optimal size that for most cases should be enough for using, but as I stated earlier user has a right to change that allocation size on initialization stage.

Texture management

DirectX 12 has two types of allocation of textures.

First one is to send texture to GPU as a single buffer, like if it is 4 Mbs then we send 4 Mbs as one single buffer. It is straight and simple and generally used among all modern GAPIs.

But there's a second variant for allocating textures aka placement PlacedResource (see link). That means you can allocate multiple textures into one buffer like you allocate one big buffer and suballocate space for textures thus it is like you "placed" those textures into one buffer. But that works only for not big sized textures that less some specific size, because in official tests it won't give any profit from performance, but still useful for rational resource management.

So based on texture size and its calculation the system tries to choose best way for uploading it.

As a conclusion I tried to make backend that utilizes all memory efficiently as much as possible and make all possible to fill all buffers and buffers for textures in most optimal way that user doesn't need even think about it at all.

Warning

Since we formally force people to use our backend then I don't see any motivation to help to people who make own backends based on our implementations and there's a vital reason for this, because it is better to have "one" (not in directly meaning) backend that be tested on many devices across different OSes than having some custom backends that can't be well tested at all. It is important warning for all users who have tendency to make own wheel ignoring obvious sane way of living.

I need to say that I tried to keep things without breaking changes at all, like if you want to initialize RmlUI as you did before you just don't pass an init structure and from function calling it is just a default argument that you don't specify thus nothing is changed/broken.

But we will (at least me) accept all incoming that relate to backend and it's working state on different graphics cards and OSes for @mikke89 I suggest to create template issue that has the following form (just as an idea):

If you have trouble with rendering backend

Specify GAPI

Blah 12

Specify graphics card's driver

Blah 12.451.16 oct 2023

Specify graphics card

Blah RTX 24000

Specify OS

Blah 13

Specify version and commit of RmlIUI

6.0 d23a3da

I guess after finishing "modern" backends we will boost for some time the popularity of library but at the same time amount of running tests and examples would be high since everyone can easily integrate the library... :D

For now I am making support for multisampling feature and I hope I will finish this work till August.

@mikke89 mikke89 added the backends Platforms and renderers label Aug 11, 2024
@mikke89
Copy link
Owner

mikke89 commented Aug 11, 2024

Thanks a lot for working on this, a DirectX 12 backend will be a very welcome addition! Let me know once you feel it is ready for review.

I quite like the initiative for introducing such a "renderer initialization" type that provides the user's own parameters. Although, I'll have to think a bit more about this, and how it fits into the library and how it integrates. I think it's important to keep it so that we don't take control over the main loop and event system, to ensure that the library plugs in to their existing infrastructure. Which is why we currently say that users should copy the backend itself into their own code (as opposed to the renderer and platform parts of the backend). But at the same time, we want to make it easier to get started for users that perhaps only want to provide their renderer details, but otherwise use the backend as it is. This generally looks like a nice opt-in solution that could be helpful in many use cases, but I'll need to take some more rounds and think about it.

Regarding issue templates. I actually quite like the informal nature of giving users a blank slate to describe their issues. I think that has some value as a community. Of course, I understand that with growing number of issues, some system like this could be helpful to speed things up, but I don't believe this is an issue for us at this point. I generally find that users are good at describing their issues. Regardless of templates, there will always be some times where more information is necessary. And that is perfectly fine in my view, there is also some value to this interaction as well. So I would prefer to keep this as it is.

@Paril
Copy link
Contributor

Paril commented Aug 12, 2024

Regarding issue templates. I actually quite like the informal nature of giving users a blank slate to describe their issues.

Just wanted to chime in on this one and say I agree; overly-complicated forms and templates have dissuaded me from making issues on other projects (same for something like stalebot, which I hate even more). I understand why some people use them but I find most people are pretty good with issue-posting when you don't give them any instructions at all.

… overloading these fields + need to change preprocessors to initialization structure
… for render target and depth stencil clear values at creation stage;
… prevent calling if engine is passing invalid scissor region to renderer (or is it even possible from outside?);
…itialization stage; refactor making BindTexture and BindRenderTarget (as in DX11 for consistency, but need to send feedback about it); new pipelines for msaa render targets; fix std::swap situation where object triggered false positive assert in destructor; setting invalid data by compile time preprocessors; making renderfilters but need to carefully debug order of pipeline set;
@wh1t3lord
Copy link
Contributor Author

@mikke89 just FYI, I refactored upload policy for textures and improved it so we create staging buffer that uses two fields check if user wants to upload texture that bigger than initial size of staging buffer than it has dynamic nature as it was before (uses temp buffer but allocates for requested size), but now we allocated that buffer once and until we didn't face a such big texture we just re-use existed buffer without constant allocation/deallocation that can leads to bad things as degraded performance with time and possible (in theory) memory fragmentation.

Same thing I did for Vulkan.

@mikke89
Copy link
Owner

mikke89 commented Oct 20, 2025

Yeah, I think that sounds very reasonable, to keep one buffer like a sort of scratch buffer.

@wh1t3lord
Copy link
Contributor Author

@mikke89 revisited again the trouble with effects sample where it was guessed that barrier was missed but now when Windows 11 dropped update related to DX12 SDK the bug was gone (aka stable image problem). Probably it was the SDK's or Driver's bug because my investigations showed that on our side it was clear and we didn't get any validation error report related to barriers usage so on trouble videocards the bug is gone on debug/release configurations. So in any user report it goes to vendors report not to us.

So the last thing I need to finish and I will do that very soon it is postprocess sample and you can start to merge my work (also I need to fix all warnings :D).

I fixed the new API validation error it is really minor but annoying.

NVIDIA 3060 laptop RTX (Release)

nv3060rtxlaptop.mp4

@mikke89
Copy link
Owner

mikke89 commented Oct 27, 2025

Very nice! Thanks for the update, looks really good!

@wh1t3lord
Copy link
Contributor Author

@mikke89 I finished my integration samples for win32 but for other input platforms like glfw3, sdl2, sdl3 (if they're not finished and probably they're not finished because it is separated files) it is just copy and paste code from native win32 samples and just change code (replace win32 loop messages and provide functions from these libraries respectively), anyway

So you can start to merge my work, but keep in mind that:

  1. You should verify and validate my vision about integration architecture, it might seem raw at first glance and maybe it requires some refactoring (somewhere to rename, somewhere to make consistent by writting and etc), but it is just improtant that you understand my idea and you agree with my design (or at least knowing my idea and my approach you could formulate yours in case if my variant is not sufficient for making extendable and easy-maintanable thing but I guess it is okay though :D), still at least spend some time and think about others backends/new backends that could be provided from other people and does it fit easily/comfortably and etc

  2. About integration itself, I tried to not reduce freedom of users and what they would like to do, but I made two versions of how possibly ever user can use renderer it is just directly use swapchain images and render to them or just make postprocess approach, it depends on use-case, it depends on users condition, business environment what they can do, what legacy they have and etc, but from my understanding it could be enough for them, so only question is about like it is okay for them to use that init struct or not, I tried to ask user a minimum info from their side like what to fill in struct but maybe we can wait some time and people would like to give some feedback (i just don't know), ofc there could some elaborate and reason about why not to provide just output image for user but... it would be reasonable if we are closed source library, but since we provide source for everything we could at some point expect that users would like to edit code of existed renderer and we just don't know how they would like to operate with library so full freedom to them as I would say. From my point of view just making one variant and forcing all people using it I am not sure that it is okay so I did both possible variants

What I didn't yet implement it is .is_execute_when_end_frame_issued when true and .p_command_list fields are true and nullptr (or it might not nullptr it depends, but still it is main thing is when .is_execute_when_end_frame_issued==true) respectively, so according to this it fits for multithreaded variant where user just push whole UI to different thread, we have probably dedicated queue from GAPI and we push commands and it executes separately to main render but I don't know maybe it is too much rn I just want to see at least half of my work will be merged and then we can talk further otherwise we could stuck for a long time with such timings...

  1. Probably there should be a thing with what we can easily change pages for demonstration in integration samples but again it is up to you (or me, or any other volunteers). But The beginning has been made and it is great :)

So I hope you doing well, happy holidays

Best regards

@mikke89
Copy link
Owner

mikke89 commented Dec 29, 2025

That's great! Glad to hear that, and thanks for the continued work on this one.

I'm a bit backlogged right now, but I'll come around to this eventually. I might make some changes or additions (like the other backends) as I see fit, and then I'll likely just merge it. It's been some time in progress, and I agree that it's better to have something merged in sooner, rather then discussing minor details, and then everyone can help improve it over time.

Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backends Platforms and renderers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants