新的纹理创建

This commit is contained in:
hyzboy 2019-11-25 22:05:05 +08:00
parent 14e4d493dc
commit 5846913197
19 changed files with 431 additions and 363 deletions

@ -1 +1 @@
Subproject commit 4ce04480ec5469fe7ebbdd66c3016090a704d81b Subproject commit fd5aa3ad51ece55a1b51fe6bfb271db6844ae291

@ -1 +1 @@
Subproject commit 23e1c0cbc9915d5e1aa9bea683c06ca4e67e4f09 Subproject commit 16397c1849c2b180bc7fe1e5ef103ba03a8990d5

@ -1 +1 @@
Subproject commit 56a75a8c50661512be1cdf319a2cfabdae7ce2d0 Subproject commit 884d6883c1f58e7224f1ab14b153f3633cacd495

View File

@ -11,7 +11,8 @@ endmacro()
CreateProject(00.triangle first_triangle.cpp) CreateProject(00.triangle first_triangle.cpp)
CreateProject(01.indices_rect indices_rect.cpp) CreateProject(01.indices_rect indices_rect.cpp)
CreateProject(02.texture_rect texture_rect.cpp TGATexture.cpp) CreateProject(02.1.texture_rect texture_rect.cpp TGATexture.cpp)
CreateProject(02.2.texture_linear texture_linear.cpp TGATexture.cpp)
CreateProject(03.HQFilterTexture HQFilterTexture.cpp TGATexture.cpp) CreateProject(03.HQFilterTexture HQFilterTexture.cpp TGATexture.cpp)
CreateProject(04.Geometry2D Geometry2D.cpp) CreateProject(04.Geometry2D Geometry2D.cpp)
CreateProject(05.Geometry3D Geometry3D.cpp) CreateProject(05.Geometry3D Geometry3D.cpp)

View File

