Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various gfx_api / shadow tweaks and fixes #3451

Merged
merged 14 commits into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions data/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ function(WZ_FETCH_PREBUILT_PACKAGE PACKAGE_URL PACKAGE_FILENAME PACKAGE_SHA512 O
endif()
endif()

# Check if file already exists at output path
if (EXISTS "${OUTPUT_PATH}")
file(SHA512 "${OUTPUT_PATH}" _dl_received_sha512)
if("${_dl_received_sha512}" STREQUAL "${PACKAGE_SHA512}")
message(STATUS "Found: Already downloaded prebuilt package: ${OUTPUT_PATH}, with hash: ${PACKAGE_SHA512}")
set(${STATUS} TRUE PARENT_SCOPE)
return()
endif()
endif()

# Try to download the prebuilt package
file(DOWNLOAD "${PACKAGE_URL}" "${OUTPUT_PATH}" INACTIVITY_TIMEOUT 60 SHOW_PROGRESS STATUS _dl_status TLS_VERIFY ON)
list(GET _dl_status 0 _dl_status_code)
Expand Down
4 changes: 2 additions & 2 deletions lib/ivis_opengl/gfx_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ bool gfx_api::context::initialize(const gfx_api::backend_Impl_Factory& impl, int
#if defined(WZ_VULKAN_ENABLED)
current_backend_context = new VkRoot(uses_gfx_debug);
#else
debug(LOG_FATAL, "Warzone was not compiled with the Vulkan backend enabled. Aborting.");
abort();
debug(LOG_FATAL, "Warzone 2100 was not compiled with support for the Vulkan backend.");
return false;
#endif
break;
}
Expand Down
2 changes: 2 additions & 0 deletions lib/ivis_opengl/gfx_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ namespace gfx_api
// (i.e. Don't re-use a buffer instance for different data in the same frame - use separate buffer instances.)
virtual void update(const size_t& start, const size_t& size, const void* data, const update_flag flag = update_flag::none) = 0;

virtual size_t current_buffer_size() = 0;

virtual void bind() = 0;

virtual ~buffer() {};
Expand Down
128 changes: 78 additions & 50 deletions lib/ivis_opengl/gfx_api_gl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,11 @@ void gl_buffer::update(const size_t & start, const size_t & size, const void * d
glBindBuffer(to_gl(usage), 0);
}

size_t gl_buffer::current_buffer_size()
{
return buffer_size;
}

// MARK: gl_pipeline_state_object

struct program_data
Expand Down Expand Up @@ -2267,16 +2272,16 @@ gfx_api::texture_array* gl_context::create_texture_array(const size_t& mipmap_co
gl_gpurendered_texture* gl_context::create_depthmap_texture(const size_t& layer_count, const size_t& width, const size_t& height, const std::string& filename)
{
GLenum depthInternalFormat = GL_DEPTH_COMPONENT32F;
return create_gpurendered_texture(depthInternalFormat, GL_DEPTH_COMPONENT, GL_FLOAT, width, height, layer_count, filename);
return create_gpurendered_texture_array(depthInternalFormat, GL_DEPTH_COMPONENT, GL_FLOAT, width, height, layer_count, filename);
}

gl_gpurendered_texture* gl_context::create_gpurendered_texture(GLenum internalFormat, GLenum format, GLenum type, const size_t& width, const size_t& height, const size_t& layer_count, const std::string& filename)
gl_gpurendered_texture* gl_context::create_gpurendered_texture(GLenum internalFormat, GLenum format, GLenum type, const size_t& width, const size_t& height, const std::string& filename)
{
ASSERT(width <= static_cast<size_t>(std::numeric_limits<GLsizei>::max()), "width (%zu) exceeds GLsizei max", width);
ASSERT(height <= static_cast<size_t>(std::numeric_limits<GLsizei>::max()), "height (%zu) exceeds GLsizei max", height);
auto* new_texture = new gl_gpurendered_texture();
new_texture->gles = gles;
new_texture->_isArray = (layer_count > 1);
new_texture->_isArray = false;
#if defined(WZ_DEBUG_GFX_API_LEAKS)
new_texture->debugName = filename;
#endif
Expand All @@ -2288,22 +2293,39 @@ gl_gpurendered_texture* gl_context::create_gpurendered_texture(GLenum internalFo
glObjectLabel(GL_TEXTURE, new_texture->id(), -1, filename.c_str());
}

if (!new_texture->isArray())
{
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, static_cast<GLsizei>(width), static_cast<GLsizei>(height), 0, format, type, nullptr);
}
else
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, static_cast<GLsizei>(width), static_cast<GLsizei>(height), 0, format, type, nullptr);

new_texture->unbind();
return new_texture;
}

