From fe931fcfd73bfb636a7b3be6d15a15e0641f7a07 Mon Sep 17 00:00:00 2001 From: Ivan 'provod' Avdeev Date: Sun, 19 Sep 2021 14:43:22 -0700 Subject: [PATCH] rtx: collect d/elights and static entity point lights sample all of them unconditionally for now --- ref_vk/shaders/ray.rgen | 63 +++++++--------- ref_vk/shaders/ray_interop.h | 5 ++ ref_vk/vk_const.h | 4 +- ref_vk/vk_light.c | 135 +++++++++++++++++++++++++++++------ ref_vk/vk_light.h | 13 +++- ref_vk/vk_ray_internal.h | 9 ++- ref_vk/vk_render.c | 46 ------------ ref_vk/vk_render.h | 3 - ref_vk/vk_rtx.c | 52 ++++++-------- ref_vk/vk_rtx.h | 3 - ref_vk/vk_scene.c | 10 +-- 11 files changed, 191 insertions(+), 152 deletions(-) diff --git a/ref_vk/shaders/ray.rgen b/ref_vk/shaders/ray.rgen index 6fefd48e..6245ef3e 100644 --- a/ref_vk/shaders/ray.rgen +++ b/ref_vk/shaders/ray.rgen @@ -8,68 +8,55 @@ #extension GL_EXT_shader_8bit_storage : require // FIXME what should this be? -const float dlight_attenuation_const = 10000.; +const float point_light_attenuation_const = 10000.; const float shadow_offset_fudge = .1; const float meters_per_unit = 1. / 39.37; -layout (constant_id = 0) const uint MAX_DLIGHTS = 32; +layout (constant_id = 0) const uint MAX_POINT_LIGHTS = 32; layout (constant_id = 1) const uint MAX_EMISSIVE_KUSOCHKI = 256; -layout (constant_id = 2) const uint MAX_VISIBLE_DLIGHTS = 255;//15; -layout (constant_id = 3) const uint MAX_VISIBLE_SURFACE_LIGHTS = 255;//31; +layout (constant_id = 2) const uint MAX_VISIBLE_POINT_LIGHTS = 31; +layout (constant_id = 3) const uint MAX_VISIBLE_SURFACE_LIGHTS = 255; layout (constant_id = 4) const float LIGHT_GRID_CELL_SIZE = 256.; layout (constant_id = 5) const uint MAX_LIGHT_CLUSTERS = 32768; -const uint LIGHT_CLUSTER_SIZE = 2 + MAX_VISIBLE_DLIGHTS + MAX_VISIBLE_SURFACE_LIGHTS; -const uint LIGHT_CLUSTER_NUM_DLIGHTS_OFFSET = 0; -const uint LIGHT_CLUSTER_NUM_EMISSIVE_SURFACES_OFFSET = 1; -const uint LIGHT_CLUSTER_DLIGHTS_DATA_OFFSET = 2; -const uint LIGHT_CLUSTER_EMISSIVE_SURFACES_DATA_OFFSET = 3 + MAX_VISIBLE_DLIGHTS; +//const uint LIGHT_CLUSTER_SIZE = 2 + MAX_VISIBLE_POINT_LIGHTS + MAX_VISIBLE_SURFACE_LIGHTS; +//const uint LIGHT_CLUSTER_NUM_DLIGHTS_OFFSET = 0; +//const uint LIGHT_CLUSTER_NUM_EMISSIVE_SURFACES_OFFSET = 1; +//const uint LIGHT_CLUSTER_DLIGHTS_DATA_OFFSET = 2; +//const uint LIGHT_CLUSTER_EMISSIVE_SURFACES_DATA_OFFSET = 3 + MAX_VISIBLE_DLIGHTS; -layout(binding = 0, set = 0, rgba8) uniform image2D image; -layout(binding = 1, set = 0) uniform accelerationStructureEXT tlas; -layout(binding = 2, set = 0) uniform UBO { +layout(set = 0, binding = 0, rgba8) uniform image2D image; +layout(set = 0, binding = 1) uniform accelerationStructureEXT tlas; +layout(set = 0, binding = 2) uniform UBO { mat4 inv_proj, inv_view; - - // TODO combine - //int num_lights; - //Light lights[]; } ubo; -struct Light { - vec4 pos_r; - vec4 color; -}; - -// TODO move these into light clusters -layout(set = 0, binding = 7) uniform UBODLights { - uint num_lights; - Light lights[MAX_DLIGHTS]; -}; - // TODO #include, use from here and regular shader struct EmissiveKusok { uint kusok_index; vec4 tx_row_x, tx_row_y, tx_row_z; }; -layout (set = 0, binding = 8/*, align=4*/) uniform UBOEmissiveKusochki { +layout (set = 0, binding = 7/*, align=4*/) uniform Lights { uint num_kusochki; + uint num_point_lights; EmissiveKusok kusochki[MAX_EMISSIVE_KUSOCHKI]; -} emissive_kusochki; + PointLight point_lights[MAX_POINT_LIGHTS]; +} lights; struct LightCluster { uint8_t num_dlights; uint8_t num_emissive_surfaces; - uint8_t dlights[MAX_VISIBLE_DLIGHTS]; + uint8_t point_lights[MAX_VISIBLE_POINT_LIGHTS]; uint8_t emissive_surfaces[MAX_VISIBLE_SURFACE_LIGHTS]; }; -layout (set = 0, binding = 9, align = 1) readonly buffer UBOLightClusters { +layout (set = 0, binding = 8, align = 1) readonly buffer UBOLightClusters { ivec3 grid_min, grid_size; //uint8_t clusters_data[MAX_LIGHT_CLUSTERS * LIGHT_CLUSTER_SIZE + HACK_OFFSET]; LightCluster clusters[MAX_LIGHT_CLUSTERS]; } light_grid; -layout(set = 0, binding = 10, rgba8) uniform readonly image2D previous_frame; +layout(set = 0, binding = 9, rgba8) uniform readonly image2D previous_frame; layout (push_constant) uniform PushConstants { uint random_seed; @@ -169,8 +156,8 @@ vec3 computeLighting(vec3 view_dir, MaterialProperties material) { for (uint i = 0; i < num_emissive_kusochki; ++i) { #endif const uint index_into_emissive_kusochki = uint(light_grid.clusters[cluster_index].emissive_surfaces[i]); - const EmissiveKusok ek = emissive_kusochki.kusochki[index_into_emissive_kusochki]; - const uint emissive_kusok_index = emissive_kusochki.kusochki[index_into_emissive_kusochki].kusok_index; + const EmissiveKusok ek = lights.kusochki[index_into_emissive_kusochki]; + const uint emissive_kusok_index = lights.kusochki[index_into_emissive_kusochki].kusok_index; const Kusok ekusok = kusochki[emissive_kusok_index]; const vec3 emissive = ekusok.emissive; @@ -191,9 +178,9 @@ vec3 computeLighting(vec3 view_dir, MaterialProperties material) { C += sampling_light_scale * payload.base_color * emissive * sampleSurfaceTriangle(view_dir, material, emissive_transform, emissive_transform_normal, triangle_index, ekusok.index_offset, ekusok.vertex_offset); } // for all emissive kusochki - for (uint i = 0; i < num_lights; ++i) { - const vec4 light_pos_r = lights[i].pos_r; - const vec3 light_color = lights[i].color.rgb; + for (uint i = 0; i < lights.num_point_lights; ++i) { + const vec4 light_pos_r = lights.point_lights[i].position; + const vec3 light_color = lights.point_lights[i].color.rgb; // Find random point on a sphere // TODO proper BRDF importance sampling and correct random point distribution @@ -216,7 +203,7 @@ vec3 computeLighting(vec3 view_dir, MaterialProperties material) { const float r2 = light_pos_r.w * light_pos_r.w; // TODO this is a bad approximation - const float attenuation = dlight_attenuation_const / (d2 + r2 * .5); + const float attenuation = point_light_attenuation_const / (d2 + r2 * .5); C += payload.base_color * light_color * dot_ld_norm * attenuation; } // for all lights } diff --git a/ref_vk/shaders/ray_interop.h b/ref_vk/shaders/ray_interop.h index f91d6c69..3cfe01ee 100644 --- a/ref_vk/shaders/ray_interop.h +++ b/ref_vk/shaders/ray_interop.h @@ -30,6 +30,11 @@ struct Kusok { float roughness; }; +struct PointLight { + vec4 position; + vec4 color; +}; + #ifndef GLSL #undef uint #undef vec3 diff --git a/ref_vk/vk_const.h b/ref_vk/vk_const.h index d241e905..4f024f7a 100644 --- a/ref_vk/vk_const.h +++ b/ref_vk/vk_const.h @@ -9,8 +9,8 @@ #define MAX_BUFFER_VERTICES (1 * 1024 * 1024) #define MAX_BUFFER_INDICES (MAX_BUFFER_VERTICES * 3) -#define MAX_VISIBLE_DLIGHTS 255 +#define MAX_POINT_LIGHTS 255 +#define MAX_VISIBLE_POINT_LIGHTS 31 #define MAX_VISIBLE_SURFACE_LIGHTS 255 - #define MAX_LIGHT_CLUSTERS 32768 #define LIGHT_GRID_CELL_SIZE 256 diff --git a/ref_vk/vk_light.c b/ref_vk/vk_light.c index c80d894e..0d10c373 100644 --- a/ref_vk/vk_light.c +++ b/ref_vk/vk_light.c @@ -12,6 +12,21 @@ vk_lights_t g_lights = {0}; +typedef struct { + vec3_t origin; + vec3_t color; + //int style; + //char pattern[64]; + //int dark; +} vk_light_entity_t; + +struct { + int num_lights; + vk_light_entity_t lights[64]; + + // TODO spot light entities +} g_light_entities; + typedef struct { const char *name; int r, g, b, intensity; @@ -134,7 +149,13 @@ static void loadRadData( const model_t *map, const char *fmt, ... ) { Mem_Free(buffer); } +static void addStaticPointLight(vec3_t origin, vec3_t color) +{ +} + static void parseStaticLightEntities( void ) { + g_light_entities.num_lights = 0; + const model_t* const world = gEngine.pfnGetModelByIndex( 1 ); char *pos; enum { @@ -144,9 +165,8 @@ static void parseStaticLightEntities( void ) { struct { vec3_t origin; vec3_t color; - //float radius; - int style; - } light = {0}; + //int style; + } values; enum { HaveOrigin = 1, HaveColor = 2, @@ -159,6 +179,7 @@ static void parseStaticLightEntities( void ) { ASSERT(world); pos = world->entities; + //gEngine.Con_Reportf("ENTITIES: %s\n", pos); for (;;) { string key, value; @@ -174,11 +195,24 @@ static void parseStaticLightEntities( void ) { // TODO handle entity if (have != HaveAll) continue; - if (classname != Light && classname != LightSpot) - continue; - // TODO store this - //VK_RenderAddStaticLight(light.origin, light.color); + switch (classname) { + case Light: + if (g_light_entities.num_lights == ARRAYSIZE(g_light_entities.lights)) { + gEngine.Con_Printf(S_ERROR "Too many lights entities in map\n"); + continue; + } else { + vk_light_entity_t *le = g_light_entities.lights + g_light_entities.num_lights++; + VectorCopy(values.origin, le->origin); + VectorCopy(values.color, le->color); + //le->style = values.style; + } + break; + case LightSpot: + // TODO + break; + } + continue; } @@ -188,32 +222,32 @@ static void parseStaticLightEntities( void ) { if (Q_strcmp(key, "origin") == 0) { const int components = sscanf(value, "%f %f %f", - &light.origin[0], - &light.origin[1], - &light.origin[2]); + &values.origin[0], + &values.origin[1], + &values.origin[2]); if (components == 3) have |= HaveOrigin; } else if (Q_strcmp(key, "_light") == 0) { float scale = 1.f / 255.f; const int components = sscanf(value, "%f %f %f %f", - &light.color[0], - &light.color[1], - &light.color[2], + &values.color[0], + &values.color[1], + &values.color[2], &scale); if (components == 1) { - light.color[2] = light.color[1] = light.color[0] = light.color[0] / 255.f; + values.color[2] = values.color[1] = values.color[0] = values.color[0] / 255.f; have |= HaveColor; } else if (components == 4) { scale /= 255.f * 255.f; - light.color[0] *= scale; - light.color[1] *= scale; - light.color[2] *= scale; + values.color[0] *= scale; + values.color[1] *= scale; + values.color[2] *= scale; have |= HaveColor; } else if (components == 3) { - light.color[0] *= scale; - light.color[1] *= scale; - light.color[2] *= scale; + values.color[0] *= scale; + values.color[1] *= scale; + values.color[2] *= scale; have |= HaveColor; } } else if (Q_strcmp(key, "classname") == 0) { @@ -545,6 +579,33 @@ const vk_emissive_surface_t *VK_LightsAddEmissiveSurface( const struct vk_render return NULL; } +static qboolean addDlight( const dlight_t *dlight ) { + vk_point_light_t *light = g_lights.point_lights + g_lights.num_point_lights; + + if( !dlight || dlight->die < gpGlobals->time || !dlight->radius ) + return true; + + if (g_lights.num_point_lights >= MAX_POINT_LIGHTS) + return false; + + Vector4Set( + light->color, + dlight->color.r / 255.f, + dlight->color.g / 255.f, + dlight->color.b / 255.f, + 1.f); + Vector4Set( + light->origin, + dlight->origin[0], + dlight->origin[1], + dlight->origin[2], + dlight->radius); + + ++g_lights.num_point_lights; + + return true; +} + void VK_LightsFrameFinalize( void ) { if (g_lights.num_emissive_surfaces > UINT8_MAX) { @@ -552,6 +613,40 @@ void VK_LightsFrameFinalize( void ) g_lights.num_emissive_surfaces = UINT8_MAX; } + g_lights.num_point_lights = 0; + for (int i = 0; i < g_light_entities.num_lights; ++i, ++g_lights.num_point_lights) { + const vk_light_entity_t *entity = g_light_entities.lights + i; + vk_point_light_t *light = g_lights.point_lights + g_lights.num_point_lights; + + if (g_lights.num_point_lights >= MAX_POINT_LIGHTS) { + gEngine.Con_Printf(S_ERROR "Too many point light entities, MAX_POINT_LIGHTS=%d\n", MAX_POINT_LIGHTS); + break; + } + + Vector4Copy(entity->color, light->color); + Vector4Copy(entity->origin, light->origin); + + // FIXME ??? + light->origin[3] = 50.f; + light->color[3] = 1.f; + } + + for (int i = 0; i < MAX_ELIGHTS; ++i) { + const dlight_t *dlight = gEngine.GetEntityLight(i); + if (!addDlight(dlight)) { + gEngine.Con_Printf(S_ERROR "Too many elights, MAX_POINT_LIGHTS=%d\n", MAX_POINT_LIGHTS); + break; + } + } + + for (int i = 0; i < MAX_DLIGHTS; ++i) { + const dlight_t *dlight = gEngine.GetDynamicLight(i); + if (!addDlight(dlight)) { + gEngine.Con_Printf(S_ERROR "Too many dlights, MAX_POINT_LIGHTS=%d\n", MAX_POINT_LIGHTS); + break; + } + } + #if 0 // Print light grid stats gEngine.Con_Reportf("Emissive surfaces found: %d\n", g_lights.num_emissive_surfaces); diff --git a/ref_vk/vk_light.h b/ref_vk/vk_light.h index de4438b8..89704b1a 100644 --- a/ref_vk/vk_light.h +++ b/ref_vk/vk_light.h @@ -13,9 +13,9 @@ typedef struct { } vk_emissive_texture_t; typedef struct { - uint8_t num_dlights; + uint8_t num_point_lights; uint8_t num_emissive_surfaces; - uint8_t dlights[MAX_VISIBLE_DLIGHTS]; + uint8_t point_lights[MAX_VISIBLE_POINT_LIGHTS]; uint8_t emissive_surfaces[MAX_VISIBLE_SURFACE_LIGHTS]; } vk_lights_cell_t; @@ -25,6 +25,12 @@ typedef struct { matrix3x4 transform; } vk_emissive_surface_t; +typedef struct { + vec4_t origin, color; +} vk_point_light_t; + +// TODO spotlight + typedef struct { struct { int grid_min_cell[3]; @@ -37,6 +43,9 @@ typedef struct { int num_emissive_surfaces; vk_emissive_surface_t emissive_surfaces[255]; // indexed by uint8_t + int num_point_lights; + vk_point_light_t point_lights[MAX_POINT_LIGHTS]; + vk_lights_cell_t cells[MAX_LIGHT_CLUSTERS]; } vk_lights_t; diff --git a/ref_vk/vk_ray_internal.h b/ref_vk/vk_ray_internal.h index 4399b3ed..1022afc9 100644 --- a/ref_vk/vk_ray_internal.h +++ b/ref_vk/vk_ray_internal.h @@ -2,6 +2,7 @@ #include "vk_core.h" #include "vk_buffer.h" +#include "vk_const.h" #include "shaders/ray_interop.h" @@ -29,13 +30,15 @@ typedef struct Kusok vk_kusok_data_t; typedef struct { uint32_t num_kusochki; - uint32_t padding__[3]; + uint32_t num_point_lights; + uint32_t padding__[2]; struct { uint32_t kusok_index; uint32_t padding__[3]; matrix3x4 transform; } kusochki[MAX_EMISSIVE_KUSOCHKI]; -} vk_emissive_kusochki_t; + struct PointLight point_lights[MAX_POINT_LIGHTS]; +} vk_lights_buffer_t; typedef struct { matrix3x4 transform_row; @@ -76,7 +79,7 @@ typedef struct { // - fully dynamic lights: re-built each frame, so becomes similar to scratch_buffer and could be unified (same about uniform binding opt) // This allows studio and other non-brush model to be emissive. // Needs: STORAGE/UNIFORM_BUFFER - vk_buffer_t emissive_kusochki_buffer; + vk_buffer_t lights_buffer; // Per-frame data that is accumulated between RayFrameBegin and End calls struct { diff --git a/ref_vk/vk_render.c b/ref_vk/vk_render.c index d1b9b091..6d1030a0 100644 --- a/ref_vk/vk_render.c +++ b/ref_vk/vk_render.c @@ -36,11 +36,6 @@ static struct { vk_buffer_t uniform_buffer; uint32_t ubo_align; - struct { - vec3_t origin, color; - } static_lights[32]; - int num_static_lights; - float fov_angle_y; } g_render; @@ -332,7 +327,6 @@ void XVK_RenderBufferMapFreeze( void ) { void XVK_RenderBufferMapClear( void ) { VK_RingBuffer_Clear(&g_render.buffer_alloc_ring); - g_render.num_static_lights = 0; } void XVK_RenderBufferFrameClear( /*int frame_id*/void ) { @@ -539,16 +533,6 @@ static void drawCmdPushDraw( const render_draw_t *draw ) Matrix3x4_Copy(draw_command->draw.transform, g_render_state.model); } -void VK_RenderAddStaticLight(vec3_t origin, vec3_t color) -{ - if (g_render.num_static_lights == ARRAYSIZE(g_render.static_lights)) - return; - - VectorCopy(origin, g_render.static_lights[g_render.num_static_lights].origin); - VectorCopy(color, g_render.static_lights[g_render.num_static_lights].color); - g_render.num_static_lights++; -} - // Return offset of dlights data into UBO buffer static uint32_t writeDlightsToUBO( void ) { @@ -561,26 +545,6 @@ 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 1 - for (int i = 0; i < g_render.num_static_lights && num_lights < ARRAYSIZE(ubo_lights->light); ++i) { - Vector4Set( - ubo_lights->light[num_lights].color, - g_render.static_lights[i].color[0], - g_render.static_lights[i].color[1], - g_render.static_lights[i].color[2], - 1.f); - Vector4Set( - ubo_lights->light[num_lights].pos_r, - g_render.static_lights[i].origin[0], - g_render.static_lights[i].origin[1], - g_render.static_lights[i].origin[2], - 50.f /* FIXME WHAT */); - - 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) { const dlight_t *l = gEngine.GetDynamicLight(i); @@ -689,10 +653,6 @@ void VK_RenderDebugLabelEnd( void ) void VK_RenderEndRTX( VkCommandBuffer cmdbuf, VkImageView img_dst_view, VkImage img_dst, uint32_t w, uint32_t h ) { - const uint32_t dlights_ubo_offset = writeDlightsToUBO(); - if (dlights_ubo_offset == UINT32_MAX) - return; - ASSERT(vk_core.rtx); { @@ -711,12 +671,6 @@ void VK_RenderEndRTX( VkCommandBuffer cmdbuf, VkImageView img_dst_view, VkImage .size = sizeof(matrix4x4) * 2, }, - .dlights = { - .buffer = g_render.uniform_buffer.buffer, - .offset = dlights_ubo_offset, - .size = sizeof(vk_ubo_lights_t), - }, - .geometry_data = { .buffer = g_render.buffer.buffer, .size = VK_WHOLE_SIZE, diff --git a/ref_vk/vk_render.h b/ref_vk/vk_render.h index d42c5a3c..088685a3 100644 --- a/ref_vk/vk_render.h +++ b/ref_vk/vk_render.h @@ -46,9 +46,6 @@ void VK_RenderStateSetMatrixProjection(const matrix4x4 proj, float fov_angle_y); void VK_RenderStateSetMatrixView(const matrix4x4 view); void VK_RenderStateSetMatrixModel(const matrix4x4 model); -// TODO: radius, intensity, style, PVS bits, etc.. -void VK_RenderAddStaticLight(vec3_t origin, vec3_t color); - // 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 diff --git a/ref_vk/vk_rtx.c b/ref_vk/vk_rtx.c index 109b4db2..bc27166c 100644 --- a/ref_vk/vk_rtx.c +++ b/ref_vk/vk_rtx.c @@ -67,11 +67,10 @@ enum { RayDescBinding_Vertices = 5, RayDescBinding_Textures = 6, - RayDescBinding_UBOLights = 7, - RayDescBinding_EmissiveKusochki = 8, - RayDescBinding_LightClusters = 9, + RayDescBinding_Lights = 7, + RayDescBinding_LightClusters = 8, - RayDescBinding_PrevFrame = 10, + RayDescBinding_PrevFrame = 9, RayDescBinding_COUNT }; @@ -333,24 +332,24 @@ void VK_RayFrameBegin( void ) static void createPipeline( void ) { struct RayShaderSpec { - int max_dlights; + int max_point_lights; int max_emissive_kusochki; - uint32_t max_visible_dlights; + uint32_t max_visible_point_lights; uint32_t max_visible_surface_lights; float light_grid_cell_size; int max_light_clusters; } spec_data = { - .max_dlights = MAX_DLIGHTS, + .max_point_lights = MAX_POINT_LIGHTS, .max_emissive_kusochki = MAX_EMISSIVE_KUSOCHKI, - .max_visible_dlights = MAX_VISIBLE_DLIGHTS, + .max_visible_point_lights = MAX_VISIBLE_POINT_LIGHTS, .max_visible_surface_lights = MAX_VISIBLE_SURFACE_LIGHTS, .light_grid_cell_size = LIGHT_GRID_CELL_SIZE, .max_light_clusters = MAX_LIGHT_CLUSTERS, }; const VkSpecializationMapEntry spec_map[] = { - {.constantID = 0, .offset = offsetof(struct RayShaderSpec, max_dlights), .size = sizeof(int) }, + {.constantID = 0, .offset = offsetof(struct RayShaderSpec, max_point_lights), .size = sizeof(int) }, {.constantID = 1, .offset = offsetof(struct RayShaderSpec, max_emissive_kusochki), .size = sizeof(int) }, - {.constantID = 2, .offset = offsetof(struct RayShaderSpec, max_visible_dlights), .size = sizeof(uint32_t) }, + {.constantID = 2, .offset = offsetof(struct RayShaderSpec, max_visible_point_lights), .size = sizeof(uint32_t) }, {.constantID = 3, .offset = offsetof(struct RayShaderSpec, max_visible_surface_lights), .size = sizeof(uint32_t) }, {.constantID = 4, .offset = offsetof(struct RayShaderSpec, light_grid_cell_size), .size = sizeof(float) }, {.constantID = 5, .offset = offsetof(struct RayShaderSpec, max_light_clusters), .size = sizeof(int) }, @@ -565,14 +564,8 @@ static void updateDescriptors( VkCommandBuffer cmdbuf, const vk_ray_frame_render dii_all_textures[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; } - g_rtx.desc_values[RayDescBinding_UBOLights].buffer = (VkDescriptorBufferInfo){ - .buffer = args->dlights.buffer, - .offset = args->dlights.offset, - .range = args->dlights.size, - }; - - g_rtx.desc_values[RayDescBinding_EmissiveKusochki].buffer = (VkDescriptorBufferInfo){ - .buffer = g_ray_model_state.emissive_kusochki_buffer.buffer, + g_rtx.desc_values[RayDescBinding_Lights].buffer = (VkDescriptorBufferInfo){ + .buffer = g_ray_model_state.lights_buffer.buffer, .offset = 0, .range = VK_WHOLE_SIZE, }; @@ -665,13 +658,19 @@ static void updateLights( void ) // Upload dynamic emissive kusochki { - vk_emissive_kusochki_t *ek = g_ray_model_state.emissive_kusochki_buffer.mapped; + vk_lights_buffer_t *ek = g_ray_model_state.lights_buffer.mapped; ASSERT(g_lights.num_emissive_surfaces <= MAX_EMISSIVE_KUSOCHKI); ek->num_kusochki = g_lights.num_emissive_surfaces; for (int i = 0; i < g_lights.num_emissive_surfaces; ++i) { ek->kusochki[i].kusok_index = g_lights.emissive_surfaces[i].kusok_index; Matrix3x4_Copy(ek->kusochki[i].transform, g_lights.emissive_surfaces[i].transform); } + + ek->num_point_lights = g_lights.num_point_lights; + for (int i = 0; i < g_lights.num_point_lights; ++i) { + Vector4Copy(g_lights.point_lights[i].origin, ek->point_lights[i].position); + Vector4Copy(g_lights.point_lights[i].color, ek->point_lights[i].color); + } } } @@ -915,15 +914,8 @@ static void createLayouts( void ) { // for (int i = 0; i < ARRAYSIZE(samplers); ++i) // samplers[i] = vk_core.default_sampler; - g_rtx.desc_bindings[RayDescBinding_UBOLights] = (VkDescriptorSetLayoutBinding){ - .binding = RayDescBinding_UBOLights, - .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR, - }; - - g_rtx.desc_bindings[RayDescBinding_EmissiveKusochki] = (VkDescriptorSetLayoutBinding){ - .binding = RayDescBinding_EmissiveKusochki, + g_rtx.desc_bindings[RayDescBinding_Lights] = (VkDescriptorSetLayoutBinding){ + .binding = RayDescBinding_Lights, .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorCount = 1, .stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR, @@ -1008,7 +1000,7 @@ qboolean VK_RayInit( void ) } g_ray_model_state.kusochki_alloc.size = MAX_KUSOCHKI; - if (!createBuffer("ray emissive_kusochki_buffer", &g_ray_model_state.emissive_kusochki_buffer, sizeof(vk_emissive_kusochki_t), + if (!createBuffer("ray lights_buffer", &g_ray_model_state.lights_buffer, sizeof(vk_lights_buffer_t), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT /* | VK_BUFFER_USAGE_TRANSFER_DST_BIT */, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) { // FIXME complain, handle @@ -1085,7 +1077,7 @@ void VK_RayShutdown( void ) destroyBuffer(&g_rtx.accels_buffer); destroyBuffer(&g_rtx.tlas_geom_buffer); destroyBuffer(&g_ray_model_state.kusochki_buffer); - destroyBuffer(&g_ray_model_state.emissive_kusochki_buffer); + destroyBuffer(&g_ray_model_state.lights_buffer); destroyBuffer(&g_rtx.light_grid_buffer); destroyBuffer(&g_rtx.sbt_buffer); } diff --git a/ref_vk/vk_rtx.h b/ref_vk/vk_rtx.h index 8c01fd30..56f046c2 100644 --- a/ref_vk/vk_rtx.h +++ b/ref_vk/vk_rtx.h @@ -37,9 +37,6 @@ typedef struct { // TODO inv_view/proj matrices instead of UBO vk_buffer_region_t ubo; - // TODO get rid of this, dlights should be in light clusters - vk_buffer_region_t dlights; - // Buffer holding vertex and index data struct { VkBuffer buffer; // must be the same as in vk_ray_model_create_t TODO: validate or make impossible to specify incorrectly diff --git a/ref_vk/vk_scene.c b/ref_vk/vk_scene.c index 02a91a2b..7e1a8e0e 100644 --- a/ref_vk/vk_scene.c +++ b/ref_vk/vk_scene.c @@ -97,6 +97,11 @@ void R_NewMap( void ) if (is_save_load) return; + // TODO should we do something like VK_BrushBeginLoad? + VK_BrushStatsClear(); + + XVK_RenderBufferMapClear(); + VK_ClearLightmap(); // This is to ensure that we have computed lightstyles properly @@ -104,11 +109,6 @@ void R_NewMap( void ) VK_LightsNewMap(); - // TODO should we do something like VK_BrushBeginLoad? - VK_BrushStatsClear(); - - XVK_RenderBufferMapClear(); - if (vk_core.rtx) VK_RayNewMap();