rt: step even closer to explicit blas+kusochki management
- stop tracking color/xform/mmode with vk_ray_model - do not expose model to things that don't need to know
This commit is contained in:
parent
8724efd748
commit
9200cbfc25
|
@ -157,7 +157,7 @@ static qboolean buildAccel(VkBuffer geometry_buffer, VkAccelerationStructureBuil
|
|||
}
|
||||
|
||||
// TODO split this into smaller building blocks in a separate module
|
||||
qboolean createOrUpdateAccelerationStructure(vk_combuf_t *combuf, const as_build_args_t *args, vk_ray_model_t *model) {
|
||||
qboolean createOrUpdateAccelerationStructure(vk_combuf_t *combuf, const as_build_args_t *args) {
|
||||
ASSERT(args->geoms);
|
||||
ASSERT(args->n_geoms > 0);
|
||||
ASSERT(args->p_accel);
|
||||
|
@ -182,9 +182,11 @@ qboolean createOrUpdateAccelerationStructure(vk_combuf_t *combuf, const as_build
|
|||
if (!args->p_accel)
|
||||
return false;
|
||||
|
||||
if (model) {
|
||||
model->cache.size = build_size.accelerationStructureSize;
|
||||
}
|
||||
if (args->out_accel_addr)
|
||||
*args->out_accel_addr = getAccelAddress(*args->p_accel);
|
||||
|
||||
if (args->inout_size)
|
||||
*args->inout_size = build_size.accelerationStructureSize;
|
||||
|
||||
// gEngine.Con_Reportf("AS=%p, n_geoms=%u, build: %#x %d %#x\n", *args->p_accel, args->n_geoms, buffer_offset, asci.size, buffer_offset + asci.size);
|
||||
}
|
||||
|
@ -193,9 +195,8 @@ qboolean createOrUpdateAccelerationStructure(vk_combuf_t *combuf, const as_build
|
|||
if (!combuf || !args->build_ranges)
|
||||
return true;
|
||||
|
||||
if (model) {
|
||||
ASSERT(model->cache.size >= build_size.accelerationStructureSize);
|
||||
}
|
||||
if (args->inout_size)
|
||||
ASSERT(*args->inout_size >= build_size.accelerationStructureSize);
|
||||
|
||||
build_info.dstAccelerationStructure = *args->p_accel;
|
||||
const VkBuffer geometry_buffer = R_GeometryBuffer_Get();
|
||||
|
@ -230,8 +231,10 @@ static void createTlas( vk_combuf_t *combuf, VkDeviceAddress instances_addr ) {
|
|||
.dynamic = false,
|
||||
.p_accel = &g_accel.tlas,
|
||||
.debug_name = "TLAS",
|
||||
.out_accel_addr = NULL,
|
||||
.inout_size = NULL,
|
||||
};
|
||||
if (!createOrUpdateAccelerationStructure(combuf, &asrgs, NULL)) {
|
||||
if (!createOrUpdateAccelerationStructure(combuf, &asrgs)) {
|
||||
gEngine.Host_Error("Could not create/update TLAS\n");
|
||||
return;
|
||||
}
|
||||
|
@ -260,12 +263,11 @@ vk_resource_t RT_VkAccelPrepareTlas(vk_combuf_t *combuf) {
|
|||
VkAccelerationStructureInstanceKHR* inst = ((VkAccelerationStructureInstanceKHR*)g_accel.tlas_geom_buffer.mapped) + instance_offset;
|
||||
for (int i = 0; i < g_ray_model_state.frame.instances_count; ++i) {
|
||||
const rt_draw_instance_t* const instance = g_ray_model_state.frame.instances + i;
|
||||
ASSERT(instance->model);
|
||||
ASSERT(instance->model->as != VK_NULL_HANDLE);
|
||||
ASSERT(instance->blas_addr != 0);
|
||||
inst[i] = (VkAccelerationStructureInstanceKHR){
|
||||
.instanceCustomIndex = instance->model->kusochki_offset,
|
||||
.instanceCustomIndex = instance->kusochki_offset,
|
||||
.instanceShaderBindingTableRecordOffset = 0,
|
||||
.accelerationStructureReference = getAccelAddress(instance->model->as), // TODO cache this addr
|
||||
.accelerationStructureReference = instance->blas_addr,
|
||||
};
|
||||
switch (instance->material_mode) {
|
||||
case MATERIAL_MODE_OPAQUE:
|
||||
|
@ -298,8 +300,8 @@ vk_resource_t RT_VkAccelPrepareTlas(vk_combuf_t *combuf) {
|
|||
|
||||
struct ModelHeader *const header = ((struct ModelHeader*)headers_lock.ptr) + i;
|
||||
header->mode = instance->material_mode;
|
||||
Vector4Copy(instance->model->color, header->color);
|
||||
Matrix4x4_ToArrayFloatGL(instance->model->prev_transform, (float*)header->prev_transform);
|
||||
Vector4Copy(instance->color, header->color);
|
||||
Matrix4x4_ToArrayFloatGL(instance->prev_transform_row, (float*)header->prev_transform);
|
||||
}
|
||||
|
||||
R_VkStagingUnlock(headers_lock.handle);
|
||||
|
@ -398,9 +400,9 @@ void RT_VkAccelShutdown(void) {
|
|||
|
||||
for (int i = 0; i < COUNTOF(g_ray_model_state.models_cache); ++i) {
|
||||
vk_ray_model_t *model = g_ray_model_state.models_cache + i;
|
||||
if (model->as != VK_NULL_HANDLE)
|
||||
vkDestroyAccelerationStructureKHR(vk_core.device, model->as, NULL);
|
||||
model->as = VK_NULL_HANDLE;
|
||||
if (model->blas != VK_NULL_HANDLE)
|
||||
vkDestroyAccelerationStructureKHR(vk_core.device, model->blas, NULL);
|
||||
model->blas = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
VK_BufferDestroy(&g_accel.scratch_buffer);
|
||||
|
|
|
@ -11,29 +11,30 @@
|
|||
#include "shaders/ray_interop.h"
|
||||
|
||||
typedef struct vk_ray_model_s {
|
||||
VkAccelerationStructureKHR as;
|
||||
VkAccelerationStructureKHR blas;
|
||||
VkDeviceAddress blas_addr;
|
||||
uint32_t kusochki_offset;
|
||||
qboolean dynamic;
|
||||
|
||||
// TODO remove
|
||||
struct {
|
||||
VkAccelerationStructureGeometryKHR *geoms;
|
||||
int max_prims;
|
||||
int num_geoms;
|
||||
int size;
|
||||
uint32_t size;
|
||||
qboolean taken;
|
||||
} cache;
|
||||
|
||||
uint32_t kusochki_offset;
|
||||
qboolean dynamic;
|
||||
|
||||
// TODO remove with the split of Kusok in Model+Material+Kusok
|
||||
vec4_t color;
|
||||
matrix4x4 prev_transform;
|
||||
} cache_toremove;
|
||||
} vk_ray_model_t;
|
||||
|
||||
typedef struct Kusok vk_kusok_data_t;
|
||||
|
||||
typedef struct rt_draw_instance_s {
|
||||
vk_ray_model_t *model_toremove;
|
||||
VkDeviceAddress blas_addr;
|
||||
uint32_t kusochki_offset;
|
||||
matrix3x4 transform_row;
|
||||
vk_ray_model_t *model;
|
||||
matrix4x4 prev_transform_row;
|
||||
vec4_t color;
|
||||
uint32_t material_mode; // MATERIAL_MODE_ from ray_interop.h
|
||||
} rt_draw_instance_t;
|
||||
|
||||
|
@ -46,10 +47,13 @@ typedef struct {
|
|||
uint32_t n_geoms;
|
||||
VkAccelerationStructureTypeKHR type;
|
||||
qboolean dynamic;
|
||||
|
||||
VkDeviceAddress *out_accel_addr;
|
||||
uint32_t *inout_size;
|
||||
} as_build_args_t;
|
||||
|
||||
struct vk_combuf_s;
|
||||
qboolean createOrUpdateAccelerationStructure(struct vk_combuf_s *combuf, const as_build_args_t *args, vk_ray_model_t *model);
|
||||
qboolean createOrUpdateAccelerationStructure(struct vk_combuf_s *combuf, const as_build_args_t *args);
|
||||
|
||||
#define MAX_SCRATCH_BUFFER (32*1024*1024)
|
||||
#define MAX_ACCELS_BUFFER (64*1024*1024)
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
xvk_ray_model_state_t g_ray_model_state;
|
||||
|
||||
static void returnModelToCache(vk_ray_model_t *model) {
|
||||
ASSERT(model->cache.taken);
|
||||
model->cache.taken = false;
|
||||
ASSERT(model->cache_toremove.taken);
|
||||
model->cache_toremove.taken = false;
|
||||
}
|
||||
|
||||
static vk_ray_model_t *getModelFromCache(int num_geoms, int max_prims, const VkAccelerationStructureGeometryKHR *geoms) { //}, int size) {
|
||||
|
@ -29,33 +29,33 @@ static vk_ray_model_t *getModelFromCache(int num_geoms, int max_prims, const VkA
|
|||
{
|
||||
int j;
|
||||
model = g_ray_model_state.models_cache + i;
|
||||
if (model->cache.taken)
|
||||
if (model->cache_toremove.taken)
|
||||
continue;
|
||||
|
||||
if (!model->as)
|
||||
if (!model->blas)
|
||||
break;
|
||||
|
||||
if (model->cache.num_geoms != num_geoms)
|
||||
if (model->cache_toremove.num_geoms != num_geoms)
|
||||
continue;
|
||||
|
||||
if (model->cache.max_prims != max_prims)
|
||||
if (model->cache_toremove.max_prims != max_prims)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < num_geoms; ++j) {
|
||||
if (model->cache.geoms[j].geometryType != geoms[j].geometryType)
|
||||
if (model->cache_toremove.geoms[j].geometryType != geoms[j].geometryType)
|
||||
break;
|
||||
|
||||
if (model->cache.geoms[j].flags != geoms[j].flags)
|
||||
if (model->cache_toremove.geoms[j].flags != geoms[j].flags)
|
||||
break;
|
||||
|
||||
if (geoms[j].geometryType == VK_GEOMETRY_TYPE_TRIANGLES_KHR) {
|
||||
// TODO what else should we compare?
|
||||
if (model->cache.geoms[j].geometry.triangles.maxVertex != geoms[j].geometry.triangles.maxVertex)
|
||||
if (model->cache_toremove.geoms[j].geometry.triangles.maxVertex != geoms[j].geometry.triangles.maxVertex)
|
||||
break;
|
||||
|
||||
ASSERT(model->cache.geoms[j].geometry.triangles.vertexStride == geoms[j].geometry.triangles.vertexStride);
|
||||
ASSERT(model->cache.geoms[j].geometry.triangles.vertexFormat == geoms[j].geometry.triangles.vertexFormat);
|
||||
ASSERT(model->cache.geoms[j].geometry.triangles.indexType == geoms[j].geometry.triangles.indexType);
|
||||
ASSERT(model->cache_toremove.geoms[j].geometry.triangles.vertexStride == geoms[j].geometry.triangles.vertexStride);
|
||||
ASSERT(model->cache_toremove.geoms[j].geometry.triangles.vertexFormat == geoms[j].geometry.triangles.vertexFormat);
|
||||
ASSERT(model->cache_toremove.geoms[j].geometry.triangles.indexType == geoms[j].geometry.triangles.indexType);
|
||||
} else {
|
||||
PRINT_NOT_IMPLEMENTED_ARGS("Non-tri geometries are not implemented");
|
||||
break;
|
||||
|
@ -72,15 +72,15 @@ static vk_ray_model_t *getModelFromCache(int num_geoms, int max_prims, const VkA
|
|||
// if (model->size > 0)
|
||||
// ASSERT(model->size >= size);
|
||||
|
||||
if (!model->cache.geoms) {
|
||||
if (!model->cache_toremove.geoms) {
|
||||
const size_t size = sizeof(*geoms) * num_geoms;
|
||||
model->cache.geoms = Mem_Malloc(vk_core.pool, size);
|
||||
memcpy(model->cache.geoms, geoms, size);
|
||||
model->cache.num_geoms = num_geoms;
|
||||
model->cache.max_prims = max_prims;
|
||||
model->cache_toremove.geoms = Mem_Malloc(vk_core.pool, size);
|
||||
memcpy(model->cache_toremove.geoms, geoms, size);
|
||||
model->cache_toremove.num_geoms = num_geoms;
|
||||
model->cache_toremove.max_prims = max_prims;
|
||||
}
|
||||
|
||||
model->cache.taken = true;
|
||||
model->cache_toremove.taken = true;
|
||||
return model;
|
||||
}
|
||||
|
||||
|
@ -203,10 +203,12 @@ vk_ray_model_t* VK_RayModelCreate( vk_ray_model_init_t args ) {
|
|||
gEngine.Con_Printf(S_ERROR "Ran out of model cache slots\n");
|
||||
} else {
|
||||
qboolean result;
|
||||
asrgs.p_accel = &ray_model->as;
|
||||
asrgs.p_accel = &ray_model->blas;
|
||||
asrgs.out_accel_addr = &ray_model->blas_addr;
|
||||
asrgs.inout_size = &ray_model->cache_toremove.size;
|
||||
|
||||
DEBUG_BEGINF(combuf->cmdbuf, "build blas for %s", args.model->debug_name);
|
||||
result = createOrUpdateAccelerationStructure(combuf, &asrgs, ray_model);
|
||||
result = createOrUpdateAccelerationStructure(combuf, &asrgs);
|
||||
DEBUG_END(combuf->cmdbuf);
|
||||
|
||||
if (!result)
|
||||
|
@ -217,8 +219,6 @@ vk_ray_model_t* VK_RayModelCreate( vk_ray_model_init_t args ) {
|
|||
} else {
|
||||
ray_model->kusochki_offset = ALO_ALLOC_FAILED;
|
||||
ray_model->dynamic = args.model->dynamic;
|
||||
Vector4Set(ray_model->color, 1, 1, 1, 1);
|
||||
Matrix4x4_LoadIdentity(ray_model->prev_transform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -234,11 +234,11 @@ vk_ray_model_t* VK_RayModelCreate( vk_ray_model_init_t args ) {
|
|||
|
||||
void VK_RayModelDestroy( struct vk_ray_model_s *model ) {
|
||||
ASSERT(vk_core.rtx);
|
||||
if (model->as != VK_NULL_HANDLE) {
|
||||
if (model->blas != VK_NULL_HANDLE) {
|
||||
//gEngine.Con_Reportf("Model %s destroying AS=%p blas_index=%d\n", model->debug_name, model->rtx.blas, blas_index);
|
||||
|
||||
vkDestroyAccelerationStructureKHR(vk_core.device, model->as, NULL);
|
||||
Mem_Free(model->cache.geoms);
|
||||
vkDestroyAccelerationStructureKHR(vk_core.device, model->blas, NULL);
|
||||
Mem_Free(model->cache_toremove.geoms);
|
||||
memset(model, 0, sizeof(*model));
|
||||
}
|
||||
}
|
||||
|
@ -347,14 +347,14 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render
|
|||
|
||||
ASSERT(vk_core.rtx);
|
||||
ASSERT(g_ray_model_state.frame.instances_count <= ARRAYSIZE(g_ray_model_state.frame.instances));
|
||||
ASSERT(model->cache.num_geoms == render_model->num_geometries);
|
||||
ASSERT(model->cache_toremove.num_geoms == render_model->num_geometries);
|
||||
|
||||
if (g_ray_model_state.frame.instances_count == ARRAYSIZE(g_ray_model_state.frame.instances)) {
|
||||
gEngine.Con_Printf(S_ERROR "Ran out of AccelerationStructure slots\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(model->as != VK_NULL_HANDLE);
|
||||
ASSERT(model->blas != VK_NULL_HANDLE);
|
||||
|
||||
// TODO this material mapping is context dependent. I.e. different entity types might need different ray tracing behaviours for
|
||||
// same render_mode/type and even texture.
|
||||
|
@ -401,10 +401,6 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render
|
|||
return;
|
||||
}
|
||||
|
||||
// TODO expunge
|
||||
Vector4Copy(render_model->color, model->color);
|
||||
Matrix4x4_Copy(model->prev_transform, render_model->prev_transform);
|
||||
|
||||
// TODO needed for brush models only
|
||||
// (? TODO studio models?)
|
||||
for (int i = 0; i < render_model->dynamic_polylights_count; ++i) {
|
||||
|
@ -414,9 +410,13 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render
|
|||
RT_LightAddPolygon(polylight);
|
||||
}
|
||||
|
||||
draw_instance->model = model;
|
||||
draw_instance->model_toremove = model;
|
||||
draw_instance->blas_addr = model->blas_addr;
|
||||
draw_instance->kusochki_offset = model->kusochki_offset;
|
||||
draw_instance->material_mode = material_mode;
|
||||
Vector4Copy(render_model->color, draw_instance->color);
|
||||
Matrix3x4_Copy(draw_instance->transform_row, render_model->transform);
|
||||
Matrix4x4_Copy(draw_instance->prev_transform_row, render_model->prev_transform);
|
||||
|
||||
g_ray_model_state.frame.instances_count++;
|
||||
}
|
||||
|
@ -432,13 +432,13 @@ void XVK_RayModel_ClearForNextFrame( void ) {
|
|||
// destroy/reuse dynamic ASes from previous frame
|
||||
for (int i = 0; i < g_ray_model_state.frame.instances_count; ++i) {
|
||||
rt_draw_instance_t *instance = g_ray_model_state.frame.instances + i;
|
||||
ASSERT(instance->model);
|
||||
ASSERT(instance->model_toremove);
|
||||
|
||||
if (!instance->model->dynamic)
|
||||
if (!instance->model_toremove->dynamic)
|
||||
continue;
|
||||
|
||||
returnModelToCache(instance->model);
|
||||
instance->model = NULL;
|
||||
returnModelToCache(instance->model_toremove);
|
||||
instance->model_toremove = NULL;
|
||||
}
|
||||
|
||||
g_ray_model_state.frame.instances_count = 0;
|
||||
|
|
Loading…
Reference in New Issue