gl_gpurendered_texture* gl_context::create_gpurendered_texture_array(GLenum internalFormat, GLenum format, GLenum type, const size_t& width, const size_t& height, const size_t& layer_count, const std::string& filename)
{
ASSERT(width <= static_cast<size_t>(std::numeric_limits<GLsizei>::max()), "width (%zu) exceeds GLsizei max", width);
ASSERT(height <= static_cast<size_t>(std::numeric_limits<GLsizei>::max()), "height (%zu) exceeds GLsizei max", height);
auto* new_texture = new gl_gpurendered_texture();
new_texture->gles = gles;
new_texture->_isArray = true;
#if defined(WZ_DEBUG_GFX_API_LEAKS)
new_texture->debugName = filename;
#endif
new_texture->bind();
glTexParameteri(new_texture->target(), GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(new_texture->target(), GL_TEXTURE_MAX_LEVEL, 0);
if (!filename.empty() && ((/*GLEW_VERSION_4_3 ||*/ GLAD_GL_KHR_debug) && glObjectLabel))
{
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, internalFormat, static_cast<GLsizei>(width), static_cast<GLsizei>(height), static_cast<GLsizei>(layer_count), 0, format, type, nullptr);
glObjectLabel(GL_TEXTURE, new_texture->id(), -1, filename.c_str());
}

glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, internalFormat, static_cast<GLsizei>(width), static_cast<GLsizei>(height), static_cast<GLsizei>(layer_count), 0, format, type, nullptr);

new_texture->unbind();
return new_texture;
}

gl_gpurendered_texture* gl_context::create_framebuffer_color_texture(GLenum internalFormat, GLenum format, GLenum type, const size_t& width, const size_t& height, const std::string& filename)
{
return create_gpurendered_texture(internalFormat, format, type, width, height, 1, filename);
return create_gpurendered_texture(internalFormat, format, type, width, height, filename);
}

