diff --git a/include/QF/Vulkan/qf_bsp.h b/include/QF/Vulkan/qf_bsp.h index 7f279ffc2..6c69f2586 100644 --- a/include/QF/Vulkan/qf_bsp.h +++ b/include/QF/Vulkan/qf_bsp.h @@ -146,7 +146,8 @@ typedef struct bspctx_s { VkDeviceMemory texture_memory; VkPipeline depth; VkPipeline gbuf; - VkPipeline sky; + VkPipeline skysheet; + VkPipeline skybox; VkPipeline turb; VkPipelineLayout layout; size_t vertex_buffer_size; @@ -162,6 +163,7 @@ struct vulkan_ctx_s; void Vulkan_ClearElements (struct vulkan_ctx_s *ctx); void Vulkan_DrawWorld (struct vulkan_ctx_s *ctx); void Vulkan_DrawSky (struct vulkan_ctx_s *ctx); +void Vulkan_LoadSkys (const char *sky, struct vulkan_ctx_s *ctx); void Vulkan_RegisterTextures (model_t **models, int num_models, struct vulkan_ctx_s *ctx); void Vulkan_BuildDisplayLists (model_t **models, int num_models, diff --git a/include/QF/Vulkan/qf_texture.h b/include/QF/Vulkan/qf_texture.h index a70ba1116..55a631f62 100644 --- a/include/QF/Vulkan/qf_texture.h +++ b/include/QF/Vulkan/qf_texture.h @@ -15,6 +15,10 @@ void Vulkan_ExpandPalette (byte *dst, const byte *src, const byte *palette, int alpha, int count); qfv_tex_t *Vulkan_LoadTex (struct vulkan_ctx_s *ctx, tex_t *tex, int mip, const char *name); +qfv_tex_t *Vulkan_LoadEnvMap (struct vulkan_ctx_s *ctx, tex_t *tex, + const char *name); +qfv_tex_t *Vulkan_LoadEnvSides (struct vulkan_ctx_s *ctx, tex_t **tex, + const char *name); VkImageView Vulkan_TexImageView (qfv_tex_t *tex) __attribute__((pure)); void Vulkan_UnloadTex (struct vulkan_ctx_s *ctx, qfv_tex_t *tex); void Vulkan_Texture_Init (struct vulkan_ctx_s *ctx); diff --git a/libs/video/renderer/vid_render_vulkan.c b/libs/video/renderer/vid_render_vulkan.c index 82f677e33..836e1349a 100644 --- a/libs/video/renderer/vid_render_vulkan.c +++ b/libs/video/renderer/vid_render_vulkan.c @@ -223,6 +223,7 @@ vulkan_R_ClearState (void) static void vulkan_R_LoadSkys (const char *skyname) { + Vulkan_LoadSkys (skyname, vulkan_ctx); } static void diff --git a/libs/video/renderer/vulkan/qfpipeline.plist b/libs/video/renderer/vulkan/qfpipeline.plist index 2d95f06b4..d19294a80 100644 --- a/libs/video/renderer/vulkan/qfpipeline.plist +++ b/libs/video/renderer/vulkan/qfpipeline.plist @@ -652,6 +652,43 @@ layout = quakebsp_layout; //renderPass = renderpass; }; + bsp_skybox = { + subpass = 1; + stages = ( + { + stage = vertex; + name = main; + module = $builtin/quakebsp.vert; + }, + { + stage = fragment; + name = main; + module = $builtin/bsp_sky.frag; + specializationInfo = { + mapEntries = ( + { size = 4; offset = 0; constantID = 1; }, + { size = 4; offset = 4; constantID = 0; }, + ); + data = <00000000ffffffff>; + }; + }, + ); + vertexInput = $properties.vertexInput.brush; + inputAssembly = $properties.inputAssembly.brush; + viewport = $properties.viewport; + rasterization = $properties.rasterization.cw_cull_back; + multisample = $properties.multisample; + depthStencil = $properties.depthStencil.test_only; + colorBlend = { + logicOpEnable = false; + attachments = ($properties.attachmentBlendOp.disabled); + }; + dynamic = { + dynamicState = ( viewport, scissor ); + }; + layout = quakebsp_layout; + //renderPass = renderpass; + }; bsp_skysheet = { subpass = 1; stages = ( diff --git a/libs/video/renderer/vulkan/shader/bsp_sky.frag b/libs/video/renderer/vulkan/shader/bsp_sky.frag index 28ce41421..ed6828a10 100644 --- a/libs/video/renderer/vulkan/shader/bsp_sky.frag +++ b/libs/video/renderer/vulkan/shader/bsp_sky.frag @@ -14,7 +14,7 @@ layout (location = 1) in vec3 direction; layout (location = 0) out vec4 frag_color; -layout (constant_id = 0) const bool doSkyCube = false; +layout (constant_id = 0) const bool doSkyBox = false; layout (constant_id = 1) const bool doSkySheet = false; const float SCALE = 8.0; @@ -55,12 +55,14 @@ sky_sheet (vec3 dir, float time) } vec4 -sky_cube (vec3 dir, float time) +sky_box (vec3 dir, float time) { // NOTE: quake's world is right-handed with Z up and X forward, but // Vulkan's cube maps are left-handed with Y up and Z forward. The // rotation to X foward is done by the Sky matrix so all that's left // to do here is swizzle the Y and Z coordinates + dir = normalize(dir); + //return vec4(dir.xyz, 1) * 0.5 + vec4(0.5); return texture (SkyCube, dir.xzy); } @@ -68,15 +70,14 @@ vec4 sky_color (vec3 dir, float time) { if (!doSkySheet) { - return vec4 (1, 0, 1, 1); - //return sky_cube (dir, time); - } if (!doSkyCube) { + return sky_box (dir, time); + } if (!doSkyBox) { return sky_sheet (dir, time); } else { // can see through the sheet (may look funny when looking down) // maybe have 4 sheet layers instead of 2? vec4 c1 = sky_sheet (dir, time); - vec4 c2 = sky_cube (dir, time); + vec4 c2 = sky_box (dir, time); return vec4 (mix (c2.rgb, c1.rgb, c1.a), max (c1.a, c2.a)); return vec4 (1, 0, 1, 1); } @@ -87,7 +88,7 @@ main (void) { vec4 c; - if (doSkyCube || doSkySheet) { + if (doSkyBox || doSkySheet) { c = sky_color (direction, time); } else { c = vec4 (0, 0, 0, 1); diff --git a/libs/video/renderer/vulkan/vulkan_bsp.c b/libs/video/renderer/vulkan/vulkan_bsp.c index a85625440..bceea6666 100644 --- a/libs/video/renderer/vulkan/vulkan_bsp.c +++ b/libs/video/renderer/vulkan/vulkan_bsp.c @@ -1054,7 +1054,11 @@ sky_begin (vulkan_ctx_t *ctx) bframe->imageInfo[4].imageView = get_view (bctx->skybox_tex, bctx->default_skybox); - bsp_begin_subpass (QFV_bspSky, bctx->sky, ctx); + if (bctx->skybox_tex) { + bsp_begin_subpass (QFV_bspSky, bctx->skybox, ctx); + } else { + bsp_begin_subpass (QFV_bspSky, bctx->skysheet, ctx); + } } static void @@ -1370,7 +1374,7 @@ create_default_skys (vulkan_ctx_t *ctx) VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT); QFV_duSetObjectName (device, VK_OBJECT_TYPE_IMAGE_VIEW, boxview, - "bsp:iview:default_skysheet"); + "bsp:iview:default_skybox"); sheetview = QFV_CreateImageView (device, skysheet, VK_IMAGE_VIEW_TYPE_2D_ARRAY, @@ -1481,7 +1485,8 @@ Vulkan_Bsp_Init (vulkan_ctx_t *ctx) bctx->depth = Vulkan_CreatePipeline (ctx, "bsp_depth"); bctx->gbuf = Vulkan_CreatePipeline (ctx, "bsp_gbuf"); - bctx->sky = Vulkan_CreatePipeline (ctx, "bsp_skysheet"); + bctx->skybox = Vulkan_CreatePipeline (ctx, "bsp_skybox"); + bctx->skysheet = Vulkan_CreatePipeline (ctx, "bsp_skysheet"); bctx->turb = Vulkan_CreatePipeline (ctx, "bsp_turb"); bctx->layout = Vulkan_CreatePipelineLayout (ctx, "quakebsp_layout"); bctx->sampler = Vulkan_CreateSampler (ctx, "quakebsp_sampler"); @@ -1533,7 +1538,8 @@ Vulkan_Bsp_Shutdown (struct vulkan_ctx_s *ctx) dfunc->vkDestroyPipeline (device->dev, bctx->depth, 0); dfunc->vkDestroyPipeline (device->dev, bctx->gbuf, 0); - dfunc->vkDestroyPipeline (device->dev, bctx->sky, 0); + dfunc->vkDestroyPipeline (device->dev, bctx->skybox, 0); + dfunc->vkDestroyPipeline (device->dev, bctx->skysheet, 0); dfunc->vkDestroyPipeline (device->dev, bctx->turb, 0); DARRAY_CLEAR (&bctx->texture_chains); DARRAY_CLEAR (&bctx->frames); @@ -1548,6 +1554,10 @@ Vulkan_Bsp_Shutdown (struct vulkan_ctx_s *ctx) dfunc->vkFreeMemory (device->dev, bctx->index_memory, 0); } + if (bctx->skybox_tex) { + Vulkan_UnloadTex (ctx, bctx->skybox_tex); + } + dfunc->vkDestroyImageView (device->dev, bctx->default_skysheet->view, 0); dfunc->vkDestroyImage (device->dev, bctx->default_skysheet->image, 0); @@ -1590,103 +1600,61 @@ copy_sub_tex (tex_t *src, int x, int y, tex_t *dst) dstbytes); }*/ -/*XXX void -Vulkan_R_LoadSkys (const char *sky, vulkan_ctx_t *ctx) +void +Vulkan_LoadSkys (const char *sky, vulkan_ctx_t *ctx) { -const char *name; + bspctx_t *bctx = ctx->bsp_context; + + const char *name; int i; tex_t *tex; - // NOTE: quake's world and GL's world are rotated relative to each other - // quake has x right, y in, z up. gl has x right, y up, z out - // quake order: +x -x +z -z +y -y - // gl order: +x -x +y -y +z -z - // fizquake orger: -y +y +z -z +x -x - // to get from quake order to fitzquake order, all that's needed is - // a -90 degree rotation on the (quake) z-axis. This is taken care of in - // the sky_matrix setup code. - // However, from the player's perspective, skymaps have lf and rt - // swapped, but everythink makes sense if looking at the cube from outside - // along the positive y axis, with the front of the cube being the nearest - // face. This matches nicely with Blender's default cube in front (num-1) - // view. static const char *sky_suffix[] = { "ft", "bk", "up", "dn", "rt", "lf"}; - static int sky_coords[][2] = { - {2, 0}, // front - {0, 0}, // back - {1, 1}, // up - {0, 1}, // down - {2, 1}, // left - {1, 0}, // right - }; - if (!sky || !*sky) + if (bctx->skybox_tex) { + Vulkan_UnloadTex (ctx, bctx->skybox_tex); + } + bctx->skybox_tex = 0; + + if (!sky || !*sky) { sky = r_skyname->string; + } if (!*sky || !strcasecmp (sky, "none")) { - skybox_loaded = false; + Sys_MaskPrintf (SYS_VULKAN, "Skybox unloaded\n"); return; } - if (!skybox_tex) - qfeglGenTextures (1, &skybox_tex); - - qfeglBindTexture (GL_TEXTURE_CUBE_MAP, skybox_tex); - - //blender envmap - // bk rt ft - // dn up lt - tex = LoadImage (name = va ("env/%s_map", sky)); - if (tex && tex->format >= 3 && tex->height * 3 == tex->width * 2 - && is_pow2 (tex->height)) { - tex_t *sub; - int size = tex->height / 2; - - skybox_loaded = true; - sub = malloc (field_offset (tex_t, data[size * size * tex->format])); - sub->width = size; - sub->height = size; - sub->format = tex->format; - sub->palette = tex->palette; - for (i = 0; i < 6; i++) { - int x, y; - x = sky_coords[i][0] * size; - y = sky_coords[i][1] * size; - copy_sub_tex (tex, x, y, sub); - qfeglTexImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, - sub->format == 3 ? GL_RGB : GL_RGBA, - sub->width, sub->height, 0, - sub->format == 3 ? GL_RGB : GL_RGBA, - GL_UNSIGNED_BYTE, sub->data); - } - free (sub); + name = va (ctx->va_ctx, "env/%s_map", sky); + tex = LoadImage (name, 1); + if (tex) { + bctx->skybox_tex = Vulkan_LoadEnvMap (ctx, tex, sky); + Sys_MaskPrintf (SYS_VULKAN, "Loaded %s\n", name); } else { - skybox_loaded = true; + int failed = 0; + tex_t *sides[6] = { }; + for (i = 0; i < 6; i++) { - tex = LoadImage (name = va ("env/%s%s", sky, sky_suffix[i])); - if (!tex || tex->format < 3) { // FIXME pcx support - Sys_MaskPrintf (SYS_GLSL, "Couldn't load %s\n", name); + name = va (ctx->va_ctx, "env/%s%s", sky, sky_suffix[i]); + tex = LoadImage (name, 1); + if (!tex) { + Sys_MaskPrintf (SYS_VULKAN, "Couldn't load %s\n", name); // also look in gfx/env, where Darkplaces looks for skies - tex = LoadImage (name = va ("gfx/env/%s%s", sky, - sky_suffix[i])); - if (!tex || tex->format < 3) { // FIXME pcx support - Sys_MaskPrintf (SYS_GLSL, "Couldn't load %s\n", name); - skybox_loaded = false; + name = va (ctx->va_ctx, "gfx/env/%s%s", sky, sky_suffix[i]); + tex = LoadImage (name, 1); + if (!tex) { + Sys_MaskPrintf (SYS_VULKAN, "Couldn't load %s\n", name); + failed = 1; continue; } } - Sys_MaskPrintf (SYS_GLSL, "Loaded %s\n", name); - qfeglTexImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, - tex->format == 3 ? GL_RGB : GL_RGBA, - tex->width, tex->height, 0, - tex->format == 3 ? GL_RGB : GL_RGBA, - GL_UNSIGNED_BYTE, tex->data); + sides[i] = tex; + Sys_MaskPrintf (SYS_VULKAN, "Loaded %s\n", name); + } + if (!failed) { + bctx->skybox_tex = Vulkan_LoadEnvSides (ctx, sides, sky); } } - qfeglTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, - GL_CLAMP_TO_EDGE); - qfeglTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, - GL_CLAMP_TO_EDGE); - qfeglTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qfeglTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - qfeglGenerateMipmap (GL_TEXTURE_CUBE_MAP); -}*/ + if (bctx->skybox_tex) { + Sys_MaskPrintf (SYS_VULKAN, "Skybox %s loaded\n", sky); + } +} diff --git a/libs/video/renderer/vulkan/vulkan_texture.c b/libs/video/renderer/vulkan/vulkan_texture.c index 7d975298d..7aa8cfc64 100644 --- a/libs/video/renderer/vulkan/vulkan_texture.c +++ b/libs/video/renderer/vulkan/vulkan_texture.c @@ -96,45 +96,76 @@ Vulkan_ExpandPalette (byte *dst, const byte *src, const byte *palette, } } +static int +tex_format (const tex_t *tex, VkFormat *format, int *bpp) +{ + switch (tex->format) { + case tex_l: + case tex_a: + *format = VK_FORMAT_R8_UNORM; + *bpp = 1; + return 1; + case tex_la: + *format = VK_FORMAT_R8G8_UNORM; + *bpp = 2; + return 1; + case tex_palette: + if (!tex->palette) { + return 0; + } + *format = VK_FORMAT_R8G8B8A8_UNORM; + *bpp = 4; + return 1; + case tex_rgb: + *format = VK_FORMAT_R8G8B8A8_UNORM; + *bpp = 4; + return 1; + case tex_rgba: + *format = VK_FORMAT_R8G8B8A8_UNORM; + *bpp = 4; + return 1; + case tex_frgba: + *format = VK_FORMAT_R32G32B32A32_SFLOAT; + *bpp = 16; + return 1; + } + return 0; +} + +static size_t +stage_tex_data (qfv_packet_t *packet, tex_t *tex, int bpp) +{ + size_t texels = tex->width * tex->height; + byte *tex_data = QFV_PacketExtend (packet, bpp * texels); + + if (tex->format == tex_palette) { + Vulkan_ExpandPalette (tex_data, tex->data, tex->palette, 1, texels); + } else { + if (tex->format == 3) { + byte *in = tex->data; + byte *out = tex_data; + while (texels-- > 0) { + *out++ = *in++; + *out++ = *in++; + *out++ = *in++; + *out++ = 255; + } + } else { + memcpy (tex_data, tex->data, bpp * texels); + } + } + return tex_data - (byte *) packet->stage->data; +} + qfv_tex_t * Vulkan_LoadTex (vulkan_ctx_t *ctx, tex_t *tex, int mip, const char *name) { qfv_device_t *device = ctx->device; qfv_devfuncs_t *dfunc = device->funcs; - int bpp = 0; - VkFormat format = VK_FORMAT_UNDEFINED; + int bpp; + VkFormat format; - switch (tex->format) { - case tex_l: - case tex_a: - format = VK_FORMAT_R8_UNORM; - bpp = 1; - break; - case tex_la: - format = VK_FORMAT_R8G8_UNORM; - bpp = 2; - break; - case tex_palette: - if (!tex->palette) { - return 0; - } - format = VK_FORMAT_R8G8B8A8_UNORM; - bpp = 4; - break; - case tex_rgb: - format = VK_FORMAT_R8G8B8_UNORM; - bpp = 3; - break; - case tex_rgba: - format = VK_FORMAT_R8G8B8A8_UNORM; - bpp = 4; - break; - case tex_frgba: - format = VK_FORMAT_R32G32B32A32_SFLOAT; - bpp = 16; - break; - } - if (format == VK_FORMAT_UNDEFINED) { + if (!tex_format (tex, &format, &bpp)) { return 0; } @@ -169,16 +200,8 @@ Vulkan_LoadTex (vulkan_ctx_t *ctx, tex_t *tex, int mip, const char *name) QFV_duSetObjectName (device, VK_OBJECT_TYPE_IMAGE_VIEW, qtex->view, va (ctx->va_ctx, "iview:%s", name)); - size_t bytes = bpp * tex->width * tex->height; qfv_packet_t *packet = QFV_PacketAcquire (ctx->staging); - byte *tex_data = QFV_PacketExtend (packet, bytes); - - if (tex->format == tex_palette) { - Vulkan_ExpandPalette (tex_data, tex->data, tex->palette, - 1, tex->width * tex->height); - } else { - memcpy (tex_data, tex->data, bytes); - } + stage_tex_data (packet, tex, bpp); VkImageMemoryBarrier barrier; qfv_pipelinestagepair_t stages; @@ -214,6 +237,176 @@ Vulkan_LoadTex (vulkan_ctx_t *ctx, tex_t *tex, int mip, const char *name) return qtex; } +static qfv_tex_t * +create_cubetex (vulkan_ctx_t *ctx, int size, VkFormat format, + const char *name) +{ + qfv_device_t *device = ctx->device; + + qfv_tex_t *qtex = malloc (sizeof (qfv_tex_t)); + + VkExtent3D extent = { size, size, 1 }; + qtex->image = QFV_CreateImage (device, 1, VK_IMAGE_TYPE_2D, format, extent, + 1, 1, VK_SAMPLE_COUNT_1_BIT, + VK_IMAGE_USAGE_SAMPLED_BIT + | VK_IMAGE_USAGE_TRANSFER_DST_BIT); + QFV_duSetObjectName (device, VK_OBJECT_TYPE_IMAGE, qtex->image, + va (ctx->va_ctx, "image:envmap:%s", name)); + qtex->memory = QFV_AllocImageMemory (device, qtex->image, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + 0, 0); + QFV_duSetObjectName (device, VK_OBJECT_TYPE_DEVICE_MEMORY, qtex->memory, + va (ctx->va_ctx, "memory:%s", name)); + QFV_BindImageMemory (device, qtex->image, qtex->memory, 0); + qtex->view = QFV_CreateImageView (device, qtex->image, + VK_IMAGE_VIEW_TYPE_CUBE, format, + VK_IMAGE_ASPECT_COLOR_BIT); + QFV_duSetObjectName (device, VK_OBJECT_TYPE_IMAGE_VIEW, qtex->view, + va (ctx->va_ctx, "iview:envmap:%s", name)); + + return qtex; +} + +qfv_tex_t * +Vulkan_LoadEnvMap (vulkan_ctx_t *ctx, tex_t *tex, const char *name) +{ + qfv_device_t *device = ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; + int bpp; + VkFormat format; + + static int env_coords[][2] = { + {2, 0}, // right + {0, 0}, // left + {1, 1}, // top + {0, 1}, // bottom + {2, 1}, // front + {1, 0}, // back + }; + + if (!tex_format (tex, &format, &bpp)) { + return 0; + } + if (tex->height * 3 != tex->width * 2) { + return 0; + } + + int size = tex->height / 2; + qfv_tex_t *qtex = create_cubetex (ctx, size, format, name); + + qfv_packet_t *packet = QFV_PacketAcquire (ctx->staging); + stage_tex_data (packet, tex, bpp); + + VkImageMemoryBarrier barrier; + qfv_pipelinestagepair_t stages; + + stages = imageLayoutTransitionStages[qfv_LT_Undefined_to_TransferDst]; + barrier = imageLayoutTransitionBarriers[qfv_LT_Undefined_to_TransferDst]; + barrier.image = qtex->image; + barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; + barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; + dfunc->vkCmdPipelineBarrier (packet->cmd, stages.src, stages.dst, + 0, 0, 0, 0, 0, + 1, &barrier); + + VkBufferImageCopy copy[6] = { + { + 0, tex->width, 0, + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, + {0, 0, 0}, {size, size, 1}, + }, + }; + for (int i = 0; i < 6; i++) { + int x = env_coords[i][0] * size; + int y = env_coords[i][1] * size; + int offset = x + y * tex->width; + copy[i] = copy[0]; + copy[i].bufferOffset = packet->offset + bpp * offset; + copy[i].imageSubresource.baseArrayLayer = i; + } + dfunc->vkCmdCopyBufferToImage (packet->cmd, packet->stage->buffer, + qtex->image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 6, copy); + stages = imageLayoutTransitionStages[qfv_LT_TransferDst_to_ShaderReadOnly]; + barrier=imageLayoutTransitionBarriers[qfv_LT_TransferDst_to_ShaderReadOnly]; + barrier.image = qtex->image; + barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; + barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; + dfunc->vkCmdPipelineBarrier (packet->cmd, stages.src, stages.dst, + 0, 0, 0, 0, 0, + 1, &barrier); + QFV_PacketSubmit (packet); + return qtex; +} + +qfv_tex_t * +Vulkan_LoadEnvSides (vulkan_ctx_t *ctx, tex_t **tex, const char *name) +{ + qfv_device_t *device = ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; + int bpp; + VkFormat format; + + if (!tex_format (tex[0], &format, &bpp)) { + return 0; + } + if (tex[0]->height != tex[0]->width) { + return 0; + } + for (int i = 1; i < 6; i++) { + if (tex[i]->format != tex[0]->format + || tex[i]->width != tex[0]->width + || tex[i]->height != tex[0]->height) { + return 0; + } + } + + int size = tex[0]->height; + qfv_tex_t *qtex = create_cubetex (ctx, size, format, name); + + qfv_packet_t *packet = QFV_PacketAcquire (ctx->staging); + + VkImageMemoryBarrier barrier; + qfv_pipelinestagepair_t stages; + + stages = imageLayoutTransitionStages[qfv_LT_Undefined_to_TransferDst]; + barrier = imageLayoutTransitionBarriers[qfv_LT_Undefined_to_TransferDst]; + barrier.image = qtex->image; + barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; + barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; + dfunc->vkCmdPipelineBarrier (packet->cmd, stages.src, stages.dst, + 0, 0, 0, 0, 0, + 1, &barrier); + + VkBufferImageCopy copy[6] = { + { + 0, 0, 0, + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, + {0, 0, 0}, {size, size, 1}, + }, + }; + for (int i = 0; i < 6; i++) { + copy[i] = copy[0]; + copy[i].bufferOffset = stage_tex_data (packet, tex[i], bpp); + copy[i].imageSubresource.baseArrayLayer = i; + } + dfunc->vkCmdCopyBufferToImage (packet->cmd, packet->stage->buffer, + qtex->image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 6, copy); + stages = imageLayoutTransitionStages[qfv_LT_TransferDst_to_ShaderReadOnly]; + barrier=imageLayoutTransitionBarriers[qfv_LT_TransferDst_to_ShaderReadOnly]; + barrier.image = qtex->image; + barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; + barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; + dfunc->vkCmdPipelineBarrier (packet->cmd, stages.src, stages.dst, + 0, 0, 0, 0, 0, + 1, &barrier); + QFV_PacketSubmit (packet); + return qtex; +} + VkImageView Vulkan_TexImageView (qfv_tex_t *tex) { diff --git a/libs/video/renderer/vulkan/vulkan_vid_common.c b/libs/video/renderer/vulkan/vulkan_vid_common.c index a0301e1a1..e18b5d689 100644 --- a/libs/video/renderer/vulkan/vulkan_vid_common.c +++ b/libs/video/renderer/vulkan/vulkan_vid_common.c @@ -237,7 +237,7 @@ void Vulkan_CreateStagingBuffers (vulkan_ctx_t *ctx) { ctx->staging = QFV_CreateStagingBuffer (ctx->device, "vulkan_ctx", - 4*1024*1024, ctx->cmdpool); + 16*1024*1024, ctx->cmdpool); } void