rt: apply instanced texture overrides to rt_model; makes sprites apply correct textures
This commit is contained in:
parent
8f47115a01
commit
edb151bd1b
|
@ -260,3 +260,18 @@ RT model draw:
|
|||
- NO similar calls for `*` brush submodels.
|
||||
2. For the rest of studio and sprite models:
|
||||
- Mod_ProcessRenderData(create=0)
|
||||
|
||||
# E274
|
||||
|
||||
rt_model:
|
||||
- kusok/geom
|
||||
- index_,vertex_offset (static, same as geom/blas lifetime)
|
||||
- ref to material (static or dynamic)
|
||||
- emissive (mostly static, independent to material)
|
||||
- instanceCustomIndex (24 bits) = offset to kusochki buffer
|
||||
- kusochki[G]
|
||||
- geom data (index, vertex offsets)
|
||||
- emissive
|
||||
- material
|
||||
- materials[M]
|
||||
- kusochki[N] <- iCI
|
||||
|
|
|
@ -103,11 +103,10 @@ struct Kusok {
|
|||
// Geometry data, static
|
||||
uint index_offset;
|
||||
uint vertex_offset;
|
||||
uint triangles;
|
||||
|
||||
// material below consists of scalar fields only, so it's not aligned to vec4.
|
||||
// Alignt it here to vec4 explicitly, so that later vector fields are properly aligned (for simplicity).
|
||||
uint _padding0;
|
||||
uint _padding0[2];
|
||||
|
||||
// Per-kusok because individual surfaces can be patched
|
||||
// TODO? still move to material, or its own table? As this can be dynamic
|
||||
|
|
|
@ -463,7 +463,6 @@ struct rt_blas_s* RT_BlasCreate(const char *name, rt_blas_usage_e usage) {
|
|||
|
||||
blas->debug_name = name;
|
||||
blas->usage = usage;
|
||||
//blas->kusochki_offset = -1;
|
||||
blas->blas_size = -1;
|
||||
|
||||
return blas;
|
||||
|
|
|
@ -64,10 +64,11 @@ qboolean createOrUpdateAccelerationStructure(struct vk_combuf_s *combuf, const a
|
|||
typedef struct {
|
||||
// Geometry metadata. Lifetime is similar to geometry lifetime itself.
|
||||
// Semantically close to render buffer (describes layout for those objects)
|
||||
// TODO unify with render buffer
|
||||
// TODO unify with render buffer?
|
||||
// Needs: STORAGE_BUFFER
|
||||
vk_buffer_t kusochki_buffer;
|
||||
r_debuffer_t kusochki_alloc;
|
||||
// TODO when fully rt_model: r_blocks_t alloc;
|
||||
|
||||
// Model header
|
||||
// Array of struct ModelHeader: color, material_mode, prev_transform
|
||||
|
@ -112,12 +113,12 @@ typedef struct rt_kusochki_s {
|
|||
int internal_index__;
|
||||
} rt_kusochki_t;
|
||||
|
||||
// TODO lifetime arg here is KORYAVY
|
||||
rt_kusochki_t RT_KusochkiAlloc(int count, r_geometry_lifetime_t lifetime);
|
||||
rt_kusochki_t RT_KusochkiAllocLong(int count);
|
||||
uint32_t RT_KusochkiAllocOnce(int count);
|
||||
void RT_KusochkiFree(const rt_kusochki_t*);
|
||||
|
||||
struct vk_render_geometry_s;
|
||||
qboolean RT_KusochkiUpload(const rt_kusochki_t *kusochki, const struct vk_render_geometry_s *geoms, int geoms_count, int override_texture_id);
|
||||
qboolean RT_KusochkiUpload(uint32_t kusochki_offset, const struct vk_render_geometry_s *geoms, int geoms_count, int override_texture_id);
|
||||
|
||||
// Update animated materials
|
||||
void RT_KusochkiUploadSubset(rt_kusochki_t *kusochki, const struct vk_render_geometry_s *geoms, const int *geoms_indices, int geoms_indices_count);
|
||||
|
|
|
@ -90,15 +90,15 @@ static vk_ray_model_t *getModelFromCache(int num_geoms, int max_prims, const VkA
|
|||
return model;
|
||||
}
|
||||
|
||||
static void applyMaterialToKusok(vk_kusok_data_t* kusok, const vk_render_geometry_t *geom) {
|
||||
const xvk_material_t *const mat = XVK_GetMaterialForTextureIndex( geom->texture );
|
||||
static void applyMaterialToKusok(vk_kusok_data_t* kusok, const vk_render_geometry_t *geom, int override_texture_id) {
|
||||
const int tex_id = override_texture_id > 0 ? override_texture_id : geom->texture;
|
||||
const xvk_material_t *const mat = XVK_GetMaterialForTextureIndex( tex_id );
|
||||
ASSERT(mat);
|
||||
|
||||
// TODO split kusochki into static geometry data and potentially dynamic material data
|
||||
// This data is static, should never change
|
||||
kusok->vertex_offset = geom->vertex_offset;
|
||||
kusok->index_offset = geom->index_offset;
|
||||
kusok->triangles = geom->element_count / 3;
|
||||
|
||||
// Material data itself is mostly static. Except for animated textures, which just get a new material slot for each frame.
|
||||
kusok->material = (struct Material){
|
||||
|
@ -300,7 +300,7 @@ static qboolean uploadKusochkiSubset(const vk_ray_model_t *const model, const vk
|
|||
vk_kusok_data_t *const kusochki = kusok_staging.ptr;
|
||||
|
||||
vk_render_geometry_t *geom = render_model->geometries + index;
|
||||
applyMaterialToKusok(kusochki + 0, geom);
|
||||
applyMaterialToKusok(kusochki + 0, geom, -1);
|
||||
|
||||
/* gEngine.Con_Reportf("model %s: geom=%d kuoffs=%d kustoff=%d kustsz=%d sthndl=%d\n", */
|
||||
/* render_model->debug_name, */
|
||||
|
@ -333,7 +333,7 @@ static qboolean uploadKusochki(const vk_ray_model_t *const model, const vk_rende
|
|||
|
||||
for (int i = 0; i < render_model->num_geometries; ++i) {
|
||||
vk_render_geometry_t *geom = render_model->geometries + i;
|
||||
applyMaterialToKusok(kusochki + i, geom);
|
||||
applyMaterialToKusok(kusochki + i, geom, -1);
|
||||
}
|
||||
|
||||
/* gEngine.Con_Reportf("model %s: geom=%d kuoffs=%d kustoff=%d kustsz=%d sthndl=%d\n", */
|
||||
|
@ -463,10 +463,9 @@ void XVK_RayModel_ClearForNextFrame( void ) {
|
|||
R_DEBuffer_Flip(&g_ray_model_state.kusochki_alloc);
|
||||
}
|
||||
|
||||
rt_kusochki_t RT_KusochkiAlloc(int count, r_geometry_lifetime_t lifetime) {
|
||||
rt_kusochki_t RT_KusochkiAllocLong(int count) {
|
||||
// TODO Proper block allocator
|
||||
const r_lifetime_t rlifetime = lifetime == LifetimeSingleFrame ? LifetimeDynamic : LifetimeStatic;
|
||||
uint32_t kusochki_offset = R_DEBuffer_Alloc(&g_ray_model_state.kusochki_alloc, rlifetime, count, 1);
|
||||
uint32_t kusochki_offset = R_DEBuffer_Alloc(&g_ray_model_state.kusochki_alloc, LifetimeStatic, count, 1);
|
||||
|
||||
if (kusochki_offset == ALO_ALLOC_FAILED) {
|
||||
gEngine.Con_Printf(S_ERROR "Maximum number of kusochki exceeded\n");
|
||||
|
@ -480,20 +479,27 @@ rt_kusochki_t RT_KusochkiAlloc(int count, r_geometry_lifetime_t lifetime) {
|
|||
};
|
||||
}
|
||||
|
||||
uint32_t RT_KusochkiAllocOnce(int count) {
|
||||
// TODO Proper block allocator
|
||||
uint32_t kusochki_offset = R_DEBuffer_Alloc(&g_ray_model_state.kusochki_alloc, LifetimeDynamic, count, 1);
|
||||
|
||||
if (kusochki_offset == ALO_ALLOC_FAILED) {
|
||||
gEngine.Con_Printf(S_ERROR "Maximum number of kusochki exceeded\n");
|
||||
return ALO_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
return kusochki_offset;
|
||||
}
|
||||
|
||||
void RT_KusochkiFree(const rt_kusochki_t *kusochki) {
|
||||
// TODO block alloc
|
||||
PRINT_NOT_IMPLEMENTED();
|
||||
}
|
||||
|
||||
qboolean RT_KusochkiUpload(const rt_kusochki_t *kusochki, const struct vk_render_geometry_s *geoms, int geoms_count, int override_texture_id) {
|
||||
ASSERT(kusochki->count == geoms_count);
|
||||
|
||||
// TODO not implemented yet
|
||||
ASSERT(override_texture_id < 0);
|
||||
|
||||
qboolean RT_KusochkiUpload(uint32_t kusochki_offset, const struct vk_render_geometry_s *geoms, int geoms_count, int override_texture_id) {
|
||||
const vk_staging_buffer_args_t staging_args = {
|
||||
.buffer = g_ray_model_state.kusochki_buffer.buffer,
|
||||
.offset = kusochki->offset * sizeof(vk_kusok_data_t),
|
||||
.offset = kusochki_offset * sizeof(vk_kusok_data_t),
|
||||
.size = geoms_count * sizeof(vk_kusok_data_t),
|
||||
.alignment = 16,
|
||||
};
|
||||
|
@ -507,7 +513,7 @@ qboolean RT_KusochkiUpload(const rt_kusochki_t *kusochki, const struct vk_render
|
|||
vk_kusok_data_t *const p = kusok_staging.ptr;
|
||||
for (int i = 0; i < geoms_count; ++i) {
|
||||
const vk_render_geometry_t *geom = geoms + i;
|
||||
applyMaterialToKusok(p + i, geom);
|
||||
applyMaterialToKusok(p + i, geom, override_texture_id);
|
||||
}
|
||||
|
||||
R_VkStagingUnlock(kusok_staging.handle);
|
||||
|
@ -515,7 +521,7 @@ qboolean RT_KusochkiUpload(const rt_kusochki_t *kusochki, const struct vk_render
|
|||
}
|
||||
|
||||
struct rt_model_s *RT_ModelCreate(rt_model_create_t args) {
|
||||
const rt_kusochki_t kusochki = RT_KusochkiAlloc(args.geometries_count, LifetimeLong);
|
||||
const rt_kusochki_t kusochki = RT_KusochkiAllocLong(args.geometries_count);
|
||||
if (kusochki.count == 0) {
|
||||
gEngine.Con_Printf(S_ERROR "Cannot allocate kusochki for %s\n", args.debug_name);
|
||||
return NULL;
|
||||
|
@ -532,7 +538,7 @@ struct rt_model_s *RT_ModelCreate(rt_model_create_t args) {
|
|||
goto fail;
|
||||
}
|
||||
|
||||
RT_KusochkiUpload(&kusochki, args.geometries, args.geometries_count, -1);
|
||||
RT_KusochkiUpload(kusochki.offset, args.geometries, args.geometries_count, -1);
|
||||
|
||||
{
|
||||
rt_model_t *const ret = Mem_Malloc(vk_core.pool, sizeof(*ret));
|
||||
|
@ -574,15 +580,22 @@ void RT_FrameAddModel( struct rt_model_s *model, rt_frame_add_model_t args ) {
|
|||
|
||||
rt_draw_instance_t* draw_instance = g_ray_model_state.frame.instances + g_ray_model_state.frame.instances_count;
|
||||
|
||||
/* if (args.textures_override > 0) { */
|
||||
/* // FIXME need geometries + count */
|
||||
/* rt_kusochki_t temp_kusok = RT_KusochkiAlloc(int count, r_geometry_lifetime_t lifetime); */
|
||||
/* qboolean RT_KusochkiUpload(const rt_kusochki_t *kusochki, const struct vk_render_geometry_s *geoms, int geoms_count, int override_texture_id); */
|
||||
/* } */
|
||||
uint32_t kusochki_offset = model->kusochki.offset;
|
||||
|
||||
if (args.override.textures > 0) {
|
||||
kusochki_offset = RT_KusochkiAllocOnce(args.override.geoms_count);
|
||||
if (kusochki_offset == ALO_ALLOC_FAILED)
|
||||
return;
|
||||
|
||||
if (!RT_KusochkiUpload(kusochki_offset, args.override.geoms, args.override.geoms_count, args.override.textures)) {
|
||||
gEngine.Con_Printf(S_ERROR "Couldn't upload kusochki for instanced model\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
draw_instance->model_toremove = NULL;
|
||||
draw_instance->blas_addr = model->blas_addr;
|
||||
draw_instance->kusochki_offset = model->kusochki.offset;
|
||||
draw_instance->kusochki_offset = kusochki_offset;
|
||||
draw_instance->material_mode = materialModeFromRenderType(args.render_type);
|
||||
Vector4Copy(*args.color, draw_instance->color);
|
||||
Matrix3x4_Copy(draw_instance->transform_row, args.transform);
|
||||
|
|
|
@ -809,7 +809,11 @@ void R_RenderModelDraw(const vk_render_model_t *model, r_model_draw_t args) {
|
|||
.transform = (const matrix3x4*)args.transform,
|
||||
.prev_transform = (const matrix3x4*)args.prev_transform,
|
||||
.color = args.color,
|
||||
.textures_override = args.textures_override,
|
||||
.override = {
|
||||
.textures = args.textures_override,
|
||||
.geoms = model->geometries,
|
||||
.geoms_count = model->num_geometries,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
submitToTraditionalRender(model, *args.transform, *args.color, args.render_type, args.textures_override);
|
||||
|
|
|
@ -76,7 +76,12 @@ typedef struct {
|
|||
int render_type; // TODO material_mode
|
||||
const matrix3x4 *transform, *prev_transform;
|
||||
const vec4_t *color;
|
||||
int textures_override; // Override kusochki/material textures if > 0
|
||||
|
||||
struct {
|
||||
int textures; // Override kusochki/material textures if > 0
|
||||
int geoms_count;
|
||||
const struct vk_render_geometry_s *geoms;
|
||||
} override;
|
||||
} rt_frame_add_model_t;
|
||||
|
||||
void RT_FrameAddModel( struct rt_model_s *model, rt_frame_add_model_t args );
|
||||
|
|
Loading…
Reference in New Issue