vk: Conform to current spec (#1981)

* vk: define rtt images with transfer_dst set

* vk: Bind a buffer view for attribs with undefined data

* vk: Properly define renderpass clip region to fit the framebuffer

* vk: respect type bits from returned memory requirements
This commit is contained in:
kd-11 2016-07-24 19:28:49 +03:00 committed by raven02
parent deeb4acbe5
commit 09ae45c566
5 changed files with 83 additions and 41 deletions

View File

@ -475,12 +475,13 @@ VKGSRender::VKGSRender() : GSRender(frame_type::Vulkan)
#define RING_BUFFER_SIZE 16 * 1024 * DESCRIPTOR_MAX_DRAW_CALLS
m_uniform_buffer_ring_info.init(RING_BUFFER_SIZE);
m_uniform_buffer_ring_info.heap.reset(new vk::buffer(*m_device, RING_BUFFER_SIZE, m_memory_type_mapping.host_visible_coherent, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, 0));
m_uniform_buffer_ring_info.heap.reset(new vk::buffer(*m_device, RING_BUFFER_SIZE, m_memory_type_mapping.host_visible_coherent, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, 0));
m_index_buffer_ring_info.init(RING_BUFFER_SIZE);
m_index_buffer_ring_info.heap.reset(new vk::buffer(*m_device, RING_BUFFER_SIZE, m_memory_type_mapping.host_visible_coherent, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, 0));
m_index_buffer_ring_info.heap.reset(new vk::buffer(*m_device, RING_BUFFER_SIZE, m_memory_type_mapping.host_visible_coherent, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, 0));
m_texture_upload_buffer_ring_info.init(8 * RING_BUFFER_SIZE);
m_texture_upload_buffer_ring_info.heap.reset(new vk::buffer(*m_device, 8 * RING_BUFFER_SIZE, m_memory_type_mapping.host_visible_coherent, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, 0));
m_texture_upload_buffer_ring_info.heap.reset(new vk::buffer(*m_device, 8 * RING_BUFFER_SIZE, m_memory_type_mapping.host_visible_coherent, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, 0));
m_render_passes = get_precomputed_render_passes(*m_device, m_optimal_tiling_supported_formats);
@ -495,7 +496,7 @@ VKGSRender::VKGSRender() : GSRender(frame_type::Vulkan)
descriptor_pool.create(*m_device, sizes.data(), static_cast<uint32_t>(sizes.size()));
null_buffer = std::make_unique<vk::buffer>(*m_device, 32, m_memory_type_mapping.host_visible_coherent, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, 0);
null_buffer = std::make_unique<vk::buffer>(*m_device, 32, m_memory_type_mapping.host_visible_coherent, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, 0);
null_buffer_view = std::make_unique<vk::buffer_view>(*m_device, null_buffer->value, VK_FORMAT_R32_SFLOAT, 0, 32);
VkFenceCreateInfo fence_info = {};
@ -613,27 +614,6 @@ void VKGSRender::begin()
m_used_descriptors++;
}
namespace
{
bool normalize(rsx::vertex_base_type type)
{
switch (type)
{
case rsx::vertex_base_type::s1:
case rsx::vertex_base_type::ub:
case rsx::vertex_base_type::cmp:
return true;
case rsx::vertex_base_type::f:
case rsx::vertex_base_type::sf:
case rsx::vertex_base_type::ub256:
case rsx::vertex_base_type::s32k:
return false;
}
throw EXCEPTION("unknown vertex type");
}
}
void VKGSRender::end()
{
size_t idx = vk::get_render_pass_location(
@ -673,8 +653,8 @@ void VKGSRender::end()
rp_begin.framebuffer = m_framebuffer_to_clean.back()->value;
rp_begin.renderArea.offset.x = 0;
rp_begin.renderArea.offset.y = 0;
rp_begin.renderArea.extent.width = m_frame->client_width();
rp_begin.renderArea.extent.height = m_frame->client_height();
rp_begin.renderArea.extent.width = m_framebuffer_to_clean.back()->width();
rp_begin.renderArea.extent.height = m_framebuffer_to_clean.back()->height();
vkCmdBeginRenderPass(m_command_buffer, &rp_begin, VK_SUBPASS_CONTENTS_INLINE);
@ -740,7 +720,7 @@ void VKGSRender::on_init_thread()
{
GSRender::on_init_thread();
m_attrib_ring_info.init(8 * RING_BUFFER_SIZE);
m_attrib_ring_info.heap.reset(new vk::buffer(*m_device, 8 * RING_BUFFER_SIZE, m_memory_type_mapping.host_visible_coherent, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, 0));
m_attrib_ring_info.heap.reset(new vk::buffer(*m_device, 8 * RING_BUFFER_SIZE, m_memory_type_mapping.host_visible_coherent, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, 0));
}
void VKGSRender::on_exit()
@ -1076,14 +1056,18 @@ bool VKGSRender::load_program()
m_uniform_buffer_ring_info.unmap();
const size_t fragment_constants_sz = m_prog_buffer.get_fragment_constants_buffer_size(fragment_program);
const size_t fragment_constants_offset = m_uniform_buffer_ring_info.alloc<256>(fragment_constants_sz);
const size_t fragment_constants_offset = m_uniform_buffer_ring_info.alloc<256>(std::max(fragment_constants_sz, static_cast<size_t>(32)));
if (fragment_constants_sz)
{
buf = (u8*)m_uniform_buffer_ring_info.map(fragment_constants_offset, fragment_constants_sz);
m_prog_buffer.fill_fragment_constans_buffer({ reinterpret_cast<float*>(buf), gsl::narrow<int>(fragment_constants_sz) }, fragment_program);
m_uniform_buffer_ring_info.unmap();
}
m_program->bind_uniform({ m_uniform_buffer_ring_info.heap->value, scale_offset_offset, 256 }, SCALE_OFFSET_BIND_SLOT, descriptor_sets);
m_program->bind_uniform({ m_uniform_buffer_ring_info.heap->value, vertex_constants_offset, 512 * 4 * sizeof(float) }, VERTEX_CONSTANT_BUFFERS_BIND_SLOT, descriptor_sets);
m_program->bind_uniform({ m_uniform_buffer_ring_info.heap->value, fragment_constants_offset, fragment_constants_sz }, FRAGMENT_CONSTANT_BUFFERS_BIND_SLOT, descriptor_sets);
m_program->bind_uniform({ m_uniform_buffer_ring_info.heap->value, fragment_constants_offset, (fragment_constants_sz? fragment_constants_sz: 32) }, FRAGMENT_CONSTANT_BUFFERS_BIND_SLOT, descriptor_sets);
return true;
}

View File

@ -338,7 +338,9 @@ namespace vk
VkImageCreateInfo info = {};
std::shared_ptr<vk::memory_block> memory;
image(VkDevice dev, uint32_t memory_type_index,
image(vk::render_device &dev,
uint32_t memory_type_index,
uint32_t access_flags,
VkImageType image_type,
VkFormat format,
uint32_t width, uint32_t height, uint32_t depth,
@ -367,8 +369,16 @@ namespace vk
VkMemoryRequirements memory_req;
vkGetImageMemoryRequirements(m_device, value, &memory_req);
memory = std::make_shared<vk::memory_block>(m_device, memory_req.size, memory_type_index);
if (!(memory_req.memoryTypeBits & (1 << memory_type_index)))
{
//Suggested memory type is incompatible with this memory type.
//Go through the bitset and test for requested props.
if (!dev.get_compatible_memory_type(memory_req.memoryTypeBits, access_flags, &memory_type_index))
throw EXCEPTION("No compatible memory type was found!");
}
memory = std::make_shared<vk::memory_block>(m_device, memory_req.size, memory_type_index);
CHECK_RESULT(vkBindImageMemory(m_device, value, memory->memory, 0));
}
@ -472,7 +482,7 @@ namespace vk
VkBufferCreateInfo info = {};
std::unique_ptr<vk::memory_block> memory;
buffer(VkDevice dev, u64 size, uint32_t memory_type_index, VkBufferUsageFlagBits usage, VkBufferCreateFlags flags)
buffer(vk::render_device& dev, u64 size, uint32_t memory_type_index, uint32_t access_flags, VkBufferUsageFlagBits usage, VkBufferCreateFlags flags)
: m_device(dev)
{
info.size = size;
@ -483,9 +493,18 @@ namespace vk
CHECK_RESULT(vkCreateBuffer(m_device, &info, nullptr, &value));
VkMemoryRequirements memory_reqs;
//Allocate vram for this buffer
VkMemoryRequirements memory_reqs;
vkGetBufferMemoryRequirements(m_device, value, &memory_reqs);
if (!(memory_reqs.memoryTypeBits & (1 << memory_type_index)))
{
//Suggested memory type is incompatible with this memory type.
//Go through the bitset and test for requested props.
if (!dev.get_compatible_memory_type(memory_reqs.memoryTypeBits, access_flags, &memory_type_index))
throw EXCEPTION("No compatible memory type was found!");
}
memory.reset(new memory_block(m_device, memory_reqs.size, memory_type_index));
vkBindBufferMemory(dev, value, memory->memory, 0);
}
@ -589,6 +608,9 @@ namespace vk
VkFramebuffer value;
VkFramebufferCreateInfo info = {};
std::vector<std::unique_ptr<vk::image_view>> attachements;
u32 m_width = 0;
u32 m_height = 0;
public:
framebuffer(VkDevice dev, VkRenderPass pass, u32 width, u32 height, std::vector<std::unique_ptr<vk::image_view>> &&atts)
: m_device(dev), attachements(std::move(atts))
@ -608,6 +630,9 @@ namespace vk
info.renderPass = pass;
info.layers = 1;
m_width = width;
m_height = height;
CHECK_RESULT(vkCreateFramebuffer(dev, &info, nullptr, &value));
}
@ -616,6 +641,16 @@ namespace vk
vkDestroyFramebuffer(m_device, value, nullptr);
}
u32 width()
{
return m_width;
}
u32 height()
{
return m_height;
}
framebuffer(const framebuffer&) = delete;
framebuffer(framebuffer&&) = delete;

