티스토리 뷰

Game/TODO

Threaded OpenGL

newpolaris 2020. 1. 21. 16:20

어렵당

Render queue enqueue

참고용 자료들

draw command 를 객체로 바꾸고, 그걸 thread safe 하게 전달하는 것

serialize 해서 전달하는 bgfx

bgfx의 기본 예제는 별도의 thread 안에서 queue를 쌓고,

execute는 main 에서 수행

case CommandBuffer::CreateUniform:
{
    BGFX_PROFILER_SCOPE("CreateUniform", 0xff2040ff);

    UniformHandle handle;
    _cmdbuf.read(handle);

    UniformType::Enum type;
    _cmdbuf.read(type);

    uint16_t num;
    _cmdbuf.read(num);

    uint8_t len;
    _cmdbuf.read(len);

    const char* name = (const char*)_cmdbuf.skip(len);

    m_renderCtx->createUniform(handle, type, num, name);
}
break;

tuxalin/CommandBuffer는

    COMMAND_TEMPLATE
        template <class CommandClass>
    CommandClass* COMMAND_QUAL::addCommand(const key_t& key, uint32_t auxilarySize)
    {
        CommandPacket* packet = CommandPacket::create<CommandClass>(m_allocator, auxilarySize);
        // store the key and command packet ptr
        {
            const uint32_t currentIndex = m_currentIndex.fetch_add(1, std::memory_order_relaxed);
            assert(currentIndex < (uint32_t)m_commands.size());
            command_t& pair = m_commands[currentIndex];
            pair.cmd = packet;
            pair.key = key;
        }
        packet->dispatchFunction = CommandClass::kDispatchFunction;
        assert(packet->dispatchFunction);

        return CommandPacket::getCommandData<CommandClass>(packet);
    }

TNT 는 어렵당

#define DECL_DRIVER_API_RETURN(RetType, methodName, paramsDecl, params)                         \
    inline RetType methodName(paramsDecl) {                                                     \
        DEBUG_COMMAND(methodName, params);                                                      \
        RetType result = mDriver->methodName##S();                                              \
        using Cmd = COMMAND_TYPE(methodName##R);                                                \
        void* const p = allocateCommand(CommandBase::align(sizeof(Cmd)));                       \
        new(p) Cmd(mDispatcher->methodName##_, RetType(result), params);                        \
        return result;                                                                          \
    }

Queue excute and swapbuffer

리사이즈 시에도 계속 렌더링을 수행하는 예제는 glfw의 splitview
리사이즈 시 멈추는 건 나머지 예제를 참조하면 됨, Filament 도

splitview는 message loop는 glfwWaitEvents 로 대기하게 만들고,

framebuffer 크기는 'WM_SIZE' message 를 처리하게 하고,
rendering 은 'WM_PAINT' message 에서 처리하게하여 계속 렌더링 하게 함

glfwPollEvents resize는 window에서 크기 조정시 해당 함수 안에서 blocking 된다

 *  On some platforms, a window move, resize or menu operation will cause event
 *  processing to block.  This is due to how event processing is designed on
 *  those platforms.  You can use the
 *  [window refresh callback](@ref window_refresh) to redraw the contents of
 *  your window when necessary during such operations.

https://www.khronos.org/opengl/wiki/Swap_Interval
https://www.khronos.org/registry/OpenGL/extensions/EXT/WGL_EXT_swap_control.txt

VSync 설정

iOS & MAC

GLEssential 및 MetalBasic3D 예제를 보면, displayLink 나 다른걸 써서 하는 법 나와있다

Windows

DirectX는 DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT 를 통한 swapchain 관리 가능

변태적으로, OpenGL을 DXGI 위에 돌리는 예제도 존재

https://github.com/nlguillemot/OpenGL-on-DXGI/blob/master/main.cpp

'Game > TODO' 카테고리의 다른 글

Surface Flinger etc  (0) 2020.01.21
http://gameworksdocs.nvidia.com/GraphicsSamples/ThreadedRenderingGLSample.htm  (0) 2020.01.02
CLSPSM  (0) 2018.11.01
2018.10.16  (0) 2018.10.16
5.13  (0) 2018.05.13
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크