summaryrefslogtreecommitdiff
path: root/video.cpp
diff options
context:
space:
mode:
authorquou <quou@disroot.org>2025-03-10 13:18:03 +1100
committerquou <quou@disroot.org>2025-03-10 13:18:03 +1100
commita7ef36bc519dff1700048ba8f21658daa138a81a (patch)
tree8778d112afdf21be6c1856fc062b8969f5ee3739 /video.cpp
parent0bc95e2084b970819d15306f7e3ab8b81a108dcd (diff)
msaa
Diffstat (limited to 'video.cpp')
-rw-r--r--video.cpp115
1 files changed, 100 insertions, 15 deletions
diff --git a/video.cpp b/video.cpp
index 08ee606..9e2699e 100644
--- a/video.cpp
+++ b/video.cpp
@@ -561,7 +561,8 @@ struct Texture_Vk : public Texture, public Late_Terminated {
int array_size,
int start_mip,
int start_array,
- bool alias
+ bool alias,
+ int samples
);
void destroy(Device_Vk*) override;
void set_name(Device_Vk* dev, const char* name);
@@ -732,7 +733,8 @@ struct Pipeline_Vk {
Arena& scope,
Device_Vk* dev,
VkGraphicsPipelineCreateInfo& info,
- const Pipeline& desc
+ const Pipeline& desc,
+ const Render_Pass& rpo
);
void init_depthstencil(
Arena& scope,
@@ -934,6 +936,7 @@ struct Device_Vk : public Device {
VkPhysicalDevice phys_dev;
VkSurfaceKHR surf;
uint32_t backbuffer_index;
+ VkSampleCountFlagBits max_samples;
Texture_Id backbuffer_id;
Swap_Cap swap_cap;
VkPhysicalDeviceMemoryProperties mem_props;
@@ -1021,6 +1024,9 @@ struct Device_Vk : public Device {
void create_terminators();
void create_depth(int w, int h);
+ VkSampleCountFlagBits get_max_samples();
+ VkSampleCountFlagBits get_samples(int);
+
int find_memory_type(
uint32_t filter,
VkMemoryPropertyFlags flags
@@ -1114,6 +1120,37 @@ void Device_Vk::init_validation() {
#endif
+VkSampleCountFlagBits Device_Vk::get_max_samples() {
+ VkPhysicalDeviceProperties p;
+ VkSampleCountFlagBits
+ i = VK_SAMPLE_COUNT_64_BIT,
+ e = VK_SAMPLE_COUNT_1_BIT;
+ VkSampleCountFlags c;
+ vkGetPhysicalDeviceProperties(phys_dev, &p);
+ c =
+ p.limits.framebufferColorSampleCounts &
+ p.limits.framebufferDepthSampleCounts;
+ for (; i >= e; i = (VkSampleCountFlagBits)(i >> 1))
+ if (c & i) return i;
+ return VK_SAMPLE_COUNT_1_BIT;
+}
+
+VkSampleCountFlagBits Device_Vk::get_samples(
+ int c
+) {
+ VkSampleCountFlagBits b = VK_SAMPLE_COUNT_1_BIT;
+ switch (c) {
+ case 1: b = VK_SAMPLE_COUNT_1_BIT; break;
+ case 2: b = VK_SAMPLE_COUNT_2_BIT; break;
+ case 4: b = VK_SAMPLE_COUNT_4_BIT; break;
+ case 8: b = VK_SAMPLE_COUNT_8_BIT; break;
+ case 16: b = VK_SAMPLE_COUNT_16_BIT; break;
+ case 32: b = VK_SAMPLE_COUNT_32_BIT; break;
+ case 64: b = VK_SAMPLE_COUNT_64_BIT; break;
+ default: break;
+ }
+ return std::min(max_samples, b);
+}
bool Device_Vk::has_validation() {
unsigned count, i;
@@ -1352,6 +1389,7 @@ void Device_Vk::init_internal() {
#endif
surf = app_create_vk_surface(app, inst);
create_dev(&swap_cap);
+ max_samples = get_max_samples();
vrama.init(this);
gladLoaderLoadVulkan(inst, phys_dev, dev);
vkGetDeviceQueue(dev, (uint32_t)queue_index, 0, &queue);
@@ -1642,7 +1680,7 @@ void Renderpass_Vk::init(
auto& colour = rp.colours[i];
auto& ad = ads[index];
ad.format = get_vk_format(colour.fmt);
- ad.samples = VK_SAMPLE_COUNT_1_BIT;
+ ad.samples = dev->get_samples(colour.samples);
ad.loadOp = load_op_from_mode(colour.mode);
ad.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
ad.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
@@ -1659,9 +1697,10 @@ void Renderpass_Vk::init(
if (has_depth) {
int i = count++;
auto& ad = ads[i];
- ad.format = get_vk_format(dev->get_texture(rp.depth.id).fmt);
- ad.samples = VK_SAMPLE_COUNT_1_BIT;
- ad.loadOp = load_op_from_mode(rp.depth.mode);
+ auto& depth = rp.depth;
+ ad.format = get_vk_format(dev->get_texture(depth.id).fmt);
+ ad.samples = dev->get_samples(depth.samples);
+ ad.loadOp = load_op_from_mode(depth.mode);
ad.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
ad.stencilLoadOp = ad.loadOp;
ad.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
@@ -1887,7 +1926,8 @@ Texture_Id Swapchain::create_image(
1,
0,
0,
- true
+ true,
+ 1
);
return id;
}
@@ -2286,6 +2326,37 @@ void Context::copy(
);
}
+void Context::resolve(Texture_Id dst, Texture_Id src) {
+ Context_Vk* ctx = (Context_Vk*)this;
+ Device_Vk* dev = ctx->dev;
+ Texture_Vk& d = *(Texture_Vk*)&dev->get_texture(dst);
+ Texture_Vk& s = *(Texture_Vk*)&dev->get_texture(src);
+ VkImageResolve r{};
+ r.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ r.srcSubresource.layerCount = 1;
+ r.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ r.dstSubresource.layerCount = 1;
+ r.extent.width = d.w;
+ r.extent.height = d.h;
+ r.extent.depth = 1;
+ assert(d.w == s.w);
+ assert(d.h == s.h);
+ assert(d.d == 1 && s.d == 1);
+ assert(d.samples == 1 && s.samples > 1);
+ ctx->check_end_rp();
+ transition(src, Resource_State::copy_src);
+ transition(dst, Resource_State::copy_dst);
+ vkCmdResolveImage(
+ ctx->cb,
+ s.image,
+ state_to_image_layout(s.state),
+ d.image,
+ state_to_image_layout(d.state),
+ 1,
+ &r
+ );
+}
+
void Context::transition(Texture_Id id, Resource_State state) {
Context_Vk* ctx = (Context_Vk*)this;
Device_Vk* dev = ctx->dev;
@@ -2434,6 +2505,14 @@ void Context::transition(Texture_Id id, Resource_State state) {
b.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
src_stage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
dst_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+ } else if (
+ src_layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL &&
+ dst_layout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
+ ) {
+ b.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+ b.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
+ src_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+ dst_stage = VK_PIPELINE_STAGE_TRANSFER_BIT;
} else {
print_err("Bad resource transition.\n");
assert(0);
@@ -2857,7 +2936,8 @@ void Pipeline_Vk::init_msaa(
Arena& scope,
Device_Vk* dev,
VkGraphicsPipelineCreateInfo& info,
- const Pipeline& desc
+ const Pipeline& desc,
+ const Render_Pass& rpo
) {
VkPipelineMultisampleStateCreateInfo& mi =
*(VkPipelineMultisampleStateCreateInfo*)arena_alloc(
@@ -2869,7 +2949,7 @@ void Pipeline_Vk::init_msaa(
zero(&mi, sizeof mi);
mi.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
mi.sampleShadingEnable = VK_FALSE;
- mi.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
+ mi.rasterizationSamples = dev->get_samples(rpo.get_samples());
info.pMultisampleState = &mi;
}
@@ -3064,7 +3144,7 @@ void Pipeline_Vk::init(Device_Vk* dev, const Pso_Key& key) {
init_input_assembly(scope, dev, info, desc);
init_viewport(scope, info, desc);
init_rasterisation(scope, dev, info, desc);
- init_msaa(scope, dev, info, desc);
+ init_msaa(scope, dev, info, desc, key.rpo.rpo);
init_depthstencil(scope, dev, info, desc);
init_blending(scope, dev, info, key.rpo.rpo, desc);
info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
@@ -3594,7 +3674,8 @@ Texture_Id Device::create_texture(
int d,
int mip_count,
int array_size,
- Buffer_Id init
+ Buffer_Id init,
+ int samples
) {
VkImageCreateInfo ii{};
VkResult r;
@@ -3626,7 +3707,7 @@ Texture_Id Device::create_texture(
ii.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
ii.usage = get_texture_usage(flags);
ii.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
- ii.samples = VK_SAMPLE_COUNT_1_BIT;
+ ii.samples = dev->get_samples(samples);
ii.flags = image_flags;
r = vkCreateImage(dev->dev, &ii, &dev->ac, &image);
if (r != VK_SUCCESS) {
@@ -3684,7 +3765,8 @@ Texture_Id Device::create_texture(
array_size,
0,
0,
- false
+ false,
+ samples
);
if (init) {
Context& ctx = dev->acquire();
@@ -3747,7 +3829,8 @@ Texture_Id Device::alias_texture(
array_size,
start_mip,
start_array,
- true
+ true,
+ texture.samples
);
nt.set_name(dev, name);
return ntid;
@@ -4049,7 +4132,8 @@ void Texture_Vk::init(
int array_size,
int start_mip,
int start_array,
- bool alias
+ bool alias,
+ int samples
) {
t->id = id;
t->parent = parent;
@@ -4069,6 +4153,7 @@ void Texture_Vk::init(
t->start_mip = start_mip;
t->start_array = start_array;
t->alias = alias;
+ t->samples = samples;
}
void Texture_Vk::destroy(Device_Vk* dev) {