View File

@ -22,13 +22,14 @@ namespace rsx
std::unique_ptr<vk::image> rtt;
rtt.reset(new vk::image(device, mem_mapping.device_local,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
VK_IMAGE_TYPE_2D,
requested_format,
static_cast<uint32_t>(width), static_cast<uint32_t>(height), 1, 1, 1,
VK_SAMPLE_COUNT_1_BIT,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_SAMPLED_BIT,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT,
0));
change_image_layout(*cmd, rtt->value, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT));
//Clear new surface
@ -57,7 +58,15 @@ namespace rsx
std::unique_ptr<vk::image> ds;
ds.reset(new vk::image(device, mem_mapping.device_local,
VK_IMAGE_TYPE_2D, requested_format, static_cast<uint32_t>(width), static_cast<uint32_t>(height), 1, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT|VK_IMAGE_USAGE_SAMPLED_BIT, 0));
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
VK_IMAGE_TYPE_2D,
requested_format,
static_cast<uint32_t>(width), static_cast<uint32_t>(height), 1, 1, 1,
VK_SAMPLE_COUNT_1_BIT,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT|VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0));
change_image_layout(*cmd, ds->value, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, range);
//Clear new surface..

View File

@ -229,7 +229,7 @@ namespace vk
bool is_cubemap = tex.get_extended_texture_dimension() == rsx::texture_dimension_extended::texture_dimension_cubemap;
VkImageSubresourceRange subresource_range = vk::get_image_subresource_range(0, 0, is_cubemap ? 6 : 1, tex.get_exact_mipmap_count(), VK_IMAGE_ASPECT_COLOR_BIT);
cto.uploaded_texture = std::make_unique<vk::image>(*vk::get_current_renderer(), memory_type_mapping.device_local,
cto.uploaded_texture = std::make_unique<vk::image>(*vk::get_current_renderer(), memory_type_mapping.device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
image_type,
vk_format,
tex.width(), height, depth, tex.get_exact_mipmap_count(), layer, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED,

View File

@ -549,6 +549,20 @@ VKGSRender::upload_vertex_data()
break;
}
}
else
{
//This section should theoretically be unreachable (data stream without available data)
//Variable is defined in the shaders but no data is available
//Bind a buffer view to keep the driver from crashing if access is attempted.
u32 offset_in_attrib_buffer = m_attrib_ring_info.alloc<256>(32);
void *dst = m_attrib_ring_info.map(offset_in_attrib_buffer, 32);
memset(dst, 0, 32);
m_attrib_ring_info.unmap();
m_buffer_view_to_clean.push_back(std::make_unique<vk::buffer_view>(*m_device, m_attrib_ring_info.heap->value, VK_FORMAT_R32_SFLOAT, offset_in_attrib_buffer, 32));
m_program->bind_uniform(m_buffer_view_to_clean.back()->value, reg_table[index], descriptor_sets);
}
}
}