gfx_api::buffer * gl_context::create_buffer_object(const gfx_api::buffer::usage &usage, const buffer_storage_hint& hint /*= buffer_storage_hint::static_draw*/, const std::string& debugName /*= ""*/)
Expand Down Expand Up @@ -2703,9 +2725,10 @@ uint64_t gl_context::get_estimated_vram_mb()
{
if (GLAD_GL_NVX_gpu_memory_info)
{
// If GL_NVX_gpu_memory_info is available, get the total graphics memory
// If GL_NVX_gpu_memory_info is available, get the total dedicated graphics memory
GLint total_graphics_mem_kb = 0;
glGetIntegerv(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &total_graphics_mem_kb);
glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &total_graphics_mem_kb);
debug(LOG_3D, "GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX: %d", total_graphics_mem_kb);

if (total_graphics_mem_kb > 0)
{
Expand All @@ -2719,6 +2742,9 @@ uint64_t gl_context::get_estimated_vram_mb()
glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, stats_kb);
if (stats_kb[0] > 0)
{
debug(LOG_3D, "GL_TEXTURE_FREE_MEMORY_ATI [0: total pool avail]: %d", stats_kb[0]);
debug(LOG_3D, "GL_TEXTURE_FREE_MEMORY_ATI [1: largest pool avail]: %d", stats_kb[1]);

uint64_t currentFreeTextureMemory_mb = static_cast<uint64_t>(stats_kb[0] / 1024);
return currentFreeTextureMemory_mb;
}
Expand Down Expand Up @@ -3029,11 +3055,12 @@ uint32_t gl_context::getSuggestedDefaultDepthBufferResolution() const
// Use a (very simple) heuristic, that may or may not be useful - but basically try to find graphics cards that have lots of memory...
if (GLAD_GL_NVX_gpu_memory_info)
{
// If GL_NVX_gpu_memory_info is available, get the total graphics memory (in kB)
// If GL_NVX_gpu_memory_info is available, get the total dedicated graphics memory
GLint total_graphics_mem_kb = 0;
glGetIntegerv(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &total_graphics_mem_kb);
glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &total_graphics_mem_kb);
debug(LOG_3D, "GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX: %d", total_graphics_mem_kb);

if ((total_graphics_mem_kb / 1024) >= 4096) // If >= 4GB graphics memory
if ((total_graphics_mem_kb / 1024) >= 8192) // If >= 8 GiB graphics memory
{
return 4096;
}
Expand All @@ -3042,45 +3069,42 @@ uint32_t gl_context::getSuggestedDefaultDepthBufferResolution() const
return 2048;
}
}
else if (GLAD_GL_ATI_meminfo)
{
// For GL_ATI_meminfo, get the current free texture memory (stats_kb[0])
GLint stats_kb[4] = {0, 0, 0, 0};
glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, stats_kb);
if (stats_kb[0] > 0)
{
uint32_t currentFreeTextureMemory_mb = static_cast<uint32_t>(stats_kb[0] / 1024);

if (currentFreeTextureMemory_mb >= 4096) // If >= 4 GB free texture memory
{
return 4096;
}
else
{
return 2048;
}
}
}
// else if (GLAD_GL_ATI_meminfo)
// {
// // For GL_ATI_meminfo, we could get the current free texture memory (w/ GL_TEXTURE_FREE_MEMORY_ATI, checking stats_kb[0])
// // However we don't really have any way of differentiating between dedicated VRAM and shared system memory (ex. with integrated graphics)
// // So instead, just ignore this
// }

// don't currently have a good way of checking video memory on this system
// instead, check system RAM
auto systemRAMinMiB = wzGetCurrentSystemRAM();
if (systemRAMinMiB >= 16384) // If >= 16 GB of system RAM
{
// check some specific GL_RENDERER values...
#if defined(WZ_OS_WIN)
WzString openGL_renderer = (const char*)wzSafeGlGetString(GL_RENDERER);
if (openGL_renderer.startsWith("Intel(R) HD Graphics"))
WzString openGL_renderer = (const char*)wzSafeGlGetString(GL_RENDERER);
if (openGL_renderer.startsWith("Intel(R) HD Graphics"))
{
// always default to 2048 on Intel HD Graphics...
return 2048;
}
#elif defined (__APPLE__)
WzString openGL_vendor = (const char*)wzSafeGlGetString(GL_VENDOR);
WzString openGL_renderer = (const char*)wzSafeGlGetString(GL_RENDERER);
if (openGL_vendor == "Apple" && openGL_renderer.startsWith("Apple"))
{
// For Apple GPUs, check system RAM
auto systemRAMinMiB = wzGetCurrentSystemRAM();
if (systemRAMinMiB >= 16384) // If >= 16 GB of system (unified) RAM
{
return 4096;
}
else
{
// always default to 2048 on Intel HD Graphics...
return 2048;
}
#endif
return 4096;
}
else
{
return 2048;
}
#endif

// In all other cases, default to 2048 for better performance by default
return 2048;
}

bool gl_context::_initialize(const gfx_api::backend_Impl_Factory& impl, int32_t antialiasing, swap_interval_mode mode, optional<float> _mipLodBias, uint32_t _depthMapResolution)
Expand Down Expand Up @@ -3412,6 +3436,12 @@ bool gl_context::initGLContext()
debug(LOG_3D, " * (current) Max array texture layers is %d.", (int) glMaxArrayTextureLayers);
maxArrayTextureLayers = glMaxArrayTextureLayers;

uint32_t estimatedVRAMinMiB = get_estimated_vram_mb();
if (estimatedVRAMinMiB > 0)
{
debug(LOG_3D, " * Estimated VRAM is %" PRIu32 " MiB", estimatedVRAMinMiB);
}

