Vulkan: Push constants #104880
|
@ -16,6 +16,8 @@
|
|||
# include <vulkan/vulkan.h>
|
||||
#endif
|
||||
|
||||
#include "vk_mem_alloc.h"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
/**
|
||||
|
@ -40,8 +42,8 @@ class VKBuffer {
|
|||
bool update(VKContext &context, const void *data);
|
||||
// TODO: add partial_update (update_sub)
|
||||
bool free(VKContext &context);
|
||||
bool map(VKContext &context, void **r_mapped_memory)const;
|
||||
void unmap(VKContext &context)const ;
|
||||
bool map(VKContext &context, void **r_mapped_memory) const;
|
||||
void unmap(VKContext &context) const;
|
||||
|
||||
int64_t size_in_bytes() const
|
||||
{
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
*/
|
||||
|
||||
#include "vk_command_buffer.hh"
|
||||
#include "vk_buffer.hh"
|
||||
#include "vk_context.hh"
|
||||
#include "vk_memory.hh"
|
||||
#include "vk_texture.hh"
|
||||
|
||||
#include "BLI_assert.h"
|
||||
|
||||
|
@ -68,6 +70,47 @@ void VKCommandBuffer::bind(const VKDescriptorSet &descriptor_set,
|
|||
vk_command_buffer_, bind_point, vk_pipeline_layout, 0, 1, &vk_descriptor_set, 0, 0);
|
||||
}
|
||||
|
||||
void VKCommandBuffer::copy(VKBuffer &dst_buffer,
|
||||
VKTexture &src_texture,
|
||||
Span<VkBufferImageCopy> regions)
|
||||
{
|
||||
vkCmdCopyImageToBuffer(vk_command_buffer_,
|
||||
src_texture.vk_image_handle(),
|
||||
VK_IMAGE_LAYOUT_GENERAL,
|
||||
dst_buffer.vk_handle(),
|
||||
regions.size(),
|
||||
regions.data());
|
||||
}
|
||||
|
||||
void VKCommandBuffer::pipeline_barrier(VkPipelineStageFlags source_stages,
|
||||
VkPipelineStageFlags destination_stages)
|
||||
{
|
||||
vkCmdPipelineBarrier(vk_command_buffer_,
|
||||
source_stages,
|
||||
destination_stages,
|
||||
0,
|
||||
0,
|
||||
nullptr,
|
||||
0,
|
||||
nullptr,
|
||||
0,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
void VKCommandBuffer::pipeline_barrier(Span<VkImageMemoryBarrier> image_memory_barriers)
|
||||
{
|
||||
vkCmdPipelineBarrier(vk_command_buffer_,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_DEPENDENCY_BY_REGION_BIT,
|
||||
0,
|
||||
nullptr,
|
||||
0,
|
||||
nullptr,
|
||||
image_memory_barriers.size(),
|
||||
image_memory_barriers.data());
|
||||
}
|
||||
|
||||
void VKCommandBuffer::dispatch(int groups_x_len, int groups_y_len, int groups_z_len)
|
||||
{
|
||||
vkCmdDispatch(vk_command_buffer_, groups_x_len, groups_y_len, groups_z_len);
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#include "vk_pipeline.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
class VKBuffer;
|
||||
class VKTexture;
|
||||
|
||||
/** Command buffer to keep track of the life-time of a command buffer.*/
|
||||
class VKCommandBuffer : NonCopyable, NonMovable {
|
||||
|
@ -37,6 +39,11 @@ class VKCommandBuffer : NonCopyable, NonMovable {
|
|||
const VkPipelineLayout vk_pipeline_layout,
|
||||
VkPipelineBindPoint bind_point);
|
||||
void dispatch(int groups_x_len, int groups_y_len, int groups_z_len);
|
||||
/* Copy the contents of a texture mip level to the dst buffer.*/
|
||||
void copy(VKBuffer &dst_buffer, VKTexture &src_texture, Span<VkBufferImageCopy> regions);
|
||||
void pipeline_barrier(VkPipelineStageFlags source_stages,
|
||||
VkPipelineStageFlags destination_stages);
|
||||
void pipeline_barrier(Span<VkImageMemoryBarrier> image_memory_barriers);
|
||||
|
||||
/**
|
||||
* Stop recording commands, encode + send the recordings to Vulkan, wait for the until the
|
||||
|
|
|
@ -79,10 +79,12 @@ void VKContext::end_frame()
|
|||
|
||||
void VKContext::flush()
|
||||
{
|
||||
command_buffer_.submit();
|
||||
}
|
||||
|
||||
void VKContext::finish()
|
||||
{
|
||||
command_buffer_.submit();
|
||||
}
|
||||
|
||||
void VKContext::memory_statistics_get(int * /*total_mem*/, int * /*free_mem*/)
|
||||
|
|
|
@ -56,6 +56,9 @@ void VKDescriptorSet::bind_as_ssbo(VKIndexBuffer &buffer, int location)
|
|||
|
||||
void VKDescriptorSet::image_bind(VKTexture &texture, int location)
|
||||
{
|
||||
Binding &binding = ensure_location(location);
|
||||
binding.type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
||||
binding.vk_image_view = texture.vk_image_view_handle();
|
||||
}
|
||||
|
||||
VKDescriptorSet::Binding &VKDescriptorSet::ensure_location(int location)
|
||||
|
@ -66,9 +69,7 @@ VKDescriptorSet::Binding &VKDescriptorSet::ensure_location(int location)
|
|||
}
|
||||
}
|
||||
|
||||
Binding binding;
|
||||
binding.vk_buffer = VK_NULL_HANDLE;
|
||||
binding.buffer_size = 0;
|
||||
Binding binding = {};
|
||||
binding.location = location;
|
||||
bindings_.append(binding);
|
||||
return bindings_.last();
|
||||
|
@ -78,7 +79,11 @@ void VKDescriptorSet::update(VkDevice vk_device)
|
|||
{
|
||||
Vector<VkDescriptorBufferInfo> buffer_infos;
|
||||
Vector<VkWriteDescriptorSet> descriptor_writes;
|
||||
|
||||
for (const Binding &binding : bindings_) {
|
||||
if (!binding.is_buffer()) {
|
||||
continue;
|
||||
}
|
||||
VkDescriptorBufferInfo buffer_info = {};
|
||||
buffer_info.buffer = binding.vk_buffer;
|
||||
buffer_info.range = binding.buffer_size;
|
||||
|
@ -91,7 +96,26 @@ void VKDescriptorSet::update(VkDevice vk_device)
|
|||
write_descriptor.descriptorCount = 1;
|
||||
write_descriptor.descriptorType = binding.type;
|
||||
write_descriptor.pBufferInfo = &buffer_infos.last();
|
||||
descriptor_writes.append(write_descriptor);
|
||||
}
|
||||
|
||||
Vector<VkDescriptorImageInfo> image_infos;
|
||||
for (const Binding &binding : bindings_) {
|
||||
if (!binding.is_image()) {
|
||||
continue;
|
||||
}
|
||||
VkDescriptorImageInfo image_info = {};
|
||||
image_info.imageView = binding.vk_image_view;
|
||||
image_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
image_infos.append(image_info);
|
||||
|
||||
VkWriteDescriptorSet write_descriptor = {};
|
||||
write_descriptor.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
write_descriptor.dstSet = vk_descriptor_set_;
|
||||
write_descriptor.dstBinding = binding.location;
|
||||
write_descriptor.descriptorCount = 1;
|
||||
write_descriptor.descriptorType = binding.type;
|
||||
write_descriptor.pImageInfo = &image_infos.last();
|
||||
descriptor_writes.append(write_descriptor);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,10 +24,23 @@ class VKTexture;
|
|||
|
||||
class VKDescriptorSet : NonCopyable {
|
||||
struct Binding {
|
||||
int location;
|
||||
int location = -1;
|
||||
VkDescriptorType type;
|
||||
|
||||
VkBuffer vk_buffer = VK_NULL_HANDLE;
|
||||
VkDeviceSize buffer_size;
|
||||
VkDeviceSize buffer_size = 0;
|
||||
|
||||
VkImageView vk_image_view = VK_NULL_HANDLE;
|
||||
|
||||
bool is_buffer() const
|
||||
{
|
||||
return ELEM(type, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
}
|
||||
|
||||
bool is_image() const
|
||||
{
|
||||
return ELEM(type, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
|
||||
}
|
||||
};
|
||||
|
||||
VkDescriptorPool vk_descriptor_pool_ = VK_NULL_HANDLE;
|
||||
|
|
|
@ -19,6 +19,11 @@ void VKStateManager::force_state()
|
|||
|
||||
void VKStateManager::issue_barrier(eGPUBarrier /*barrier_bits*/)
|
||||
{
|
||||
VKContext &context = *VKContext::get();
|
||||
VKCommandBuffer &command_buffer = context.command_buffer_get();
|
||||
/* TODO: Pipeline barriers should be added. We might be able to extract it from
|
||||
* the actual pipeline, later on, but for now we submit the work as barrier. */
|
||||
command_buffer.submit();
|
||||
}
|
||||
|
||||
void VKStateManager::texture_bind(Texture * /*tex*/, eGPUSamplerState /*sampler*/, int /*unit*/)
|
||||
|
|
|
@ -7,15 +7,81 @@
|
|||
|
||||
#include "vk_texture.hh"
|
||||
|
||||
#include "vk_buffer.hh"
|
||||
#include "vk_context.hh"
|
||||
#include "vk_memory.hh"
|
||||
#include "vk_shader.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
static VkImageAspectFlagBits to_vk_image_aspect_flag_bits(const eGPUTextureFormat format)
|
||||
{
|
||||
switch (format) {
|
||||
case GPU_RGBA32F:
|
||||
case GPU_RGBA8UI:
|
||||
case GPU_RGBA8I:
|
||||
case GPU_RGBA8:
|
||||
case GPU_RGBA32UI:
|
||||
case GPU_RGBA32I:
|
||||
case GPU_RGBA16UI:
|
||||
case GPU_RGBA16I:
|
||||
case GPU_RGBA16F:
|
||||
case GPU_RGBA16:
|
||||
case GPU_RG8UI:
|
||||
case GPU_RG8I:
|
||||
case GPU_RG8:
|
||||
case GPU_RG32UI:
|
||||
case GPU_RG32I:
|
||||
case GPU_RG32F:
|
||||
case GPU_RG16UI:
|
||||
case GPU_RG16I:
|
||||
case GPU_RG16F:
|
||||
case GPU_RG16:
|
||||
case GPU_R8UI:
|
||||
case GPU_R8I:
|
||||
case GPU_R8:
|
||||
case GPU_R32UI:
|
||||
case GPU_R32I:
|
||||
case GPU_R32F:
|
||||
case GPU_R16UI:
|
||||
case GPU_R16I:
|
||||
case GPU_R16F:
|
||||
case GPU_R16:
|
||||
case GPU_RGB10_A2:
|
||||
case GPU_R11F_G11F_B10F:
|
||||
case GPU_SRGB8_A8:
|
||||
case GPU_RGB16F:
|
||||
case GPU_SRGB8_A8_DXT1:
|
||||
case GPU_SRGB8_A8_DXT3:
|
||||
case GPU_SRGB8_A8_DXT5:
|
||||
case GPU_RGBA8_DXT1:
|
||||
case GPU_RGBA8_DXT3:
|
||||
case GPU_RGBA8_DXT5:
|
||||
return VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
||||
case GPU_DEPTH32F_STENCIL8:
|
||||
case GPU_DEPTH24_STENCIL8:
|
||||
return static_cast<VkImageAspectFlagBits>(VK_IMAGE_ASPECT_DEPTH_BIT |
|
||||
VK_IMAGE_ASPECT_STENCIL_BIT);
|
||||
|
||||
case GPU_DEPTH_COMPONENT24:
|
||||
case GPU_DEPTH_COMPONENT16:
|
||||
return VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
|
||||
case GPU_DEPTH_COMPONENT32F:
|
||||
/* Not supported by Vulkan*/
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
return static_cast<VkImageAspectFlagBits>(0);
|
||||
}
|
||||
|
||||
VKTexture::~VKTexture()
|
||||
{
|
||||
VK_ALLOCATION_CALLBACKS
|
||||
|
||||
VKContext &context = *VKContext::get();
|
||||
vmaDestroyImage(context.mem_allocator_get(), vk_image_, allocation_);
|
||||
vkDestroyImageView(context.device_get(), vk_image_view_, vk_allocation_callbacks);
|
||||
}
|
||||
|
||||
void VKTexture::generate_mipmap()
|
||||
|
@ -42,9 +108,49 @@ void VKTexture::mip_range_set(int /*min*/, int /*max*/)
|
|||
{
|
||||
}
|
||||
|
||||
void *VKTexture::read(int /*mip*/, eGPUDataFormat /*format*/)
|
||||
void *VKTexture::read(int mip, eGPUDataFormat format)
|
||||
{
|
||||
return nullptr;
|
||||
/* Vulkan images cannot be directly mapped to host memory and requires a staging buffer.*/
|
||||
VKContext &context = *VKContext::get();
|
||||
VKBuffer staging_buffer;
|
||||
|
||||
/* NOTE: mip_size_get() won't override any dimension that is equal to 0. */
|
||||
int extent[3] = {1, 1, 1};
|
||||
mip_size_get(mip, extent);
|
||||
size_t sample_len = extent[0] * extent[1] * extent[2];
|
||||
/* NOTE: to_bytesize returns number of bits. */
|
||||
size_t device_memory_size = sample_len * to_component_len(format_) * to_bytesize(format_) / 8;
|
||||
/* NOTE: to_bytesize returns number of bytes here. */
|
||||
size_t host_memory_size = sample_len * to_bytesize(format_, format);
|
||||
|
||||
staging_buffer.create(
|
||||
context, device_memory_size, GPU_USAGE_DEVICE_ONLY, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
|
||||
|
||||
VkBufferImageCopy region = {};
|
||||
region.imageExtent.width = extent[0];
|
||||
region.imageExtent.height = extent[1];
|
||||
region.imageExtent.depth = extent[2];
|
||||
region.imageSubresource.aspectMask = to_vk_image_aspect_flag_bits(format_);
|
||||
region.imageSubresource.mipLevel = mip;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
|
||||
VKCommandBuffer &command_buffer = context.command_buffer_get();
|
||||
command_buffer.copy(staging_buffer, *this, Span<VkBufferImageCopy>(®ion, 1));
|
||||
command_buffer.submit();
|
||||
|
||||
void *mapped_data;
|
||||
staging_buffer.map(context, &mapped_data);
|
||||
|
||||
void *data = MEM_mallocN(host_memory_size, __func__);
|
||||
|
||||
/* TODO: add conversion when data format is different.*/
|
||||
BLI_assert_msg(device_memory_size == host_memory_size,
|
||||
"Memory data conversions not implemented yet");
|
||||
|
||||
memcpy(data, mapped_data, host_memory_size);
|
||||
staging_buffer.unmap(context);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void VKTexture::update_sub(int /*mip*/,
|
||||
|
@ -103,12 +209,11 @@ static VkFormat to_vk_format(const eGPUTextureFormat format)
|
|||
case GPU_R16F:
|
||||
case GPU_R16:
|
||||
|
||||
/*
|
||||
case GPU_RGB10_A2:
|
||||
case GPU_R11F_G11F_B10F:
|
||||
case GPU_DEPTH32F_STENCIL8:
|
||||
case GPU_DEPTH24_STENCIL8:
|
||||
case GPU_SRGB8_A8:*/
|
||||
case GPU_SRGB8_A8:
|
||||
|
||||
/* Texture only format */
|
||||
case GPU_RGB16F:
|
||||
|
@ -125,7 +230,6 @@ static VkFormat to_vk_format(const eGPUTextureFormat format)
|
|||
case GPU_DEPTH_COMPONENT32F:
|
||||
case GPU_DEPTH_COMPONENT24:
|
||||
case GPU_DEPTH_COMPONENT16:
|
||||
default:
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
return VK_FORMAT_UNDEFINED;
|
||||
|
@ -152,23 +256,66 @@ bool VKTexture::is_allocated()
|
|||
return vk_image_ != VK_NULL_HANDLE && allocation_ != VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
static VkImageViewType to_vk_image_view_type(const eGPUTextureType type)
|
||||
{
|
||||
switch (type) {
|
||||
case GPU_TEXTURE_1D:
|
||||
case GPU_TEXTURE_BUFFER:
|
||||
return VK_IMAGE_VIEW_TYPE_1D;
|
||||
case GPU_TEXTURE_2D:
|
||||
return VK_IMAGE_VIEW_TYPE_2D;
|
||||
case GPU_TEXTURE_3D:
|
||||
return VK_IMAGE_VIEW_TYPE_3D;
|
||||
case GPU_TEXTURE_CUBE:
|
||||
return VK_IMAGE_VIEW_TYPE_CUBE;
|
||||
case GPU_TEXTURE_1D_ARRAY:
|
||||
return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
|
||||
case GPU_TEXTURE_2D_ARRAY:
|
||||
return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||
case GPU_TEXTURE_CUBE_ARRAY:
|
||||
return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
|
||||
|
||||
case GPU_TEXTURE_ARRAY:
|
||||
/* GPU_TEXTURE_ARRAY should always be used together with 1D, 2D, or CUBE*/
|
||||
BLI_assert_unreachable();
|
||||
break;
|
||||
}
|
||||
|
||||
return VK_IMAGE_VIEW_TYPE_1D;
|
||||
}
|
||||
|
||||
static VkComponentMapping to_vk_component_mapping(const eGPUTextureFormat /*format*/)
|
||||
{
|
||||
/* TODO: this should map to OpenGL defaults based on the eGPUTextureFormat*/
|
||||
VkComponentMapping component_mapping;
|
||||
component_mapping.r = VK_COMPONENT_SWIZZLE_R;
|
||||
component_mapping.g = VK_COMPONENT_SWIZZLE_G;
|
||||
component_mapping.b = VK_COMPONENT_SWIZZLE_B;
|
||||
component_mapping.a = VK_COMPONENT_SWIZZLE_A;
|
||||
return component_mapping;
|
||||
}
|
||||
|
||||
bool VKTexture::allocate()
|
||||
{
|
||||
BLI_assert(!is_allocated());
|
||||
|
||||
VKContext &context = *VKContext::get();
|
||||
VkImageCreateInfo imgCreateInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
|
||||
imgCreateInfo.imageType = VK_IMAGE_TYPE_1D;
|
||||
imgCreateInfo.extent.width = width_get();
|
||||
imgCreateInfo.extent.height = 1;
|
||||
imgCreateInfo.extent.depth = 1;
|
||||
imgCreateInfo.mipLevels = 1;
|
||||
imgCreateInfo.arrayLayers = 1;
|
||||
imgCreateInfo.format = to_vk_format(format_);
|
||||
imgCreateInfo.tiling = VK_IMAGE_TILING_LINEAR;
|
||||
imgCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
imgCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT;
|
||||
imgCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
VkImageCreateInfo image_info = {};
|
||||
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
image_info.imageType = VK_IMAGE_TYPE_1D;
|
||||
image_info.extent.width = width_get();
|
||||
image_info.extent.height = 1;
|
||||
image_info.extent.depth = 1;
|
||||
image_info.mipLevels = 1;
|
||||
image_info.arrayLayers = 1;
|
||||
image_info.format = to_vk_format(format_);
|
||||
image_info.tiling = VK_IMAGE_TILING_LINEAR;
|
||||
/* TODO: PREINITIALIZED should be for device only textures. Others should use
|
||||
* VK_IMAGE_LAYOUT_UNDEFINED and upload its content.*/
|
||||
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
image_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
|
||||
VK_IMAGE_USAGE_STORAGE_BIT;
|
||||
image_info.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
VmaAllocationCreateInfo allocCreateInfo = {};
|
||||
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
|
||||
|
@ -177,7 +324,7 @@ bool VKTexture::allocate()
|
|||
allocCreateInfo.priority = 1.0f;
|
||||
|
||||
VkResult result = vmaCreateImage(context.mem_allocator_get(),
|
||||
&imgCreateInfo,
|
||||
&image_info,
|
||||
&allocCreateInfo,
|
||||
&vk_image_,
|
||||
&allocation_,
|
||||
|
@ -185,7 +332,32 @@ bool VKTexture::allocate()
|
|||
if (result != VK_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
/* Promote image to the correct layout.*/
|
||||
VkImageMemoryBarrier barrier{};
|
||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
barrier.image = vk_image_;
|
||||
barrier.subresourceRange.aspectMask = to_vk_image_aspect_flag_bits(format_);
|
||||
barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||
barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
||||
context.command_buffer_get().pipeline_barrier(Span<VkImageMemoryBarrier>(&barrier, 1));
|
||||
|
||||
VK_ALLOCATION_CALLBACKS
|
||||
VkImageViewCreateInfo image_view_info = {};
|
||||
image_view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
image_view_info.image = vk_image_;
|
||||
image_view_info.viewType = to_vk_image_view_type(type_);
|
||||
image_view_info.format = to_vk_format(format_);
|
||||
image_view_info.components = to_vk_component_mapping(format_);
|
||||
image_view_info.subresourceRange.aspectMask = to_vk_image_aspect_flag_bits(format_);
|
||||
image_view_info.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||
image_view_info.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
||||
|
||||
result = vkCreateImageView(
|
||||
context.device_get(), &image_view_info, vk_allocation_callbacks, &vk_image_view_);
|
||||
return result == VK_SUCCESS;
|
||||
}
|
||||
|
||||
void VKTexture::image_bind(int location)
|
||||
|
|
|
@ -10,10 +10,13 @@
|
|||
#include "gpu_texture_private.hh"
|
||||
#include "vk_context.hh"
|
||||
|
||||
#include "vk_mem_alloc.h"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
class VKTexture : public Texture {
|
||||
VkImage vk_image_ = VK_NULL_HANDLE;
|
||||
VkImageView vk_image_view_ = VK_NULL_HANDLE;
|
||||
VmaAllocation allocation_ = VK_NULL_HANDLE;
|
||||
|
||||
public:
|
||||
|
@ -40,6 +43,14 @@ class VKTexture : public Texture {
|
|||
uint gl_bindcode_get() const override;
|
||||
|
||||
void image_bind(int location);
|
||||
VkImage vk_image_handle() const
|
||||
{
|
||||
return vk_image_;
|
||||
}
|
||||
VkImageView vk_image_view_handle() const
|
||||
{
|
||||
return vk_image_view_;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool init_internal() override;
|
||||
|
@ -54,6 +65,8 @@ class VKTexture : public Texture {
|
|||
* on the device.
|
||||
*/
|
||||
bool allocate();
|
||||
|
||||
VkImageViewType vk_image_view_type() const;
|
||||
};
|
||||
|
||||
static inline VKTexture *unwrap(Texture *tex)
|
||||
|
|
Loading…
Reference in New Issue