@ -37,16 +37,11 @@ constexpr VkFormat normal_candidate_format []={FMT_RGBA32F,
FMT_A2BGR10SN}; FMT_A2BGR10SN};
constexpr VkFormat depth_candidate_format []={FMT_D32F,FMT_D32F_S8U,FMT_X8_D24UN,FMT_D24UN_S8U,FMT_D16UN,FMT_D16UN_S8U}; constexpr VkFormat depth_candidate_format []={FMT_D32F,FMT_D32F_S8U,FMT_X8_D24UN,FMT_D24UN_S8U,FMT_D16UN,FMT_D16UN_S8U};
class TestApp:public CameraAppFramework class DeferredRenderingFramework:public CameraAppFramework
{ {
private:
SceneNode render_root;
RenderList render_list;
struct DeferredGBuffer struct DeferredGBuffer
{ {
vulkan::Semaphore *render_complete_semaphore =nullptr; vulkan::Semaphore *render_complete_semaphore = nullptr;
vulkan::RenderTarget *rt; vulkan::RenderTarget *rt;
@ -58,7 +53,7 @@ private:
{ {
struct struct
{ {
Texture2DPointer position,normal,color,depth; Texture2DPointer position, normal, color, depth;
}; };
Texture2DPointer texture_list[4]; Texture2DPointer texture_list[4];
@ -72,7 +67,7 @@ private:
List<VkAttachmentDescription> desc_list; List<VkAttachmentDescription> desc_list;
List<VkAttachmentReference> ref_list; List<VkAttachmentReference> ref_list;
}attachment; }attachment;
struct struct
{ {
List<VkSubpassDescription> desc; List<VkSubpassDescription> desc;
@ -82,15 +77,195 @@ private:
struct SubpassParam struct SubpassParam
{ {
vulkan::Material * material; vulkan::Material *material;
vulkan::DescriptorSets *desc_sets; vulkan::DescriptorSets *desc_sets;
vulkan::Pipeline * pipeline_fan; vulkan::Pipeline *pipeline_fan;
vulkan::Pipeline * pipeline_triangles; vulkan::Pipeline *pipeline_triangles;
};// };//
SubpassParam sp_gbuffer; SubpassParam sp_gbuffer;
SubpassParam sp_composition; SubpassParam sp_composition;
vulkan::CommandBuffer *gbuffer_cmd = nullptr;
public:
DeferredRenderingFramework()
{
}
~DeferredRenderingFramework()
{
SAFE_CLEAR(gbuffer_cmd);
}
private:
const VkFormat GetCandidateFormat(const VkFormat *fmt_list, const uint count)
{
auto pd = device->GetPhysicalDevice();
for (uint i = 0; i < count; i++)
if (pd->IsColorAttachmentOptimal(fmt_list[i]))
return fmt_list[i];
for (uint i = 0; i < count; i++)
if (pd->IsColorAttachmentLinear(fmt_list[i]))
return fmt_list[i];
return FMT_UNDEFINED;
}
const VkFormat GetDepthCandidateFormat()
{
auto pd = device->GetPhysicalDevice();
for (VkFormat fmt : depth_candidate_format)
if (pd->IsDepthAttachmentOptimal(fmt))
return fmt;
for (VkFormat fmt : depth_candidate_format)
if (pd->IsDepthAttachmentLinear(fmt))
return fmt;
return FMT_UNDEFINED;
}
bool InitGBuffer()
{
gbuffer.extent.width = 1024;
gbuffer.extent.height = 1024;
gbuffer.render_complete_semaphore = device->CreateSem();
//根据候选格式表选择格式
//const VkFormat position_format =GetCandidateFormat(position_candidate_format, sizeof(position_candidate_format));
//const VkFormat color_format =GetCandidateFormat(color_candidate_format, sizeof(color_candidate_format));
//const VkFormat normal_format =GetCandidateFormat(normal_candidate_format, sizeof(normal_candidate_format));
//const VkFormat depth_format =GetDepthCandidateFormat();
//if(position_format ==FMT_UNDEFINED
// ||color_format ==FMT_UNDEFINED
// ||normal_format ==FMT_UNDEFINED
// ||depth_format ==FMT_UNDEFINED)
// return(false);
const VkFormat position_format = FMT_RGBA32F;
const VkFormat color_format = FMT_RGBA32F;
const VkFormat normal_format = FMT_RGBA32F;
const VkFormat depth_format = FMT_D32F;
gbuffer.position = device->CreateAttachmentTextureColor(position_format, gbuffer.extent.width, gbuffer.extent.height);
gbuffer.color = device->CreateAttachmentTextureColor(color_format, gbuffer.extent.width, gbuffer.extent.height);
gbuffer.normal = device->CreateAttachmentTextureColor(normal_format, gbuffer.extent.width, gbuffer.extent.height);
gbuffer.depth = device->CreateAttachmentTextureDepth(depth_format, gbuffer.extent.width, gbuffer.extent.height);
for (uint i = 0; i < 3; i++)
{
gbuffer.gbuffer_format_list.Add(gbuffer.texture_list[i]->GetFormat());
gbuffer.image_view_list.Add(gbuffer.texture_list[i]->GetImageView());
}
if (!device->CreateAttachment(gbuffer.attachment.ref_list,
gbuffer.attachment.desc_list,
gbuffer.gbuffer_format_list,
gbuffer.depth->GetFormat()))
return(false);
VkSubpassDescription desc;
device->CreateSubpassDescription(desc, gbuffer.attachment.ref_list);
gbuffer.subpass.desc.Add(desc);
device->CreateSubpassDependency(gbuffer.subpass.dependency, 2); //为啥要2个还不清楚
gbuffer.renderpass = device->CreateRenderPass(gbuffer.attachment.desc_list,
gbuffer.subpass.desc,
gbuffer.subpass.dependency,
gbuffer.gbuffer_format_list,
gbuffer.depth->GetFormat());
if (!gbuffer.renderpass)
return(false);
gbuffer.framebuffer = vulkan::CreateFramebuffer(device, gbuffer.renderpass, gbuffer.image_view_list, gbuffer.depth->GetImageView());
if (!gbuffer.framebuffer)
return(false);
gbuffer.rt = device->CreateRenderTarget(gbuffer.framebuffer);
return(true);
}
bool InitSubpass(SubpassParam *sp, const OSString &vs, const OSString &fs)
{
sp->material = shader_manage->CreateMaterial(vs, fs);
if (!sp->material)
return(false);
sp->desc_sets = sp->material->CreateDescriptorSets();
db->Add(sp->material);
db->Add(sp->desc_sets);
return(true);
}
bool InitGBufferPipeline(SubpassParam *sp)
{
AutoDelete<vulkan::PipelineCreater> pipeline_creater = new vulkan::PipelineCreater(device, sp->material, gbuffer.rt);
{
pipeline_creater->Set(PRIM_TRIANGLES);
sp->pipeline_triangles = pipeline_creater->Create();
if (!sp->pipeline_triangles)
return(false);
db->Add(sp->pipeline_triangles);
}
{
pipeline_creater->Set(PRIM_TRIANGLE_FAN);
sp->pipeline_fan = pipeline_creater->Create();
if (!sp->pipeline_fan)
return(false);
db->Add(sp->pipeline_fan);
}
return(true);
}
bool InitCompositionPipeline(SubpassParam *sp)
{
AutoDelete<vulkan::PipelineCreater> pipeline_creater = new vulkan::PipelineCreater(device, sp->material, sc_render_target);
pipeline_creater->SetDepthTest(false);
pipeline_creater->SetDepthWrite(false);
pipeline_creater->SetCullMode(VK_CULL_MODE_NONE);
pipeline_creater->Set(PRIM_TRIANGLE_FAN);
sp->pipeline_triangles = pipeline_creater->Create();
if (!sp->pipeline_triangles)
return(false);
db->Add(sp->pipeline_triangles);
return(true);
}
};//class DeferredRenderingFramework:public CameraAppFramework
class TestApp:public CameraAppFramework
{
private:
SceneNode render_root;
RenderList render_list;
vulkan::Renderable *ro_plane, vulkan::Renderable *ro_plane,
*ro_cube, *ro_cube,
*ro_sphere, *ro_sphere,
@ -109,176 +284,16 @@ private:
// Texture2DPointer specular=nullptr; // Texture2DPointer specular=nullptr;
}texture; }texture;
vulkan::CommandBuffer *gbuffer_cmd=nullptr;
public: public:
~TestApp() ~TestApp()
{ {
SAFE_CLEAR(gbuffer_cmd);
//SAFE_CLEAR(texture.specular); //SAFE_CLEAR(texture.specular);
SAFE_CLEAR(texture.normal); SAFE_CLEAR(texture.normal);
SAFE_CLEAR(texture.color); SAFE_CLEAR(texture.color);
SAFE_CLEAR(sampler); SAFE_CLEAR(sampler);
} }
private:
const VkFormat GetCandidateFormat(const VkFormat *fmt_list,const uint count)
{
auto pd=device->GetPhysicalDevice();
for(uint i=0;i<count;i++)
if(pd->IsColorAttachmentOptimal(fmt_list[i]))
return fmt_list[i];
for(uint i=0;i<count;i++)
if(pd->IsColorAttachmentLinear(fmt_list[i]))
return fmt_list[i];
return FMT_UNDEFINED;
}
const VkFormat GetDepthCandidateFormat()
{
auto pd=device->GetPhysicalDevice();
for(VkFormat fmt:depth_candidate_format)
if(pd->IsDepthAttachmentOptimal(fmt))
return fmt;
for(VkFormat fmt:depth_candidate_format)
if(pd->IsDepthAttachmentLinear(fmt))
return fmt;
return FMT_UNDEFINED;
}
bool InitGBuffer()
{
gbuffer.extent.width =1024;
gbuffer.extent.height =1024;
gbuffer.render_complete_semaphore =device->CreateSem();
//根据候选格式表选择格式
//const VkFormat position_format =GetCandidateFormat(position_candidate_format, sizeof(position_candidate_format));
//const VkFormat color_format =GetCandidateFormat(color_candidate_format, sizeof(color_candidate_format));
//const VkFormat normal_format =GetCandidateFormat(normal_candidate_format, sizeof(normal_candidate_format));
//const VkFormat depth_format =GetDepthCandidateFormat();
//if(position_format ==FMT_UNDEFINED
// ||color_format ==FMT_UNDEFINED
// ||normal_format ==FMT_UNDEFINED
// ||depth_format ==FMT_UNDEFINED)
// return(false);
const VkFormat position_format =FMT_RGBA32F;
const VkFormat color_format =FMT_RGBA32F;
const VkFormat normal_format =FMT_RGBA32F;
const VkFormat depth_format =FMT_D32F;
gbuffer.position=device->CreateAttachmentTextureColor(position_format, gbuffer.extent.width,gbuffer.extent.height);
gbuffer.color =device->CreateAttachmentTextureColor(color_format, gbuffer.extent.width,gbuffer.extent.height);
gbuffer.normal =device->CreateAttachmentTextureColor(normal_format, gbuffer.extent.width,gbuffer.extent.height);
gbuffer.depth =device->CreateAttachmentTextureDepth(depth_format, gbuffer.extent.width,gbuffer.extent.height);
for(uint i=0;i<3;i++)
{
gbuffer.gbuffer_format_list.Add(gbuffer.texture_list[i]->GetFormat());
gbuffer.image_view_list.Add(gbuffer.texture_list[i]->GetImageView());
}
if(!device->CreateAttachment( gbuffer.attachment.ref_list,
gbuffer.attachment.desc_list,
gbuffer.gbuffer_format_list,
gbuffer.depth->GetFormat()))
return(false);
VkSubpassDescription desc;
device->CreateSubpassDescription(desc,gbuffer.attachment.ref_list);
gbuffer.subpass.desc.Add(desc);
device->CreateSubpassDependency(gbuffer.subpass.dependency,2); //为啥要2个还不清楚
gbuffer.renderpass=device->CreateRenderPass(gbuffer.attachment.desc_list,
gbuffer.subpass.desc,
gbuffer.subpass.dependency,
gbuffer.gbuffer_format_list,
gbuffer.depth->GetFormat());
if(!gbuffer.renderpass)
return(false);
gbuffer.framebuffer=vulkan::CreateFramebuffer(device,gbuffer.renderpass,gbuffer.image_view_list,gbuffer.depth->GetImageView());
if(!gbuffer.framebuffer)
return(false);
gbuffer.rt=device->CreateRenderTarget(gbuffer.framebuffer);
return(true);
}
bool InitSubpass(SubpassParam *sp,const OSString &vs,const OSString &fs)
{
sp->material=shader_manage->CreateMaterial(vs,fs);
if(!sp->material)
return(false);
sp->desc_sets=sp->material->CreateDescriptorSets();
db->Add(sp->material);
db->Add(sp->desc_sets);
return(true);
}
bool InitGBufferPipeline(SubpassParam *sp)
{
AutoDelete<vulkan::PipelineCreater> pipeline_creater=new vulkan::PipelineCreater(device,sp->material,gbuffer.rt);
{
pipeline_creater->Set(PRIM_TRIANGLES);
sp->pipeline_triangles=pipeline_creater->Create();
if(!sp->pipeline_triangles)
return(false);
db->Add(sp->pipeline_triangles);
}
{
pipeline_creater->Set(PRIM_TRIANGLE_FAN);
sp->pipeline_fan=pipeline_creater->Create();
if(!sp->pipeline_fan)
return(false);
db->Add(sp->pipeline_fan);
}
return(true);
}
bool InitCompositionPipeline(SubpassParam *sp)
{
AutoDelete<vulkan::PipelineCreater> pipeline_creater=new vulkan::PipelineCreater(device,sp->material,sc_render_target);
pipeline_creater->SetDepthTest(false);
pipeline_creater->SetDepthWrite(false);
pipeline_creater->SetCullMode(VK_CULL_MODE_NONE);
pipeline_creater->Set(PRIM_TRIANGLE_FAN);
sp->pipeline_triangles=pipeline_creater->Create();
if(!sp->pipeline_triangles)
return(false);
db->Add(sp->pipeline_triangles);
return(true);
}
bool InitMaterial() bool InitMaterial()
{ {

View File

@ -1,4 +1,4 @@
// 10.PBR Basic // 10.PBR Basic
#include"VulkanAppFramework.h" #include"VulkanAppFramework.h"
#include<hgl/filesystem/FileSystem.h> #include<hgl/filesystem/FileSystem.h>

View File

@ -138,7 +138,7 @@ namespace
} }
}//namespace }//namespace
Texture2D *LoadTGATexture(const OSString &filename,Device *device) Texture2D *LoadTGATexture(const OSString &filename,Device *device,bool use_optimar)
{ {
io::OpenFileInputStream fis(filename); io::OpenFileInputStream fis(filename);
@ -199,7 +199,7 @@ Texture2D *LoadTGATexture(const OSString &filename,Device *device)
} }
vulkan::Buffer *buf; vulkan::Buffer *buf;
if(header.image_type==tga::ImageType::TrueColor if(header.image_type==tga::ImageType::TrueColor
&&(header.bit==24||header.bit==48||header.bit==72)) &&(header.bit==24||header.bit==48||header.bit==72))
{ {
@ -251,16 +251,21 @@ Texture2D *LoadTGATexture(const OSString &filename,Device *device)
buf->Unmap(); buf->Unmap();
} }
Texture2D *tex=device->CreateTexture2D(format,buf,header.width,header.height); Texture2D *tex;
delete buf; if(use_optimar)
{
device->CreateTexture2D(format,buf,header.width,header.height);
delete buf;
}
else
{
device->CreateTexture2DLinear(format,buf,header.width, header.height);
}
if(tex) if(tex)
{ {
LOG_INFO(OS_TEXT("load image file<")+filename+OS_TEXT(">:<")+OSString(header.width)+OS_TEXT("x")+OSString(header.height)+OS_TEXT("> to texture ok")); LOG_INFO(OS_TEXT("load image file<")+filename+OS_TEXT(">:<")+OSString(header.width)+OS_TEXT("x")+OSString(header.height)+OS_TEXT("> to texture ok"));
//下面代码用于测试修改纹理
//device->ChangeTexture2D(tex,pixel_data,header->width/4,header->height/4,header->width/2,header->height/2,line_size*header->height/4);
} }
else else
{ {

View File

@ -350,9 +350,9 @@ public:
if(key_status[kbR])camera.Up (move_speed);else if(key_status[kbR])camera.Up (move_speed);else
if(key_status[kbF])camera.Down (move_speed);else if(key_status[kbF])camera.Down (move_speed);else
if(key_status[kbLeft ])camera.WrapHorzRotate(move_speed);else if(key_status[kbLeft ])camera.WrapHorzRotate( move_speed);else
if(key_status[kbRight ])camera.WrapHorzRotate(-move_speed);else if(key_status[kbRight ])camera.WrapHorzRotate(-move_speed);else
if(key_status[kbUp ])camera.WrapVertRotate(move_speed);else if(key_status[kbUp ])camera.WrapVertRotate( move_speed);else
if(key_status[kbDown ])camera.WrapVertRotate(-move_speed);else if(key_status[kbDown ])camera.WrapVertRotate(-move_speed);else
return; return;
} }

View File

@ -35,6 +35,7 @@ class Sampler;
class Memory; class Memory;
class Buffer; class Buffer;
struct BufferData;
class VertexBuffer; class VertexBuffer;
class IndexBuffer; class IndexBuffer;

View File

@ -4,8 +4,7 @@
#include<hgl/graph/vulkan/VK.h> #include<hgl/graph/vulkan/VK.h>
#include<hgl/graph/vulkan/VKMemory.h> #include<hgl/graph/vulkan/VKMemory.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
struct BufferData
struct VulkanBuffer
{ {
VkBuffer buffer; VkBuffer buffer;
Memory * memory=nullptr; Memory * memory=nullptr;
@ -17,7 +16,7 @@ class Buffer
protected: protected:
VkDevice device; VkDevice device;
VulkanBuffer buf; BufferData buf;
private: private:
@ -25,10 +24,10 @@ private:
friend class VertexBuffer; friend class VertexBuffer;
friend class IndexBuffer; friend class IndexBuffer;
Buffer(VkDevice d,const VulkanBuffer &vb) Buffer(VkDevice d,const BufferData &b)
{ {
device=d; device=d;
buf=vb; buf=b;
} }
public: public:
@ -57,7 +56,7 @@ private:
friend class Device; friend class Device;
VertexBuffer(VkDevice d,const VulkanBuffer &vb,VkFormat fmt,uint32_t _stride,uint32_t _count):Buffer(d,vb) VertexBuffer(VkDevice d,const BufferData &vb,VkFormat fmt,uint32_t _stride,uint32_t _count):Buffer(d,vb)
{ {
format=fmt; format=fmt;
stride=_stride; stride=_stride;
@ -87,7 +86,7 @@ private:
friend class Device; friend class Device;
IndexBuffer(VkDevice d,const VulkanBuffer &vb,VkIndexType it,uint32_t _count):Buffer(d,vb) IndexBuffer(VkDevice d,const BufferData &vb,VkIndexType it,uint32_t _count):Buffer(d,vb)
{ {
index_type=it; index_type=it;
count=_count; count=_count;

View File

@ -61,7 +61,11 @@ public:
public: //内存相关 public: //内存相关
Memory *Device::CreateMemory(const VkMemoryRequirements &,uint32_t properties); Memory *CreateMemory(const VkMemoryRequirements &,const uint32_t properties);
private: //Buffer相关
bool CreateBuffer(BufferData *buf,VkBufferUsageFlags buf_usage,VkDeviceSize size,const void *data,VkSharingMode sharing_mode);
public: //Buffer相关 public: //Buffer相关
@ -89,24 +93,36 @@ public: //Buffer相关
#undef CREATE_BUFFER_OBJECT #undef CREATE_BUFFER_OBJECT
public: //material相关 public: //Image
Texture2D *CreateTexture2D(const VkFormat video_format,uint32_t width,uint32_t height,const VkImageAspectFlags aspectMask,const uint usage,const VkImageLayout image_layout); VkImage CreateImage(const VkFormat format,uint32_t width,uint32_t height,const uint usage,const VkImageTiling tiling);
void DestoryImage(VkImage);
Texture2D *CreateTexture2DColor(const VkFormat video_format,uint32_t width,uint32_t height) Memory *CreateMemory(VkImage,const uint32 flag=VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
public: //Texture
Texture2D *CreateTexture2D(Memory *mem,VkImage image,ImageView *image_view,VkImageLayout image_layout,bool linear);
Texture2D *CreateTexture2D(VkFormat format,uint32_t width,uint32_t height,VkImageAspectFlagBits aspectMask,VkImage image,VkImageLayout image_layout,bool linear=false);
Texture2D *CreateTexture2D(const VkFormat format,uint32_t width,uint32_t height,const VkImageAspectFlags aspectMask,const uint usage,const VkImageLayout image_layout,bool linear=false);
Texture2D *CreateTexture2DColor(const VkFormat video_format,uint32_t width,uint32_t height,bool linear=false)
{ {
return CreateTexture2D(video_format,width,height, return CreateTexture2D(video_format,width,height,
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
linear);
} }
Texture2D *CreateTexture2DDepth(const VkFormat video_format,uint32_t width,uint32_t height) Texture2D *CreateTexture2DDepth(const VkFormat video_format,uint32_t width,uint32_t height,bool linear=false)
{ {
return CreateTexture2D(video_format,width,height, return CreateTexture2D(video_format,width,height,
VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_ASPECT_DEPTH_BIT,
VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
linear);
} }
Texture2D *CreateAttachmentTexture(const VkFormat video_format,uint32_t width,uint32_t height,const VkImageAspectFlags aspectMask,const uint usage,const VkImageLayout image_layout) Texture2D *CreateAttachmentTexture(const VkFormat video_format,uint32_t width,uint32_t height,const VkImageAspectFlags aspectMask,const uint usage,const VkImageLayout image_layout)
@ -133,15 +149,20 @@ public: //material相关
Texture2D *CreateTexture2D( const VkFormat video_format,Buffer *buf,uint32_t width,uint32_t height, Texture2D *CreateTexture2D( const VkFormat video_format,Buffer *buf,uint32_t width,uint32_t height,
const VkImageAspectFlags aspectMask =VK_IMAGE_ASPECT_COLOR_BIT, const VkImageAspectFlags aspectMask =VK_IMAGE_ASPECT_COLOR_BIT,
const uint usage =VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT, const uint usage =VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT,
const VkImageLayout image_layout=VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); const VkImageLayout image_layout=VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
const bool linear =false);
Texture2D *CreateTexture2D( const VkFormat video_format,void *data,uint32_t width,uint32_t height,uint32_t size, Texture2D *CreateTexture2D( const VkFormat video_format,void *data,uint32_t width,uint32_t height,uint32_t size,
const VkImageAspectFlags aspectMask =VK_IMAGE_ASPECT_COLOR_BIT, const VkImageAspectFlags aspectMask =VK_IMAGE_ASPECT_COLOR_BIT,
const uint usage =VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT, const uint usage =VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT,
const VkImageLayout image_layout=VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); const VkImageLayout image_layout=VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
const bool linear =false);
bool ChangeTexture2D(Texture2D *,Buffer *buf,uint32_t left,uint32_t top,uint32_t width,uint32_t height); bool ChangeTexture2D(Texture2D *,Buffer *buf,uint32_t left,uint32_t top,uint32_t width,uint32_t height);
bool ChangeTexture2D(Texture2D *,void *data,uint32_t left,uint32_t top,uint32_t width,uint32_t height,uint32_t size); bool ChangeTexture2D(Texture2D *,void *data,uint32_t left,uint32_t top,uint32_t width,uint32_t height,uint32_t size);
public: //
Sampler *CreateSampler(VkSamplerCreateInfo *); Sampler *CreateSampler(VkSamplerCreateInfo *);
ShaderModuleManage *CreateShaderModuleManage(); ShaderModuleManage *CreateShaderModuleManage();

View File

@ -13,7 +13,7 @@ class Memory
private: private:
friend Memory *CreateMemory(VkDevice device,const PhysicalDevice *pd,const VkMemoryRequirements &req,uint32_t properties); friend class Device;
Memory(VkDevice dev,VkDeviceMemory dm,const VkMemoryRequirements &mr,const uint32 i,const uint32_t p) Memory(VkDevice dev,VkDeviceMemory dm,const VkMemoryRequirements &mr,const uint32 i,const uint32_t p)
{ {
@ -48,7 +48,5 @@ public:
bool BindBuffer(VkBuffer buffer); bool BindBuffer(VkBuffer buffer);
bool BindImage(VkImage image); bool BindImage(VkImage image);
};//class Memory };//class Memory
Memory *CreateMemory(VkDevice device,const PhysicalDevice *pd,const VkMemoryRequirements &req,uint32_t properties);
VK_NAMESPACE_END VK_NAMESPACE_END
#endif//HGL_GRAPH_VULKAN_MEMORY_INCLUDE #endif//HGL_GRAPH_VULKAN_MEMORY_INCLUDE

View File

@ -13,9 +13,6 @@ struct TextureData
ImageView * image_view =nullptr; ImageView * image_view =nullptr;
uint32 mip_levels =0; uint32 mip_levels =0;
bool linear =false; bool linear =false;
VkFormat format =VK_FORMAT_UNDEFINED;
VkImageAspectFlags aspect =0;
VkExtent3D extent;
};//struct TextureData };//struct TextureData
class Texture class Texture
@ -40,9 +37,9 @@ public:
const uint32 GetMipLevels()const{return data?data->mip_levels:0;} const uint32 GetMipLevels()const{return data?data->mip_levels:0;}
const bool IsLinear ()const{return data?data->linear:false;} const bool IsLinear ()const{return data?data->linear:false;}
const VkFormat GetFormat ()const{return data?data->format:VK_FORMAT_UNDEFINED;} const VkFormat GetFormat ()const{return data?data->image_view->GetFormat():VK_FORMAT_UNDEFINED;}
const VkImageAspectFlags GetAspect ()const{return data?data->aspect:0;} const VkImageAspectFlags GetAspect ()const{return data?data->image_view->GetAspectFlags():0;}
const VkExtent3D * GetExtent ()const{return data?&data->extent:nullptr;} const VkExtent3D * GetExtent ()const{return data?&data->image_view->GetExtent():nullptr;}
public: public:
@ -67,15 +64,13 @@ public:
class Texture2D:public Texture class Texture2D:public Texture
{ {
uint32_t width,height;
public: public:
Texture2D(uint32_t w,uint32_t h,VkDevice dev,TextureData *td):width(w),height(h),Texture(dev,td){} Texture2D(VkDevice dev,TextureData *td):Texture(dev,td){}
~Texture2D()=default; ~Texture2D()=default;
const uint32_t GetWidth()const{return width;} const uint32_t GetWidth()const{return data?data->image_view->GetExtent().width:0;}
const uint32_t GetHeight()const{return height;} const uint32_t GetHeight()const{return data?data->image_view->GetExtent().height:0;}
};//class Texture2D:public Texture };//class Texture2D:public Texture
//class Texture2DArray:public Texture //class Texture2DArray:public Texture

View File

@ -5,13 +5,14 @@ SET(RENDER_DEVICE_VULKAN_SOURCE VKFormat.cpp
VKProperties.cpp VKProperties.cpp
VKDebugOut.cpp VKDebugOut.cpp
VKInstance.cpp VKInstance.cpp
VKPhysicalDevice.cpp VKPhysicalDevice.cpp
VKImageView.cpp VKImageView.cpp
VKCommandBuffer.cpp VKCommandBuffer.cpp
VKDeviceAttribute.cpp VKDeviceAttribute.cpp
VKDeviceCreater.cpp VKDeviceCreater.cpp
VKDevice.cpp VKDevice.cpp
VKDeviceBuffer.cpp VKDeviceBuffer.cpp
VKDeviceImage.cpp
VKDeviceTexture.cpp VKDeviceTexture.cpp
VKDeviceRenderPass.cpp VKDeviceRenderPass.cpp
VKBuffer.cpp VKBuffer.cpp

View File

@ -2,49 +2,47 @@
#include<hgl/graph/vulkan/VKBuffer.h> #include<hgl/graph/vulkan/VKBuffer.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
namespace bool Device::CreateBuffer(BufferData *buf,VkBufferUsageFlags buf_usage,VkDeviceSize size,const void *data,VkSharingMode sharing_mode)
{ {
bool CreateVulkanBuffer(VulkanBuffer &vb,const DeviceAttribute *rsa,VkBufferUsageFlags buf_usage,VkDeviceSize size,const void *data,VkSharingMode sharing_mode) VkBufferCreateInfo buf_info={};
{ buf_info.sType =VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
VkBufferCreateInfo buf_info={}; buf_info.pNext =nullptr;
buf_info.sType=VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; buf_info.usage =buf_usage;
buf_info.pNext=nullptr; buf_info.size =size;
buf_info.usage=buf_usage; buf_info.queueFamilyIndexCount =0;
buf_info.size=size; buf_info.pQueueFamilyIndices =nullptr;
buf_info.queueFamilyIndexCount=0; buf_info.sharingMode =sharing_mode;
buf_info.pQueueFamilyIndices=nullptr; buf_info.flags =0;
buf_info.sharingMode=sharing_mode;
buf_info.flags=0;
if(vkCreateBuffer(rsa->device,&buf_info,nullptr,&vb.buffer)!=VK_SUCCESS) if(vkCreateBuffer(attr->device,&buf_info,nullptr,&buf->buffer)!=VK_SUCCESS)
return(false);
VkMemoryRequirements mem_reqs;
vkGetBufferMemoryRequirements(rsa->device,vb.buffer,&mem_reqs);
Memory *dm=CreateMemory(rsa->device,rsa->physical_device,mem_reqs,VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
if(dm&&dm->BindBuffer(vb.buffer))
{
vb.info.buffer =vb.buffer;
vb.info.offset =0;
vb.info.range =size;
vb.memory =dm;
if(!data)
return(true);
dm->Write(data,0,size);
return(true);
}
delete dm;
vkDestroyBuffer(rsa->device,vb.buffer,nullptr);
return(false); return(false);
VkMemoryRequirements mem_reqs;
vkGetBufferMemoryRequirements(attr->device,buf->buffer,&mem_reqs);
Memory *dm=CreateMemory(mem_reqs,VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
if(dm&&dm->BindBuffer(buf->buffer))
{
buf->info.buffer =buf->buffer;
buf->info.offset =0;
buf->info.range =size;
buf->memory =dm;
if(!data)
return(true);
dm->Write(data,0,size);
return(true);
} }
}//namespace
delete dm;
vkDestroyBuffer(attr->device,buf->buffer,nullptr);
return(false);
}
VertexBuffer *Device::CreateVBO(VkFormat format,uint32_t count,const void *data,VkSharingMode sharing_mode) VertexBuffer *Device::CreateVBO(VkFormat format,uint32_t count,const void *data,VkSharingMode sharing_mode)
{ {
@ -58,12 +56,12 @@ VertexBuffer *Device::CreateVBO(VkFormat format,uint32_t count,const void *data,
const VkDeviceSize size=stride*count; const VkDeviceSize size=stride*count;
VulkanBuffer vb; BufferData buf;
if(!CreateVulkanBuffer(vb,attr,VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,size,data,sharing_mode)) if(!CreateBuffer(&buf,VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,size,data,sharing_mode))
return(nullptr); return(nullptr);
return(new VertexBuffer(attr->device,vb,format,stride,count)); return(new VertexBuffer(attr->device,buf,format,stride,count));
} }
IndexBuffer *Device::CreateIBO(VkIndexType index_type,uint32_t count,const void *data,VkSharingMode sharing_mode) IndexBuffer *Device::CreateIBO(VkIndexType index_type,uint32_t count,const void *data,VkSharingMode sharing_mode)
@ -76,21 +74,21 @@ IndexBuffer *Device::CreateIBO(VkIndexType index_type,uint32_t count,const void
const VkDeviceSize size=stride*count; const VkDeviceSize size=stride*count;
VulkanBuffer vb; BufferData buf;
if(!CreateVulkanBuffer(vb,attr,VK_BUFFER_USAGE_INDEX_BUFFER_BIT,size,data,sharing_mode)) if(!CreateBuffer(&buf,VK_BUFFER_USAGE_INDEX_BUFFER_BIT,size,data,sharing_mode))
return(nullptr); return(nullptr);
return(new IndexBuffer(attr->device,vb,index_type,count)); return(new IndexBuffer(attr->device,buf,index_type,count));
} }
Buffer *Device::CreateBuffer(VkBufferUsageFlags buf_usage,VkDeviceSize size,const void *data,VkSharingMode sharing_mode) Buffer *Device::CreateBuffer(VkBufferUsageFlags buf_usage,VkDeviceSize size,const void *data,VkSharingMode sharing_mode)
{ {
VulkanBuffer vb; BufferData buf;
if(!CreateVulkanBuffer(vb,attr,buf_usage,size,data,sharing_mode)) if(!CreateBuffer(&buf,buf_usage,size,data,sharing_mode))
return(nullptr); return(nullptr);
return(new Buffer(attr->device,vb)); return(new Buffer(attr->device,buf));
} }
VK_NAMESPACE_END VK_NAMESPACE_END

View File

@ -0,0 +1,52 @@
#include<hgl/graph/vulkan/VKDevice.h>
VK_NAMESPACE_BEGIN
VkImage Device::CreateImage(const VkFormat format,uint32_t width,uint32_t height,const uint usage,const VkImageTiling tiling)
{
if(format<VK_FORMAT_BEGIN_RANGE||format>VK_FORMAT_END_RANGE)return(nullptr);
if(width<1||height<1)return(nullptr);
VkImageCreateInfo imageCreateInfo;
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageCreateInfo.pNext = nullptr;
imageCreateInfo.flags = 0;
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
imageCreateInfo.format = format;
imageCreateInfo.extent.width = width;
imageCreateInfo.extent.height = height;
imageCreateInfo.extent.depth = 1;
imageCreateInfo.mipLevels = 1;
imageCreateInfo.arrayLayers = 1;
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
imageCreateInfo.usage = usage;
imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageCreateInfo.queueFamilyIndexCount = 0;
imageCreateInfo.pQueueFamilyIndices = nullptr;
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
imageCreateInfo.tiling = tiling;
VkImage image;
if(vkCreateImage(attr->device,&imageCreateInfo, nullptr, &image)!=VK_SUCCESS)
return(nullptr);
return image;
}
void Device::DestoryImage(VkImage img)
{
if(img==VK_NULL_HANDLE)return;
vkDestroyImage(attr->device,img,nullptr);
}
Memory *Device::CreateMemory(VkImage image,const uint32_t flag)
{
VkMemoryRequirements memReqs;
vkGetImageMemoryRequirements(attr->device,image,&memReqs);
return CreateMemory(memReqs,flag);
}
VK_NAMESPACE_END

View File

@ -20,22 +20,86 @@ namespace
} }
}//namespace }//namespace
Texture2D *Device::CreateTexture2D(const VkFormat format,uint32_t width,uint32_t height,const VkImageAspectFlags aspectMask,const uint usage,const VkImageLayout image_layout) Texture2D *Device::CreateTexture2D(Memory *mem,VkImage image,ImageView *image_view,VkImageLayout image_layout,bool linear)
{
TextureData *tex_data=new TextureData;
tex_data->memory = mem;
tex_data->image_layout = image_layout;
tex_data->image = image;
tex_data->image_view = image_view;
tex_data->mip_levels = 0;
tex_data->linear = linear;
return(new Texture2D(attr->device,tex_data));
}
Texture2D *Device::CreateTexture2D(VkFormat format,uint32_t width,uint32_t height,VkImageAspectFlagBits aspectMask,VkImage image,VkImageLayout image_layout,bool linear)
{
VkExtent3D extent={width,height,1};
ImageView *iv=CreateImageView(attr->device,VK_IMAGE_VIEW_TYPE_2D,format,extent,aspectMask,image);
return this->CreateTexture2D(nullptr,image,iv,image_layout,false);
}
Texture2D *Device::CreateTexture2D(const VkFormat format,uint32_t width,uint32_t height,const VkImageAspectFlags aspectMask,const uint usage,const VkImageLayout image_layout,bool linear)
{ {
const VkFormatProperties fp=attr->physical_device->GetFormatProperties(format); const VkFormatProperties fp=attr->physical_device->GetFormatProperties(format);
if(!(fp.optimalTilingFeatures&VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) enum VkImageTiling tiling;
&&!(fp.linearTilingFeatures&VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
return(nullptr);
return VK_NAMESPACE::CreateTexture2D(attr->device,attr->physical_device,format,width,height,aspectMask,usage,image_layout,(fp.optimalTilingFeatures&VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)?VK_IMAGE_TILING_OPTIMAL:VK_IMAGE_TILING_LINEAR); if(linear)
{
if(fp.linearTilingFeatures&VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)
tiling=VK_IMAGE_TILING_LINEAR;
else
return(nullptr);
}
else
{
if(fp.optimalTilingFeatures&VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)
{
tiling=VK_IMAGE_TILING_OPTIMAL;
}
else
{
if(fp.linearTilingFeatures&VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)
{
tiling=VK_IMAGE_TILING_LINEAR;
linear=true;
}
else
return(nullptr);
}
}
VkImage img=CreateImage(format,width,height,usage,tiling);
if(!img)return(nullptr);
Memory *mem=CreateMemory(img);
if(!mem->BindImage(img))
{
delete mem;
DestoryImage(img);
return(nullptr);
}
const VkExtent3D ext={width,height,1};
ImageView *iv=CreateImageView2D(attr->device,format,ext,aspectMask,img);
return CreateTexture2D(format,width,height,aspectMask,usage,image_layout,linear);
} }
Texture2D *Device::CreateTexture2D(const VkFormat format,Buffer *buf,uint32_t width,uint32_t height,const VkImageAspectFlags aspectMask,const uint usage,const VkImageLayout image_layout) Texture2D *Device::CreateTexture2D(const VkFormat format,Buffer *buf,uint32_t width,uint32_t height,const VkImageAspectFlags aspectMask,const uint usage,const VkImageLayout image_layout,const bool linear)
{ {
if(!buf)return(nullptr); if(!buf)return(nullptr);
Texture2D *tex=CreateTexture2D(format,width,height,aspectMask,usage,image_layout); Texture2D *tex=CreateTexture2D(format,width,height,aspectMask,usage,image_layout,false);
if(!tex)return(nullptr); if(!tex)return(nullptr);
@ -44,13 +108,13 @@ Texture2D *Device::CreateTexture2D(const VkFormat format,Buffer *buf,uint32_t wi
return(tex); return(tex);
} }
Texture2D *Device::CreateTexture2D(const VkFormat format,void *data,uint32_t width,uint32_t height,uint32_t size,const VkImageAspectFlags aspectMask,const uint usage,const VkImageLayout image_layout) Texture2D *Device::CreateTexture2D(const VkFormat format,void *data,uint32_t width,uint32_t height,uint32_t size,const VkImageAspectFlags aspectMask,const uint usage,const VkImageLayout image_layout,const bool linear)
{ {
Buffer *buf=CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,size,data); Buffer *buf=CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,size,data);
if(!buf)return(nullptr); if(!buf)return(nullptr);
Texture2D *tex=CreateTexture2D(format,buf,width,height,aspectMask,image_layout); Texture2D *tex=CreateTexture2D(format,buf,width,height,aspectMask,image_layout,linear);
delete buf; delete buf;
return(tex); return(tex);

View File

@ -1,11 +1,12 @@
#include<hgl/graph/vulkan/VKMemory.h> #include<hgl/graph/vulkan/VKDevice.h>
#include<hgl/graph/vulkan/VKMemory.h>
#include<hgl/graph/vulkan/VKPhysicalDevice.h> #include<hgl/graph/vulkan/VKPhysicalDevice.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
Memory *CreateMemory(VkDevice device,const PhysicalDevice *pd,const VkMemoryRequirements &req,uint32_t properties) Memory *Device::CreateMemory(const VkMemoryRequirements &req,uint32_t properties)
{ {
uint32_t index; uint32_t index;
if(!pd->CheckMemoryType(req.memoryTypeBits,properties,&index)) if(!attr->physical_device->CheckMemoryType(req.memoryTypeBits,properties,&index))
return(false); return(false);
VkMemoryAllocateInfo alloc_info; VkMemoryAllocateInfo alloc_info;
@ -17,10 +18,10 @@ Memory *CreateMemory(VkDevice device,const PhysicalDevice *pd,const VkMemoryRequ
VkDeviceMemory memory; VkDeviceMemory memory;
if(vkAllocateMemory(device,&alloc_info,nullptr,&memory)!=VK_SUCCESS) if(vkAllocateMemory(attr->device,&alloc_info,nullptr,&memory)!=VK_SUCCESS)
return(nullptr); return(nullptr);
return(new Memory(device,memory,req,index,properties)); return(new Memory(attr->device,memory,req,index,properties));
} }
Memory::~Memory() Memory::~Memory()

View File

@ -17,87 +17,4 @@ Texture::~Texture()
vkDestroyImage(device,data->image,nullptr); vkDestroyImage(device,data->image,nullptr);
} }
} }
Texture2D *CreateTexture2D(VkDevice device,VkFormat format,uint32_t width,uint32_t height,VkImageAspectFlagBits aspectMask,VkImage image,VkImageLayout image_layout)
{
TextureData *tex_data=new TextureData;
tex_data->extent.width =width;
tex_data->extent.height =height;
tex_data->extent.depth =1;
tex_data->memory =nullptr;
tex_data->image =image;
tex_data->image_layout =image_layout;
tex_data->image_view =CreateImageView(device,VK_IMAGE_VIEW_TYPE_2D,format,tex_data->extent,aspectMask,image);
tex_data->mip_levels =0;
tex_data->linear =false;
tex_data->format =format;
tex_data->aspect =aspectMask;
return(new Texture2D(width,height,device,tex_data));
}
Texture2D *CreateTexture2D(VkDevice device,const PhysicalDevice *pd,const VkFormat format,uint32_t width,uint32_t height,const VkImageAspectFlags aspectMask,const uint usage,const VkImageLayout image_layout,const VkImageTiling tiling)
{
if(format<VK_FORMAT_BEGIN_RANGE||format>VK_FORMAT_END_RANGE)return(nullptr);
if(width<1||height<1)return(nullptr);
VkImageCreateInfo imageCreateInfo;
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageCreateInfo.pNext = nullptr;
imageCreateInfo.flags = 0;
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
imageCreateInfo.format = format;
imageCreateInfo.extent.width = width;
imageCreateInfo.extent.height = height;
imageCreateInfo.extent.depth = 1;
imageCreateInfo.mipLevels = 1;
imageCreateInfo.arrayLayers = 1;
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
imageCreateInfo.usage = usage;
imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageCreateInfo.queueFamilyIndexCount = 0;
imageCreateInfo.pQueueFamilyIndices = nullptr;
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
imageCreateInfo.tiling = tiling;
VkImage image;
if(vkCreateImage(device, &imageCreateInfo, nullptr, &image)!=VK_SUCCESS)
return(nullptr);
VkMemoryRequirements memReqs;
vkGetImageMemoryRequirements(device, image, &memReqs);
Memory *dm=CreateMemory(device,pd,memReqs,VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
if(dm&&dm->BindImage(image))
{
ImageView *image_view=CreateImageView2D(device,format,imageCreateInfo.extent,aspectMask,image);
if(image_view)
{
TextureData *tex_data=new TextureData;
tex_data->mip_levels = 0;
tex_data->memory = dm;
tex_data->image_layout = image_layout;
tex_data->image = image;
tex_data->image_view = image_view;
tex_data->format = format;
tex_data->aspect = aspectMask;
tex_data->extent = imageCreateInfo.extent;
return(new Texture2D(width,height,device,tex_data));
}
}
delete dm;
vkDestroyImage(device,image,nullptr);
return(nullptr);
}
VK_NAMESPACE_END VK_NAMESPACE_END