// IMPORTANT: Reserve enough slots in enabledVertexAttribIndexes based on glmaxVertexAttribs
if (glmaxVertexAttribs == 0)
{
Expand Down Expand Up @@ -4128,9 +4158,7 @@ size_t gl_context::initDepthPasses(size_t resolution)
if ((!gles && !GLAD_GL_VERSION_3_0) || (gles && !GLAD_GL_ES_VERSION_3_0))
{
// glFramebufferTextureLayer requires OpenGL 3.0+ / ES 3.0+
debug(LOG_ERROR, "Cannot create depth texture array - requires OpenGL 3.0+ / OpenGL ES 3.0+");
// could use a single depth pass (as a 2d texture) - but only bother if we want to keep support // TODO: decide
depthPassCount = 1;
debug(LOG_ERROR, "Cannot create depth texture array - requires OpenGL 3.0+ / OpenGL ES 3.0+ - this will fail");
}
}

Expand Down
4 changes: 3 additions & 1 deletion lib/ivis_opengl/gfx_api_gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ struct gl_buffer final : public gfx_api::buffer
void unbind();
virtual void upload(const size_t & size, const void * data) override;
virtual void update(const size_t & start, const size_t & size, const void * data, const update_flag flag = update_flag::none) override;
virtual size_t current_buffer_size() override;
};

struct gl_pipeline_id final : public gfx_api::pipeline_state_object
Expand Down Expand Up @@ -343,7 +344,8 @@ struct gl_context final : public gfx_api::context
void initPixelFormatsSupport();
bool initInstancedFunctions();
size_t initDepthPasses(size_t resolution);
gl_gpurendered_texture* create_gpurendered_texture(GLenum internalFormat, GLenum format, GLenum type, const size_t& width, const size_t& height, const size_t& layer_count, const std::string& filename);
gl_gpurendered_texture* create_gpurendered_texture(GLenum internalFormat, GLenum format, GLenum type, const size_t& width, const size_t& height, const std::string& filename);
gl_gpurendered_texture* create_gpurendered_texture_array(GLenum internalFormat, GLenum format, GLenum type, const size_t& width, const size_t& height, const size_t& layer_count, const std::string& filename);
gl_gpurendered_texture* create_depthmap_texture(const size_t& layer_count, const size_t& width, const size_t& height, const std::string& filename);
gl_gpurendered_texture* create_framebuffer_color_texture(GLenum internalFormat, GLenum format, GLenum type, const size_t& width, const size_t& height, const std::string& filename);
bool createSceneRenderpass();
Expand Down
5 changes: 5 additions & 0 deletions lib/ivis_opengl/gfx_api_null.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@ void null_buffer::update(const size_t & start, const size_t & size, const void *
// no-op
}

size_t null_buffer::current_buffer_size()
{
return buffer_size;
}

// MARK: null_pipeline_state_object

null_pipeline_state_object::null_pipeline_state_object(const gfx_api::state_description& _desc, const std::vector<gfx_api::vertex_buffer>& _vertex_buffer_desc)
Expand Down
1 change: 1 addition & 0 deletions lib/ivis_opengl/gfx_api_null.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ struct null_buffer final : public gfx_api::buffer
void bind() override;
virtual void upload(const size_t & size, const void * data) override;
virtual void update(const size_t & start, const size_t & size, const void * data, const update_flag flag = update_flag::none) override;
virtual size_t current_buffer_size() override;
};

struct null_pipeline_state_object final : public gfx_api::pipeline_state_object
Expand Down
44 changes: 37 additions & 7 deletions lib/ivis_opengl/gfx_api_vk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,12 @@ bool checkDeviceExtensionSupport(const vk::PhysicalDevice &device, const std::ve
requiredExtensions.erase(extension.extensionName);
}

debug(LOG_3D, "Found %zu extensions / did not find %zu extensions, in the enumerated list of %zu device extensions", desiredExtensions.size() - requiredExtensions.size(), requiredExtensions.size(), availableExtensions.size());
for (const auto& extension : requiredExtensions)
{
debug(LOG_3D, "Did not find extension: \"%s\"", extension.c_str());
}

