Compare commits
92 Commits
temp-gpu-i
...
tmp-vulkan
Author | SHA1 | Date | |
---|---|---|---|
b40787115b | |||
fc502a8710 | |||
d944b969f0 | |||
8e43757834 | |||
b65df10346 | |||
8bf8db8ca2 | |||
5bd7a2c416 | |||
8c3e8d0eb6 | |||
8bfdec76c0 | |||
9cc5075680 | |||
2ea8725339 | |||
a55bbedc06 | |||
5d52da2e65 | |||
25b341a4ae | |||
dfa5bc25ae | |||
ddd64ba03a | |||
0b3caae8a7 | |||
b1d5950471 | |||
99886f91a9 | |||
fa00caba88 | |||
f853163a54 | |||
87492f93a4 | |||
6152113b45 | |||
2741a4106a | |||
3420792ea8 | |||
3eaddb4da8 | |||
1a85a68a5e | |||
adba79a04f | |||
c73894ea5b | |||
48360afb10 | |||
0493a32803 | |||
79346fd72e | |||
44c875f59a | |||
a68be3b3c2 | |||
c124606d70 | |||
975b09e3e7 | |||
15ac620204 | |||
983f61e9c5 | |||
ed959cd912 | |||
193a17474e | |||
5b246fd4b3 | |||
f7d7a5aad7 | |||
8b68ee3a17 | |||
230b24159e | |||
a5a01cc0c3 | |||
e7b3a7028b | |||
fced6f19be | |||
402e19ddc8 | |||
af2bc8be40 | |||
72bce1be8e | |||
d390f01e48 | |||
0956a5134a | |||
9a08daae92 | |||
dd4405121c | |||
b996cc6440 | |||
0bcd24c0c4 | |||
12e88ee722 | |||
b908c3fa0a | |||
ef8e53c15b | |||
639829ea1a | |||
0ef5c14de0 | |||
26fd1c71e1 | |||
de062ffd10 | |||
fc0f409911 | |||
c72e6c25d7 | |||
816bd8bed6 | |||
47613a40f5 | |||
ea5a70973d | |||
70c0f652de | |||
e70dcde88b | |||
6d82ae3581 | |||
99fc68bf6a | |||
3efdb3f232 | |||
193cebd3c2 | |||
bdeca237ff | |||
a08d242acd | |||
5629ff5f69 | |||
eb23ecd1b3 | |||
a02da40732 | |||
bd0c1d8c53 | |||
73b585b0b2 | |||
b549b1f477 | |||
c155c10888 | |||
bc86701b58 | |||
6dc1d823ba | |||
392e744ed5 | |||
f56af0b899 | |||
78cbcccf34 | |||
b671b33871 | |||
be9dc493a4 | |||
8dec7e5219 | |||
b79e7f92bf |
@@ -514,9 +514,13 @@ if(UNIX AND NOT APPLE)
|
||||
endif()
|
||||
|
||||
|
||||
# Vulkan
|
||||
option(WITH_VULKAN "Enable Vulkan backend (Experimental)" OFF)
|
||||
option(WITH_VULKAN_SHADER_COMPILATION "Temporary flag to enable vulkan shader compilation needed to continue development during the migration of GLSL to Vulkan." OFF)
|
||||
|
||||
# OpenGL
|
||||
|
||||
option(WITH_OPENGL "When off limits visibility of the opengl headers to just bf_gpu and gawain (temporary option for development purposes)" ON)
|
||||
option(WITH_OPENGL "When off limits visibility of the opengl headers to just bf_gpu (temporary option for development purposes)" ON)
|
||||
option(WITH_GLEW_ES "Switches to experimental copy of GLEW that has support for OpenGL ES. (temporary option for development purposes)" OFF)
|
||||
option(WITH_GL_EGL "Use the EGL OpenGL system library instead of the platform specific OpenGL system library (CGL, glX, or WGL)" OFF)
|
||||
option(WITH_GL_PROFILE_ES20 "Support using OpenGL ES 2.0. (through either EGL or the AGL/WGL/XGL 'es20' profile)" OFF)
|
||||
@@ -526,6 +530,7 @@ mark_as_advanced(
|
||||
WITH_GLEW_ES
|
||||
WITH_GL_EGL
|
||||
WITH_GL_PROFILE_ES20
|
||||
WITH_VULKAN_SHADER_COMPILATION
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
@@ -1126,6 +1131,18 @@ if(WITH_OPENVDB)
|
||||
list(APPEND OPENVDB_LIBRARIES ${BOOST_LIBRARIES} ${TBB_LIBRARIES})
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Configure Vulkan.
|
||||
|
||||
if(WITH_VULKAN)
|
||||
list(APPEND BLENDER_GL_LIBRARIES ${Vulkan_LIBRARY})
|
||||
|
||||
add_definitions(-DWITH_VULKAN)
|
||||
if(WITH_VULKAN_SHADER_COMPILATION)
|
||||
add_definitions(-DWITH_VULKAN_SHADER_COMPILATION)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Configure OpenGL.
|
||||
|
||||
|
66
build_files/cmake/Modules/FindShaderC.cmake
Normal file
66
build_files/cmake/Modules/FindShaderC.cmake
Normal file
@@ -0,0 +1,66 @@
|
||||
# - Find SHADERC library
|
||||
# Find the native Haru includes and library
|
||||
# This module defines
|
||||
# SHADERC_INCLUDE_DIRS, where to find hpdf.h, set when
|
||||
# SHADERC_INCLUDE_DIR is found.
|
||||
# SHADERC_LIBRARIES, libraries to link against to use Haru.
|
||||
# SHADERC_ROOT_DIR, The base directory to search for Haru.
|
||||
# This can also be an environment variable.
|
||||
# SHADERC_FOUND, If false, do not try to use Haru.
|
||||
#
|
||||
# also defined, but not for general use are
|
||||
# SHADERC_LIBRARY, where to find the Haru library.
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2021 Blender Foundation.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD 3-Clause License,
|
||||
# see accompanying file BSD-3-Clause-license.txt for details.
|
||||
#=============================================================================
|
||||
|
||||
# If SHADERC_ROOT_DIR was defined in the environment, use it.
|
||||
if(NOT SHADERC_ROOT_DIR AND NOT $ENV{SHADERC_ROOT_DIR} STREQUAL "")
|
||||
set(SHADERC_ROOT_DIR $ENV{SHADERC_ROOT_DIR})
|
||||
endif()
|
||||
|
||||
set(_shaderc_SEARCH_DIRS
|
||||
${SHADERC_ROOT_DIR}
|
||||
/opt/lib/haru
|
||||
)
|
||||
|
||||
find_path(SHADERC_INCLUDE_DIR
|
||||
NAMES
|
||||
shaderc.hpp
|
||||
HINTS
|
||||
${_shaderc_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
include/shaderc
|
||||
include
|
||||
)
|
||||
|
||||
find_library(SHADERC_LIBRARY
|
||||
NAMES
|
||||
shaderc_combined
|
||||
shaderc
|
||||
HINTS
|
||||
${_shaderc_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
lib64 lib
|
||||
)
|
||||
|
||||
# Handle the QUIETLY and REQUIRED arguments and set SHADERC_FOUND to TRUE if
|
||||
# all listed variables are TRUE.
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(ShaderC DEFAULT_MSG SHADERC_LIBRARY SHADERC_INCLUDE_DIR)
|
||||
|
||||
if(SHADERC_FOUND)
|
||||
set(SHADERC_LIBRARIES ${SHADERC_LIBRARY})
|
||||
set(SHADERC_INCLUDE_DIRS ${SHADERC_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(
|
||||
SHADERC_INCLUDE_DIR
|
||||
SHADERC_LIBRARY
|
||||
)
|
||||
|
||||
unset(_shaderc_SEARCH_DIRS)
|
@@ -102,6 +102,11 @@ find_package_wrapper(ZLIB REQUIRED)
|
||||
find_package_wrapper(Zstd REQUIRED)
|
||||
find_package_wrapper(Freetype REQUIRED)
|
||||
|
||||
if(WITH_VULKAN)
|
||||
find_package_wrapper(Vulkan REQUIRED)
|
||||
find_package(ShaderC REQUIRED)
|
||||
endif()
|
||||
|
||||
if(WITH_PYTHON)
|
||||
# No way to set py35, remove for now.
|
||||
# find_package(PythonLibs)
|
||||
|
@@ -874,5 +874,32 @@ if(WITH_HARU)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_VULKAN)
|
||||
if(EXISTS ${LIBDIR}/vulkan)
|
||||
set(Vulkan_FOUND On)
|
||||
set(Vulkan_ROOT_DIR ${LIBDIR}/vulkan)
|
||||
set(Vulkan_INCLUDE_DIR ${Vulkan_ROOT_DIR}/include)
|
||||
set(Vulkan_INCLUDE_DIRS ${Vulkan_INCLUDE_DIR})
|
||||
set(Vulkan_LIBRARY ${Vulkan_ROOT_DIR}/lib/vulkan-1.lib)
|
||||
set(Vulkan_LIBRARIES ${Vulkan_LIBRARY})
|
||||
else()
|
||||
message(WARNING "vulkan was not found, disabling WITH_VULKAN")
|
||||
set(WITH_VULKAN OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_VULKAN)
|
||||
if(EXISTS ${LIBDIR}/shaderc)
|
||||
set(SHADERC_ROOT_DIR ${LIBDIR}/shaderc)
|
||||
set(SHADERC_INCLUDE_DIR ${SHADERC_ROOT_DIR}/include)
|
||||
set(SHADERC_INCLUDE_DIRS ${SHADERC_INCLUDE_DIR})
|
||||
set(SHADERC_LIBRARY optimized ${SHADERC_ROOT_DIR}/lib/shaderc_shared.lib debug ${SHADERC_ROOT_DIR}/lib/shaderc_shared_d.lib)
|
||||
set(SHADERC_LIBRARIES ${SHADERC_LIBRARY})
|
||||
else()
|
||||
message(WARNING "shaderc was not found, disabling WITH_VULKAN")
|
||||
set(WITH_VULKAN OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(ZSTD_INCLUDE_DIRS ${LIBDIR}/zstd/include)
|
||||
set(ZSTD_LIBRARIES ${LIBDIR}/zstd/lib/zstd_static.lib)
|
||||
|
4
extern/CMakeLists.txt
vendored
4
extern/CMakeLists.txt
vendored
@@ -116,3 +116,7 @@ endif()
|
||||
if (WITH_COMPOSITOR)
|
||||
add_subdirectory(smaa_areatex)
|
||||
endif()
|
||||
|
||||
if(WITH_VULKAN)
|
||||
add_subdirectory(vulkan_memory_allocator)
|
||||
endif()
|
||||
|
42
extern/vulkan_memory_allocator/CMakeLists.txt
vendored
Normal file
42
extern/vulkan_memory_allocator/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2012, Blender Foundation
|
||||
# All rights reserved.
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
|
||||
set(INC
|
||||
.
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
${Vulkan_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(SRC
|
||||
vk_mem_alloc_impl.cc
|
||||
|
||||
vk_mem_alloc.h
|
||||
)
|
||||
|
||||
blender_add_lib(extern_vulkan_memory_allocator "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
target_compile_options(extern_vulkan_memory_allocator
|
||||
PRIVATE "-Wno-nullability-completeness"
|
||||
)
|
||||
endif()
|
19
extern/vulkan_memory_allocator/LICENSE.txt
vendored
Normal file
19
extern/vulkan_memory_allocator/LICENSE.txt
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2017-2021 Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
5
extern/vulkan_memory_allocator/README.blender
vendored
Normal file
5
extern/vulkan_memory_allocator/README.blender
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
Project: VulkanMemoryAllocator
|
||||
URL: https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
|
||||
License: MIT
|
||||
Upstream version: 4b047fd
|
||||
Local modifications: None
|
134
extern/vulkan_memory_allocator/README.md
vendored
Normal file
134
extern/vulkan_memory_allocator/README.md
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
# Vulkan Memory Allocator
|
||||
|
||||
Easy to integrate Vulkan memory allocation library.
|
||||
|
||||
**Documentation:** See [Vulkan Memory Allocator](https://gpuopen-librariesandsdks.github.io/VulkanMemoryAllocator/html/) (generated from Doxygen-style comments in [src/vk_mem_alloc.h](src/vk_mem_alloc.h))
|
||||
|
||||
**License:** MIT. See [LICENSE.txt](LICENSE.txt)
|
||||
|
||||
**Changelog:** See [CHANGELOG.md](CHANGELOG.md)
|
||||
|
||||
**Product page:** [Vulkan Memory Allocator on GPUOpen](https://gpuopen.com/gaming-product/vulkan-memory-allocator/)
|
||||
|
||||
**Build status:**
|
||||
|
||||
- Windows: [](https://ci.appveyor.com/project/adam-sawicki-amd/vulkanmemoryallocator/branch/master)
|
||||
- Linux: [](https://travis-ci.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator)
|
||||
|
||||
# Problem
|
||||
|
||||
Memory allocation and resource (buffer and image) creation in Vulkan is difficult (comparing to older graphics API-s, like D3D11 or OpenGL) for several reasons:
|
||||
|
||||
- It requires a lot of boilerplate code, just like everything else in Vulkan, because it is a low-level and high-performance API.
|
||||
- There is additional level of indirection: `VkDeviceMemory` is allocated separately from creating `VkBuffer`/`VkImage` and they must be bound together.
|
||||
- Driver must be queried for supported memory heaps and memory types. Different IHVs provide different types of it.
|
||||
- It is recommended practice to allocate bigger chunks of memory and assign parts of them to particular resources.
|
||||
|
||||
# Features
|
||||
|
||||
This library can help game developers to manage memory allocations and resource creation by offering some higher-level functions:
|
||||
|
||||
1. Functions that help to choose correct and optimal memory type based on intended usage of the memory.
|
||||
- Required or preferred traits of the memory are expressed using higher-level description comparing to Vulkan flags.
|
||||
2. Functions that allocate memory blocks, reserve and return parts of them (`VkDeviceMemory` + offset + size) to the user.
|
||||
- Library keeps track of allocated memory blocks, used and unused ranges inside them, finds best matching unused ranges for new allocations, respects all the rules of alignment and buffer/image granularity.
|
||||
3. Functions that can create an image/buffer, allocate memory for it and bind them together - all in one call.
|
||||
|
||||
Additional features:
|
||||
|
||||
- Well-documented - description of all functions and structures provided, along with chapters that contain general description and example code.
|
||||
- Thread-safety: Library is designed to be used in multithreaded code. Access to a single device memory block referred by different buffers and textures (binding, mapping) is synchronized internally.
|
||||
- Configuration: Fill optional members of CreateInfo structure to provide custom CPU memory allocator, pointers to Vulkan functions and other parameters.
|
||||
- Customization: Predefine appropriate macros to provide your own implementation of all external facilities used by the library, from assert, mutex, and atomic, to vector and linked list.
|
||||
- Support for memory mapping, reference-counted internally. Support for persistently mapped memory: Just allocate with appropriate flag and you get access to mapped pointer.
|
||||
- Support for non-coherent memory. Functions that flush/invalidate memory. `nonCoherentAtomSize` is respected automatically.
|
||||
- Support for resource aliasing (overlap).
|
||||
- Support for sparse binding and sparse residency: Convenience functions that allocate or free multiple memory pages at once.
|
||||
- Custom memory pools: Create a pool with desired parameters (e.g. fixed or limited maximum size) and allocate memory out of it.
|
||||
- Linear allocator: Create a pool with linear algorithm and use it for much faster allocations and deallocations in free-at-once, stack, double stack, or ring buffer fashion.
|
||||
- Support for Vulkan 1.0, 1.1, 1.2.
|
||||
- Support for extensions (and equivalent functionality included in new Vulkan versions):
|
||||
- VK_EXT_memory_budget: Used internally if available to query for current usage and budget. If not available, it falls back to an estimation based on memory heap sizes.
|
||||
- VK_KHR_dedicated_allocation: Just enable it and it will be used automatically by the library.
|
||||
- VK_AMD_device_coherent_memory
|
||||
- VK_KHR_buffer_device_address
|
||||
- Defragmentation of GPU and CPU memory: Let the library move data around to free some memory blocks and make your allocations better compacted.
|
||||
- Lost allocations: Allocate memory with appropriate flags and let the library remove allocations that are not used for many frames to make room for new ones.
|
||||
- Statistics: Obtain detailed statistics about the amount of memory used, unused, number of allocated blocks, number of allocations etc. - globally, per memory heap, and per memory type.
|
||||
- Debug annotations: Associate string with name or opaque pointer to your own data with every allocation.
|
||||
- JSON dump: Obtain a string in JSON format with detailed map of internal state, including list of allocations and gaps between them.
|
||||
- Convert this JSON dump into a picture to visualize your memory. See [tools/VmaDumpVis](tools/VmaDumpVis/README.md).
|
||||
- Debugging incorrect memory usage: Enable initialization of all allocated memory with a bit pattern to detect usage of uninitialized or freed memory. Enable validation of a magic number before and after every allocation to detect out-of-bounds memory corruption.
|
||||
- Record and replay sequence of calls to library functions to a file to check correctness, measure performance, and gather statistics.
|
||||
|
||||
# Prequisites
|
||||
|
||||
- Self-contained C++ library in single header file. No external dependencies other than standard C and C++ library and of course Vulkan. STL containers are not used by default.
|
||||
- Public interface in C, in same convention as Vulkan API. Implementation in C++.
|
||||
- Error handling implemented by returning `VkResult` error codes - same way as in Vulkan.
|
||||
- Interface documented using Doxygen-style comments.
|
||||
- Platform-independent, but developed and tested on Windows using Visual Studio. Continuous integration setup for Windows and Linux. Used also on Android, MacOS, and other platforms.
|
||||
|
||||
# Example
|
||||
|
||||
Basic usage of this library is very simple. Advanced features are optional. After you created global `VmaAllocator` object, a complete code needed to create a buffer may look like this:
|
||||
|
||||
```cpp
|
||||
VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
|
||||
bufferInfo.size = 65536;
|
||||
bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
|
||||
VmaAllocationCreateInfo allocInfo = {};
|
||||
allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
|
||||
|
||||
VkBuffer buffer;
|
||||
VmaAllocation allocation;
|
||||
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr);
|
||||
```
|
||||
|
||||
With this one function call:
|
||||
|
||||
1. `VkBuffer` is created.
|
||||
2. `VkDeviceMemory` block is allocated if needed.
|
||||
3. An unused region of the memory block is bound to this buffer.
|
||||
|
||||
`VmaAllocation` is an object that represents memory assigned to this buffer. It can be queried for parameters like Vulkan memory handle and offset.
|
||||
|
||||
# Binaries
|
||||
|
||||
The release comes with precompiled binary executables for "VulkanSample" application which contains test suite and "VmaReplay" tool. They are compiled using Visual Studio 2019, so they require appropriate libraries to work, including "MSVCP140.dll", "VCRUNTIME140.dll", "VCRUNTIME140_1.dll". If their launch fails with error message telling about those files missing, please download and install [Microsoft Visual C++ Redistributable for Visual Studio 2015, 2017 and 2019](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads), "x64" version.
|
||||
|
||||
# Read more
|
||||
|
||||
See **[Documentation](https://gpuopen-librariesandsdks.github.io/VulkanMemoryAllocator/html/)**.
|
||||
|
||||
# Software using this library
|
||||
|
||||
- **[Detroit: Become Human](https://gpuopen.com/learn/porting-detroit-3/)**
|
||||
- **[Vulkan Samples](https://github.com/LunarG/VulkanSamples)** - official Khronos Vulkan samples. License: Apache-style.
|
||||
- **[Anvil](https://github.com/GPUOpen-LibrariesAndSDKs/Anvil)** - cross-platform framework for Vulkan. License: MIT.
|
||||
- **[Filament](https://github.com/google/filament)** - physically based rendering engine for Android, Windows, Linux and macOS, from Google. Apache License 2.0.
|
||||
- **[Atypical Games - proprietary game engine](https://developer.samsung.com/galaxy-gamedev/gamedev-blog/infinitejet.html)**
|
||||
- **[Flax Engine](https://flaxengine.com/)**
|
||||
- **[Lightweight Java Game Library (LWJGL)](https://www.lwjgl.org/)** - includes binding of the library for Java. License: BSD.
|
||||
- **[PowerVR SDK](https://github.com/powervr-graphics/Native_SDK)** - C++ cross-platform 3D graphics SDK, from Imagination. License: MIT.
|
||||
- **[Skia](https://github.com/google/skia)** - complete 2D graphic library for drawing Text, Geometries, and Images, from Google.
|
||||
- **[The Forge](https://github.com/ConfettiFX/The-Forge)** - cross-platform rendering framework. Apache License 2.0.
|
||||
- **[VK9](https://github.com/disks86/VK9)** - Direct3D 9 compatibility layer using Vulkan. Zlib lincese.
|
||||
- **[vkDOOM3](https://github.com/DustinHLand/vkDOOM3)** - Vulkan port of GPL DOOM 3 BFG Edition. License: GNU GPL.
|
||||
- **[vkQuake2](https://github.com/kondrak/vkQuake2)** - vanilla Quake 2 with Vulkan support. License: GNU GPL.
|
||||
- **[Vulkan Best Practice for Mobile Developers](https://github.com/ARM-software/vulkan_best_practice_for_mobile_developers)** from ARM. License: MIT.
|
||||
- **[RPCS3](https://github.com/RPCS3/rpcs3)** - PlayStation 3 emulator/debugger. License: GNU GPLv2.
|
||||
|
||||
[Many other projects on GitHub](https://github.com/search?q=AMD_VULKAN_MEMORY_ALLOCATOR_H&type=Code) and some game development studios that use Vulkan in their games.
|
||||
|
||||
# See also
|
||||
|
||||
- **[D3D12 Memory Allocator](https://github.com/GPUOpen-LibrariesAndSDKs/D3D12MemoryAllocator)** - equivalent library for Direct3D 12. License: MIT.
|
||||
- **[Awesome Vulkan](https://github.com/vinjn/awesome-vulkan)** - a curated list of awesome Vulkan libraries, debuggers and resources.
|
||||
- **[VulkanMemoryAllocator-Hpp](https://github.com/malte-v/VulkanMemoryAllocator-Hpp)** - C++ binding for this library. License: CC0-1.0.
|
||||
- **[PyVMA](https://github.com/realitix/pyvma)** - Python wrapper for this library. Author: Jean-Sébastien B. (@realitix). License: Apache 2.0.
|
||||
- **[vk-mem](https://github.com/gwihlidal/vk-mem-rs)** - Rust binding for this library. Author: Graham Wihlidal. License: Apache 2.0 or MIT.
|
||||
- **[Haskell bindings](https://hackage.haskell.org/package/VulkanMemoryAllocator)**, **[github](https://github.com/expipiplus1/vulkan/tree/master/VulkanMemoryAllocator)** - Haskell bindings for this library. Author: Joe Hermaszewski (@expipiplus1). License BSD-3-Clause.
|
||||
- **[vma_sample_sdl](https://github.com/rextimmy/vma_sample_sdl)** - SDL port of the sample app of this library (with the goal of running it on multiple platforms, including MacOS). Author: @rextimmy. License: MIT.
|
||||
- **[vulkan-malloc](https://github.com/dylanede/vulkan-malloc)** - Vulkan memory allocation library for Rust. Based on version 1 of this library. Author: Dylan Ede (@dylanede). License: MIT / Apache 2.0.
|
19560
extern/vulkan_memory_allocator/vk_mem_alloc.h
vendored
Normal file
19560
extern/vulkan_memory_allocator/vk_mem_alloc.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3
extern/vulkan_memory_allocator/vk_mem_alloc_impl.cc
vendored
Normal file
3
extern/vulkan_memory_allocator/vk_mem_alloc_impl.cc
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
#define VMA_IMPLEMENTATION
|
||||
|
||||
#include "vk_mem_alloc.h"
|
@@ -85,3 +85,7 @@ endif()
|
||||
if(UNIX AND NOT APPLE)
|
||||
add_subdirectory(libc_compat)
|
||||
endif()
|
||||
|
||||
if(WITH_VULKAN)
|
||||
add_subdirectory(shader_compiler)
|
||||
endif()
|
||||
|
@@ -89,6 +89,18 @@ set(LIB
|
||||
${GLEW_LIBRARY}
|
||||
)
|
||||
|
||||
if(WITH_VULKAN)
|
||||
list(APPEND SRC
|
||||
intern/GHOST_ContextVK.cpp
|
||||
|
||||
intern/GHOST_ContextVK.h
|
||||
)
|
||||
|
||||
list(APPEND INC_SYS
|
||||
${Vulkan_INCLUDE_DIRS}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_GHOST_DEBUG)
|
||||
list(APPEND SRC
|
||||
intern/GHOST_EventPrinter.cpp
|
||||
|
@@ -195,6 +195,7 @@ extern GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
|
||||
* \return A handle to the new context ( == NULL if creation failed).
|
||||
*/
|
||||
extern GHOST_ContextHandle GHOST_CreateOpenGLContext(GHOST_SystemHandle systemhandle,
|
||||
GHOST_TDrawingContextType type,
|
||||
GHOST_GLSettings glSettings);
|
||||
|
||||
/**
|
||||
@@ -542,6 +543,13 @@ extern int GHOST_GetValid(GHOST_WindowHandle windowhandle);
|
||||
*/
|
||||
extern GHOST_TDrawingContextType GHOST_GetDrawingContextType(GHOST_WindowHandle windowhandle);
|
||||
|
||||
/**
|
||||
* Returns the drawing context used in this window.
|
||||
* \param windowhandle: The handle to the window.
|
||||
* \return The window drawing context.
|
||||
*/
|
||||
extern GHOST_ContextHandle GHOST_GetDrawingContext(GHOST_WindowHandle windowhandle);
|
||||
|
||||
/**
|
||||
* Tries to install a rendering context in this window.
|
||||
* \param windowhandle: The handle to the window.
|
||||
@@ -1159,6 +1167,50 @@ int GHOST_XrGetControllerModelData(GHOST_XrContextHandle xr_context,
|
||||
|
||||
#endif /* WITH_XR_OPENXR */
|
||||
|
||||
#ifdef WITH_VULKAN
|
||||
|
||||
/**
|
||||
* Return vulkan handles for the given context.
|
||||
*/
|
||||
void GHOST_GetVulkanHandles(GHOST_ContextHandle context,
|
||||
void *r_instance,
|
||||
void *r_physical_device,
|
||||
void *r_device,
|
||||
uint32_t *r_graphic_queue_familly);
|
||||
|
||||
/**
|
||||
* Return vulkan backbuffer resources handles for the given window.
|
||||
*/
|
||||
void GHOST_GetVulkanBackbuffer(GHOST_WindowHandle windowhandle,
|
||||
void *image,
|
||||
void *framebuffer,
|
||||
void *command_buffer,
|
||||
void *render_pass,
|
||||
void *extent,
|
||||
uint32_t *fb_id);
|
||||
/**
|
||||
* \brief Query vulkan devices.
|
||||
*
|
||||
* \returns a device list handle or NULL when there is no vulkan available.
|
||||
*/
|
||||
GHOST_VulkanDeviceListHandle GHOST_QueryVulkanDevices(GHOST_ContextHandle system);
|
||||
|
||||
/**
|
||||
* \brief Destroy the given device list.
|
||||
*/
|
||||
GHOST_TSuccess GHOST_DestroyVulkanDeviceList(GHOST_VulkanDeviceListHandle device_list_handle);
|
||||
|
||||
/**
|
||||
* \brief Get an item from the given device list.
|
||||
*
|
||||
* \returns GHOST_kSuccess when device is loaded. GHOST_kFailure when the given device_list_handle
|
||||
* is incorrect or the given index is out of range.
|
||||
*/
|
||||
GHOST_TSuccess GHOST_GetVulkanDeviceListItem(GHOST_VulkanDeviceListHandle device_list_handle,
|
||||
int64_t index,
|
||||
GHOST_VulkanPhysicalDevice *r_device);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
|
@@ -56,6 +56,11 @@ class GHOST_IContext {
|
||||
|
||||
virtual unsigned int getDefaultFramebuffer() = 0;
|
||||
|
||||
virtual GHOST_TSuccess getVulkanHandles(void *, void *, void *, uint32_t *) = 0;
|
||||
|
||||
virtual GHOST_TSuccess getVulkanBackbuffer(
|
||||
void *, void *, void *, void *, void *, uint32_t *) = 0;
|
||||
|
||||
virtual GHOST_TSuccess swapBuffers() = 0;
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
|
@@ -265,7 +265,8 @@ class GHOST_ISystem {
|
||||
* Never explicitly delete the context, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
virtual GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings) = 0;
|
||||
virtual GHOST_IContext *createOffscreenContext(GHOST_TDrawingContextType type,
|
||||
GHOST_GLSettings glSettings) = 0;
|
||||
|
||||
/**
|
||||
* Dispose of a context.
|
||||
|
@@ -30,6 +30,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
|
||||
class GHOST_IContext;
|
||||
|
||||
/**
|
||||
* Interface for GHOST windows.
|
||||
*
|
||||
@@ -71,6 +73,12 @@ class GHOST_IWindow {
|
||||
*/
|
||||
virtual GHOST_TDrawingContextType getDrawingContextType() = 0;
|
||||
|
||||
/**
|
||||
* Returns the type of drawing context used in this window.
|
||||
* \return The current type of drawing context.
|
||||
*/
|
||||
virtual GHOST_IContext *getDrawingContext() = 0;
|
||||
|
||||
/**
|
||||
* Tries to install a rendering context in this window.
|
||||
* \param type: The type of rendering context installed.
|
||||
@@ -218,6 +226,18 @@ class GHOST_IWindow {
|
||||
*/
|
||||
virtual unsigned int getDefaultFramebuffer() = 0;
|
||||
|
||||
/**
|
||||
* Gets the Vulkan framebuffer related resource handles associated with the Vulkan context.
|
||||
* Needs to be called after each swap events as the framebuffer will change.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess getVulkanBackbuffer(void * /*image*/,
|
||||
void * /*framebuffer*/,
|
||||
void * /*command_buffer*/,
|
||||
void * /*render_pass*/,
|
||||
void * /*extent*/,
|
||||
uint32_t * /*fb_id*/) = 0;
|
||||
|
||||
/**
|
||||
* Invalidates the contents of this window.
|
||||
* \return Indication of success.
|
||||
|
@@ -29,6 +29,10 @@
|
||||
# include "MEM_guardedalloc.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_VULKAN
|
||||
# include "vulkan/vulkan.h"
|
||||
#endif
|
||||
|
||||
#if defined(WITH_CXX_GUARDEDALLOC) && defined(__cplusplus)
|
||||
# define GHOST_DECLARE_HANDLE(name) \
|
||||
typedef struct name##__ { \
|
||||
@@ -145,6 +149,9 @@ typedef enum { GHOST_kWindowOrderTop = 0, GHOST_kWindowOrderBottom } GHOST_TWind
|
||||
typedef enum {
|
||||
GHOST_kDrawingContextTypeNone = 0,
|
||||
GHOST_kDrawingContextTypeOpenGL,
|
||||
#ifdef WITH_VULKAN
|
||||
GHOST_kDrawingContextTypeVulkan,
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
GHOST_kDrawingContextTypeD3D,
|
||||
#endif
|
||||
@@ -782,3 +789,20 @@ typedef struct GHOST_XrControllerModelData {
|
||||
} GHOST_XrControllerModelData;
|
||||
|
||||
#endif /* WITH_XR_OPENXR */
|
||||
|
||||
#ifdef WITH_VULKAN
|
||||
|
||||
GHOST_DECLARE_HANDLE(GHOST_VulkanDeviceListHandle);
|
||||
|
||||
typedef struct GHOST_VulkanPhysicalDeviceID {
|
||||
uint32_t vendor_id;
|
||||
uint32_t device_id;
|
||||
int32_t index;
|
||||
} GHOST_VulkanPhysicalDeviceID;
|
||||
|
||||
typedef struct GHOST_VulkanPhysicalDevice {
|
||||
GHOST_VulkanPhysicalDeviceID device_id;
|
||||
VkPhysicalDeviceProperties device_properties;
|
||||
} GHOST_VulkanPhysicalDevice;
|
||||
|
||||
#endif
|
@@ -35,6 +35,9 @@
|
||||
# include "GHOST_IXrContext.h"
|
||||
# include "intern/GHOST_XrSession.h"
|
||||
#endif
|
||||
#ifdef WITH_VULKAN
|
||||
# include "intern/GHOST_ContextVK.h"
|
||||
#endif
|
||||
#include "intern/GHOST_CallbackEventConsumer.h"
|
||||
#include "intern/GHOST_XrException.h"
|
||||
|
||||
@@ -137,11 +140,12 @@ void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle,
|
||||
}
|
||||
|
||||
GHOST_ContextHandle GHOST_CreateOpenGLContext(GHOST_SystemHandle systemhandle,
|
||||
GHOST_TDrawingContextType type,
|
||||
GHOST_GLSettings glSettings)
|
||||
{
|
||||
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
|
||||
|
||||
return (GHOST_ContextHandle)system->createOffscreenContext(glSettings);
|
||||
return (GHOST_ContextHandle)system->createOffscreenContext(type, glSettings);
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_DisposeOpenGLContext(GHOST_SystemHandle systemhandle,
|
||||
@@ -493,6 +497,13 @@ GHOST_TDrawingContextType GHOST_GetDrawingContextType(GHOST_WindowHandle windowh
|
||||
return window->getDrawingContextType();
|
||||
}
|
||||
|
||||
GHOST_ContextHandle GHOST_GetDrawingContext(GHOST_WindowHandle windowhandle)
|
||||
{
|
||||
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
|
||||
|
||||
return (GHOST_ContextHandle)window->getDrawingContext();
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_SetDrawingContextType(GHOST_WindowHandle windowhandle,
|
||||
GHOST_TDrawingContextType type)
|
||||
{
|
||||
@@ -1105,3 +1116,74 @@ int GHOST_XrGetControllerModelData(GHOST_XrContextHandle xr_contexthandle,
|
||||
}
|
||||
|
||||
#endif /* WITH_XR_OPENXR */
|
||||
|
||||
#ifdef WITH_VULKAN
|
||||
|
||||
/**
|
||||
* Return vulkan handles for the given context.
|
||||
*/
|
||||
void GHOST_GetVulkanHandles(GHOST_ContextHandle contexthandle,
|
||||
void *r_instance,
|
||||
void *r_physical_device,
|
||||
void *r_device,
|
||||
uint32_t *r_graphic_queue_familly)
|
||||
{
|
||||
GHOST_IContext *context = (GHOST_IContext *)contexthandle;
|
||||
|
||||
context->getVulkanHandles(r_instance, r_physical_device, r_device, r_graphic_queue_familly);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return vulkan backbuffer resources handles for the given window.
|
||||
*/
|
||||
void GHOST_GetVulkanBackbuffer(GHOST_WindowHandle windowhandle,
|
||||
void *image,
|
||||
void *framebuffer,
|
||||
void *command_buffer,
|
||||
void *render_pass,
|
||||
void *extent,
|
||||
uint32_t *fb_id)
|
||||
{
|
||||
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
|
||||
|
||||
window->getVulkanBackbuffer(image, framebuffer, command_buffer, render_pass, extent, fb_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Query vulkan devices.
|
||||
*
|
||||
* \returns a device list handle or NULL when there is no vulkan available.
|
||||
*/
|
||||
GHOST_VulkanDeviceListHandle GHOST_QueryVulkanDevices(GHOST_ContextHandle contexthandle)
|
||||
{
|
||||
GHOST_ContextVK *context = (GHOST_ContextVK *)contexthandle;
|
||||
return (GHOST_VulkanDeviceListHandle)context->queryDevices();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Destroy the given device list.
|
||||
*/
|
||||
GHOST_TSuccess GHOST_DestroyVulkanDeviceList(GHOST_VulkanDeviceListHandle device_list_handle)
|
||||
{
|
||||
if (device_list_handle == nullptr) {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
GHOST_ContextVK::destroyDeviceList((GHOST_VulkanDeviceList *)device_list_handle);
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get an item from the given device list.
|
||||
*
|
||||
* \returns GHOST_kSuccess when device is loaded. GHOST_kFailure when the given device_list_handle
|
||||
* is incorrect or the given index is out of range.
|
||||
*/
|
||||
GHOST_TSuccess GHOST_GetVulkanDeviceListItem(GHOST_VulkanDeviceListHandle device_list_handle,
|
||||
int64_t index,
|
||||
GHOST_VulkanPhysicalDevice *r_device)
|
||||
{
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
#endif /* WITH_VULKAN */
|
||||
|
@@ -135,6 +135,33 @@ class GHOST_Context : public GHOST_IContext {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Vulkan context related resource handles.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess getVulkanHandles(void * /*r_instance*/,
|
||||
void * /*r_physical_device*/,
|
||||
void * /*r_device*/,
|
||||
uint32_t * /*r_graphic_queue_familly*/)
|
||||
{
|
||||
return GHOST_kFailure;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the Vulkan framebuffer related resource handles associated with the Vulkan context.
|
||||
* Needs to be called after each swap events as the framebuffer will change.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess getVulkanBackbuffer(void * /*image*/,
|
||||
void * /*framebuffer*/,
|
||||
void * /*command_buffer*/,
|
||||
void * /*render_pass*/,
|
||||
void * /*extent*/,
|
||||
uint32_t * /*fb_id*/)
|
||||
{
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
protected:
|
||||
void initContextGLEW();
|
||||
|
||||
|
1044
intern/ghost/intern/GHOST_ContextVK.cpp
Normal file
1044
intern/ghost/intern/GHOST_ContextVK.cpp
Normal file
File diff suppressed because it is too large
Load Diff
236
intern/ghost/intern/GHOST_ContextVK.h
Normal file
236
intern/ghost/intern/GHOST_ContextVK.h
Normal file
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2014 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
*/
|
||||
|
||||
#ifndef __GHOST_CONTEXTVK_H__
|
||||
#define __GHOST_CONTEXTVK_H__
|
||||
|
||||
#include "GHOST_Context.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
# include "GHOST_SystemWin32.h"
|
||||
#elif defined(__APPLE__)
|
||||
# include "GHOST_SystemCocoa.h"
|
||||
#else
|
||||
# include "GHOST_SystemX11.h"
|
||||
# ifdef WITH_GHOST_WAYLAND
|
||||
# include "GHOST_SystemWayland.h"
|
||||
# else
|
||||
# define wl_surface void
|
||||
# define wl_display void
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <MoltenVK/vk_mvk_moltenvk.h>
|
||||
#else
|
||||
# include <vulkan/vulkan.h>
|
||||
#endif
|
||||
|
||||
#ifndef GHOST_OPENGL_VK_CONTEXT_FLAGS
|
||||
/* leave as convenience define for the future */
|
||||
# define GHOST_OPENGL_VK_CONTEXT_FLAGS 0
|
||||
#endif
|
||||
|
||||
#ifndef GHOST_OPENGL_VK_RESET_NOTIFICATION_STRATEGY
|
||||
# define GHOST_OPENGL_VK_RESET_NOTIFICATION_STRATEGY 0
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
GHOST_kVulkanPlatformX11 = 0,
|
||||
#ifdef WITH_GHOST_WAYLAND
|
||||
GHOST_kVulkanPlatformWayland,
|
||||
#endif
|
||||
} GHOST_TVulkanPlatformType;
|
||||
|
||||
struct GHOST_VulkanDeviceList {
|
||||
std::vector<GHOST_VulkanPhysicalDevice> m_devices;
|
||||
};
|
||||
|
||||
class GHOST_ContextVK : public GHOST_Context {
|
||||
/* XR code needs low level graphics data to send to OpenXR. */
|
||||
// friend class GHOST_XrGraphicsBindingOpenGL;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
GHOST_ContextVK(bool stereoVisual,
|
||||
#ifdef _WIN32
|
||||
HWND hwnd,
|
||||
#elif defined(__APPLE__)
|
||||
/* FIXME CAMetalLayer but have issue with linking. */
|
||||
void *metal_layer,
|
||||
#else
|
||||
GHOST_TVulkanPlatformType platform,
|
||||
/* X11 */
|
||||
Window window,
|
||||
Display *display,
|
||||
/* Wayland */
|
||||
wl_surface *wayland_surface,
|
||||
wl_display *wayland_display,
|
||||
#endif
|
||||
int contextMajorVersion,
|
||||
int contextMinorVersion,
|
||||
int m_debug);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~GHOST_ContextVK();
|
||||
|
||||
/**
|
||||
* Swaps front and back buffers of a window.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
GHOST_TSuccess swapBuffers();
|
||||
|
||||
/**
|
||||
* Activates the drawing context of this window.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
GHOST_TSuccess activateDrawingContext();
|
||||
|
||||
/**
|
||||
* Release the drawing context of the calling thread.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
GHOST_TSuccess releaseDrawingContext();
|
||||
|
||||
/**
|
||||
* Call immediately after new to initialize. If this fails then immediately delete the object.
|
||||
* \return Indication as to whether initialization has succeeded.
|
||||
*/
|
||||
GHOST_TSuccess initializeDrawingContext();
|
||||
|
||||
/**
|
||||
* Removes references to native handles from this context and then returns
|
||||
* \return GHOST_kSuccess if it is OK for the parent to release the handles and
|
||||
* GHOST_kFailure if releasing the handles will interfere with sharing
|
||||
*/
|
||||
GHOST_TSuccess releaseNativeHandles();
|
||||
|
||||
/**
|
||||
* Gets the Vulkan context related resource handles.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
GHOST_TSuccess getVulkanHandles(void *r_instance,
|
||||
void *r_physical_device,
|
||||
void *r_device,
|
||||
uint32_t *r_graphic_queue_familly);
|
||||
/**
|
||||
* Gets the Vulkan framebuffer related resource handles associated with the Vulkan context.
|
||||
* Needs to be called after each swap events as the framebuffer will change.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
GHOST_TSuccess getVulkanBackbuffer(void *image,
|
||||
void *framebuffer,
|
||||
void *command_buffer,
|
||||
void *render_pass,
|
||||
void *extent,
|
||||
uint32_t *fb_id);
|
||||
|
||||
/**
|
||||
* Sets the swap interval for swapBuffers.
|
||||
* \param interval The swap interval to use.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
GHOST_TSuccess setSwapInterval(int /* interval */)
|
||||
{
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current swap interval for swapBuffers.
|
||||
* \param intervalOut Variable to store the swap interval if it can be read.
|
||||
* \return Whether the swap interval can be read.
|
||||
*/
|
||||
GHOST_TSuccess getSwapInterval(int &)
|
||||
{
|
||||
return GHOST_kFailure;
|
||||
};
|
||||
|
||||
GHOST_VulkanDeviceList *queryDevices();
|
||||
static void destroyDeviceList(GHOST_VulkanDeviceList *device_list);
|
||||
|
||||
private:
|
||||
#ifdef _WIN32
|
||||
HWND m_hwnd;
|
||||
#elif defined(__APPLE__)
|
||||
/* FIXME CAMetalLayer but have issue with linking. */
|
||||
void *m_metal_layer;
|
||||
#else /* Linux */
|
||||
GHOST_TVulkanPlatformType m_platform;
|
||||
/* X11 */
|
||||
Display *m_display;
|
||||
Window m_window;
|
||||
/* Wayland */
|
||||
wl_surface *m_wayland_surface;
|
||||
wl_display *m_wayland_display;
|
||||
#endif
|
||||
|
||||
const int m_context_major_version;
|
||||
const int m_context_minor_version;
|
||||
const int m_debug;
|
||||
|
||||
VkInstance m_instance;
|
||||
VkPhysicalDevice m_physical_device;
|
||||
VkDevice m_device;
|
||||
VkCommandPool m_command_pool;
|
||||
|
||||
uint32_t m_queue_family_graphic;
|
||||
uint32_t m_queue_family_present;
|
||||
|
||||
VkQueue m_graphic_queue;
|
||||
VkQueue m_present_queue;
|
||||
|
||||
/* For display only. */
|
||||
VkSurfaceKHR m_surface;
|
||||
VkSwapchainKHR m_swapchain;
|
||||
std::vector<VkImage> m_swapchain_images;
|
||||
std::vector<VkImageView> m_swapchain_image_views;
|
||||
std::vector<VkFramebuffer> m_swapchain_framebuffers;
|
||||
std::vector<VkCommandBuffer> m_command_buffers;
|
||||
VkRenderPass m_render_pass;
|
||||
VkExtent2D m_render_extent;
|
||||
std::vector<VkSemaphore> m_image_available_semaphores;
|
||||
std::vector<VkSemaphore> m_render_finished_semaphores;
|
||||
std::vector<VkFence> m_in_flight_fences;
|
||||
std::vector<VkFence> m_in_flight_images;
|
||||
/** frame modulo swapchain_len. Used as index for sync objects. */
|
||||
int m_currentFrame = 0;
|
||||
/** Image index in the swapchain. Used as index for render objects. */
|
||||
uint32_t m_currentImage = 0;
|
||||
/** Used to unique framebuffer ids to return when swapchain is recreated. */
|
||||
uint32_t m_swapchain_id = 0;
|
||||
|
||||
const char *getPlatformSpecificSurfaceExtension() const;
|
||||
GHOST_TSuccess pickPhysicalDevice(std::vector<const char *> required_exts);
|
||||
GHOST_TSuccess createSwapchain(void);
|
||||
GHOST_TSuccess destroySwapchain(void);
|
||||
GHOST_TSuccess createCommandBuffers(void);
|
||||
GHOST_TSuccess recordCommandBuffers(void);
|
||||
};
|
||||
|
||||
#endif // __GHOST_CONTEXTVK_H__
|
@@ -117,7 +117,8 @@ class GHOST_System : public GHOST_ISystem {
|
||||
* Never explicitly delete the context, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
virtual GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings) = 0;
|
||||
virtual GHOST_IContext *createOffscreenContext(GHOST_TDrawingContextType type,
|
||||
GHOST_GLSettings glSettings) = 0;
|
||||
|
||||
/**
|
||||
* Returns whether a window is valid.
|
||||
|
@@ -116,7 +116,8 @@ class GHOST_SystemCocoa : public GHOST_System {
|
||||
* Never explicitly delete the context, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings);
|
||||
GHOST_IContext *createOffscreenContext(GHOST_TDrawingContextType type,
|
||||
GHOST_GLSettings glSettings);
|
||||
|
||||
/**
|
||||
* Dispose of a context.
|
||||
|
@@ -34,6 +34,10 @@
|
||||
|
||||
#include "GHOST_ContextCGL.h"
|
||||
|
||||
#if defined(WITH_VULKAN)
|
||||
# include "GHOST_ContextVK.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
# include "GHOST_NDOFManagerCocoa.h"
|
||||
#endif
|
||||
@@ -764,8 +768,21 @@ GHOST_IWindow *GHOST_SystemCocoa::createWindow(const char *title,
|
||||
* Never explicitly delete the context, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
GHOST_IContext *GHOST_SystemCocoa::createOffscreenContext(GHOST_GLSettings glSettings)
|
||||
GHOST_IContext *GHOST_SystemCocoa::createOffscreenContext(GHOST_TDrawingContextType type,
|
||||
GHOST_GLSettings glSettings)
|
||||
{
|
||||
#ifdef WITH_VULKAN
|
||||
if (type == GHOST_kDrawingContextTypeVulkan) {
|
||||
const bool debug_context = (glSettings.flags & GHOST_glDebugContext) != 0;
|
||||
GHOST_Context *context = new GHOST_ContextVK(false, NULL, 1, 0, debug_context);
|
||||
if (context->initializeDrawingContext()) {
|
||||
return context;
|
||||
}
|
||||
delete context;
|
||||
type = GHOST_kDrawingContextTypeOpenGL;
|
||||
}
|
||||
#endif
|
||||
|
||||
GHOST_Context *context = new GHOST_ContextCGL(false, NULL, NULL, NULL);
|
||||
if (context->initializeDrawingContext())
|
||||
return context;
|
||||
|
@@ -81,7 +81,8 @@ class GHOST_SystemNULL : public GHOST_System {
|
||||
void getAllDisplayDimensions(uint32_t &width, uint32_t &height) const
|
||||
{ /* nop */
|
||||
}
|
||||
GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings)
|
||||
GHOST_IContext *createOffscreenContext(GHOST_TDrawingContextType /* type */,
|
||||
GHOST_GLSettings glSettings)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@@ -139,7 +139,8 @@ uint8_t GHOST_SystemSDL::getNumDisplays() const
|
||||
return SDL_GetNumVideoDisplays();
|
||||
}
|
||||
|
||||
GHOST_IContext *GHOST_SystemSDL::createOffscreenContext(GHOST_GLSettings glSettings)
|
||||
GHOST_IContext *GHOST_SystemSDL::createOffscreenContext(GHOST_TDrawingContextType /* type */,
|
||||
GHOST_GLSettings glSettings)
|
||||
{
|
||||
GHOST_Context *context = new GHOST_ContextSDL(0,
|
||||
NULL,
|
||||
|
@@ -72,7 +72,8 @@ class GHOST_SystemSDL : public GHOST_System {
|
||||
|
||||
void getMainDisplayDimensions(uint32_t &width, uint32_t &height) const;
|
||||
|
||||
GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings);
|
||||
GHOST_IContext *createOffscreenContext(GHOST_TDrawingContextType type,
|
||||
GHOST_GLSettings glSettings);
|
||||
|
||||
GHOST_TSuccess disposeContext(GHOST_IContext *context);
|
||||
|
||||
|
@@ -30,6 +30,10 @@
|
||||
|
||||
#include "GHOST_ContextEGL.h"
|
||||
|
||||
#if defined(WITH_VULKAN)
|
||||
# include "GHOST_ContextVK.h"
|
||||
#endif
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <wayland-egl.h>
|
||||
|
||||
@@ -1588,55 +1592,75 @@ void GHOST_SystemWayland::getAllDisplayDimensions(uint32_t &width, uint32_t &hei
|
||||
getMainDisplayDimensions(width, height);
|
||||
}
|
||||
|
||||
GHOST_IContext *GHOST_SystemWayland::createOffscreenContext(GHOST_GLSettings /*glSettings*/)
|
||||
GHOST_IContext *GHOST_SystemWayland::createOffscreenContext(GHOST_TDrawingContextType type,
|
||||
GHOST_GLSettings glSettings)
|
||||
{
|
||||
/* Create new off-screen window. */
|
||||
wl_surface *os_surface = wl_compositor_create_surface(compositor());
|
||||
wl_egl_window *os_egl_window = wl_egl_window_create(os_surface, int(1), int(1));
|
||||
#if defined(WITH_VULKAN)
|
||||
const bool debug_context = (glSettings.flags & GHOST_glDebugContext) != 0;
|
||||
|
||||
d->os_surfaces.push_back(os_surface);
|
||||
d->os_egl_windows.push_back(os_egl_window);
|
||||
if (type == GHOST_kDrawingContextTypeVulkan) {
|
||||
GHOST_Context *context = new GHOST_ContextVK(
|
||||
false, GHOST_kVulkanPlatformWayland, 0, NULL, NULL, d->display, 1, 0, debug_context);
|
||||
|
||||
GHOST_Context *context;
|
||||
if (context->initializeDrawingContext()) {
|
||||
return context;
|
||||
}
|
||||
else {
|
||||
delete context;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)glSettings;
|
||||
#endif
|
||||
|
||||
if (type == GHOST_kDrawingContextTypeOpenGL) {
|
||||
/* Create new off-screen window. */
|
||||
wl_surface *os_surface = wl_compositor_create_surface(compositor());
|
||||
wl_egl_window *os_egl_window = wl_egl_window_create(os_surface, int(1), int(1));
|
||||
|
||||
d->os_surfaces.push_back(os_surface);
|
||||
d->os_egl_windows.push_back(os_egl_window);
|
||||
|
||||
GHOST_Context *context;
|
||||
|
||||
for (int minor = 6; minor >= 0; --minor) {
|
||||
context = new GHOST_ContextEGL(this,
|
||||
false,
|
||||
EGLNativeWindowType(os_egl_window),
|
||||
EGLNativeDisplayType(d->display),
|
||||
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
|
||||
4,
|
||||
minor,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_API);
|
||||
|
||||
if (context->initializeDrawingContext())
|
||||
return context;
|
||||
else
|
||||
delete context;
|
||||
}
|
||||
|
||||
for (int minor = 6; minor >= 0; --minor) {
|
||||
context = new GHOST_ContextEGL(this,
|
||||
false,
|
||||
EGLNativeWindowType(os_egl_window),
|
||||
EGLNativeDisplayType(d->display),
|
||||
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
|
||||
4,
|
||||
minor,
|
||||
3,
|
||||
3,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_API);
|
||||
|
||||
if (context->initializeDrawingContext())
|
||||
if (context->initializeDrawingContext()) {
|
||||
return context;
|
||||
else
|
||||
}
|
||||
else {
|
||||
delete context;
|
||||
}
|
||||
|
||||
GHOST_PRINT("Cannot create off-screen EGL context" << std::endl);
|
||||
}
|
||||
|
||||
context = new GHOST_ContextEGL(this,
|
||||
false,
|
||||
EGLNativeWindowType(os_egl_window),
|
||||
EGLNativeDisplayType(d->display),
|
||||
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
|
||||
3,
|
||||
3,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_API);
|
||||
|
||||
if (context->initializeDrawingContext()) {
|
||||
return context;
|
||||
}
|
||||
else {
|
||||
delete context;
|
||||
}
|
||||
|
||||
GHOST_PRINT("Cannot create off-screen EGL context" << std::endl);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@@ -73,7 +73,8 @@ class GHOST_SystemWayland : public GHOST_System {
|
||||
|
||||
void getAllDisplayDimensions(uint32_t &width, uint32_t &height) const override;
|
||||
|
||||
GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings) override;
|
||||
GHOST_IContext *createOffscreenContext(GHOST_TDrawingContextType type,
|
||||
GHOST_GLSettings glSettings) override;
|
||||
|
||||
GHOST_TSuccess disposeContext(GHOST_IContext *context) override;
|
||||
|
||||
|
@@ -50,7 +50,15 @@
|
||||
#include "GHOST_WindowManager.h"
|
||||
#include "GHOST_WindowWin32.h"
|
||||
|
||||
#include "GHOST_ContextWGL.h"
|
||||
#if defined(WITH_VULKAN)
|
||||
# include "GHOST_ContextVK.h"
|
||||
#endif
|
||||
|
||||
#if defined(WITH_GL_EGL)
|
||||
# include "GHOST_ContextEGL.h"
|
||||
#else
|
||||
# include "GHOST_ContextWGL.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
# include "GHOST_NDOFManagerWin32.h"
|
||||
@@ -263,10 +271,26 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow(const char *title,
|
||||
* Never explicitly delete the window, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
GHOST_IContext *GHOST_SystemWin32::createOffscreenContext(GHOST_GLSettings glSettings)
|
||||
GHOST_IContext *GHOST_SystemWin32::createOffscreenContext(GHOST_TDrawingContextType type,
|
||||
GHOST_GLSettings glSettings)
|
||||
{
|
||||
const bool debug_context = (glSettings.flags & GHOST_glDebugContext) != 0;
|
||||
|
||||
#if defined(WITH_VULKAN)
|
||||
/* Vulkan does not need a window. */
|
||||
if (type == GHOST_kDrawingContextTypeVulkan) {
|
||||
GHOST_Context *context = new GHOST_ContextVK(false, (HWND)0, 1, 0, debug_context);
|
||||
|
||||
if (context->initializeDrawingContext()) {
|
||||
return context;
|
||||
}
|
||||
else {
|
||||
delete context;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
GHOST_Context *context;
|
||||
|
||||
HWND wnd = CreateWindowA("STATIC",
|
||||
|
@@ -142,7 +142,8 @@ class GHOST_SystemWin32 : public GHOST_System {
|
||||
* Never explicitly delete the window, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings);
|
||||
GHOST_IContext *createOffscreenContext(GHOST_TDrawingContextType type,
|
||||
GHOST_GLSettings glSettings);
|
||||
|
||||
/**
|
||||
* Dispose of a context.
|
||||
|
@@ -48,6 +48,10 @@
|
||||
|
||||
#include "GHOST_Debug.h"
|
||||
|
||||
#if defined(WITH_VULKAN)
|
||||
# include "GHOST_ContextVK.h"
|
||||
#endif
|
||||
|
||||
#if defined(WITH_GL_EGL)
|
||||
# include "GHOST_ContextEGL.h"
|
||||
# include <EGL/eglext.h>
|
||||
@@ -394,7 +398,8 @@ GHOST_IWindow *GHOST_SystemX11::createWindow(const char *title,
|
||||
* Never explicitly delete the context, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GLSettings glSettings)
|
||||
GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_TDrawingContextType type,
|
||||
GHOST_GLSettings glSettings)
|
||||
{
|
||||
/* During development:
|
||||
* try 4.x compatibility profile
|
||||
@@ -408,46 +413,97 @@ GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GLSettings glSetti
|
||||
|
||||
const bool debug_context = (glSettings.flags & GHOST_glDebugContext) != 0;
|
||||
|
||||
#if defined(WITH_GL_PROFILE_CORE)
|
||||
{
|
||||
const char *version_major = (char *)glewGetString(GLEW_VERSION_MAJOR);
|
||||
if (version_major != NULL && version_major[0] == '1') {
|
||||
fprintf(stderr, "Error: GLEW version 2.0 and above is required.\n");
|
||||
abort();
|
||||
#if defined(WITH_VULKAN)
|
||||
if (type == GHOST_kDrawingContextTypeVulkan) {
|
||||
GHOST_Context *context = new GHOST_ContextVK(
|
||||
false, GHOST_kVulkanPlatformX11, 0, m_display, NULL, NULL, 1, 0, debug_context);
|
||||
|
||||
if (context->initializeDrawingContext()) {
|
||||
return context;
|
||||
}
|
||||
else {
|
||||
delete context;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
const int profile_mask =
|
||||
if (type == GHOST_kDrawingContextTypeOpenGL) {
|
||||
/* Final Blender 2.8:
|
||||
* try 4.x core profile
|
||||
* try 3.3 core profile
|
||||
* no fallbacks. */
|
||||
|
||||
#if defined(WITH_GL_PROFILE_CORE)
|
||||
{
|
||||
const char *version_major = (char *)glewGetString(GLEW_VERSION_MAJOR);
|
||||
if (version_major != NULL && version_major[0] == '1') {
|
||||
fprintf(stderr, "Error: GLEW version 2.0 and above is required.\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
const int profile_mask =
|
||||
#ifdef WITH_GL_EGL
|
||||
# if defined(WITH_GL_PROFILE_CORE)
|
||||
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT;
|
||||
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT;
|
||||
# elif defined(WITH_GL_PROFILE_COMPAT)
|
||||
EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT;
|
||||
EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT;
|
||||
# else
|
||||
# error // must specify either core or compat at build time
|
||||
# endif
|
||||
#else
|
||||
# if defined(WITH_GL_PROFILE_CORE)
|
||||
GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
|
||||
GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
|
||||
# elif defined(WITH_GL_PROFILE_COMPAT)
|
||||
GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
|
||||
GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
|
||||
# else
|
||||
# error // must specify either core or compat at build time
|
||||
# endif
|
||||
#endif
|
||||
|
||||
GHOST_Context *context;
|
||||
GHOST_Context *context;
|
||||
|
||||
for (int minor = 5; minor >= 0; --minor) {
|
||||
#if defined(WITH_GL_EGL)
|
||||
context = new GHOST_ContextEGL(this,
|
||||
false,
|
||||
EGLNativeWindowType(nullptr),
|
||||
EGLNativeDisplayType(m_display),
|
||||
profile_mask,
|
||||
4,
|
||||
minor,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS |
|
||||
(false ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0),
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_API);
|
||||
#else
|
||||
context = new GHOST_ContextGLX(false,
|
||||
(Window)NULL,
|
||||
m_display,
|
||||
(GLXFBConfig)NULL,
|
||||
profile_mask,
|
||||
4,
|
||||
minor,
|
||||
GHOST_OPENGL_GLX_CONTEXT_FLAGS |
|
||||
(false ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
|
||||
GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
|
||||
#endif
|
||||
|
||||
if (context->initializeDrawingContext())
|
||||
return context;
|
||||
else
|
||||
delete context;
|
||||
}
|
||||
|
||||
for (int minor = 5; minor >= 0; --minor) {
|
||||
#if defined(WITH_GL_EGL)
|
||||
context = new GHOST_ContextEGL(this,
|
||||
false,
|
||||
EGLNativeWindowType(nullptr),
|
||||
EGLNativeDisplayType(m_display),
|
||||
profile_mask,
|
||||
4,
|
||||
minor,
|
||||
3,
|
||||
3,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS |
|
||||
(debug_context ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0),
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
@@ -458,49 +514,21 @@ GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GLSettings glSetti
|
||||
m_display,
|
||||
(GLXFBConfig)NULL,
|
||||
profile_mask,
|
||||
4,
|
||||
minor,
|
||||
3,
|
||||
3,
|
||||
GHOST_OPENGL_GLX_CONTEXT_FLAGS |
|
||||
(debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
|
||||
GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
|
||||
#endif
|
||||
|
||||
if (context->initializeDrawingContext())
|
||||
if (context->initializeDrawingContext()) {
|
||||
return context;
|
||||
else
|
||||
}
|
||||
else {
|
||||
delete context;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(WITH_GL_EGL)
|
||||
context = new GHOST_ContextEGL(this,
|
||||
false,
|
||||
EGLNativeWindowType(nullptr),
|
||||
EGLNativeDisplayType(m_display),
|
||||
profile_mask,
|
||||
3,
|
||||
3,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS |
|
||||
(debug_context ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0),
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_API);
|
||||
#else
|
||||
context = new GHOST_ContextGLX(false,
|
||||
(Window)NULL,
|
||||
m_display,
|
||||
(GLXFBConfig)NULL,
|
||||
profile_mask,
|
||||
3,
|
||||
3,
|
||||
GHOST_OPENGL_GLX_CONTEXT_FLAGS |
|
||||
(debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
|
||||
GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
|
||||
#endif
|
||||
|
||||
if (context->initializeDrawingContext())
|
||||
return context;
|
||||
else
|
||||
delete context;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@@ -152,7 +152,8 @@ class GHOST_SystemX11 : public GHOST_System {
|
||||
* Never explicitly delete the context, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings);
|
||||
GHOST_IContext *createOffscreenContext(GHOST_TDrawingContextType type,
|
||||
GHOST_GLSettings glSettings);
|
||||
|
||||
/**
|
||||
* Dispose of a context.
|
||||
|
@@ -26,7 +26,7 @@
|
||||
|
||||
#include "GHOST_IWindow.h"
|
||||
|
||||
class GHOST_Context;
|
||||
#include "GHOST_Context.h"
|
||||
|
||||
/**
|
||||
* Platform independent implementation of GHOST_IWindow.
|
||||
@@ -94,6 +94,22 @@ class GHOST_Window : public GHOST_IWindow {
|
||||
return m_context != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Vulkan framebuffer related resource handles associated with the Vulkan context.
|
||||
* Needs to be called after each swap events as the framebuffer will change.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
GHOST_TSuccess getVulkanBackbuffer(void *image,
|
||||
void *framebuffer,
|
||||
void *command_buffer,
|
||||
void *render_pass,
|
||||
void *extent,
|
||||
uint32_t *fb_id)
|
||||
{
|
||||
return m_context->getVulkanBackbuffer(
|
||||
image, framebuffer, command_buffer, render_pass, extent, fb_id);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the associated OS object/handle
|
||||
* \return The associated OS object/handle
|
||||
@@ -229,6 +245,12 @@ class GHOST_Window : public GHOST_IWindow {
|
||||
*/
|
||||
inline GHOST_TDrawingContextType getDrawingContextType();
|
||||
|
||||
/**
|
||||
* Returns the drawing context used in this window.
|
||||
* \return The drawing context.
|
||||
*/
|
||||
inline GHOST_IContext *getDrawingContext();
|
||||
|
||||
/**
|
||||
* Tries to install a rendering context in this window.
|
||||
* Child classes do not need to overload this method,
|
||||
@@ -411,6 +433,11 @@ inline GHOST_TDrawingContextType GHOST_Window::getDrawingContextType()
|
||||
return m_drawingContextType;
|
||||
}
|
||||
|
||||
inline GHOST_IContext *GHOST_Window::getDrawingContext()
|
||||
{
|
||||
return m_context;
|
||||
}
|
||||
|
||||
inline bool GHOST_Window::getCursorVisibility() const
|
||||
{
|
||||
return m_cursorVisible;
|
||||
|
@@ -24,6 +24,10 @@
|
||||
|
||||
#include "GHOST_ContextCGL.h"
|
||||
|
||||
#if defined(WITH_VULKAN)
|
||||
# include "GHOST_ContextVK.h"
|
||||
#endif
|
||||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include <Metal/Metal.h>
|
||||
#include <QuartzCore/QuartzCore.h>
|
||||
@@ -819,8 +823,21 @@ GHOST_TSuccess GHOST_WindowCocoa::setOrder(GHOST_TWindowOrder order)
|
||||
|
||||
GHOST_Context *GHOST_WindowCocoa::newDrawingContext(GHOST_TDrawingContextType type)
|
||||
{
|
||||
if (type == GHOST_kDrawingContextTypeOpenGL) {
|
||||
#ifdef WITH_VULKAN
|
||||
if (type == GHOST_kDrawingContextTypeVulkan) {
|
||||
GHOST_Context *context = new GHOST_ContextVK(m_wantStereoVisual, m_metalLayer, 1, 0, true);
|
||||
|
||||
if (context->initializeDrawingContext()) {
|
||||
return context;
|
||||
}
|
||||
|
||||
delete context;
|
||||
/* Fallback to opengl. */
|
||||
type = GHOST_kDrawingContextTypeOpenGL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (type == GHOST_kDrawingContextTypeOpenGL) {
|
||||
GHOST_Context *context = new GHOST_ContextCGL(
|
||||
m_wantStereoVisual, m_metalView, m_metalLayer, m_openGLView);
|
||||
|
||||
|
@@ -26,6 +26,9 @@
|
||||
|
||||
#include "GHOST_ContextEGL.h"
|
||||
#include "GHOST_ContextNone.h"
|
||||
#if defined(WITH_VULKAN)
|
||||
# include "GHOST_ContextVK.h"
|
||||
#endif
|
||||
|
||||
#include <wayland-egl.h>
|
||||
|
||||
@@ -554,6 +557,21 @@ GHOST_Context *GHOST_WindowWayland::newDrawingContext(GHOST_TDrawingContextType
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_API);
|
||||
break;
|
||||
#if defined(WITH_VULKAN)
|
||||
case GHOST_kDrawingContextTypeVulkan:
|
||||
context = new GHOST_ContextVK(m_wantStereoVisual,
|
||||
GHOST_kVulkanPlatformWayland,
|
||||
0,
|
||||
NULL,
|
||||
w->surface,
|
||||
m_system->display(),
|
||||
1,
|
||||
0,
|
||||
false);
|
||||
break;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
return (context->initializeDrawingContext() == GHOST_kSuccess) ? context : nullptr;
|
||||
|
@@ -30,8 +30,15 @@
|
||||
#include "utf_winfunc.h"
|
||||
#include "utfconv.h"
|
||||
|
||||
#include "GHOST_ContextWGL.h"
|
||||
#if defined(WITH_VULKAN)
|
||||
# include "GHOST_ContextVK.h"
|
||||
#endif
|
||||
|
||||
#if defined(WITH_GL_EGL)
|
||||
# include "GHOST_ContextEGL.h"
|
||||
#else
|
||||
# include "GHOST_ContextWGL.h"
|
||||
#endif
|
||||
#ifdef WIN32_COMPOSITING
|
||||
# include <Dwmapi.h>
|
||||
#endif
|
||||
@@ -615,6 +622,18 @@ GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType ty
|
||||
|
||||
return context;
|
||||
}
|
||||
#if defined(WITH_VULKAN)
|
||||
else if (type == GHOST_kDrawingContextTypeVulkan) {
|
||||
GHOST_Context *context = new GHOST_ContextVK(false, m_hWnd, 1, 0, m_debug_context);
|
||||
|
||||
if (context->initializeDrawingContext()) {
|
||||
return context;
|
||||
}
|
||||
else {
|
||||
delete context;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@@ -38,6 +38,10 @@
|
||||
# include "GHOST_DropTargetX11.h"
|
||||
#endif
|
||||
|
||||
#if defined(WITH_VULKAN)
|
||||
# include "GHOST_ContextVK.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_GL_EGL
|
||||
# include "GHOST_ContextEGL.h"
|
||||
# include <EGL/eglext.h>
|
||||
@@ -1273,8 +1277,38 @@ GHOST_WindowX11::~GHOST_WindowX11()
|
||||
|
||||
GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type)
|
||||
{
|
||||
if (type == GHOST_kDrawingContextTypeOpenGL) {
|
||||
#if defined(WITH_VULKAN)
|
||||
if (type == GHOST_kDrawingContextTypeVulkan) {
|
||||
/* Vulkan port
|
||||
* try vulkan
|
||||
* fallback to OGL */
|
||||
GHOST_Context *context = new GHOST_ContextVK(m_wantStereoVisual,
|
||||
GHOST_kVulkanPlatformX11,
|
||||
m_window,
|
||||
m_display,
|
||||
NULL,
|
||||
NULL,
|
||||
1,
|
||||
0,
|
||||
m_is_debug_context);
|
||||
|
||||
if (context->initializeDrawingContext()) {
|
||||
return context;
|
||||
}
|
||||
else {
|
||||
delete context;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Error! Unsupported graphics card or driver.\n");
|
||||
fprintf(stderr, "A graphics card and driver with support for Vulkan 1.0.\n");
|
||||
fprintf(stderr, "You can try the `--debug-gpu' option to have more information.\n");
|
||||
fprintf(stderr, "The program will now close.\n");
|
||||
fflush(stderr);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (type == GHOST_kDrawingContextTypeOpenGL) {
|
||||
/* During development:
|
||||
* - Try 4.x compatibility profile.
|
||||
* - Try 3.3 compatibility profile.
|
||||
|
@@ -266,6 +266,8 @@ class GHOST_WindowX11 : public GHOST_Window {
|
||||
XIC m_xic;
|
||||
#endif
|
||||
|
||||
GHOST_TDrawingContextType m_context_type;
|
||||
|
||||
bool m_valid_setup;
|
||||
bool m_is_debug_context;
|
||||
|
||||
|
@@ -332,7 +332,7 @@ MainWindow *mainwindow_new(MultiTestApp *app)
|
||||
if (win) {
|
||||
MainWindow *mw = MEM_callocN(sizeof(*mw), "mainwindow_new");
|
||||
|
||||
mw->gpu_context = GPU_context_create(win);
|
||||
mw->gpu_context = GPU_context_create(win, NULL);
|
||||
GPU_init();
|
||||
|
||||
mw->app = app;
|
||||
@@ -589,7 +589,7 @@ LoggerWindow *loggerwindow_new(MultiTestApp *app)
|
||||
if (win) {
|
||||
LoggerWindow *lw = MEM_callocN(sizeof(*lw), "loggerwindow_new");
|
||||
|
||||
lw->gpu_context = GPU_context_create(win);
|
||||
lw->gpu_context = GPU_context_create(win, NULL);
|
||||
GPU_init();
|
||||
|
||||
int bbox[2][2];
|
||||
@@ -791,7 +791,7 @@ ExtraWindow *extrawindow_new(MultiTestApp *app)
|
||||
if (win) {
|
||||
ExtraWindow *ew = MEM_callocN(sizeof(*ew), "mainwindow_new");
|
||||
|
||||
ew->gpu_context = GPU_context_create(win);
|
||||
ew->gpu_context = GPU_context_create(win, NULL);
|
||||
GPU_init();
|
||||
|
||||
ew->app = app;
|
||||
|
44
intern/shader_compiler/CMakeLists.txt
Normal file
44
intern/shader_compiler/CMakeLists.txt
Normal file
@@ -0,0 +1,44 @@
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2012, Blender Foundation
|
||||
# All rights reserved.
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
set(INC
|
||||
.
|
||||
../guardedalloc
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
${SHADERC_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(SRC
|
||||
intern/Compiler.cc
|
||||
intern/Result.cc
|
||||
|
||||
intern/shaderc/ShaderCCompiler.cc
|
||||
intern/shaderc/ShaderCResult.cc
|
||||
|
||||
shader_compiler.hh
|
||||
)
|
||||
|
||||
set(LIB
|
||||
${SHADERC_LIBRARIES}
|
||||
)
|
||||
|
||||
blender_add_lib(bf_intern_shadercompiler "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
32
intern/shader_compiler/intern/Compiler.cc
Normal file
32
intern/shader_compiler/intern/Compiler.cc
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2021 by Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include "shader_compiler.hh"
|
||||
|
||||
#include "intern/shaderc/ShaderCCompiler.hh"
|
||||
|
||||
namespace shader_compiler {
|
||||
|
||||
Compiler *Compiler::create_default()
|
||||
{
|
||||
Compiler *compiler = new shaderc::ShaderCCompiler();
|
||||
return compiler;
|
||||
}
|
||||
|
||||
} // namespace shader_compiler
|
29
intern/shader_compiler/intern/Result.cc
Normal file
29
intern/shader_compiler/intern/Result.cc
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2021 by Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include "shader_compiler.hh"
|
||||
|
||||
namespace shader_compiler {
|
||||
|
||||
void Result::init(const Job &job)
|
||||
{
|
||||
type = job.compilation_target;
|
||||
}
|
||||
|
||||
} // namespace shader_compiler
|
92
intern/shader_compiler/intern/shaderc/ShaderCCompiler.cc
Normal file
92
intern/shader_compiler/intern/shaderc/ShaderCCompiler.cc
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2021 by Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include "ShaderCCompiler.hh"
|
||||
#include "ShaderCResult.hh"
|
||||
#include "shaderc/shaderc.hpp"
|
||||
|
||||
namespace shader_compiler::shaderc {
|
||||
|
||||
ShaderCCompiler::ShaderCCompiler()
|
||||
{
|
||||
}
|
||||
|
||||
ShaderCCompiler::~ShaderCCompiler()
|
||||
{
|
||||
}
|
||||
|
||||
void ShaderCCompiler::set_optimization_level(::shaderc::CompileOptions options,
|
||||
const OptimizationLevel new_value)
|
||||
{
|
||||
switch (new_value) {
|
||||
case OptimizationLevel::NotOptimized:
|
||||
options.SetOptimizationLevel(shaderc_optimization_level_zero);
|
||||
break;
|
||||
case OptimizationLevel::SizeOptimized:
|
||||
options.SetOptimizationLevel(shaderc_optimization_level_size);
|
||||
break;
|
||||
case OptimizationLevel::SpeedOptimized:
|
||||
options.SetOptimizationLevel(shaderc_optimization_level_performance);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
shaderc_shader_kind ShaderCCompiler::get_source_kind(SourceType source_type)
|
||||
{
|
||||
switch (source_type) {
|
||||
case SourceType::GlslVertexShader:
|
||||
return shaderc_glsl_vertex_shader;
|
||||
|
||||
case SourceType::GlslGeometryShader:
|
||||
return shaderc_glsl_geometry_shader;
|
||||
|
||||
case SourceType::GlslFragmentShader:
|
||||
return shaderc_glsl_fragment_shader;
|
||||
|
||||
case SourceType::GlslComputeShader:
|
||||
return shaderc_glsl_compute_shader;
|
||||
}
|
||||
return shaderc_glsl_vertex_shader;
|
||||
}
|
||||
|
||||
ShaderCResult *ShaderCCompiler::compile_spirv(const Job &job)
|
||||
{
|
||||
::shaderc::CompileOptions options;
|
||||
set_optimization_level(options, job.optimization_level);
|
||||
shaderc_shader_kind kind = get_source_kind(job.source_type);
|
||||
|
||||
::shaderc::SpvCompilationResult shaderc_result = compiler_.CompileGlslToSpv(
|
||||
job.source.c_str(), kind, job.name.c_str(), options);
|
||||
|
||||
ShaderCResult *result = new ShaderCResult();
|
||||
result->init(job, shaderc_result);
|
||||
return result;
|
||||
}
|
||||
|
||||
Result *ShaderCCompiler::compile(const Job &job)
|
||||
{
|
||||
switch (job.compilation_target) {
|
||||
case TargetType::SpirV:
|
||||
return compile_spirv(job);
|
||||
break;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace shader_compiler::shaderc
|
48
intern/shader_compiler/intern/shaderc/ShaderCCompiler.hh
Normal file
48
intern/shader_compiler/intern/shaderc/ShaderCCompiler.hh
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2021 by Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shader_compiler.hh"
|
||||
|
||||
#include "shaderc/shaderc.hpp"
|
||||
|
||||
namespace shader_compiler::shaderc {
|
||||
|
||||
class ShaderCResult;
|
||||
|
||||
class ShaderCCompiler : public Compiler {
|
||||
private:
|
||||
::shaderc::Compiler compiler_;
|
||||
|
||||
public:
|
||||
ShaderCCompiler();
|
||||
~ShaderCCompiler() override;
|
||||
|
||||
Result *compile(const Job &job) override;
|
||||
|
||||
private:
|
||||
ShaderCResult *compile_spirv(const Job &job);
|
||||
|
||||
static void set_optimization_level(::shaderc::CompileOptions options,
|
||||
const OptimizationLevel new_value);
|
||||
static shaderc_shader_kind get_source_kind(SourceType source_type);
|
||||
};
|
||||
|
||||
} // namespace shader_compiler::shaderc
|
58
intern/shader_compiler/intern/shaderc/ShaderCResult.cc
Normal file
58
intern/shader_compiler/intern/shaderc/ShaderCResult.cc
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2021 by Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include "ShaderCResult.hh"
|
||||
|
||||
namespace shader_compiler::shaderc {
|
||||
|
||||
void ShaderCResult::init(const Job &job, ::shaderc::SpvCompilationResult &shaderc_result)
|
||||
{
|
||||
Result::init(job);
|
||||
status_code = status_code_from(shaderc_result);
|
||||
|
||||
switch (status_code) {
|
||||
case StatusCode::Ok:
|
||||
bin = {shaderc_result.cbegin(), shaderc_result.cend()};
|
||||
break;
|
||||
|
||||
case StatusCode::CompilationError:
|
||||
error_log = shaderc_result.GetErrorMessage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
StatusCode ShaderCResult::status_code_from(::shaderc::SpvCompilationResult &shaderc_result)
|
||||
{
|
||||
if (shaderc_result.GetCompilationStatus() != shaderc_compilation_status_success) {
|
||||
return StatusCode::CompilationError;
|
||||
}
|
||||
return StatusCode::Ok;
|
||||
}
|
||||
|
||||
std::vector<uint32_t> ShaderCResult::bin_from(::shaderc::SpvCompilationResult &shaderc_result)
|
||||
{
|
||||
return {shaderc_result.cbegin(), shaderc_result.cend()};
|
||||
}
|
||||
|
||||
std::string ShaderCResult::error_log_from(::shaderc::SpvCompilationResult &shaderc_result)
|
||||
{
|
||||
return shaderc_result.GetErrorMessage();
|
||||
}
|
||||
|
||||
} // namespace shader_compiler::shaderc
|
39
intern/shader_compiler/intern/shaderc/ShaderCResult.hh
Normal file
39
intern/shader_compiler/intern/shaderc/ShaderCResult.hh
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2021 by Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shader_compiler.hh"
|
||||
|
||||
#include "shaderc/shaderc.hpp"
|
||||
|
||||
namespace shader_compiler::shaderc {
|
||||
|
||||
class ShaderCResult : public Result {
|
||||
|
||||
public:
|
||||
void init(const Job &job, ::shaderc::SpvCompilationResult &shaderc_result);
|
||||
|
||||
private:
|
||||
StatusCode status_code_from(::shaderc::SpvCompilationResult &shaderc_result);
|
||||
std::string error_log_from(::shaderc::SpvCompilationResult &shaderc_result);
|
||||
std::vector<uint32_t> bin_from(::shaderc::SpvCompilationResult &shaderc_result);
|
||||
};
|
||||
|
||||
} // namespace shader_compiler::shaderc
|
106
intern/shader_compiler/shader_compiler.hh
Normal file
106
intern/shader_compiler/shader_compiler.hh
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2021 by Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
# include "MEM_guardedalloc.h"
|
||||
#endif
|
||||
|
||||
namespace shader_compiler {
|
||||
|
||||
enum class SourceType {
|
||||
GlslVertexShader,
|
||||
GlslGeometryShader,
|
||||
GlslFragmentShader,
|
||||
GlslComputeShader,
|
||||
};
|
||||
|
||||
enum class TargetType {
|
||||
SpirV,
|
||||
// SpirVAssembly,
|
||||
};
|
||||
|
||||
enum class OptimizationLevel {
|
||||
NotOptimized,
|
||||
SizeOptimized,
|
||||
SpeedOptimized,
|
||||
};
|
||||
|
||||
enum class StatusCode {
|
||||
Ok,
|
||||
CompilationError,
|
||||
};
|
||||
|
||||
class Job;
|
||||
class Result;
|
||||
|
||||
class Compiler {
|
||||
protected:
|
||||
Compiler(){};
|
||||
|
||||
public:
|
||||
virtual ~Compiler(){};
|
||||
|
||||
static Compiler *create_default();
|
||||
virtual Result *compile(const Job &job) = 0;
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("ShadeCompiler:Compiler")
|
||||
#endif
|
||||
};
|
||||
|
||||
class Job {
|
||||
public:
|
||||
std::string name;
|
||||
std::string source;
|
||||
SourceType source_type;
|
||||
TargetType compilation_target;
|
||||
OptimizationLevel optimization_level = OptimizationLevel::NotOptimized;
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("ShaderCompiler:Job")
|
||||
#endif
|
||||
};
|
||||
|
||||
class Result {
|
||||
public:
|
||||
TargetType type;
|
||||
StatusCode status_code;
|
||||
std::string error_log;
|
||||
std::vector<uint32_t> bin;
|
||||
|
||||
virtual ~Result(){};
|
||||
|
||||
protected:
|
||||
void init(const Job &job);
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("ShaderCompiler:Result")
|
||||
#endif
|
||||
};
|
||||
|
||||
void init();
|
||||
void free();
|
||||
|
||||
} // namespace shader_compiler
|
Submodule release/scripts/addons updated: 4de1bcce5a...1c390038f6
@@ -158,7 +158,8 @@ enum {
|
||||
G_DEBUG_XR = (1 << 19), /* XR/OpenXR messages */
|
||||
G_DEBUG_XR_TIME = (1 << 20), /* XR/OpenXR timing messages */
|
||||
|
||||
G_DEBUG_GHOST = (1 << 21), /* Debug GHOST module. */
|
||||
G_DEBUG_GHOST = (1 << 21), /* Debug GHOST module. */
|
||||
G_DEBUG_VK_CONTEXT = (1 << 22), /* not a debug flag, TODO move it. */
|
||||
};
|
||||
|
||||
#define G_DEBUG_ALL \
|
||||
|
@@ -530,7 +530,7 @@ if(WITH_GTESTS)
|
||||
set(TEST_SRC
|
||||
tests/draw_testing.cc
|
||||
tests/shaders_test.cc
|
||||
|
||||
tests/performance_test.cc
|
||||
tests/draw_testing.hh
|
||||
)
|
||||
set(TEST_INC
|
||||
|
@@ -612,7 +612,7 @@ static void eevee_lightbake_context_enable(EEVEE_LightBake *lbake)
|
||||
if (lbake->gl_context) {
|
||||
DRW_opengl_render_context_enable(lbake->gl_context);
|
||||
if (lbake->gpu_context == NULL) {
|
||||
lbake->gpu_context = GPU_context_create(NULL);
|
||||
lbake->gpu_context = GPU_context_create(NULL, lbake->gl_context);
|
||||
}
|
||||
DRW_gpu_render_context_enable(lbake->gpu_context);
|
||||
}
|
||||
|
@@ -59,7 +59,7 @@ void main()
|
||||
{
|
||||
ivec2 tex_size = textureSize(cocBuffer, 0);
|
||||
|
||||
int t_id = gl_VertexID / 3; /* Triangle Id */
|
||||
int t_id = gl_VertexIndex / 3; /* Triangle Id */
|
||||
|
||||
/* Some math to get the target pixel. */
|
||||
ivec2 texelco = ivec2(t_id % spritePerRow, t_id / spritePerRow) * 2;
|
||||
@@ -118,7 +118,7 @@ void main()
|
||||
*/
|
||||
|
||||
/* Generate Triangle : less memory fetches from a VBO */
|
||||
int v_id = gl_VertexID % 3; /* Vertex Id */
|
||||
int v_id = gl_VertexIndex % 3; /* Vertex Id */
|
||||
gl_Position.x = float(v_id / 2) * extend - 1.0; /* int divisor round down */
|
||||
gl_Position.y = float(v_id % 2) * extend - 1.0;
|
||||
gl_Position.z = 0.0;
|
||||
|
@@ -30,8 +30,8 @@ const vec2 pos[6] = vec2[6](vec2(-1.0, -1.0),
|
||||
|
||||
void main()
|
||||
{
|
||||
pid = 1 + (gl_VertexID / 6); /* +1 for the world */
|
||||
int vert_id = gl_VertexID % 6;
|
||||
pid = 1 + (gl_VertexIndex / 6); /* +1 for the world */
|
||||
int vert_id = gl_VertexIndex % 6;
|
||||
|
||||
quadCoord = pos[vert_id];
|
||||
|
||||
|
@@ -23,8 +23,8 @@ const vec2 pos[6] = vec2[6](vec2(-1.0, -1.0),
|
||||
|
||||
void main()
|
||||
{
|
||||
int cell_id = gl_VertexID / 6;
|
||||
int vert_id = gl_VertexID % 6;
|
||||
int cell_id = gl_VertexIndex / 6;
|
||||
int vert_id = gl_VertexIndex % 6;
|
||||
|
||||
vec3 ls_cell_location;
|
||||
/* Keep in sync with update_irradiance_probe */
|
||||
|
@@ -4,9 +4,9 @@ out vec2 vPos;
|
||||
|
||||
void main()
|
||||
{
|
||||
int v = gl_VertexID % 3;
|
||||
int v = gl_VertexIndex % 3;
|
||||
vPos.x = -1.0 + float((v & 1) << 2);
|
||||
vPos.y = -1.0 + float((v & 2) << 1);
|
||||
|
||||
instance = gl_VertexID / 3;
|
||||
instance = gl_VertexIndex / 3;
|
||||
}
|
||||
|
@@ -8,8 +8,8 @@ RESOURCE_ID_VARYING
|
||||
void main()
|
||||
{
|
||||
/* Generate Triangle : less memory fetches from a VBO */
|
||||
int v_id = gl_VertexID % 3; /* Vertex Id */
|
||||
int t_id = gl_VertexID / 3; /* Triangle Id */
|
||||
int v_id = gl_VertexIndex % 3; /* Vertex Id */
|
||||
int t_id = gl_VertexIndex / 3; /* Triangle Id */
|
||||
|
||||
/* Crappy diagram
|
||||
* ex 1
|
||||
|
@@ -5,7 +5,7 @@ out vec4 offset[3];
|
||||
|
||||
void main()
|
||||
{
|
||||
int v = gl_VertexID % 3;
|
||||
int v = gl_VertexIndex % 3;
|
||||
float x = -1.0 + float((v & 1) << 2);
|
||||
float y = -1.0 + float((v & 2) << 1);
|
||||
gl_Position = vec4(x, y, 1.0, 1.0);
|
||||
|
@@ -245,7 +245,7 @@ in vec4 col1;
|
||||
in vec4 col2;
|
||||
in vec4 fcol1;
|
||||
/* WARNING: Max attribute count is actually 14 because OSX OpenGL implementation
|
||||
* considers gl_VertexID and gl_InstanceID as vertex attribute. (see T74536) */
|
||||
* considers gl_VertexIndex and gl_InstanceID as vertex attribute. (see T74536) */
|
||||
# define stroke_id1 ma1.y
|
||||
# define point_id1 ma1.z
|
||||
# define thickness1 pos1.w
|
||||
@@ -408,8 +408,8 @@ void stroke_vertex()
|
||||
mat4 model_mat = model_matrix_get();
|
||||
|
||||
/* Avoid using a vertex attribute for quad positioning. */
|
||||
float x = float(gl_VertexID & 1) * 2.0 - 1.0; /* [-1..1] */
|
||||
float y = float(gl_VertexID & 2) - 1.0; /* [-1..1] */
|
||||
float x = float(gl_VertexIndex & 1) * 2.0 - 1.0; /* [-1..1] */
|
||||
float y = float(gl_VertexIndex & 2) - 1.0; /* [-1..1] */
|
||||
|
||||
bool use_curr = is_dot || (x == -1.0);
|
||||
|
||||
|
@@ -4,7 +4,7 @@ uniform vec4 gpModelMatrix[4];
|
||||
void main()
|
||||
{
|
||||
mat4 model_matrix = mat4(gpModelMatrix[0], gpModelMatrix[1], gpModelMatrix[2], gpModelMatrix[3]);
|
||||
int v = gl_VertexID % 3;
|
||||
int v = gl_VertexIndex % 3;
|
||||
float x = -1.0 + float((v & 1) << 2);
|
||||
float y = -1.0 + float((v & 2) << 1);
|
||||
gl_Position = ViewProjectionMatrix * (model_matrix * vec4(x, y, 0.0, 1.0));
|
||||
|
@@ -3,7 +3,7 @@ out vec2 uvs;
|
||||
|
||||
void main()
|
||||
{
|
||||
int v = gl_VertexID % 3;
|
||||
int v = gl_VertexIndex % 3;
|
||||
float x = float((v & 1) << 2);
|
||||
float y = float((v & 2) << 1);
|
||||
gl_Position = vec4(x - 1.0, y - 1.0, 1.0, 1.0);
|
||||
|
@@ -3,7 +3,7 @@ uniform vec3 boundbox[8];
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 world_pos = boundbox[gl_VertexID];
|
||||
vec3 world_pos = boundbox[gl_VertexIndex];
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
/* Result in a position at 1.0 (far plane). Small epsilon to avoid precision issue.
|
||||
|
@@ -16,7 +16,7 @@ void main()
|
||||
|
||||
float flip = (gl_InstanceID != 0) ? -1.0 : 1.0;
|
||||
|
||||
if (gl_VertexID % 2 == 0) {
|
||||
if (gl_VertexIndex % 2 == 0) {
|
||||
final_pos += normalSize * rad * (flip * nor - tan);
|
||||
}
|
||||
|
||||
|
@@ -14,8 +14,8 @@ void main()
|
||||
GPU_INTEL_VERTEX_SHADER_WORKAROUND
|
||||
|
||||
vec2 pos;
|
||||
pos.x = float(gl_VertexID % 2);
|
||||
pos.y = float(gl_VertexID / 2) / float(halfLineCount - 1);
|
||||
pos.x = float(gl_VertexIndex % 2);
|
||||
pos.y = float(gl_VertexIndex / 2) / float(halfLineCount - 1);
|
||||
|
||||
if (pos.y > 1.0) {
|
||||
pos.xy = pos.yx;
|
||||
|
@@ -17,7 +17,7 @@ void main()
|
||||
vec4 pos_4d = ModelMatrix * vec4(local_pos + screen_pos, 1.0);
|
||||
gl_Position = ViewProjectionMatrix * pos_4d;
|
||||
/* Manual stipple: one segment out of 2 is transparent. */
|
||||
finalColor = ((gl_VertexID & 1) == 0) ? colorSkinRoot : vec4(0.0);
|
||||
finalColor = ((gl_VertexIndex & 1) == 0) ? colorSkinRoot : vec4(0.0);
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(pos_4d.xyz);
|
||||
|
@@ -37,9 +37,9 @@ void main()
|
||||
|
||||
vec3 ls_cell_location;
|
||||
/* Keep in sync with update_irradiance_probe */
|
||||
ls_cell_location.z = float(gl_VertexID % grid_resolution.z);
|
||||
ls_cell_location.y = float((gl_VertexID / grid_resolution.z) % grid_resolution.y);
|
||||
ls_cell_location.x = float(gl_VertexID / (grid_resolution.z * grid_resolution.y));
|
||||
ls_cell_location.z = float(gl_VertexIndex % grid_resolution.z);
|
||||
ls_cell_location.y = float((gl_VertexIndex / grid_resolution.z) % grid_resolution.y);
|
||||
ls_cell_location.x = float(gl_VertexIndex / (grid_resolution.z * grid_resolution.y));
|
||||
|
||||
ls_cell_location += 0.5;
|
||||
ls_cell_location /= vec3(grid_resolution);
|
||||
|
@@ -225,7 +225,7 @@ void main()
|
||||
/* HACK: to avoid losing sub-pixel object in selections, we add a bit of randomness to the
|
||||
* wire to at least create one fragment that will pass the occlusion query. */
|
||||
/* TODO(fclem): Limit this workaround to selection. It's not very noticeable but still... */
|
||||
gl_Position.xy += sizeViewportInv.xy * gl_Position.w * ((gl_VertexID % 2 == 0) ? -1.0 : 1.0);
|
||||
gl_Position.xy += sizeViewportInv.xy * gl_Position.w * ((gl_VertexIndex % 2 == 0) ? -1.0 : 1.0);
|
||||
#endif
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
|
@@ -21,7 +21,7 @@ void main()
|
||||
/* HACK: to avoid losing sub-pixel object in selections, we add a bit of randomness to the
|
||||
* wire to at least create one fragment that will pass the occlusion query. */
|
||||
/* TODO(fclem): Limit this workaround to selection. It's not very noticeable but still... */
|
||||
gl_Position.xy += sizeViewportInv.xy * gl_Position.w * ((gl_VertexID % 2 == 0) ? -1.0 : 1.0);
|
||||
gl_Position.xy += sizeViewportInv.xy * gl_Position.w * ((gl_VertexIndex % 2 == 0) ? -1.0 : 1.0);
|
||||
#endif
|
||||
|
||||
stipple_coord = stipple_start = screen_position(gl_Position);
|
||||
|
@@ -28,7 +28,7 @@ void main()
|
||||
|
||||
ssPos = proj(gl_Position);
|
||||
|
||||
int frame = gl_VertexID + cacheStart;
|
||||
int frame = gl_VertexIndex + cacheStart;
|
||||
|
||||
float intensity; /* how faint */
|
||||
|
||||
|
@@ -21,14 +21,14 @@ void main()
|
||||
gl_Position = ViewProjectionMatrix * vec4(pos, 1.0);
|
||||
gl_PointSize = float(pointSize + 2);
|
||||
|
||||
int frame = gl_VertexID + cacheStart;
|
||||
int frame = gl_VertexIndex + cacheStart;
|
||||
bool use_custom_color = customColor.x >= 0.0;
|
||||
finalColor = (use_custom_color) ? vec4(customColor, 1.0) : vec4(1.0);
|
||||
|
||||
/* Bias to reduce z fighting with the path */
|
||||
gl_Position.z -= 1e-4;
|
||||
|
||||
if (gl_VertexID % stepSize == 0) {
|
||||
if (gl_VertexIndex % stepSize == 0) {
|
||||
gl_PointSize = float(pointSize) + 4;
|
||||
}
|
||||
|
||||
|
@@ -61,7 +61,7 @@ vec4 flag_to_color(uint flag)
|
||||
|
||||
void main()
|
||||
{
|
||||
int cell = gl_VertexID / 8;
|
||||
int cell = gl_VertexIndex / 8;
|
||||
mat3 rot_mat = mat3(0.0);
|
||||
|
||||
vec3 cell_offset = vec3(0.5);
|
||||
@@ -113,7 +113,7 @@ void main()
|
||||
#endif
|
||||
|
||||
vec3 pos = domainOriginOffset + cellSize * (vec3(cell_co + adaptiveCellOffset) + cell_offset);
|
||||
vec3 rotated_pos = rot_mat * corners[indices[gl_VertexID % 8]];
|
||||
vec3 rotated_pos = rot_mat * corners[indices[gl_VertexIndex % 8]];
|
||||
pos += rotated_pos * cellSize;
|
||||
|
||||
vec3 world_pos = point_object_to_world(pos);
|
||||
|
@@ -118,11 +118,11 @@ vec3 get_vector_mac(ivec3 cell_co)
|
||||
void main()
|
||||
{
|
||||
#ifdef USE_NEEDLE
|
||||
int cell = gl_VertexID / 12;
|
||||
int cell = gl_VertexIndex / 12;
|
||||
#elif defined(USE_MAC)
|
||||
int cell = gl_VertexID / 6;
|
||||
int cell = gl_VertexIndex / 6;
|
||||
#else
|
||||
int cell = gl_VertexID / 2;
|
||||
int cell = gl_VertexIndex / 2;
|
||||
#endif
|
||||
|
||||
ivec3 volume_size = textureSize(velocityX, 0);
|
||||
@@ -156,7 +156,7 @@ void main()
|
||||
vec3 color;
|
||||
vector = (isCellCentered) ? get_vector_mac(cell_co) : get_vector(cell_co);
|
||||
|
||||
switch (gl_VertexID % 6) {
|
||||
switch (gl_VertexIndex % 6) {
|
||||
case 0: /* Tail of X component. */
|
||||
pos.x += (drawMACX) ? -0.5 * cellSize.x : 0.0;
|
||||
color = vec3(1.0, 0.0, 0.0); /* red */
|
||||
@@ -201,12 +201,12 @@ void main()
|
||||
mat3 rot_mat = rotation_from_vector(vector);
|
||||
|
||||
# ifdef USE_NEEDLE
|
||||
vec3 rotated_pos = rot_mat * corners[indices[gl_VertexID % 12]];
|
||||
vec3 rotated_pos = rot_mat * corners[indices[gl_VertexIndex % 12]];
|
||||
pos += rotated_pos * vector_length * displaySize * cellSize;
|
||||
# else
|
||||
vec3 rotated_pos = rot_mat * vec3(0.0, 0.0, 1.0);
|
||||
pos += ((gl_VertexID % 2) == 1) ? rotated_pos * vector_length * displaySize * cellSize :
|
||||
vec3(0.0);
|
||||
pos += ((gl_VertexIndex % 2) == 1) ? rotated_pos * vector_length * displaySize * cellSize :
|
||||
vec3(0.0);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
@@ -156,7 +156,7 @@ void main()
|
||||
#ifdef SELECT_EDGES
|
||||
/* HACK: to avoid losing sub-pixel object in selections, we add a bit of randomness to the
|
||||
* wire to at least create one fragment that will pass the occlusion query. */
|
||||
gl_Position.xy += sizeViewportInv.xy * gl_Position.w * ((gl_VertexID % 2 == 0) ? -1.0 : 1.0);
|
||||
gl_Position.xy += sizeViewportInv.xy * gl_Position.w * ((gl_VertexIndex % 2 == 0) ? -1.0 : 1.0);
|
||||
#endif
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
|
@@ -5,7 +5,7 @@ out vec4 offset[3];
|
||||
|
||||
void main()
|
||||
{
|
||||
int v = gl_VertexID % 3;
|
||||
int v = gl_VertexIndex % 3;
|
||||
float x = -1.0 + float((v & 1) << 2);
|
||||
float y = -1.0 + float((v & 2) << 1);
|
||||
gl_Position = vec4(x, y, 1.0, 1.0);
|
||||
|
@@ -22,6 +22,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BKE_mesh_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct GPUBatch;
|
||||
struct GPUIndexBuf;
|
||||
struct GPUMaterial;
|
||||
@@ -41,12 +47,6 @@ struct PointCloud;
|
||||
struct Volume;
|
||||
struct bGPdata;
|
||||
|
||||
#include "BKE_mesh_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Expose via BKE callbacks */
|
||||
void DRW_mball_batch_cache_dirty_tag(struct MetaBall *mb, int mode);
|
||||
void DRW_mball_batch_cache_validate(struct MetaBall *mb);
|
||||
|
@@ -3108,7 +3108,7 @@ void DRW_opengl_context_create(void)
|
||||
DST.gl_context = WM_opengl_context_create();
|
||||
WM_opengl_context_activate(DST.gl_context);
|
||||
/* Be sure to create gpu_context too. */
|
||||
DST.gpu_context = GPU_context_create(NULL);
|
||||
DST.gpu_context = GPU_context_create(NULL, DST.gl_context);
|
||||
/* So we activate the window's one afterwards. */
|
||||
wm_window_reset_drawable();
|
||||
}
|
||||
|
@@ -1299,6 +1299,7 @@ static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader)
|
||||
shgroup, view_ubo_location, DRW_UNIFORM_BLOCK, G_draw.view_ubo, 0, 0, 1);
|
||||
}
|
||||
|
||||
#ifndef WITH_VULKAN /* This is needed until we have proper shader interfaces for vulkan. */
|
||||
/* Not supported. */
|
||||
BLI_assert(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MODELVIEW_INV) == -1);
|
||||
BLI_assert(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MODELVIEW) == -1);
|
||||
@@ -1311,6 +1312,7 @@ static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader)
|
||||
BLI_assert(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_PROJECTION_INV) == -1);
|
||||
BLI_assert(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_CLIPPLANES) == -1);
|
||||
BLI_assert(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MVP) == -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static DRWShadingGroup *drw_shgroup_create_ex(struct GPUShader *shader, DRWPass *pass)
|
||||
|
@@ -265,7 +265,7 @@ static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred)
|
||||
}
|
||||
else {
|
||||
comp->gl_context = WM_opengl_context_create();
|
||||
comp->gpu_context = GPU_context_create(NULL);
|
||||
comp->gpu_context = GPU_context_create(NULL, comp->gl_context);
|
||||
GPU_context_active_set(NULL);
|
||||
|
||||
WM_opengl_context_activate(DST.gl_context);
|
||||
|
@@ -3,7 +3,7 @@ out vec4 uvcoordsvar;
|
||||
|
||||
void main()
|
||||
{
|
||||
int v = gl_VertexID % 3;
|
||||
int v = gl_VertexIndex % 3;
|
||||
float x = -1.0 + float((v & 1) << 2);
|
||||
float y = -1.0 + float((v & 2) << 1);
|
||||
gl_Position = vec4(x, y, 1.0, 1.0);
|
||||
|
@@ -126,12 +126,12 @@ void hair_get_interp_attrs(
|
||||
|
||||
int hair_get_strand_id(void)
|
||||
{
|
||||
return gl_VertexID / (hairStrandsRes * hairThicknessRes);
|
||||
return gl_VertexIndex / (hairStrandsRes * hairThicknessRes);
|
||||
}
|
||||
|
||||
int hair_get_base_id(void)
|
||||
{
|
||||
return gl_VertexID / hairThicknessRes;
|
||||
return gl_VertexIndex / hairThicknessRes;
|
||||
}
|
||||
|
||||
/* Copied from cycles. */
|
||||
@@ -199,7 +199,7 @@ void hair_get_pos_tan_binor_time(bool is_persp,
|
||||
thickness = hair_shaperadius(hairRadShape, hairRadRoot, hairRadTip, time);
|
||||
|
||||
if (hairThicknessRes > 1) {
|
||||
thick_time = float(gl_VertexID % hairThicknessRes) / float(hairThicknessRes - 1);
|
||||
thick_time = float(gl_VertexIndex % hairThicknessRes) / float(hairThicknessRes - 1);
|
||||
thick_time = thickness * (thick_time * 2.0 - 1.0);
|
||||
|
||||
/* Take object scale into account.
|
||||
|
@@ -19,7 +19,7 @@ void main(void)
|
||||
finalColor = hair_interp_data(data0, data1, data2, data3, weights);
|
||||
|
||||
#ifdef TF_WORKAROUND
|
||||
int id = gl_VertexID - idOffset;
|
||||
int id = gl_VertexIndex - idOffset;
|
||||
gl_Position.x = ((float(id % targetWidth) + 0.5) / float(targetWidth)) * 2.0 - 1.0;
|
||||
gl_Position.y = ((float(id / targetWidth) + 0.5) / float(targetHeight)) * 2.0 - 1.0;
|
||||
gl_Position.z = 0.0;
|
||||
|
@@ -201,10 +201,10 @@ uniform mat4 ModelMatrixInverse;
|
||||
#define point_world_to_object(p) ((ModelMatrixInverse * vec4(p, 1.0)).xyz)
|
||||
#define point_world_to_view(p) ((ViewMatrix * vec4(p, 1.0)).xyz)
|
||||
|
||||
/* Due to some shader compiler bug, we somewhat need to access gl_VertexID
|
||||
/* Due to some shader compiler bug, we somewhat need to access gl_VertexIndex
|
||||
* to make vertex shaders work. even if it's actually dead code. */
|
||||
#ifdef GPU_INTEL
|
||||
# define GPU_INTEL_VERTEX_SHADER_WORKAROUND gl_Position.x = float(gl_VertexID);
|
||||
# define GPU_INTEL_VERTEX_SHADER_WORKAROUND gl_Position.x = float(gl_VertexIndex);
|
||||
#else
|
||||
# define GPU_INTEL_VERTEX_SHADER_WORKAROUND
|
||||
#endif
|
||||
|
@@ -4,6 +4,12 @@
|
||||
|
||||
#include "GPU_shader.h"
|
||||
|
||||
#include "IMB_imbuf.h"
|
||||
|
||||
#include "BKE_appdir.h"
|
||||
#include "BKE_idtype.h"
|
||||
|
||||
#include "DRW_engine.h"
|
||||
#include "draw_manager_testing.h"
|
||||
|
||||
namespace blender::draw {
|
||||
@@ -12,7 +18,25 @@ namespace blender::draw {
|
||||
void DrawOpenGLTest::SetUp()
|
||||
{
|
||||
GPUOpenGLTest::SetUp();
|
||||
|
||||
/* Initialize color management. Required to construct a scene creation depends on it. */
|
||||
BKE_idtype_init();
|
||||
BKE_appdir_init();
|
||||
IMB_init();
|
||||
|
||||
DRW_engines_register();
|
||||
|
||||
DRW_draw_state_init_gtests(GPU_SHADER_CFG_DEFAULT);
|
||||
}
|
||||
|
||||
void DrawOpenGLTest::TearDown()
|
||||
{
|
||||
DRW_engines_free();
|
||||
|
||||
IMB_exit();
|
||||
BKE_appdir_exit();
|
||||
|
||||
GPUTest::TearDown();
|
||||
}
|
||||
|
||||
} // namespace blender::draw
|
||||
|
@@ -8,6 +8,7 @@ namespace blender::draw {
|
||||
class DrawOpenGLTest : public blender::gpu::GPUOpenGLTest {
|
||||
public:
|
||||
void SetUp() override;
|
||||
void TearDown() override;
|
||||
};
|
||||
|
||||
#define DRAW_TEST(test_name) \
|
||||
|
223
source/blender/draw/tests/performance_test.cc
Normal file
223
source/blender/draw/tests/performance_test.cc
Normal file
@@ -0,0 +1,223 @@
|
||||
/* Apache License, Version 2.0 */
|
||||
|
||||
#include "testing/testing.h"
|
||||
|
||||
#include "draw_testing.hh"
|
||||
#include "intern/draw_manager_testing.h"
|
||||
|
||||
#include "DRW_engine.h"
|
||||
#include "draw_cache_impl.h"
|
||||
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_mesh_wrapper.h"
|
||||
#include "BKE_scene.h"
|
||||
|
||||
#include "BLI_rand.hh"
|
||||
#include "BLI_task.h"
|
||||
|
||||
#include "ED_mesh.h"
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "GPU_context.h"
|
||||
#include "GPU_init_exit.h"
|
||||
#include "GPU_shader.h"
|
||||
|
||||
#include "engines/eevee/eevee_private.h"
|
||||
#include "engines/gpencil/gpencil_engine.h"
|
||||
#include "engines/image/image_private.hh"
|
||||
#include "engines/overlay/overlay_private.h"
|
||||
#include "engines/workbench/workbench_private.h"
|
||||
|
||||
namespace blender::draw {
|
||||
|
||||
/**
|
||||
* During investigation or executing in a profiler it is handly to disable multithreading. This can
|
||||
* be done by setting RUN_SINGLE_THREADED to true.
|
||||
*
|
||||
* Default(false) => run multithreaded
|
||||
*/
|
||||
constexpr bool RUN_SINGLE_THREADED = false;
|
||||
|
||||
class DrawCacheTest : public DrawOpenGLTest {
|
||||
protected:
|
||||
TaskGraph *task_graph;
|
||||
|
||||
public:
|
||||
void SetUp() override
|
||||
{
|
||||
DrawOpenGLTest::SetUp();
|
||||
if (RUN_SINGLE_THREADED) {
|
||||
BLI_system_num_threads_override_set(1);
|
||||
}
|
||||
task_graph = BLI_task_graph_create();
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
BLI_task_graph_free(task_graph);
|
||||
if (RUN_SINGLE_THREADED) {
|
||||
BLI_system_num_threads_override_set(0);
|
||||
}
|
||||
DrawOpenGLTest::TearDown();
|
||||
}
|
||||
};
|
||||
|
||||
class DrawCachePerformanceTest : public DrawCacheTest {
|
||||
protected:
|
||||
Scene scene = {{nullptr}};
|
||||
Object ob_mesh = {{nullptr}};
|
||||
Mesh mesh = {{nullptr}};
|
||||
BMesh *bm = nullptr;
|
||||
RandomNumberGenerator rng;
|
||||
|
||||
public:
|
||||
void SetUp() override
|
||||
{
|
||||
DrawCacheTest::SetUp();
|
||||
IDType_ID_SCE.init_data(&scene.id);
|
||||
IDType_ID_OB.init_data(&ob_mesh.id);
|
||||
IDType_ID_ME.init_data(&mesh.id);
|
||||
ob_mesh.type = OB_MESH;
|
||||
ob_mesh.data = &mesh;
|
||||
EDBM_mesh_make(&ob_mesh, SCE_SELECT_VERTEX, false);
|
||||
bm = mesh.edit_mesh->bm;
|
||||
|
||||
/* Ensure batch cache is available. */
|
||||
DRW_mesh_batch_cache_validate(&mesh);
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
EDBM_mesh_free_data(mesh.edit_mesh);
|
||||
bm = nullptr;
|
||||
IDType_ID_ME.free_data(&mesh.id);
|
||||
IDType_ID_OB.free_data(&ob_mesh.id);
|
||||
IDType_ID_SCE.free_data(&scene.id);
|
||||
DrawCacheTest::TearDown();
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Build a test mesh with given number of polygons.
|
||||
* Each polygon is created from 3 random generated verts.
|
||||
*/
|
||||
void build_mesh(size_t num_polygons)
|
||||
{
|
||||
add_polygons_to_bm(num_polygons);
|
||||
|
||||
/* Make sure mesh_eval_final is up to date (inline depsgraph evaluation). See
|
||||
* `editbmesh_calc_modifiers`. */
|
||||
mesh.edit_mesh->mesh_eval_final = BKE_mesh_from_bmesh_for_eval_nomain(
|
||||
mesh.edit_mesh->bm, nullptr, &mesh);
|
||||
mesh.edit_mesh->mesh_eval_cage = BKE_mesh_wrapper_from_editmesh_with_coords(
|
||||
mesh.edit_mesh, nullptr, nullptr, &mesh);
|
||||
|
||||
BKE_editmesh_looptri_calc(mesh.edit_mesh);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given GPUBatch is filled.
|
||||
*/
|
||||
void expect_filled(GPUBatch *batch)
|
||||
{
|
||||
EXPECT_NE(batch->elem, nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given GPUBatch is filled.
|
||||
*/
|
||||
void expect_empty(GPUBatch *batch)
|
||||
{
|
||||
EXPECT_EQ(batch->elem, nullptr);
|
||||
for (int i = 0; i < GPU_BATCH_VBO_MAX_LEN; i++) {
|
||||
EXPECT_EQ(batch->verts[i], nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Create a new random vert in BMesh.
|
||||
*/
|
||||
BMVert *add_random_vert_to_bm()
|
||||
{
|
||||
float co[3] = {(rng.get_float() - 0.5f) * 10.0f,
|
||||
(rng.get_float() - 0.5f) * 10.0f,
|
||||
(rng.get_float() - 0.5f) * 10.0f};
|
||||
BMVert *result = BM_vert_create(bm, co, nullptr, BM_CREATE_NOP);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add `num_polygons` polygons to the BMesh.
|
||||
*/
|
||||
void add_polygons_to_bm(size_t num_polygons)
|
||||
{
|
||||
/* Use 3 verts per face to skip triangulation. */
|
||||
const int verts_per_face = 3;
|
||||
|
||||
for (int i = 0; i < num_polygons; i++) {
|
||||
BMVert *verts[verts_per_face];
|
||||
for (int j = 0; j < verts_per_face; j++) {
|
||||
verts[j] = add_random_vert_to_bm();
|
||||
}
|
||||
BM_face_create_verts(bm, verts, verts_per_face, nullptr, BM_CREATE_NOP, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Base line benchmark simulating edit mesh vertice transform of a large mesh.
|
||||
*
|
||||
* In Blender 2.93 the whole cache would be freed so the baseline is to recalculate
|
||||
* all needed caches.
|
||||
*/
|
||||
TEST_F(DrawCachePerformanceTest, edit_mesh_performance_baseline_293)
|
||||
{
|
||||
/* Approximates a subdivided cube 7 times in faces. */
|
||||
const int num_polygons = 100000;
|
||||
const int num_benchmark_loops = 32;
|
||||
/* Create a bmesh object in edit mode. */
|
||||
build_mesh(num_polygons);
|
||||
|
||||
for (int i = 0; i < num_benchmark_loops; i++) {
|
||||
/* Invalidate caches.
|
||||
* In reality the mesh gets a copy on write signal and frees the cache (mesh_data_free). */
|
||||
BKE_mesh_batch_cache_dirty_tag_cb(&mesh, BKE_MESH_BATCH_DIRTY_ALL);
|
||||
DRW_mesh_batch_cache_validate(&mesh);
|
||||
|
||||
/* Request caches. */
|
||||
GPUBatch *batch_triangles = DRW_mesh_batch_cache_get_edit_triangles(&mesh);
|
||||
GPUBatch *batch_vertices = DRW_mesh_batch_cache_get_edit_vertices(&mesh);
|
||||
GPUBatch *batch_edges = DRW_mesh_batch_cache_get_edit_edges(&mesh);
|
||||
GPUBatch *batch_vnors = DRW_mesh_batch_cache_get_edit_vnors(&mesh);
|
||||
GPUBatch *batch_lnors = DRW_mesh_batch_cache_get_edit_lnors(&mesh);
|
||||
GPUBatch *batch_facedots = DRW_mesh_batch_cache_get_edit_facedots(&mesh);
|
||||
|
||||
/* Check if caches are empty. */
|
||||
expect_empty(batch_triangles);
|
||||
expect_empty(batch_vertices);
|
||||
expect_empty(batch_edges);
|
||||
expect_empty(batch_vnors);
|
||||
expect_empty(batch_lnors);
|
||||
expect_empty(batch_facedots);
|
||||
|
||||
/* Update caches. */
|
||||
DRW_mesh_batch_cache_create_requested(task_graph, &ob_mesh, &mesh, &scene, false, true);
|
||||
BLI_task_graph_work_and_wait(task_graph);
|
||||
|
||||
/* Check if caches are filled. */
|
||||
expect_filled(batch_triangles);
|
||||
expect_filled(batch_vertices);
|
||||
expect_filled(batch_edges);
|
||||
expect_filled(batch_vnors);
|
||||
expect_filled(batch_lnors);
|
||||
expect_filled(batch_facedots);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::draw
|
@@ -162,6 +162,7 @@ DRAW_TEST(workbench_glsl_shaders)
|
||||
|
||||
static void test_gpencil_glsl_shaders()
|
||||
{
|
||||
|
||||
EXPECT_NE(GPENCIL_shader_antialiasing(0), nullptr);
|
||||
EXPECT_NE(GPENCIL_shader_antialiasing(1), nullptr);
|
||||
EXPECT_NE(GPENCIL_shader_antialiasing(2), nullptr);
|
||||
@@ -185,6 +186,7 @@ DRAW_TEST(gpencil_glsl_shaders)
|
||||
|
||||
static void test_image_glsl_shaders()
|
||||
{
|
||||
|
||||
IMAGE_shader_library_ensure();
|
||||
|
||||
EXPECT_NE(IMAGE_shader_image_get(false), nullptr);
|
||||
@@ -289,7 +291,7 @@ static void test_overlay_glsl_shaders()
|
||||
}
|
||||
DRAW_TEST(overlay_glsl_shaders)
|
||||
|
||||
static void test_eevee_glsl_shaders_static()
|
||||
static void test_eevee_glsl_shaders()
|
||||
{
|
||||
EEVEE_shaders_material_shaders_init();
|
||||
|
||||
@@ -378,7 +380,7 @@ static void test_eevee_glsl_shaders_static()
|
||||
EXPECT_NE(EEVEE_shaders_effect_reflection_resolve_sh_get(), nullptr);
|
||||
EEVEE_shaders_free();
|
||||
}
|
||||
DRAW_TEST(eevee_glsl_shaders_static)
|
||||
DRAW_TEST(eevee_glsl_shaders)
|
||||
|
||||
static void test_draw_shaders(eParticleRefineShaderType sh_type)
|
||||
{
|
||||
|
@@ -30,6 +30,7 @@ set(INC
|
||||
.
|
||||
intern
|
||||
opengl
|
||||
vulkan
|
||||
../blenkernel
|
||||
../blenlib
|
||||
../bmesh
|
||||
@@ -191,6 +192,49 @@ set(LIB
|
||||
${BLENDER_GL_LIBRARIES}
|
||||
)
|
||||
|
||||
if(WITH_VULKAN)
|
||||
list(APPEND INC_SYS
|
||||
${Vulkan_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
list(APPEND LIB
|
||||
extern_vulkan_memory_allocator
|
||||
bf_intern_shadercompiler
|
||||
${SHADERC_LIBRARIES}
|
||||
)
|
||||
|
||||
list(APPEND INC
|
||||
../../../extern/vulkan_memory_allocator
|
||||
../../../intern/shader_compiler
|
||||
|
||||
)
|
||||
|
||||
list(APPEND SRC
|
||||
vulkan/vk_backend.cc
|
||||
vulkan/vk_context.cc
|
||||
vulkan/vk_framebuffer.cc
|
||||
vulkan/vk_texture.cc
|
||||
vulkan/vk_shader_log.cc
|
||||
vulkan/vk_shader.cc
|
||||
|
||||
vulkan/vk_backend.hh
|
||||
vulkan/vk_batch.hh
|
||||
vulkan/vk_context.hh
|
||||
vulkan/vk_drawlist.hh
|
||||
vulkan/vk_framebuffer.hh
|
||||
vulkan/vk_immediate.hh
|
||||
vulkan/vk_index_buffer.hh
|
||||
vulkan/vk_primitive.hh
|
||||
vulkan/vk_query.hh
|
||||
vulkan/vk_shader_interface.hh
|
||||
vulkan/vk_shader.hh
|
||||
vulkan/vk_state.hh
|
||||
vulkan/vk_texture.hh
|
||||
vulkan/vk_uniform_buffer.hh
|
||||
vulkan/vk_vertex_buffer.hh
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT WITH_SYSTEM_GLEW)
|
||||
list(APPEND LIB
|
||||
${BLENDER_GLEW_LIBRARIES}
|
||||
@@ -391,6 +435,12 @@ endif()
|
||||
|
||||
blender_add_lib(bf_gpu "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
target_compile_options(bf_gpu
|
||||
PRIVATE "-Wno-nullability-completeness"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CXX_WARN_NO_SUGGEST_OVERRIDE)
|
||||
target_compile_options(bf_gpu PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-Wsuggest-override>)
|
||||
endif()
|
||||
@@ -399,8 +449,8 @@ if(WITH_GTESTS)
|
||||
if(WITH_OPENGL_DRAW_TESTS)
|
||||
set(TEST_SRC
|
||||
tests/gpu_testing.cc
|
||||
|
||||
tests/gpu_index_buffer_test.cc
|
||||
tests/gpu_shader_compiler_test.cc
|
||||
tests/gpu_shader_builtin_test.cc
|
||||
tests/gpu_shader_test.cc
|
||||
|
||||
@@ -408,10 +458,11 @@ if(WITH_GTESTS)
|
||||
)
|
||||
set(TEST_INC
|
||||
"../../../intern/ghost/"
|
||||
"../../../intern/shader_compiler/"
|
||||
)
|
||||
set(TEST_LIB
|
||||
|
||||
)
|
||||
|
||||
include(GTestTesting)
|
||||
blender_add_test_lib(bf_gpu_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
|
||||
endif()
|
||||
|
@@ -35,15 +35,20 @@ extern "C" {
|
||||
typedef enum eGPUBackendType {
|
||||
GPU_BACKEND_NONE = 0,
|
||||
GPU_BACKEND_OPENGL,
|
||||
#ifdef WITH_VULKAN
|
||||
GPU_BACKEND_VULKAN,
|
||||
#endif
|
||||
} eGPUBackendType;
|
||||
|
||||
void GPU_backend_init(eGPUBackendType backend);
|
||||
void GPU_backend_create(eGPUBackendType backend);
|
||||
void GPU_backend_exit(void);
|
||||
|
||||
/** Opaque type hiding blender::gpu::Context. */
|
||||
typedef struct GPUContext GPUContext;
|
||||
|
||||
GPUContext *GPU_context_create(void *ghost_window);
|
||||
/* Only one of them must be set. */
|
||||
/* TODO(fclem) clean this mess. */
|
||||
GPUContext *GPU_context_create(void *ghost_window, void *ghost_context);
|
||||
void GPU_context_discard(GPUContext *);
|
||||
|
||||
void GPU_context_active_set(GPUContext *);
|
||||
|
@@ -46,10 +46,12 @@ class GPUBackend {
|
||||
|
||||
static GPUBackend *get(void);
|
||||
|
||||
virtual void init() = 0;
|
||||
|
||||
virtual void samplers_update(void) = 0;
|
||||
virtual void compute_dispatch(int groups_x_len, int groups_y_len, int groups_z_len) = 0;
|
||||
|
||||
virtual Context *context_alloc(void *ghost_window) = 0;
|
||||
virtual Context *context_alloc(void *ghost_window, void *ghost_context) = 0;
|
||||
|
||||
virtual Batch *batch_alloc(void) = 0;
|
||||
virtual DrawList *drawlist_alloc(int list_length) = 0;
|
||||
|
@@ -34,6 +34,8 @@
|
||||
#include "BLI_assert.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_global.h"
|
||||
|
||||
#include "GPU_context.h"
|
||||
#include "GPU_framebuffer.h"
|
||||
|
||||
@@ -49,6 +51,11 @@
|
||||
# include "gl_context.hh"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_VULKAN
|
||||
# include "vk_backend.hh"
|
||||
# include "vk_context.hh"
|
||||
#endif
|
||||
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
@@ -96,16 +103,27 @@ Context *Context::get()
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
GPUContext *GPU_context_create(void *ghost_window)
|
||||
GPUContext *GPU_context_create(void *ghost_window, void *ghost_context)
|
||||
{
|
||||
bool backend_created = false;
|
||||
if (GPUBackend::get() == nullptr) {
|
||||
/* TODO: move where it make sense. */
|
||||
GPU_backend_init(GPU_BACKEND_OPENGL);
|
||||
/* FIXME We should get the context type from ghost instead of guessing it. */
|
||||
eGPUBackendType type = GPU_BACKEND_OPENGL;
|
||||
#ifdef WITH_VULKAN
|
||||
if (G.debug & G_DEBUG_VK_CONTEXT) {
|
||||
type = GPU_BACKEND_VULKAN;
|
||||
}
|
||||
#endif
|
||||
backend_created = true;
|
||||
GPU_backend_create(type);
|
||||
}
|
||||
|
||||
Context *ctx = GPUBackend::get()->context_alloc(ghost_window);
|
||||
|
||||
GPUBackend *backend = GPUBackend::get();
|
||||
Context *ctx = backend->context_alloc(ghost_window, ghost_context);
|
||||
GPU_context_active_set(wrap(ctx));
|
||||
|
||||
if (backend_created) {
|
||||
backend->init();
|
||||
}
|
||||
return wrap(ctx);
|
||||
}
|
||||
|
||||
@@ -164,15 +182,20 @@ void GPU_context_main_unlock(void)
|
||||
|
||||
static GPUBackend *g_backend;
|
||||
|
||||
void GPU_backend_init(eGPUBackendType backend_type)
|
||||
void GPU_backend_create(eGPUBackendType backend_type)
|
||||
{
|
||||
BLI_assert(g_backend == nullptr);
|
||||
|
||||
switch (backend_type) {
|
||||
#if WITH_OPENGL_BACKEND
|
||||
#ifdef WITH_OPENGL_BACKEND
|
||||
case GPU_BACKEND_OPENGL:
|
||||
g_backend = new GLBackend;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WITH_VULKAN
|
||||
case GPU_BACKEND_VULKAN:
|
||||
g_backend = new VKBackend;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
BLI_assert(0);
|
||||
|
@@ -47,7 +47,14 @@ class GLBackend : public GPUBackend {
|
||||
GLSharedOrphanLists shared_orphan_list_;
|
||||
|
||||
public:
|
||||
GLBackend()
|
||||
~GLBackend()
|
||||
{
|
||||
GLTexture::samplers_free();
|
||||
|
||||
GLBackend::platform_exit();
|
||||
}
|
||||
|
||||
void init() override
|
||||
{
|
||||
/* platform_init needs to go first. */
|
||||
GLBackend::platform_init();
|
||||
@@ -55,12 +62,6 @@ class GLBackend : public GPUBackend {
|
||||
GLBackend::capabilities_init();
|
||||
GLTexture::samplers_init();
|
||||
}
|
||||
~GLBackend()
|
||||
{
|
||||
GLTexture::samplers_free();
|
||||
|
||||
GLBackend::platform_exit();
|
||||
}
|
||||
|
||||
static GLBackend *get(void)
|
||||
{
|
||||
@@ -72,7 +73,7 @@ class GLBackend : public GPUBackend {
|
||||
GLTexture::samplers_update();
|
||||
};
|
||||
|
||||
Context *context_alloc(void *ghost_window) override
|
||||
Context *context_alloc(void *ghost_window, void *UNUSED(ghost_context)) override
|
||||
{
|
||||
return new GLContext(ghost_window, shared_orphan_list_);
|
||||
};
|
||||
|
@@ -109,6 +109,9 @@ static char *glsl_patch_default_get()
|
||||
STR_CONCATF(patch, slen, "#define DFDX_SIGN %1.1f\n", GLContext::derivative_signs[0]);
|
||||
STR_CONCATF(patch, slen, "#define DFDY_SIGN %1.1f\n", GLContext::derivative_signs[1]);
|
||||
|
||||
/* Converting Vulkan GLSL to OpenGL GLSL. */
|
||||
STR_CONCAT(patch, slen, "#define gl_VertexIndex gl_VertexID\n");
|
||||
|
||||
BLI_assert(slen < sizeof(patch));
|
||||
return patch;
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@ out vec2 uv;
|
||||
|
||||
void main()
|
||||
{
|
||||
int corner_id = (gl_VertexID / cornerLen) % 4;
|
||||
int corner_id = (gl_VertexIndex / cornerLen) % 4;
|
||||
|
||||
vec2 final_pos = pos * scale;
|
||||
|
||||
|
@@ -19,7 +19,7 @@ void main()
|
||||
vec4 tex = calls_data[gl_InstanceID * 3 + 1];
|
||||
finalColor = calls_data[gl_InstanceID * 3 + 2];
|
||||
|
||||
/* Use pos to select the right swizzle (instead of gl_VertexID)
|
||||
/* Use pos to select the right swizzle (instead of gl_VertexIndex)
|
||||
* in order to workaround an OSX driver bug. */
|
||||
if (pos == vec2(0.0, 0.0)) {
|
||||
rect.xy = rect.xz;
|
||||
|
@@ -13,15 +13,15 @@ void main()
|
||||
{
|
||||
vec2 uv;
|
||||
vec2 co;
|
||||
if (gl_VertexID == 0) {
|
||||
if (gl_VertexIndex == 0) {
|
||||
co = rect_geom.xy;
|
||||
uv = rect_icon.xy;
|
||||
}
|
||||
else if (gl_VertexID == 1) {
|
||||
else if (gl_VertexIndex == 1) {
|
||||
co = rect_geom.xw;
|
||||
uv = rect_icon.xw;
|
||||
}
|
||||
else if (gl_VertexID == 2) {
|
||||
else if (gl_VertexIndex == 2) {
|
||||
co = rect_geom.zw;
|
||||
uv = rect_icon.zw;
|
||||
}
|
||||
|
@@ -114,7 +114,7 @@ void main(void)
|
||||
float expand_dist = (uv.y * 2.0 - 1.0);
|
||||
colorGradient = expand_dist;
|
||||
|
||||
if (gl_VertexID < MID_VERTEX) {
|
||||
if (gl_VertexIndex < MID_VERTEX) {
|
||||
/* Shadow pass */
|
||||
finalColor = colShadow;
|
||||
}
|
||||
|
@@ -108,8 +108,8 @@ vec2 do_widget(void)
|
||||
|
||||
vec2 do_tria()
|
||||
{
|
||||
int vidx = gl_VertexID % 4;
|
||||
bool tria2 = gl_VertexID > 7;
|
||||
int vidx = gl_VertexIndex % 4;
|
||||
bool tria2 = gl_VertexIndex > 7;
|
||||
|
||||
vec2 pos;
|
||||
float size = (tria2) ? -tria2Size : tria1Size;
|
||||
@@ -204,7 +204,7 @@ vec2 do_tria()
|
||||
void main()
|
||||
{
|
||||
discardFac = discardFactor;
|
||||
bool is_tria = (gl_VertexID > 3);
|
||||
bool is_tria = (gl_VertexIndex > 3);
|
||||
vec2 pos = (is_tria) ? do_tria() : do_widget();
|
||||
|
||||
gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
|
||||
|
@@ -20,8 +20,8 @@ void main()
|
||||
interp_size = int(glyph_size.x < 0) + int(glyph_size.y < 0);
|
||||
|
||||
/* Quad expension using instanced rendering. */
|
||||
float x = float(gl_VertexID % 2);
|
||||
float y = float(gl_VertexID / 2);
|
||||
float x = float(gl_VertexIndex % 2);
|
||||
float y = float(gl_VertexIndex / 2);
|
||||
vec2 quad = vec2(x, y);
|
||||
|
||||
vec2 interp_offset = float(interp_size) / abs(pos.zw - pos.xy);
|
||||
|
@@ -88,7 +88,6 @@ static void test_shader_builtin()
|
||||
test_compile_builtin_shader(GPU_SHADER_2D_UV_FACES_STRETCH_AREA, GPU_SHADER_CFG_DEFAULT);
|
||||
test_compile_builtin_shader(GPU_SHADER_2D_UV_FACES_STRETCH_ANGLE, GPU_SHADER_CFG_DEFAULT);
|
||||
}
|
||||
|
||||
GPU_TEST(shader_builtin)
|
||||
|
||||
} // namespace blender::gpu::tests
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user