vk: move geometry buffer handling to separate files
This commit is contained in:
parent
da97f664d7
commit
a2b083300c
|
@ -2,6 +2,7 @@
|
||||||
#include "vk_common.h"
|
#include "vk_common.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "vk_render.h"
|
#include "vk_render.h"
|
||||||
|
#include "vk_geometry.h"
|
||||||
#include "vk_textures.h"
|
#include "vk_textures.h"
|
||||||
#include "vk_sprite.h"
|
#include "vk_sprite.h"
|
||||||
#include "vk_scene.h"
|
#include "vk_scene.h"
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "vk_lightmap.h"
|
#include "vk_lightmap.h"
|
||||||
#include "vk_scene.h"
|
#include "vk_scene.h"
|
||||||
#include "vk_render.h"
|
#include "vk_render.h"
|
||||||
|
#include "vk_geometry.h"
|
||||||
#include "vk_light.h"
|
#include "vk_light.h"
|
||||||
#include "vk_mapents.h"
|
#include "vk_mapents.h"
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "vk_cvar.h"
|
#include "vk_cvar.h"
|
||||||
#include "vk_pipeline.h"
|
#include "vk_pipeline.h"
|
||||||
#include "vk_render.h"
|
#include "vk_render.h"
|
||||||
|
#include "vk_geometry.h"
|
||||||
#include "vk_studio.h"
|
#include "vk_studio.h"
|
||||||
#include "vk_rtx.h"
|
#include "vk_rtx.h"
|
||||||
#include "vk_descriptor.h"
|
#include "vk_descriptor.h"
|
||||||
|
@ -740,6 +741,9 @@ qboolean R_VkInit( void )
|
||||||
if (!VK_FrameCtlInit())
|
if (!VK_FrameCtlInit())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!R_GeometryBuffer_Init())
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!VK_RenderInit())
|
if (!VK_RenderInit())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -783,6 +787,7 @@ void R_VkShutdown( void ) {
|
||||||
R_VkOverlay_Shutdown();
|
R_VkOverlay_Shutdown();
|
||||||
|
|
||||||
VK_RenderShutdown();
|
VK_RenderShutdown();
|
||||||
|
R_GeometryBuffer_Shutdown();
|
||||||
|
|
||||||
VK_FrameCtlShutdown();
|
VK_FrameCtlShutdown();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
#include "vk_geometry.h"
|
||||||
|
#include "vk_buffer.h"
|
||||||
|
#include "vk_staging.h"
|
||||||
|
#include "vk_framectl.h" // MAX_CONCURRENT_FRAMES
|
||||||
|
|
||||||
|
#define MAX_BUFFER_VERTICES_STATIC (128 * 1024)
|
||||||
|
#define MAX_BUFFER_INDICES_STATIC (MAX_BUFFER_VERTICES_STATIC * 3)
|
||||||
|
#define GEOMETRY_BUFFER_STATIC_SIZE ALIGN_UP(MAX_BUFFER_VERTICES_STATIC * sizeof(vk_vertex_t) + MAX_BUFFER_INDICES_STATIC * sizeof(uint16_t), sizeof(vk_vertex_t))
|
||||||
|
|
||||||
|
#define MAX_BUFFER_VERTICES_DYNAMIC (128 * 1024 * 2)
|
||||||
|
#define MAX_BUFFER_INDICES_DYNAMIC (MAX_BUFFER_VERTICES_DYNAMIC * 3)
|
||||||
|
#define GEOMETRY_BUFFER_DYNAMIC_SIZE ALIGN_UP(MAX_BUFFER_VERTICES_DYNAMIC * sizeof(vk_vertex_t) + MAX_BUFFER_INDICES_DYNAMIC * sizeof(uint16_t), sizeof(vk_vertex_t))
|
||||||
|
|
||||||
|
#define GEOMETRY_BUFFER_SIZE (GEOMETRY_BUFFER_STATIC_SIZE + GEOMETRY_BUFFER_DYNAMIC_SIZE)
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
vk_buffer_t buffer;
|
||||||
|
alo_ring_t static_ring;
|
||||||
|
alo_ring_t dynamic_ring;
|
||||||
|
|
||||||
|
int frame_index;
|
||||||
|
uint32_t dynamic_offsets[MAX_CONCURRENT_FRAMES];
|
||||||
|
} g_geom;
|
||||||
|
|
||||||
|
qboolean R_GeometryBufferAllocAndLock( r_geometry_buffer_lock_t *lock, int vertex_count, int index_count, r_geometry_lifetime_t lifetime ) {
|
||||||
|
const uint32_t vertices_size = vertex_count * sizeof(vk_vertex_t);
|
||||||
|
const uint32_t indices_size = index_count * sizeof(uint16_t);
|
||||||
|
const uint32_t total_size = vertices_size + indices_size;
|
||||||
|
alo_ring_t * const ring = (lifetime != LifetimeSingleFrame) ? &g_geom.static_ring : &g_geom.dynamic_ring;
|
||||||
|
|
||||||
|
const uint32_t alloc_offset = aloRingAlloc(ring, total_size, sizeof(vk_vertex_t));
|
||||||
|
const uint32_t offset = alloc_offset + ((lifetime == LifetimeSingleFrame) ? GEOMETRY_BUFFER_STATIC_SIZE : 0);
|
||||||
|
if (alloc_offset == ALO_ALLOC_FAILED) {
|
||||||
|
/* gEngine.Con_Printf(S_ERROR "Cannot allocate %s geometry buffer for %d vertices (%d bytes) and %d indices (%d bytes)\n", */
|
||||||
|
/* lifetime == LifetimeSingleFrame ? "dynamic" : "static", */
|
||||||
|
/* vertex_count, vertices_size, index_count, indices_size); */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store first dynamic allocation this frame
|
||||||
|
if (lifetime == LifetimeSingleFrame && g_geom.dynamic_offsets[g_geom.frame_index] == ALO_ALLOC_FAILED) {
|
||||||
|
//gEngine.Con_Reportf("FRAME=%d FIRST_OFFSET=%d\n", g_geom.frame_index, alloc_offset);
|
||||||
|
g_geom.dynamic_offsets[g_geom.frame_index] = alloc_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const uint32_t vertices_offset = offset / sizeof(vk_vertex_t);
|
||||||
|
const uint32_t indices_offset = (offset + vertices_size) / sizeof(uint16_t);
|
||||||
|
const vk_staging_buffer_args_t staging_args = {
|
||||||
|
.buffer = g_geom.buffer.buffer,
|
||||||
|
.offset = offset,
|
||||||
|
.size = total_size,
|
||||||
|
.alignment = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
const vk_staging_region_t staging = R_VkStagingLockForBuffer(staging_args);
|
||||||
|
ASSERT(staging.ptr);
|
||||||
|
|
||||||
|
ASSERT( offset % sizeof(vk_vertex_t) == 0 );
|
||||||
|
ASSERT( (offset + vertices_size) % sizeof(uint16_t) == 0 );
|
||||||
|
|
||||||
|
*lock = (r_geometry_buffer_lock_t) {
|
||||||
|
.vertices = {
|
||||||
|
.count = vertex_count,
|
||||||
|
.ptr = (vk_vertex_t *)staging.ptr,
|
||||||
|
.unit_offset = vertices_offset,
|
||||||
|
},
|
||||||
|
.indices = {
|
||||||
|
.count = index_count,
|
||||||
|
.ptr = (uint16_t *)((char*)staging.ptr + vertices_size),
|
||||||
|
.unit_offset = indices_offset,
|
||||||
|
},
|
||||||
|
.impl_ = {
|
||||||
|
.staging_handle = staging.handle,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_GeometryBufferUnlock( const r_geometry_buffer_lock_t *lock ) {
|
||||||
|
R_VkStagingUnlock(lock->impl_.staging_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XVK_RenderBufferMapClear( void ) {
|
||||||
|
aloRingInit(&g_geom.static_ring, GEOMETRY_BUFFER_STATIC_SIZE);
|
||||||
|
aloRingInit(&g_geom.dynamic_ring, GEOMETRY_BUFFER_DYNAMIC_SIZE);
|
||||||
|
for (int i = 0; i < COUNTOF(g_geom.dynamic_offsets); ++i) {
|
||||||
|
g_geom.dynamic_offsets[i] = ALO_ALLOC_FAILED;
|
||||||
|
}
|
||||||
|
g_geom.frame_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XVK_RenderBufferPrintStats( void ) {
|
||||||
|
// TODO get alignment holes size
|
||||||
|
gEngine.Con_Reportf("Buffer usage: %uKiB of (%uKiB)\n",
|
||||||
|
g_geom.static_ring.head / 1024, g_geom.static_ring.size / 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
qboolean R_GeometryBuffer_Init(void) {
|
||||||
|
// TODO device memory and friends (e.g. handle mobile memory ...)
|
||||||
|
|
||||||
|
if (!VK_BufferCreate("geometry buffer", &g_geom.buffer, GEOMETRY_BUFFER_SIZE,
|
||||||
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | (vk_core.rtx ? VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR : 0),
|
||||||
|
(vk_core.rtx ? VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT : 0))) // TODO staging buffer?
|
||||||
|
return false;
|
||||||
|
|
||||||
|
XVK_RenderBufferMapClear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_GeometryBuffer_Shutdown(void) {
|
||||||
|
VK_BufferDestroy( &g_geom.buffer );
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_GeometryBuffer_Flip(void) {
|
||||||
|
const int new_frame = (g_geom.frame_index + 1) % COUNTOF(g_geom.dynamic_offsets);
|
||||||
|
if (g_geom.dynamic_offsets[new_frame] != ALO_ALLOC_FAILED) {
|
||||||
|
//gEngine.Con_Reportf("FRAME=%d FREE_OFFSET=%d\n", g_geom.frame_index, g_geom.dynamic_offsets[new_frame]);
|
||||||
|
aloRingFree(&g_geom.dynamic_ring, g_geom.dynamic_offsets[new_frame]);
|
||||||
|
g_geom.dynamic_offsets[new_frame] = ALO_ALLOC_FAILED;
|
||||||
|
}
|
||||||
|
g_geom.frame_index = new_frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkBuffer R_GeometryBuffer_Get(void) {
|
||||||
|
return g_geom.buffer.buffer;
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
#pragma once
|
||||||
|
#include "vk_common.h"
|
||||||
|
#include "vk_core.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// General buffer usage pattern
|
||||||
|
// 1. alloc (allocates buffer mem, stores allocation data)
|
||||||
|
// 2. (returns void* buf and handle) write to buf
|
||||||
|
// 3. upload and lock (ensures that all this data is in gpu mem, e.g. uploads from staging)
|
||||||
|
// 4. ... use it
|
||||||
|
// 5. free (frame/map end)
|
||||||
|
|
||||||
|
// TODO is this a good place?
|
||||||
|
typedef struct vk_vertex_s {
|
||||||
|
// TODO padding needed for storage buffer reading, figure out how to fix in GLSL/SPV side
|
||||||
|
vec3_t pos; float p0_;
|
||||||
|
vec3_t normal; uint32_t flags;
|
||||||
|
vec3_t tangent; uint32_t p1_;
|
||||||
|
vec2_t gl_tc; //float p2_[2];
|
||||||
|
vec2_t lm_tc; //float p3_[2];
|
||||||
|
|
||||||
|
rgba_t color; // per-vertex (non-rt lighting) color, color[3] == 1(255) => use color, discard lightmap; color[3] == 0 => use lightmap, discard color
|
||||||
|
float _padding[3];
|
||||||
|
} vk_vertex_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct {
|
||||||
|
vk_vertex_t *ptr;
|
||||||
|
int count;
|
||||||
|
int unit_offset;
|
||||||
|
} vertices;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint16_t *ptr;
|
||||||
|
int count;
|
||||||
|
int unit_offset;
|
||||||
|
} indices;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
int staging_handle;
|
||||||
|
} impl_;
|
||||||
|
} r_geometry_buffer_lock_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
LifetimeLong,
|
||||||
|
LifetimeSingleFrame
|
||||||
|
} r_geometry_lifetime_t;
|
||||||
|
|
||||||
|
qboolean R_GeometryBufferAllocAndLock( r_geometry_buffer_lock_t *lock, int vertex_count, int index_count, r_geometry_lifetime_t lifetime );
|
||||||
|
void R_GeometryBufferUnlock( const r_geometry_buffer_lock_t *lock );
|
||||||
|
//void R_VkGeometryBufferFree( int handle );
|
||||||
|
|
||||||
|
void R_GeometryBufferMapClear( void ); // Free the entire buffer for a new map
|
||||||
|
|
||||||
|
void R_GeometryBufferPrintStats( void );
|
||||||
|
|
||||||
|
qboolean R_GeometryBuffer_Init(void);
|
||||||
|
void R_GeometryBuffer_Shutdown(void);
|
||||||
|
|
||||||
|
void R_GeometryBuffer_Flip(void);
|
||||||
|
|
||||||
|
// FIXME is there a better way?
|
||||||
|
VkBuffer R_GeometryBuffer_Get(void);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "vk_rtx.h"
|
#include "vk_rtx.h"
|
||||||
#include "vk_textures.h"
|
#include "vk_textures.h"
|
||||||
#include "vk_materials.h"
|
#include "vk_materials.h"
|
||||||
|
#include "vk_geometry.h"
|
||||||
#include "vk_render.h"
|
#include "vk_render.h"
|
||||||
#include "vk_light.h"
|
#include "vk_light.h"
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "vk_core.h"
|
#include "vk_core.h"
|
||||||
#include "vk_buffer.h"
|
#include "vk_buffer.h"
|
||||||
|
#include "vk_geometry.h"
|
||||||
#include "vk_staging.h"
|
#include "vk_staging.h"
|
||||||
#include "vk_const.h"
|
#include "vk_const.h"
|
||||||
#include "vk_common.h"
|
#include "vk_common.h"
|
||||||
|
@ -21,16 +22,6 @@
|
||||||
|
|
||||||
#define MAX_UNIFORM_SLOTS (MAX_SCENE_ENTITIES * 2 /* solid + trans */ + 1)
|
#define MAX_UNIFORM_SLOTS (MAX_SCENE_ENTITIES * 2 /* solid + trans */ + 1)
|
||||||
|
|
||||||
#define MAX_BUFFER_VERTICES_STATIC (128 * 1024)
|
|
||||||
#define MAX_BUFFER_INDICES_STATIC (MAX_BUFFER_VERTICES_STATIC * 3)
|
|
||||||
#define GEOMETRY_BUFFER_STATIC_SIZE ALIGN_UP(MAX_BUFFER_VERTICES_STATIC * sizeof(vk_vertex_t) + MAX_BUFFER_INDICES_STATIC * sizeof(uint16_t), sizeof(vk_vertex_t))
|
|
||||||
|
|
||||||
#define MAX_BUFFER_VERTICES_DYNAMIC (128 * 1024 * 2)
|
|
||||||
#define MAX_BUFFER_INDICES_DYNAMIC (MAX_BUFFER_VERTICES_DYNAMIC * 3)
|
|
||||||
#define GEOMETRY_BUFFER_DYNAMIC_SIZE ALIGN_UP(MAX_BUFFER_VERTICES_DYNAMIC * sizeof(vk_vertex_t) + MAX_BUFFER_INDICES_DYNAMIC * sizeof(uint16_t), sizeof(vk_vertex_t))
|
|
||||||
|
|
||||||
#define GEOMETRY_BUFFER_SIZE (GEOMETRY_BUFFER_STATIC_SIZE + GEOMETRY_BUFFER_DYNAMIC_SIZE)
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
matrix4x4 mvp;
|
matrix4x4 mvp;
|
||||||
vec4_t color;
|
vec4_t color;
|
||||||
|
@ -46,15 +37,6 @@ static struct {
|
||||||
float fov_angle_y;
|
float fov_angle_y;
|
||||||
} g_render;
|
} g_render;
|
||||||
|
|
||||||
struct {
|
|
||||||
vk_buffer_t buffer;
|
|
||||||
alo_ring_t static_ring;
|
|
||||||
alo_ring_t dynamic_ring;
|
|
||||||
|
|
||||||
int frame_index;
|
|
||||||
uint32_t dynamic_offsets[MAX_CONCURRENT_FRAMES];
|
|
||||||
} g_geom;
|
|
||||||
|
|
||||||
static qboolean createPipelines( void )
|
static qboolean createPipelines( void )
|
||||||
{
|
{
|
||||||
/* VkPushConstantRange push_const = { */
|
/* VkPushConstantRange push_const = { */
|
||||||
|
@ -291,16 +273,9 @@ qboolean VK_RenderInit( void ) {
|
||||||
const uint32_t uniform_buffer_size = uniform_unit_size * MAX_UNIFORM_SLOTS;
|
const uint32_t uniform_buffer_size = uniform_unit_size * MAX_UNIFORM_SLOTS;
|
||||||
R_FlippingBuffer_Init(&g_render_state.uniform_alloc, uniform_buffer_size);
|
R_FlippingBuffer_Init(&g_render_state.uniform_alloc, uniform_buffer_size);
|
||||||
|
|
||||||
// TODO device memory and friends (e.g. handle mobile memory ...)
|
|
||||||
|
|
||||||
if (!VK_BufferCreate("geometry buffer", &g_geom.buffer, GEOMETRY_BUFFER_SIZE,
|
|
||||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | (vk_core.rtx ? VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR : 0),
|
|
||||||
(vk_core.rtx ? VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT : 0))) // TODO staging buffer?
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!VK_BufferCreate("render uniform_buffer", &g_render.uniform_buffer, uniform_buffer_size,
|
if (!VK_BufferCreate("render uniform_buffer", &g_render.uniform_buffer, uniform_buffer_size,
|
||||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | (vk_core.rtx ? VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT : 0))) // TODO staging buffer?
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | (vk_core.rtx ? VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT : 0)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -337,8 +312,6 @@ qboolean VK_RenderInit( void ) {
|
||||||
if (!createPipelines())
|
if (!createPipelines())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
XVK_RenderBufferMapClear();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,86 +321,9 @@ void VK_RenderShutdown( void )
|
||||||
vkDestroyPipeline(vk_core.device, g_render.pipelines[i], NULL);
|
vkDestroyPipeline(vk_core.device, g_render.pipelines[i], NULL);
|
||||||
vkDestroyPipelineLayout( vk_core.device, g_render.pipeline_layout, NULL );
|
vkDestroyPipelineLayout( vk_core.device, g_render.pipeline_layout, NULL );
|
||||||
|
|
||||||
VK_BufferDestroy( &g_geom.buffer );
|
|
||||||
VK_BufferDestroy( &g_render.uniform_buffer );
|
VK_BufferDestroy( &g_render.uniform_buffer );
|
||||||
}
|
}
|
||||||
|
|
||||||
qboolean R_GeometryBufferAllocAndLock( r_geometry_buffer_lock_t *lock, int vertex_count, int index_count, r_geometry_lifetime_t lifetime ) {
|
|
||||||
const uint32_t vertices_size = vertex_count * sizeof(vk_vertex_t);
|
|
||||||
const uint32_t indices_size = index_count * sizeof(uint16_t);
|
|
||||||
const uint32_t total_size = vertices_size + indices_size;
|
|
||||||
alo_ring_t * const ring = (lifetime != LifetimeSingleFrame) ? &g_geom.static_ring : &g_geom.dynamic_ring;
|
|
||||||
|
|
||||||
const uint32_t alloc_offset = aloRingAlloc(ring, total_size, sizeof(vk_vertex_t));
|
|
||||||
const uint32_t offset = alloc_offset + ((lifetime == LifetimeSingleFrame) ? GEOMETRY_BUFFER_STATIC_SIZE : 0);
|
|
||||||
if (alloc_offset == ALO_ALLOC_FAILED) {
|
|
||||||
/* gEngine.Con_Printf(S_ERROR "Cannot allocate %s geometry buffer for %d vertices (%d bytes) and %d indices (%d bytes)\n", */
|
|
||||||
/* lifetime == LifetimeSingleFrame ? "dynamic" : "static", */
|
|
||||||
/* vertex_count, vertices_size, index_count, indices_size); */
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store first dynamic allocation this frame
|
|
||||||
if (lifetime == LifetimeSingleFrame && g_geom.dynamic_offsets[g_geom.frame_index] == ALO_ALLOC_FAILED) {
|
|
||||||
//gEngine.Con_Reportf("FRAME=%d FIRST_OFFSET=%d\n", g_geom.frame_index, alloc_offset);
|
|
||||||
g_geom.dynamic_offsets[g_geom.frame_index] = alloc_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const uint32_t vertices_offset = offset / sizeof(vk_vertex_t);
|
|
||||||
const uint32_t indices_offset = (offset + vertices_size) / sizeof(uint16_t);
|
|
||||||
const vk_staging_buffer_args_t staging_args = {
|
|
||||||
.buffer = g_geom.buffer.buffer,
|
|
||||||
.offset = offset,
|
|
||||||
.size = total_size,
|
|
||||||
.alignment = 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
const vk_staging_region_t staging = R_VkStagingLockForBuffer(staging_args);
|
|
||||||
ASSERT(staging.ptr);
|
|
||||||
|
|
||||||
ASSERT( offset % sizeof(vk_vertex_t) == 0 );
|
|
||||||
ASSERT( (offset + vertices_size) % sizeof(uint16_t) == 0 );
|
|
||||||
|
|
||||||
*lock = (r_geometry_buffer_lock_t) {
|
|
||||||
.vertices = {
|
|
||||||
.count = vertex_count,
|
|
||||||
.ptr = (vk_vertex_t *)staging.ptr,
|
|
||||||
.unit_offset = vertices_offset,
|
|
||||||
},
|
|
||||||
.indices = {
|
|
||||||
.count = index_count,
|
|
||||||
.ptr = (uint16_t *)((char*)staging.ptr + vertices_size),
|
|
||||||
.unit_offset = indices_offset,
|
|
||||||
},
|
|
||||||
.impl_ = {
|
|
||||||
.staging_handle = staging.handle,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void R_GeometryBufferUnlock( const r_geometry_buffer_lock_t *lock ) {
|
|
||||||
R_VkStagingUnlock(lock->impl_.staging_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void XVK_RenderBufferMapClear( void ) {
|
|
||||||
aloRingInit(&g_geom.static_ring, GEOMETRY_BUFFER_STATIC_SIZE);
|
|
||||||
aloRingInit(&g_geom.dynamic_ring, GEOMETRY_BUFFER_DYNAMIC_SIZE);
|
|
||||||
for (int i = 0; i < COUNTOF(g_geom.dynamic_offsets); ++i) {
|
|
||||||
g_geom.dynamic_offsets[i] = ALO_ALLOC_FAILED;
|
|
||||||
}
|
|
||||||
g_geom.frame_index = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void XVK_RenderBufferPrintStats( void ) {
|
|
||||||
// TODO get alignment holes size
|
|
||||||
gEngine.Con_Reportf("Buffer usage: %uKiB of (%uKiB)\n",
|
|
||||||
g_geom.static_ring.head / 1024, g_geom.static_ring.size / 1024);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
UNIFORM_UNSET = 0,
|
UNIFORM_UNSET = 0,
|
||||||
UNIFORM_SET_COLOR = 1,
|
UNIFORM_SET_COLOR = 1,
|
||||||
|
@ -448,15 +344,7 @@ void VK_RenderBegin( qboolean ray_tracing ) {
|
||||||
g_render_state.num_draw_commands = 0;
|
g_render_state.num_draw_commands = 0;
|
||||||
g_render_state.current_frame_is_ray_traced = ray_tracing;
|
g_render_state.current_frame_is_ray_traced = ray_tracing;
|
||||||
|
|
||||||
{
|
R_GeometryBuffer_Flip();
|
||||||
const int new_frame = (g_geom.frame_index + 1) % COUNTOF(g_geom.dynamic_offsets);
|
|
||||||
if (g_geom.dynamic_offsets[new_frame] != ALO_ALLOC_FAILED) {
|
|
||||||
//gEngine.Con_Reportf("FRAME=%d FREE_OFFSET=%d\n", g_geom.frame_index, g_geom.dynamic_offsets[new_frame]);
|
|
||||||
aloRingFree(&g_geom.dynamic_ring, g_geom.dynamic_offsets[new_frame]);
|
|
||||||
g_geom.dynamic_offsets[new_frame] = ALO_ALLOC_FAILED;
|
|
||||||
}
|
|
||||||
g_geom.frame_index = new_frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ray_tracing)
|
if (ray_tracing)
|
||||||
VK_RayFrameBegin();
|
VK_RayFrameBegin();
|
||||||
|
@ -629,7 +517,8 @@ static uint32_t writeDlightsToUBO( void )
|
||||||
return ubo_lights_offset;
|
return ubo_lights_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VK_Render_FIXME_Barrier( VkCommandBuffer cmdbuf )
|
void VK_Render_FIXME_Barrier( VkCommandBuffer cmdbuf ) {
|
||||||
|
const VkBuffer geom_buffer = R_GeometryBuffer_Get();
|
||||||
// FIXME
|
// FIXME
|
||||||
{
|
{
|
||||||
const VkBufferMemoryBarrier bmb[] = { {
|
const VkBufferMemoryBarrier bmb[] = { {
|
||||||
|
@ -637,7 +526,7 @@ void VK_Render_FIXME_Barrier( VkCommandBuffer cmdbuf )
|
||||||
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||||
//.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, // FIXME
|
//.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, // FIXME
|
||||||
.dstAccessMask = VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT , // FIXME
|
.dstAccessMask = VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT , // FIXME
|
||||||
.buffer = g_geom.buffer.buffer,
|
.buffer = geom_buffer,
|
||||||
.offset = 0, // FIXME
|
.offset = 0, // FIXME
|
||||||
.size = VK_WHOLE_SIZE, // FIXME
|
.size = VK_WHOLE_SIZE, // FIXME
|
||||||
} };
|
} };
|
||||||
|
@ -648,6 +537,7 @@ void VK_Render_FIXME_Barrier( VkCommandBuffer cmdbuf )
|
||||||
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
|
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
|
||||||
0, 0, NULL, ARRAYSIZE(bmb), bmb, 0, NULL);
|
0, 0, NULL, ARRAYSIZE(bmb), bmb, 0, NULL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void VK_RenderEnd( VkCommandBuffer cmdbuf )
|
void VK_RenderEnd( VkCommandBuffer cmdbuf )
|
||||||
{
|
{
|
||||||
|
@ -667,9 +557,10 @@ void VK_RenderEnd( VkCommandBuffer cmdbuf )
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
|
const VkBuffer geom_buffer = R_GeometryBuffer_Get();
|
||||||
const VkDeviceSize offset = 0;
|
const VkDeviceSize offset = 0;
|
||||||
vkCmdBindVertexBuffers(cmdbuf, 0, 1, &g_geom.buffer.buffer, &offset);
|
vkCmdBindVertexBuffers(cmdbuf, 0, 1, &geom_buffer, &offset);
|
||||||
vkCmdBindIndexBuffer(cmdbuf, g_geom.buffer.buffer, 0, VK_INDEX_TYPE_UINT16);
|
vkCmdBindIndexBuffer(cmdbuf, geom_buffer, 0, VK_INDEX_TYPE_UINT16);
|
||||||
}
|
}
|
||||||
|
|
||||||
vkCmdBindDescriptorSets(cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, g_render.pipeline_layout, 3, 1, vk_desc.ubo_sets + 1, 1, &dlights_ubo_offset);
|
vkCmdBindDescriptorSets(cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, g_render.pipeline_layout, 3, 1, vk_desc.ubo_sets + 1, 1, &dlights_ubo_offset);
|
||||||
|
@ -733,6 +624,7 @@ void VK_RenderDebugLabelEnd( void )
|
||||||
|
|
||||||
void VK_RenderEndRTX( VkCommandBuffer cmdbuf, VkImageView img_dst_view, VkImage img_dst, uint32_t w, uint32_t h )
|
void VK_RenderEndRTX( VkCommandBuffer cmdbuf, VkImageView img_dst_view, VkImage img_dst, uint32_t w, uint32_t h )
|
||||||
{
|
{
|
||||||
|
const VkBuffer geom_buffer = R_GeometryBuffer_Get();
|
||||||
ASSERT(vk_core.rtx);
|
ASSERT(vk_core.rtx);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -749,7 +641,7 @@ void VK_RenderEndRTX( VkCommandBuffer cmdbuf, VkImageView img_dst_view, VkImage
|
||||||
.view = &g_render_state.view,
|
.view = &g_render_state.view,
|
||||||
|
|
||||||
.geometry_data = {
|
.geometry_data = {
|
||||||
.buffer = g_geom.buffer.buffer,
|
.buffer = geom_buffer,
|
||||||
.size = VK_WHOLE_SIZE,
|
.size = VK_WHOLE_SIZE,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -762,19 +654,20 @@ void VK_RenderEndRTX( VkCommandBuffer cmdbuf, VkImageView img_dst_view, VkImage
|
||||||
|
|
||||||
qboolean VK_RenderModelInit( VkCommandBuffer cmdbuf, vk_render_model_t *model ) {
|
qboolean VK_RenderModelInit( VkCommandBuffer cmdbuf, vk_render_model_t *model ) {
|
||||||
if (vk_core.rtx && (g_render_state.current_frame_is_ray_traced || !model->dynamic)) {
|
if (vk_core.rtx && (g_render_state.current_frame_is_ray_traced || !model->dynamic)) {
|
||||||
|
const VkBuffer geom_buffer = R_GeometryBuffer_Get();
|
||||||
// TODO runtime rtx switch: ???
|
// TODO runtime rtx switch: ???
|
||||||
const vk_ray_model_init_t args = {
|
const vk_ray_model_init_t args = {
|
||||||
.buffer = g_geom.buffer.buffer,
|
.buffer = geom_buffer,
|
||||||
.model = model,
|
.model = model,
|
||||||
};
|
};
|
||||||
R_VkStagingCommit(cmdbuf);
|
R_VkStagingCommit(cmdbuf); // FIXME this is definitely not the right place
|
||||||
{
|
{
|
||||||
const VkBufferMemoryBarrier bmb[] = { {
|
const VkBufferMemoryBarrier bmb[] = { {
|
||||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||||
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||||
//.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, // FIXME
|
//.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, // FIXME
|
||||||
.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_SHADER_READ_BIT, // FIXME
|
.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_SHADER_READ_BIT, // FIXME
|
||||||
.buffer = g_geom.buffer.buffer,
|
.buffer = geom_buffer,
|
||||||
.offset = 0, // FIXME
|
.offset = 0, // FIXME
|
||||||
.size = VK_WHOLE_SIZE, // FIXME
|
.size = VK_WHOLE_SIZE, // FIXME
|
||||||
} };
|
} };
|
||||||
|
|
|
@ -6,57 +6,6 @@
|
||||||
qboolean VK_RenderInit( void );
|
qboolean VK_RenderInit( void );
|
||||||
void VK_RenderShutdown( void );
|
void VK_RenderShutdown( void );
|
||||||
|
|
||||||
// General buffer usage pattern
|
|
||||||
// 1. alloc (allocates buffer mem, stores allocation data)
|
|
||||||
// 2. (returns void* buf and handle) write to buf
|
|
||||||
// 3. upload and lock (ensures that all this data is in gpu mem, e.g. uploads from staging)
|
|
||||||
// 4. ... use it
|
|
||||||
// 5. free (frame/map end)
|
|
||||||
|
|
||||||
// TODO is this a good place?
|
|
||||||
typedef struct vk_vertex_s {
|
|
||||||
// TODO padding needed for storage buffer reading, figure out how to fix in GLSL/SPV side
|
|
||||||
vec3_t pos; float p0_;
|
|
||||||
vec3_t normal; uint32_t flags;
|
|
||||||
vec3_t tangent; uint32_t p1_;
|
|
||||||
vec2_t gl_tc; //float p2_[2];
|
|
||||||
vec2_t lm_tc; //float p3_[2];
|
|
||||||
|
|
||||||
rgba_t color; // per-vertex (non-rt lighting) color, color[3] == 1(255) => use color, discard lightmap; color[3] == 0 => use lightmap, discard color
|
|
||||||
float _padding[3];
|
|
||||||
} vk_vertex_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
struct {
|
|
||||||
vk_vertex_t *ptr;
|
|
||||||
int count;
|
|
||||||
int unit_offset;
|
|
||||||
} vertices;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
uint16_t *ptr;
|
|
||||||
int count;
|
|
||||||
int unit_offset;
|
|
||||||
} indices;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
int staging_handle;
|
|
||||||
} impl_;
|
|
||||||
} r_geometry_buffer_lock_t;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
LifetimeLong,
|
|
||||||
LifetimeSingleFrame
|
|
||||||
} r_geometry_lifetime_t;
|
|
||||||
|
|
||||||
qboolean R_GeometryBufferAllocAndLock( r_geometry_buffer_lock_t *lock, int vertex_count, int index_count, r_geometry_lifetime_t lifetime );
|
|
||||||
void R_GeometryBufferUnlock( const r_geometry_buffer_lock_t *lock );
|
|
||||||
//void R_VkGeometryBufferFree( int handle );
|
|
||||||
|
|
||||||
void XVK_RenderBufferMapClear( void ); // Free the entire buffer for a new map
|
|
||||||
|
|
||||||
void XVK_RenderBufferPrintStats( void );
|
|
||||||
|
|
||||||
// Set UBO state for next VK_RenderScheduleDraw calls
|
// Set UBO state for next VK_RenderScheduleDraw calls
|
||||||
// Why? Xash Ref code is organized in a way where we can't reliably pass this info with
|
// Why? Xash Ref code is organized in a way where we can't reliably pass this info with
|
||||||
// ScheduleDraw itself, so we need to either set up per-submodule global state, or
|
// ScheduleDraw itself, so we need to either set up per-submodule global state, or
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "vk_textures.h"
|
#include "vk_textures.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "vk_render.h"
|
#include "vk_render.h"
|
||||||
|
#include "vk_geometry.h"
|
||||||
#include "vk_scene.h"
|
#include "vk_scene.h"
|
||||||
|
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "vk_common.h"
|
#include "vk_common.h"
|
||||||
#include "vk_textures.h"
|
#include "vk_textures.h"
|
||||||
#include "vk_render.h"
|
#include "vk_render.h"
|
||||||
|
#include "vk_geometry.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
|
|
||||||
#include "xash3d_mathlib.h"
|
#include "xash3d_mathlib.h"
|
||||||
|
|
Loading…
Reference in New Issue