return requiredExtensions.empty();
}
catch (const vk::SystemError& e)
Expand Down Expand Up @@ -1876,7 +1882,10 @@ void VkBuf::upload(const size_t & size, const void * data)
{
ASSERT(size > 0, "Attempt to upload buffer of size 0");
allocateBufferObject(size);
update(0, size, data);
if (data)
{
update(0, size, data);
}
}

void VkBuf::update(const size_t & start, const size_t & size, const void * data, const update_flag flag)
Expand Down Expand Up @@ -1907,6 +1916,11 @@ void VkBuf::update(const size_t & start, const size_t & size, const void * data,
cmdBuffer->copyBuffer(stagingMemory.buffer, object, copyRegions, root->vkDynLoader);
}

size_t VkBuf::current_buffer_size()
{
return buffer_size;
}

void VkBuf::bind() {}

// MARK: VkTexture
Expand Down Expand Up @@ -4347,21 +4361,37 @@ static optional<uint32_t> getVKLargestDeviceLocalMemoryHeapIndex(const vk::Physi
return largestDeviceLocalMemoryHeap;
}

static uint32_t getVKSuggestedDefaultDepthBufferResolution(const vk::PhysicalDeviceMemoryProperties& memprops)
static uint32_t getVKSuggestedDefaultDepthBufferResolution(const vk::PhysicalDeviceProperties &physicalDeviceProperties, const vk::PhysicalDeviceMemoryProperties& memprops)
{
optional<uint32_t> largestDeviceLocalMemoryHeap = getVKLargestDeviceLocalMemoryHeapIndex(memprops);
ASSERT_OR_RETURN(2048, largestDeviceLocalMemoryHeap.has_value(), "Couldn't find the largest device local memory heap?");

auto largestDeviceLocalMemoryHeapSize = memprops.memoryHeaps[largestDeviceLocalMemoryHeap.value()].size;

if ((largestDeviceLocalMemoryHeapSize / 1048576) >= 4096) // If >= 4GB device-local memory
if (physicalDeviceProperties.deviceType == vk::PhysicalDeviceType::eDiscreteGpu)
{
return 4096;
if ((largestDeviceLocalMemoryHeapSize / 1048576) >= 8192) // If >= 8 GiB device-local memory on a discrete GPU
{
return 4096;
}
else
{
return 2048;
}
}
else
else if (physicalDeviceProperties.vendorID == 4203) // Apple GPU
{
return 2048;
if ((largestDeviceLocalMemoryHeapSize / 1048576) >= 16384) // If >= 16 GiB device-local memory on an Apple GPU
{
return 4096;
}
else
{
return 2048;
}
}

return 2048;
}

bool VkRoot::canUseVulkanInstanceAPI(uint32_t minVulkanAPICoreVersion) const
Expand Down Expand Up @@ -4681,7 +4711,7 @@ bool VkRoot::_initialize(const gfx_api::backend_Impl_Factory& impl, int32_t anti

if (depthMapSize == 0)
{
depthMapSize = getVKSuggestedDefaultDepthBufferResolution(memprops);
depthMapSize = getVKSuggestedDefaultDepthBufferResolution(physDeviceProps, memprops);
}

createDepthPasses(depthBufferFormat); // TODO: Handle failures?
Expand Down
1 change: 1 addition & 0 deletions lib/ivis_opengl/gfx_api_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ struct VkBuf final : public gfx_api::buffer

virtual void upload(const size_t & size, const void * data) override;
virtual void update(const size_t & start, const size_t & size, const void * data, const update_flag flag = update_flag::none) override;
virtual size_t current_buffer_size() override;

virtual void bind() override;

Expand Down
3 changes: 3 additions & 0 deletions lib/ivis_opengl/piedef.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ enum class ShadowMode
};
bool pie_setShadowMode(ShadowMode mode);
ShadowMode pie_getShadowMode();
bool pie_setShadowCascades(uint32_t newValue);
uint32_t pie_getShadowCascades();

optional<bool> pie_supportsShadowMapping();
bool pie_setShadowMapResolution(uint32_t resolution);
uint32_t pie_getShadowMapResolution();
Expand Down
Loading
Loading