add persistent model api and use it for brushes

this needed for better rtx blas management
This commit is contained in:
Ivan 'provod' Avdeev 2021-04-07 12:11:20 -07:00
parent 7fe55e6d90
commit af5e20269d
14 changed files with 273 additions and 177 deletions

View File

@ -1,5 +1,10 @@
## 2021-03-28
- [x] bake s/d-lights visibility data into bsp leaves
## 2021-04-06..07
- [ ] persistent models
- [x] load brushes into render model
- [x] destroy brushes when time comes (when?)
- [x] rasterize models in renderer
- [ ] rtx: build AS for model
- [ ] rtx: include pre-built models in TLAS
# Next
- [ ] rtx: use light visibility data
@ -151,3 +156,6 @@
## 2021-03-22
- [x] rtx: traverse bsp for science!
## 2021-03-28
- [x] bake s/d-lights visibility data into bsp leaves

View File

@ -301,7 +301,7 @@ void main() {
//if (gl_GlobalInvocationID.x > imageSize(image).x / 2)
{
const float wet = .9;
const float wet = .5;
C = mix(C, imageLoad(previous_frame, ivec2(gl_GlobalInvocationID.xy)).rgb, wet);
}
imageStore(image, ivec2(gl_GlobalInvocationID.xy), vec4(C, 1.));

View File

@ -17,20 +17,12 @@
#include <math.h>
#include <memory.h>
typedef struct vk_brush_model_surface_s {
int texture_num;
msurface_t *surf;
uint32_t index_offset;
uint16_t index_count;
} vk_brush_model_surface_t;
typedef struct vk_brush_model_s {
vk_buffer_handle_t vertex_buffer;
vk_buffer_handle_t index_buffer;
vk_render_model_t render_model;
int num_surfaces;
vk_brush_model_surface_t surfaces[];
// Surfaces for getting animated textures.
// Each surface corresponds to a single geometry within render_model with the same index.
msurface_t *surf[];
} vk_brush_model_t;
static struct {
@ -123,14 +115,11 @@ texture_t *R_TextureAnimation( const cl_entity_t *ent, msurface_t *s )
return base;
}
void VK_BrushDrawModel( const cl_entity_t *ent, int render_mode )
void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode )
{
// Expect all buffers to be bound
const model_t *mod = ent->model;
const vk_brush_model_t *bmodel = mod->cache.data;
int current_texture = -1;
int index_count = 0;
int index_offset = -1;
vk_brush_model_t *bmodel = mod->cache.data;
if (!bmodel) {
gEngine.Con_Printf( S_ERROR "Model %s wasn't loaded\n", mod->name);
@ -143,63 +132,58 @@ void VK_BrushDrawModel( const cl_entity_t *ent, int render_mode )
return;
}
VK_RenderDebugLabelBegin( mod->name );
for (int i = 0; i < bmodel->num_surfaces; ++i) {
const vk_brush_model_surface_t *bsurf = bmodel->surfaces + i;
texture_t *t = R_TextureAnimation(ent, bsurf->surf);
for (int i = 0; i < bmodel->render_model.num_geometries; ++i) {
texture_t *t = R_TextureAnimation(ent, bmodel->surf[i]);
if (t->gl_texturenum < 0)
continue;
if (current_texture != t->gl_texturenum)
{
if (index_count) {
const render_draw_t draw = {
.lightmap = tglob.lightmapTextures[0],
.texture = current_texture,
.render_mode = render_mode,
.element_count = index_count,
.vertex_buffer = bmodel->vertex_buffer,
.index_buffer = bmodel->index_buffer,
.vertex_offset = 0,
.index_offset = index_offset,
};
VK_RenderScheduleDraw( &draw );
}
current_texture = t->gl_texturenum;
index_count = 0;
index_offset = -1;
}
if (index_offset < 0)
index_offset = bsurf->index_offset;
// Make sure that all surfaces are concatenated in buffers
ASSERT(index_offset + index_count == bsurf->index_offset);
index_count += bsurf->index_count;
bmodel->render_model.geometries[i].texture = t->gl_texturenum;
}
if (index_count) {
const render_draw_t draw = {
.lightmap = tglob.lightmapTextures[0],
.texture = current_texture,
.render_mode = render_mode,
.element_count = index_count,
.vertex_buffer = bmodel->vertex_buffer,
.index_buffer = bmodel->index_buffer,
.vertex_offset = 0,
.index_offset = index_offset,
};
VK_RenderScheduleDraw( &draw );
}
VK_RenderDebugLabelEnd();
bmodel->render_model.render_mode = render_mode;
VK_RenderModelDraw(&bmodel->render_model);
}
static int loadBrushSurfaces( const model_t *mod, vk_brush_model_surface_t *out_surfaces) {
static qboolean renderableSurface( const msurface_t *surf, int i ) {
if( surf->flags & ( SURF_DRAWSKY | SURF_DRAWTURB | SURF_CONVEYOR | SURF_DRAWTURB_QUADS ) ) {
gEngine.Con_Reportf("Skipping surface %d because of flags %08x\n", i, surf->flags);
return false;
}
if( FBitSet( surf->flags, SURF_DRAWTILED )) {
gEngine.Con_Reportf("Skipping surface %d because of tiled flag\n", i);
return false;
}
return true;
}
typedef struct {
int num_surfaces, num_vertices, num_indices;
int max_texture_id;
} model_sizes_t;
static model_sizes_t computeSizes( const model_t *mod ) {
model_sizes_t sizes = {0};
for( int i = 0; i < mod->nummodelsurfaces; ++i)
{
const msurface_t *surf = mod->surfaces + mod->firstmodelsurface + i;
if (!renderableSurface(surf, i))
continue;
++sizes.num_surfaces;
sizes.num_vertices += surf->numedges;
sizes.num_indices += 3 * (surf->numedges - 1);
if (surf->texinfo->texture->gl_texturenum > sizes.max_texture_id)
sizes.max_texture_id = surf->texinfo->texture->gl_texturenum;
}
return sizes;
}
static qboolean loadBrushSurfaces( model_sizes_t sizes, const model_t *mod ) {
vk_brush_model_t *bmodel = mod->cache.data;
uint32_t vertex_offset = 0;
int num_surfaces = 0;
@ -209,35 +193,13 @@ static int loadBrushSurfaces( const model_t *mod, vk_brush_model_surface_t *out_
uint16_t *bind = NULL;
uint32_t index_offset = 0;
int num_indices = 0, num_vertices = 0, max_texture_id = 0;
for( int i = 0; i < mod->nummodelsurfaces; ++i)
{
const msurface_t *surf = mod->surfaces + mod->firstmodelsurface + i;
vk_brush_model_surface_t *bsurf = out_surfaces + num_surfaces;
if( surf->flags & ( SURF_DRAWSKY | SURF_DRAWTURB | SURF_CONVEYOR | SURF_DRAWTURB_QUADS ) ) {
gEngine.Con_Reportf("Skipping surface %d because of flags %08x\n", i, surf->flags);
continue;
}
if( FBitSet( surf->flags, SURF_DRAWTILED )) {
gEngine.Con_Reportf("Skipping surface %d because of tiled flag\n", i);
continue;
}
num_vertices += surf->numedges;
num_indices += 3 * (surf->numedges - 1);
if (surf->texinfo->texture->gl_texturenum > max_texture_id)
max_texture_id = surf->texinfo->texture->gl_texturenum;
}
vertex_buffer = VK_RenderBufferAlloc( sizeof(vk_vertex_t), num_vertices, LifetimeMap );
index_buffer = VK_RenderBufferAlloc( sizeof(uint16_t), num_indices, LifetimeMap );
vertex_buffer = VK_RenderBufferAlloc( sizeof(vk_vertex_t), sizes.num_vertices, LifetimeMap );
index_buffer = VK_RenderBufferAlloc( sizeof(uint16_t), sizes.num_indices, LifetimeMap );
if (vertex_buffer == InvalidHandle || index_buffer == InvalidHandle)
{
// TODO should we free one of the above if it still succeeded?
gEngine.Con_Printf(S_ERROR "Ran out of buffer space\n");
return -1;
return false;
}
vertex_lock = VK_RenderBufferLock( vertex_buffer );
@ -245,34 +207,25 @@ static int loadBrushSurfaces( const model_t *mod, vk_brush_model_surface_t *out_
bvert = vertex_lock.ptr;
bind = index_lock.ptr;
if (!bind)
{
gEngine.Con_Printf(S_ERROR "Ran out of buffer index space\n");
return -1;
}
g_brush.stat.num_indices += num_indices;
g_brush.stat.num_vertices += num_vertices;
// Load sorted by gl_texturenum
for (int t = 0; t <= max_texture_id; ++t)
for (int t = 0; t <= sizes.max_texture_id; ++t)
{
for( int i = 0; i < mod->nummodelsurfaces; ++i)
{
msurface_t *surf = mod->surfaces + mod->firstmodelsurface + i;
vk_brush_model_surface_t *bsurf = out_surfaces + num_surfaces;
mextrasurf_t *info = surf->info;
vk_render_geometry_t *model_geometry = bmodel->render_model.geometries + num_surfaces;
const float sample_size = gEngine.Mod_SampleSizeForFace( surf );
int index_count = 0;
if( surf->flags & ( SURF_DRAWSKY | SURF_DRAWTURB | SURF_CONVEYOR | SURF_DRAWTURB_QUADS ) )
continue;
if( FBitSet( surf->flags, SURF_DRAWTILED ))
if (!renderableSurface(surf, i))
continue;
if (t != surf->texinfo->texture->gl_texturenum)
continue;
bmodel->surf[num_surfaces] = surf;
++num_surfaces;
//gEngine.Con_Reportf( "surface %d: numverts=%d numedges=%d\n", i, surf->polys ? surf->polys->numverts : -1, surf->numedges );
@ -280,13 +233,13 @@ static int loadBrushSurfaces( const model_t *mod, vk_brush_model_surface_t *out_
if (vertex_offset + surf->numedges >= UINT16_MAX)
{
gEngine.Con_Printf(S_ERROR "Model %s indices don't fit into 16 bits\n", mod->name);
return -1;
// FIXME unlock and free buffers
return false;
}
bsurf->surf = surf;
bsurf->texture_num = surf->texinfo->texture->gl_texturenum;
bsurf->index_offset = index_offset;
bsurf->index_count = 0;
model_geometry->index_offset = index_offset;
model_geometry->vertex_offset = 0;
model_geometry->texture = t;
VK_CreateSurfaceLightmap( surf, mod );
@ -335,11 +288,12 @@ static int loadBrushSurfaces( const model_t *mod, vk_brush_model_surface_t *out_
*(bind++) = (uint16_t)(vertex_offset + 0);
*(bind++) = (uint16_t)(vertex_offset + k - 1);
*(bind++) = (uint16_t)(vertex_offset + k);
bsurf->index_count += 3;
index_count += 3;
index_offset += 3;
}
}
model_geometry->element_count = index_count;
vertex_offset += surf->numedges;
}
}
@ -347,16 +301,16 @@ static int loadBrushSurfaces( const model_t *mod, vk_brush_model_surface_t *out_
VK_RenderBufferUnlock( index_buffer );
VK_RenderBufferUnlock( vertex_buffer );
bmodel->vertex_buffer = vertex_buffer;
bmodel->index_buffer = index_buffer;
ASSERT(sizes.num_surfaces == num_surfaces);
bmodel->render_model.num_geometries = num_surfaces;
bmodel->render_model.index_buffer = index_buffer;
bmodel->render_model.vertex_buffer = vertex_buffer;
return num_surfaces;
}
qboolean VK_LoadBrushModel( model_t *mod, const byte *buffer )
qboolean VK_BrushModelLoad( model_t *mod )
{
vk_brush_model_t *bmodel;
if (mod->cache.data)
{
gEngine.Con_Reportf( S_WARN "Model %s was already loaded\n", mod->name );
@ -365,20 +319,40 @@ qboolean VK_LoadBrushModel( model_t *mod, const byte *buffer )
gEngine.Con_Reportf("%s: %s flags=%08x\n", __FUNCTION__, mod->name, mod->flags);
bmodel = Mem_Malloc(vk_core.pool, sizeof(vk_brush_model_t) + sizeof(vk_brush_model_surface_t) * mod->nummodelsurfaces);
mod->cache.data = bmodel;
{
const model_sizes_t sizes = computeSizes( mod );
vk_brush_model_t *bmodel = Mem_Malloc(vk_core.pool, sizeof(vk_brush_model_t) + (sizeof(msurface_t*) + sizeof(vk_render_geometry_t)) * sizes.num_surfaces);
mod->cache.data = bmodel;
bmodel->render_model.debug_name = mod->name;
bmodel->render_model.render_mode = kRenderNormal;
bmodel->render_model.geometries = (vk_render_geometry_t*)((char*)(bmodel + 1) + sizeof(msurface_t*) * sizes.num_surfaces);
bmodel->num_surfaces = loadBrushSurfaces( mod, bmodel->surfaces );
if (bmodel->num_surfaces < 0) {
gEngine.Con_Reportf( S_ERROR "Model %s was not loaded\n", mod->name );
return false;
if (!loadBrushSurfaces(sizes, mod) || !VK_RenderModelInit(&bmodel->render_model)) {
gEngine.Con_Printf(S_ERROR "Could not load model %s\n", mod->name);
Mem_Free(bmodel);
return false;
}
g_brush.stat.num_indices += sizes.num_indices;
g_brush.stat.num_vertices += sizes.num_vertices;
gEngine.Con_Reportf("Model %s loaded surfaces: %d (of %d); total vertices: %u, total indices: %u\n", mod->name, bmodel->render_model.num_geometries, mod->nummodelsurfaces, g_brush.stat.num_vertices, g_brush.stat.num_indices);
}
gEngine.Con_Reportf("Model %s loaded surfaces: %d (of %d); total vertices: %u, total indices: %u\n", mod->name, bmodel->num_surfaces, mod->nummodelsurfaces, g_brush.stat.num_vertices, g_brush.stat.num_indices);
return true;
}
void VK_BrushClear( void )
void VK_BrushModelDestroy( model_t *mod ) {
vk_brush_model_t *bmodel = mod->cache.data;
if (!bmodel)
return;
VK_RenderModelDestroy(&bmodel->render_model);
Mem_Free(bmodel);
mod->cache.data = NULL;
}
void VK_BrushStatsClear( void )
{
// Free previous map data
g_brush.stat.num_vertices = 0;

View File

@ -9,7 +9,9 @@ struct cl_entity_s;
qboolean VK_BrushInit( void );
void VK_BrushShutdown( void );
qboolean VK_LoadBrushModel( struct model_s *mod, const byte *buffer );
qboolean VK_BrushRenderBegin( void );
void VK_BrushDrawModel( const struct cl_entity_s *ent, int render_mode );
void VK_BrushClear( void );
qboolean VK_BrushModelLoad( struct model_s *mod );
void VK_BrushModelDestroy( struct model_s *mod );
void VK_BrushModelDraw( const struct cl_entity_s *ent, int render_mode );
void VK_BrushStatsClear( void );

View File

@ -183,7 +183,7 @@ static void loadDeviceFunctions(dllfunc_t *funcs, int count)
static qboolean createInstance( void )
{
const char **instance_extensions = NULL;
char ** instance_extensions = NULL;
unsigned int num_instance_extensions = vk_core.debug ? 1 : 0;
VkApplicationInfo app_info = {
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,

View File

@ -507,6 +507,7 @@ void VK_LightsBakePVL( int frame_number ) {
for (int i = 0; i < map->numleafs; ++i) {
const mleaf_t *leaf = map->leafs + i;
vk_light_leaf_t *lights = g_lights.leaves + i;
// TODO we should not decompress PVS, as it might be faster to interate through compressed directly
const byte *visdata = Mod_DecompressPVS(leaf->compressed_vis, world->visbytes);
int num_emissive_lights = 0;
@ -551,6 +552,11 @@ void VK_LightsBakePVL( int frame_number ) {
if (lights->num_slights == MAX_VISIBLE_SURFACE_LIGHTS)
continue;
// TODO cull by:
// - front/back facing?
// - distance and intensity
// - ...
lights->slights[lights->num_slights++] = candidate_light;
}
}

View File

@ -32,6 +32,7 @@ typedef struct {
typedef struct {
int frame_number;
// TODO make this opaque light clusters
int num_leaves; // same as worldmodel->numleaves
vk_light_leaf_t *leaves;

View File

@ -620,6 +620,8 @@ static uint32_t writeDlightsToUBO( void )
}
ubo_lights = (vk_ubo_lights_t*)((byte*)(g_render.uniform_buffer.mapped) + ubo_lights_offset);
// TODO rtx and query light styles
#if 0
for (int i = 0; i < g_render.num_static_lights && num_lights < ARRAYSIZE(ubo_lights->light); ++i) {
Vector4Set(
ubo_lights->light[num_lights].color,
@ -636,6 +638,7 @@ static uint32_t writeDlightsToUBO( void )
num_lights++;
}
#endif
// TODO this should not be here (where? vk_scene?)
for (int i = 0; i < MAX_DLIGHTS && num_lights < ARRAYSIZE(ubo_lights->light); ++i) {
@ -750,6 +753,7 @@ void VK_RenderEndRTX( VkCommandBuffer cmdbuf, VkImageView img_dst_view, VkImage
ASSERT(vk_core.rtx);
VK_RaySceneBegin();
for (int i = 0; i < g_render_state.num_draw_commands; ++i) {
const draw_command_t *const draw = g_render_state.draw_commands + i;
const vk_buffer_alloc_t *vertex_buffer = getBufferFromHandle( draw->draw.vertex_buffer );
@ -761,7 +765,7 @@ void VK_RenderEndRTX( VkCommandBuffer cmdbuf, VkImageView img_dst_view, VkImage
// but here we've completely lost this info, as models are now just a stream
// of independent draws
const vk_ray_model_create_t ray_model_args = {
const vk_ray_model_dynamic_t dynamic_model = {
.element_count = draw->draw.element_count,
.max_vertex = vertex_buffer->count, // TODO this is an upper bound for brushes at least, it can be lowered
.index_offset = index_buffer ? (draw->draw.index_offset + index_buffer->buffer_offset_in_units) : UINT32_MAX,
@ -772,7 +776,7 @@ void VK_RenderEndRTX( VkCommandBuffer cmdbuf, VkImageView img_dst_view, VkImage
.texture_id = draw->draw.texture,
};
VK_RayScenePushModel(cmdbuf, &ray_model_args);
VK_RaySceneAddModelDynamic(cmdbuf, &dynamic_model);
}
{
@ -823,3 +827,76 @@ void VK_RenderEndRTX( VkCommandBuffer cmdbuf, VkImageView img_dst_view, VkImage
VK_RaySceneEnd(&args);
}
}
qboolean VK_RenderModelInit( vk_render_model_t *model) {
if (vk_core.rtx) {
PRINT_NOT_IMPLEMENTED();
return false;
}
// TODO pre-bake optimal draws
return true;
}
void VK_RenderModelDestroy( vk_render_model_t* model ) {
(void)model;
if (vk_core.rtx) {
PRINT_NOT_IMPLEMENTED();
}
}
void VK_RenderModelDraw( vk_render_model_t* model ) {
int current_texture = -1;
int index_count = 0;
int index_offset = -1;
for (int i = 0; i < model->num_geometries; ++i) {
const vk_render_geometry_t *geom = model->geometries + i;
if (geom->texture < 0)
continue;
if (current_texture != geom->texture)
{
if (index_count) {
const render_draw_t draw = {
.lightmap = tglob.lightmapTextures[0],
.texture = current_texture,
.render_mode = model->render_mode,
.element_count = index_count,
.vertex_buffer = model->vertex_buffer,
.index_buffer = model->index_buffer,
.vertex_offset = 0,
.index_offset = index_offset,
};
VK_RenderScheduleDraw( &draw );
}
current_texture = geom->texture;
index_count = 0;
index_offset = -1;
}
if (index_offset < 0)
index_offset = geom->index_offset;
// Make sure that all surfaces are concatenated in buffers
ASSERT(index_offset + index_count == geom->index_offset);
index_count += geom->element_count;
}
if (index_count) {
const render_draw_t draw = {
.lightmap = tglob.lightmapTextures[0],
.texture = current_texture,
.render_mode = model->render_mode,
.element_count = index_count,
.vertex_buffer = model->vertex_buffer,
.index_buffer = model->index_buffer,
.vertex_offset = 0,
.index_offset = index_offset,
};
VK_RenderScheduleDraw( &draw );
}
}

View File

@ -66,13 +66,44 @@ typedef struct render_draw_s {
uint32_t element_count;
uint32_t index_offset, vertex_offset;
vk_buffer_handle_t index_buffer, vertex_buffer;
struct { float r, g, b; } emissive;
/* TODO this should be a separate thing? */ struct { float r, g, b; } emissive;
} render_draw_t;
void VK_RenderBegin( void );
typedef struct {
int texture;
uint32_t element_count;
uint32_t index_offset, vertex_offset;
} vk_render_geometry_t;
typedef struct {
const char *debug_name;
int render_mode;
int num_geometries;
vk_render_geometry_t *geometries;
// Common for the entire model
vk_buffer_handle_t index_buffer, vertex_buffer;
// TODO potentially dynamic data: textures
//qboolean dynamic; // whether this model will require data reupload
struct {
void *blas; // FIXME
} rtx;
} vk_render_model_t;
qboolean VK_RenderModelInit( vk_render_model_t* model );
void VK_RenderModelDestroy( vk_render_model_t* model );
void VK_RenderModelDraw( vk_render_model_t* model );
void VK_RenderFrameBegin( void );
// void VK_RenderObjectBegin( void *tag, const char *name /* expect transient ... */ );
// void VK_RenderObjectEnd();
void VK_RenderScheduleDraw( const render_draw_t *draw );
void VK_RenderEnd( VkCommandBuffer cmdbuf );
void VK_RenderEndRTX( VkCommandBuffer cmdbuf, VkImageView img_dst_view, VkImage img_dst, uint32_t w, uint32_t h );
void VK_RenderFrameEnd( VkCommandBuffer cmdbuf );
void VK_RenderFrameEndRTX( VkCommandBuffer cmdbuf, VkImageView img_dst_view, VkImage img_dst, uint32_t w, uint32_t h );
void VK_RenderDebugLabelBegin( const char *label );
void VK_RenderDebugLabelEnd( void );

View File

@ -138,11 +138,6 @@ static void Mod_LoadAliasModel( model_t *mod, const void *buffer, qboolean *load
PRINT_NOT_IMPLEMENTED_ARGS("(%p, %s), %p, %d", mod, mod->name, buffer, *loaded);
}
static void Mod_UnloadTextures( model_t *mod )
{
PRINT_NOT_IMPLEMENTED_ARGS("(%p, %s)", mod, mod->name);
}
static qboolean Mod_ProcessRenderData( model_t *mod, qboolean create, const byte *buffer )
{
qboolean loaded = true;
@ -175,8 +170,16 @@ static qboolean Mod_ProcessRenderData( model_t *mod, qboolean create, const byte
if( loaded && gEngine.drawFuncs->Mod_ProcessUserData )
gEngine.drawFuncs->Mod_ProcessUserData( mod, create, buffer );
if( !create )
Mod_UnloadTextures( mod );
if( !create ) {
switch( mod->type )
{
case mod_brush:
VK_BrushModelDestroy( mod );
break;
default:
PRINT_NOT_IMPLEMENTED_ARGS("destroy (%p, %d, %s)", mod, mod->type, mod->name);
}
}
return loaded;
}

View File

@ -208,7 +208,7 @@ static vk_ray_model_t *getModelByHandle(vk_ray_model_handle_t handle)
}
*/
void VK_RayScenePushModel( VkCommandBuffer cmdbuf, const vk_ray_model_create_t *create_info) // _handle_t model_handle )
void VK_RaySceneAddModelDynamic( VkCommandBuffer cmdbuf, const vk_ray_model_dynamic_t *dynamic)
{
vk_ray_model_t* model = g_rtx.models + g_rtx_scene.num_models;
ASSERT(g_rtx_scene.num_models <= ARRAYSIZE(g_rtx.models));
@ -221,8 +221,8 @@ void VK_RayScenePushModel( VkCommandBuffer cmdbuf, const vk_ray_model_create_t *
ASSERT(vk_core.rtx);
{
const VkDeviceAddress buffer_addr = getBufferDeviceAddress(create_info->buffer);
const uint32_t prim_count = create_info->element_count / 3;
const VkDeviceAddress buffer_addr = getBufferDeviceAddress(dynamic->buffer);
const uint32_t prim_count = dynamic->element_count / 3;
const VkAccelerationStructureGeometryKHR geom[] = {
{
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR,
@ -231,12 +231,12 @@ void VK_RayScenePushModel( VkCommandBuffer cmdbuf, const vk_ray_model_create_t *
.geometry.triangles =
(VkAccelerationStructureGeometryTrianglesDataKHR){
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR,
.indexType = create_info->index_offset == UINT32_MAX ? VK_INDEX_TYPE_NONE_KHR : VK_INDEX_TYPE_UINT16,
.maxVertex = create_info->max_vertex,
.indexType = dynamic->index_offset == UINT32_MAX ? VK_INDEX_TYPE_NONE_KHR : VK_INDEX_TYPE_UINT16,
.maxVertex = dynamic->max_vertex,
.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT,
.vertexStride = sizeof(vk_vertex_t),
.vertexData.deviceAddress = buffer_addr + create_info->vertex_offset * sizeof(vk_vertex_t),
.indexData.deviceAddress = buffer_addr + create_info->index_offset * sizeof(uint16_t),
.vertexData.deviceAddress = buffer_addr + dynamic->vertex_offset * sizeof(vk_vertex_t),
.indexData.deviceAddress = buffer_addr + dynamic->index_offset * sizeof(uint16_t),
},
} };
@ -257,18 +257,18 @@ void VK_RayScenePushModel( VkCommandBuffer cmdbuf, const vk_ray_model_create_t *
// Store geometry references in kusochki
{
vk_kusok_data_t *kusok = (vk_kusok_data_t*)(g_rtx.kusochki_buffer.mapped) + g_rtx_scene.num_models;
kusok->vertex_offset = create_info->vertex_offset;
kusok->index_offset = create_info->index_offset;
ASSERT(create_info->element_count % 3 == 0);
kusok->triangles = create_info->element_count / 3;
kusok->vertex_offset = dynamic->vertex_offset;
kusok->index_offset = dynamic->index_offset;
ASSERT(dynamic->element_count % 3 == 0);
kusok->triangles = dynamic->element_count / 3;
ASSERT(create_info->texture_id < MAX_TEXTURES);
if (create_info->texture_id >= 0 && g_emissive_texture_table[create_info->texture_id].set) {
VectorCopy(g_emissive_texture_table[create_info->texture_id].emissive, kusok->emissive);
ASSERT(dynamic->texture_id < MAX_TEXTURES);
if (dynamic->texture_id >= 0 && g_emissive_texture_table[dynamic->texture_id].set) {
VectorCopy(g_emissive_texture_table[dynamic->texture_id].emissive, kusok->emissive);
} else {
kusok->emissive[0] = create_info->emissive.r;
kusok->emissive[1] = create_info->emissive.g;
kusok->emissive[2] = create_info->emissive.b;
kusok->emissive[0] = dynamic->emissive.r;
kusok->emissive[1] = dynamic->emissive.g;
kusok->emissive[2] = dynamic->emissive.b;
}
if (kusok->emissive[0] > 0 || kusok->emissive[1] > 0 || kusok->emissive[2] > 0) {
@ -283,7 +283,7 @@ void VK_RayScenePushModel( VkCommandBuffer cmdbuf, const vk_ray_model_create_t *
}
}
memcpy(model->transform_row, *create_info->transform_row, sizeof(model->transform_row));
memcpy(model->transform_row, *dynamic->transform_row, sizeof(model->transform_row));
g_rtx_scene.num_models++;
}

View File

@ -12,15 +12,10 @@ typedef struct {
VkBuffer buffer;
const matrix3x4 *transform_row;
struct { float r,g,b; } emissive;
} vk_ray_model_create_t;
typedef int vk_ray_model_handle_t;
enum { InvalidRayModel = -1 };
vk_ray_model_handle_t VK_RayModelCreate( const vk_ray_model_create_t *args );
} vk_ray_model_dynamic_t;
void VK_RaySceneBegin( void );
void VK_RayScenePushModel(VkCommandBuffer cmdbuf, const vk_ray_model_create_t* model); // vk_ray_model_handle_t model );
void VK_RaySceneAddModelDynamic(VkCommandBuffer cmdbuf, const vk_ray_model_dynamic_t* model);
typedef struct {
VkCommandBuffer cmdbuf;

View File

@ -93,7 +93,7 @@ void R_NewMap( void )
VK_RunLightStyles();
// TODO should we do something like VK_BrushBeginLoad?
VK_BrushClear();
VK_BrushStatsClear();
// FIXME this is totally incorrect btw.
// When loading a save game from the same map this is called, but brush models
@ -116,7 +116,7 @@ void R_NewMap( void )
if( m->type != mod_brush )
continue;
if (!VK_LoadBrushModel( m, NULL ))
if (!VK_BrushModelLoad( m ))
{
gEngine.Con_Printf( S_ERROR "Couldn't load model %s\n", m->name );
}
@ -591,7 +591,7 @@ static void drawEntity( cl_entity_t *ent, int render_mode )
case mod_brush:
R_RotateForEntity( model, ent );
VK_RenderStateSetMatrixModel( model );
VK_BrushDrawModel( ent, render_mode );
VK_BrushModelDraw( ent, render_mode );
break;
case mod_studio:
@ -643,7 +643,7 @@ void VK_SceneRender( const ref_viewpass_t *rvp )
VK_LightsBakePVL( 0 /* FIXME frame number */);
VK_RenderStateSetColor( 1.f, 1.f, 1.f, 1.f);
VK_BrushDrawModel( world, kRenderNormal );
VK_BrushModelDraw( world, kRenderNormal );
}
}

View File

@ -18,7 +18,6 @@ void VK_SceneInit( void );
void VK_SceneRender( const struct ref_viewpass_s *rvp );
qboolean VK_LoadBrushModel( model_t *mod, const byte *buffer );
qboolean R_AddEntity( struct cl_entity_s *clent, int type );
void R_ProcessEntData( qboolean allocate );
void R_ClearScreen( void );