mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
Get textures working (almost)
This commit is contained in:
parent
9f88131371
commit
25ee640c41
@ -28,12 +28,16 @@ namespace engine {
|
|||||||
struct RenderData {
|
struct RenderData {
|
||||||
std::unique_ptr<GFXDevice> gfxdev;
|
std::unique_ptr<GFXDevice> gfxdev;
|
||||||
gfx::DrawBuffer* drawBuffer = nullptr;
|
gfx::DrawBuffer* drawBuffer = nullptr;
|
||||||
|
|
||||||
/* uniforms for engine globals */
|
/* uniforms for engine globals */
|
||||||
const gfx::DescriptorSetLayout* setZeroLayout;
|
const gfx::DescriptorSetLayout* setZeroLayout;
|
||||||
const gfx::DescriptorSet* setZero;
|
const gfx::DescriptorSet* setZero;
|
||||||
struct SetZeroBuffer {
|
struct SetZeroBuffer {
|
||||||
glm::mat4 proj;
|
glm::mat4 proj;
|
||||||
};
|
};
|
||||||
|
const gfx::Image* myImage = nullptr;
|
||||||
|
const gfx::Sampler* mySampler = nullptr;
|
||||||
|
|
||||||
gfx::UniformBuffer* setZeroBuffer;
|
gfx::UniformBuffer* setZeroBuffer;
|
||||||
/* uniforms for per-frame data */
|
/* uniforms for per-frame data */
|
||||||
const gfx::DescriptorSetLayout* setOneLayout;
|
const gfx::DescriptorSetLayout* setOneLayout;
|
||||||
|
@ -17,6 +17,7 @@ namespace engine::gfx {
|
|||||||
struct DescriptorSetLayout;
|
struct DescriptorSetLayout;
|
||||||
struct DescriptorSet;
|
struct DescriptorSet;
|
||||||
struct Image;
|
struct Image;
|
||||||
|
struct Sampler;
|
||||||
|
|
||||||
enum class MSAALevel {
|
enum class MSAALevel {
|
||||||
MSAA_OFF,
|
MSAA_OFF,
|
||||||
|
@ -38,7 +38,7 @@ namespace engine {
|
|||||||
gfx::DescriptorSet* allocateDescriptorSet(const gfx::DescriptorSetLayout* layout);
|
gfx::DescriptorSet* allocateDescriptorSet(const gfx::DescriptorSetLayout* layout);
|
||||||
// This updates all copies of the descriptor. This cannot be used after any frames have been renderered
|
// This updates all copies of the descriptor. This cannot be used after any frames have been renderered
|
||||||
void updateDescriptorUniformBuffer(const gfx::DescriptorSet* set, uint32_t binding, const gfx::UniformBuffer* buffer, size_t offset, size_t range);
|
void updateDescriptorUniformBuffer(const gfx::DescriptorSet* set, uint32_t binding, const gfx::UniformBuffer* buffer, size_t offset, size_t range);
|
||||||
void updateDescriptorCombinedImageSampler(const gfx::DescriptorSet* set, uint32_t binding);
|
void updateDescriptorCombinedImageSampler(const gfx::DescriptorSet* set, uint32_t binding, const gfx::Image* image, const gfx::Sampler* sampler);
|
||||||
|
|
||||||
gfx::UniformBuffer* createUniformBuffer(uint64_t size, const void* initialData);
|
gfx::UniformBuffer* createUniformBuffer(uint64_t size, const void* initialData);
|
||||||
void destroyUniformBuffer(const gfx::UniformBuffer* descriptorBuffer);
|
void destroyUniformBuffer(const gfx::UniformBuffer* descriptorBuffer);
|
||||||
@ -50,6 +50,10 @@ namespace engine {
|
|||||||
void destroyBuffer(const gfx::Buffer* buffer);
|
void destroyBuffer(const gfx::Buffer* buffer);
|
||||||
|
|
||||||
gfx::Image* createImage(uint32_t w, uint32_t h, const void* imageData);
|
gfx::Image* createImage(uint32_t w, uint32_t h, const void* imageData);
|
||||||
|
void destroyImage(const gfx::Image* image);
|
||||||
|
|
||||||
|
gfx::Sampler* createSampler();
|
||||||
|
void destroySampler(const gfx::Sampler* sampler);
|
||||||
|
|
||||||
gfx::Texture* createTexture(
|
gfx::Texture* createTexture(
|
||||||
const void* imageData,
|
const void* imageData,
|
||||||
|
@ -7,7 +7,7 @@ layout(location = 3) in vec3 fragLightPos;
|
|||||||
|
|
||||||
layout(location = 0) out vec4 outColor;
|
layout(location = 0) out vec4 outColor;
|
||||||
|
|
||||||
//layout(set = 1, binding = 0) uniform sampler2D texSampler;
|
layout(set = 0, binding = 1) uniform sampler2D texSampler;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
||||||
@ -15,8 +15,7 @@ void main() {
|
|||||||
vec3 lightColor = vec3(1.0, 1.0, 1.0);
|
vec3 lightColor = vec3(1.0, 1.0, 1.0);
|
||||||
vec3 ambientColor = vec3(1.0, 1.0, 1.0);
|
vec3 ambientColor = vec3(1.0, 1.0, 1.0);
|
||||||
float ambientStrength = 0.05;
|
float ambientStrength = 0.05;
|
||||||
//vec3 baseColor = vec3(texture(texSampler, fragUV));
|
vec3 baseColor = vec3(texture(texSampler, fragUV));
|
||||||
vec3 baseColor = vec3(mod(fragUV.x, 1.0), mod(fragUV.y, 1.0), 0.0);
|
|
||||||
vec3 emission = vec3(0.0, 0.0, 0.0);
|
vec3 emission = vec3(0.0, 0.0, 0.0);
|
||||||
|
|
||||||
// code
|
// code
|
||||||
|
@ -76,22 +76,33 @@ namespace engine {
|
|||||||
// initialise the render data
|
// initialise the render data
|
||||||
renderData.gfxdev = std::make_unique<GFXDevice>(appName, appVersion, m_window->getHandle(), graphicsSettings);
|
renderData.gfxdev = std::make_unique<GFXDevice>(appName, appVersion, m_window->getHandle(), graphicsSettings);
|
||||||
|
|
||||||
std::vector<gfx::DescriptorSetLayoutBinding> layoutBindings;
|
std::vector<gfx::DescriptorSetLayoutBinding> setZeroLayoutBindings;
|
||||||
{
|
{
|
||||||
auto& binding0 = layoutBindings.emplace_back();
|
auto& binding0 = setZeroLayoutBindings.emplace_back();
|
||||||
binding0.descriptorType = gfx::DescriptorType::UNIFORM_BUFFER;
|
binding0.descriptorType = gfx::DescriptorType::UNIFORM_BUFFER;
|
||||||
binding0.stageFlags = gfx::ShaderStageFlags::VERTEX;
|
binding0.stageFlags = gfx::ShaderStageFlags::VERTEX;
|
||||||
|
auto& binding1 = setZeroLayoutBindings.emplace_back();
|
||||||
|
binding1.descriptorType = gfx::DescriptorType::COMBINED_IMAGE_SAMPLER;
|
||||||
|
binding1.stageFlags = gfx::ShaderStageFlags::FRAGMENT;
|
||||||
}
|
}
|
||||||
|
renderData.setZeroLayout = gfx()->createDescriptorSetLayout(setZeroLayoutBindings);
|
||||||
renderData.setZeroLayout = gfx()->createDescriptorSetLayout(layoutBindings);
|
|
||||||
renderData.setZero = gfx()->allocateDescriptorSet(renderData.setZeroLayout);
|
renderData.setZero = gfx()->allocateDescriptorSet(renderData.setZeroLayout);
|
||||||
RenderData::SetZeroBuffer initialSetZeroData{
|
RenderData::SetZeroBuffer initialSetZeroData{
|
||||||
.proj = glm::perspectiveZO(glm::radians(70.0f), 1024.0f / 768.0f, 0.1f, 1000.0f),
|
.proj = glm::perspectiveZO(glm::radians(70.0f), 1024.0f / 768.0f, 0.1f, 1000.0f),
|
||||||
};
|
};
|
||||||
renderData.setZeroBuffer = gfx()->createUniformBuffer(sizeof(RenderData::SetZeroBuffer), &initialSetZeroData);
|
renderData.setZeroBuffer = gfx()->createUniformBuffer(sizeof(RenderData::SetZeroBuffer), &initialSetZeroData);
|
||||||
gfx()->updateDescriptorUniformBuffer(renderData.setZero, 0, renderData.setZeroBuffer, 0, sizeof(RenderData::SetZeroBuffer));
|
gfx()->updateDescriptorUniformBuffer(renderData.setZero, 0, renderData.setZeroBuffer, 0, sizeof(RenderData::SetZeroBuffer));
|
||||||
|
renderData.myImage = gfx()->createImage(512, 512, nullptr);
|
||||||
|
renderData.mySampler = gfx()->createSampler();
|
||||||
|
gfx()->updateDescriptorCombinedImageSampler(renderData.setZero, 1, renderData.myImage, renderData.mySampler);
|
||||||
|
|
||||||
renderData.setOneLayout = gfx()->createDescriptorSetLayout(layoutBindings);
|
std::vector<gfx::DescriptorSetLayoutBinding> setOneLayoutBindings;
|
||||||
|
{
|
||||||
|
auto& binding0 = setOneLayoutBindings.emplace_back();
|
||||||
|
binding0.descriptorType = gfx::DescriptorType::UNIFORM_BUFFER;
|
||||||
|
binding0.stageFlags = gfx::ShaderStageFlags::VERTEX;
|
||||||
|
}
|
||||||
|
renderData.setOneLayout = gfx()->createDescriptorSetLayout(setOneLayoutBindings);
|
||||||
renderData.setOne = gfx()->allocateDescriptorSet(renderData.setOneLayout);
|
renderData.setOne = gfx()->allocateDescriptorSet(renderData.setOneLayout);
|
||||||
RenderData::SetOneBuffer initialSetOneData{
|
RenderData::SetOneBuffer initialSetOneData{
|
||||||
.view = glm::mat4{ 1.0f },
|
.view = glm::mat4{ 1.0f },
|
||||||
@ -144,6 +155,9 @@ namespace engine {
|
|||||||
{
|
{
|
||||||
gfx()->destroyUniformBuffer(renderData.setOneBuffer);
|
gfx()->destroyUniformBuffer(renderData.setOneBuffer);
|
||||||
gfx()->destroyDescriptorSetLayout(renderData.setOneLayout);
|
gfx()->destroyDescriptorSetLayout(renderData.setOneLayout);
|
||||||
|
|
||||||
|
gfx()->destroySampler(renderData.mySampler);
|
||||||
|
gfx()->destroyImage(renderData.myImage);
|
||||||
gfx()->destroyUniformBuffer(renderData.setZeroBuffer);
|
gfx()->destroyUniformBuffer(renderData.setZeroBuffer);
|
||||||
gfx()->destroyDescriptorSetLayout(renderData.setZeroLayout);
|
gfx()->destroyDescriptorSetLayout(renderData.setZeroLayout);
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,16 @@ namespace engine {
|
|||||||
VkPipeline handle = VK_NULL_HANDLE;
|
VkPipeline handle = VK_NULL_HANDLE;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct gfx::Image {
|
||||||
|
VkImage image = VK_NULL_HANDLE;
|
||||||
|
VkImageView view = VK_NULL_HANDLE;
|
||||||
|
VmaAllocation allocation = VK_NULL_HANDLE;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gfx::Sampler {
|
||||||
|
VkSampler sampler = VK_NULL_HANDLE;
|
||||||
|
};
|
||||||
|
|
||||||
struct gfx::Texture {
|
struct gfx::Texture {
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -362,7 +372,9 @@ namespace engine {
|
|||||||
.format = VK_FORMAT_R8G8B8A8_SRGB,
|
.format = VK_FORMAT_R8G8B8A8_SRGB,
|
||||||
.properties = VkFormatProperties{
|
.properties = VkFormatProperties{
|
||||||
.linearTilingFeatures = {},
|
.linearTilingFeatures = {},
|
||||||
.optimalTilingFeatures = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT,
|
.optimalTilingFeatures =
|
||||||
|
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT |
|
||||||
|
VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT,
|
||||||
.bufferFeatures = {},
|
.bufferFeatures = {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1084,13 +1096,13 @@ namespace engine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GFXDevice::updateDescriptorCombinedImageSampler(const gfx::DescriptorSet *set, uint32_t binding)
|
void GFXDevice::updateDescriptorCombinedImageSampler(const gfx::DescriptorSet *set, uint32_t binding, const gfx::Image* image, const gfx::Sampler* sampler)
|
||||||
{
|
{
|
||||||
assert(pimpl->FRAMECOUNT == 0);
|
assert(pimpl->FRAMECOUNT == 0);
|
||||||
|
|
||||||
VkDescriptorImageInfo imageInfo{};
|
VkDescriptorImageInfo imageInfo{};
|
||||||
imageInfo.sampler = VK_NULL_HANDLE;
|
imageInfo.sampler = sampler->sampler;
|
||||||
imageInfo.imageView = VK_NULL_HANDLE;
|
imageInfo.imageView = image->view;
|
||||||
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < FRAMES_IN_FLIGHT; i++) {
|
for (uint32_t i = 0; i < FRAMES_IN_FLIGHT; i++) {
|
||||||
@ -1259,10 +1271,135 @@ namespace engine {
|
|||||||
|
|
||||||
gfx::Image* GFXDevice::createImage(uint32_t w, uint32_t h, const void* imageData)
|
gfx::Image* GFXDevice::createImage(uint32_t w, uint32_t h, const void* imageData)
|
||||||
{
|
{
|
||||||
(void)w;
|
|
||||||
(void)h;
|
|
||||||
(void)imageData;
|
(void)imageData;
|
||||||
return nullptr;
|
|
||||||
|
assert(pimpl->FRAMECOUNT == 0);
|
||||||
|
|
||||||
|
gfx::Image* out = new gfx::Image{};
|
||||||
|
|
||||||
|
VkImageCreateInfo imageInfo{};
|
||||||
|
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||||
|
imageInfo.flags = 0;
|
||||||
|
imageInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||||
|
imageInfo.format = VK_FORMAT_R8G8B8A8_SRGB;
|
||||||
|
imageInfo.extent.width = w;
|
||||||
|
imageInfo.extent.height = h;
|
||||||
|
imageInfo.extent.depth = 1;
|
||||||
|
imageInfo.mipLevels = 1;
|
||||||
|
imageInfo.arrayLayers = 1;
|
||||||
|
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||||
|
imageInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
|
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
|
||||||
|
VmaAllocationCreateInfo allocCreateInfo{};
|
||||||
|
allocCreateInfo.flags = 0;
|
||||||
|
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
|
||||||
|
allocCreateInfo.priority = 0.5f;
|
||||||
|
|
||||||
|
VKCHECK(vmaCreateImage(pimpl->allocator, &imageInfo, &allocCreateInfo, &out->image, &out->allocation, nullptr));
|
||||||
|
|
||||||
|
VkImageViewCreateInfo viewInfo{};
|
||||||
|
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
|
viewInfo.image = out->image;
|
||||||
|
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
|
viewInfo.format = imageInfo.format;
|
||||||
|
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
viewInfo.subresourceRange.baseMipLevel = 0;
|
||||||
|
viewInfo.subresourceRange.levelCount = 1;
|
||||||
|
viewInfo.subresourceRange.baseArrayLayer = 0;
|
||||||
|
viewInfo.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
|
VKCHECK(vkCreateImageView(pimpl->device.device, &viewInfo, nullptr, &out->view));
|
||||||
|
|
||||||
|
// Do a pipeline barrier to transition the layout
|
||||||
|
VkCommandBufferAllocateInfo allocInfo{};
|
||||||
|
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||||
|
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||||
|
allocInfo.commandPool = pimpl->transferCommandPool;
|
||||||
|
allocInfo.commandBufferCount = 1;
|
||||||
|
|
||||||
|
VkCommandBuffer commandBuffer;
|
||||||
|
VKCHECK(vkAllocateCommandBuffers(pimpl->device.device, &allocInfo, &commandBuffer));
|
||||||
|
|
||||||
|
{ // record the command buffer
|
||||||
|
VkCommandBufferBeginInfo beginInfo{};
|
||||||
|
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
|
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||||
|
VKCHECK(vkBeginCommandBuffer(commandBuffer, &beginInfo));
|
||||||
|
|
||||||
|
VkImageMemoryBarrier2 barrier{};
|
||||||
|
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
|
||||||
|
barrier.srcStageMask = VK_PIPELINE_STAGE_2_NONE;
|
||||||
|
barrier.srcAccessMask = VK_ACCESS_2_NONE;
|
||||||
|
barrier.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT;
|
||||||
|
barrier.dstAccessMask = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT;
|
||||||
|
barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
barrier.srcQueueFamilyIndex = pimpl->device.queues.transferQueueFamily;
|
||||||
|
barrier.dstQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
|
||||||
|
barrier.image = out->image;
|
||||||
|
barrier.subresourceRange = viewInfo.subresourceRange;
|
||||||
|
|
||||||
|
VkDependencyInfo depInfo{};
|
||||||
|
depInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
|
||||||
|
depInfo.imageMemoryBarrierCount = 1;
|
||||||
|
depInfo.pImageMemoryBarriers = &barrier;
|
||||||
|
|
||||||
|
vkCmdPipelineBarrier2(commandBuffer, &depInfo);
|
||||||
|
|
||||||
|
VKCHECK(vkEndCommandBuffer(commandBuffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
// submit
|
||||||
|
VkSubmitInfo submitInfo{};
|
||||||
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
submitInfo.commandBufferCount = 1;
|
||||||
|
submitInfo.pCommandBuffers = &commandBuffer;
|
||||||
|
|
||||||
|
VKCHECK(vkQueueSubmit(pimpl->device.queues.transferQueues[0], 1, &submitInfo, VK_NULL_HANDLE));
|
||||||
|
|
||||||
|
VKCHECK(vkQueueWaitIdle(pimpl->device.queues.transferQueues[0]));
|
||||||
|
|
||||||
|
vkFreeCommandBuffers(pimpl->device.device, pimpl->transferCommandPool, 1, &commandBuffer);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GFXDevice::destroyImage(const gfx::Image *image)
|
||||||
|
{
|
||||||
|
vkDestroyImageView(pimpl->device.device, image->view, nullptr);
|
||||||
|
vmaDestroyImage(pimpl->allocator, image->image, image->allocation);
|
||||||
|
delete image;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx::Sampler *GFXDevice::createSampler()
|
||||||
|
{
|
||||||
|
gfx::Sampler* out = new gfx::Sampler{};
|
||||||
|
|
||||||
|
VkSamplerCreateInfo samplerInfo{};
|
||||||
|
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||||
|
samplerInfo.magFilter = VK_FILTER_NEAREST;
|
||||||
|
samplerInfo.minFilter = VK_FILTER_NEAREST;
|
||||||
|
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||||
|
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||||
|
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||||
|
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||||
|
samplerInfo.mipLodBias = 0.0f; // wtf
|
||||||
|
samplerInfo.anisotropyEnable = VK_FALSE;
|
||||||
|
samplerInfo.minLod = 0.0f;
|
||||||
|
samplerInfo.maxLod = 0.0f;
|
||||||
|
|
||||||
|
VKCHECK(vkCreateSampler(pimpl->device.device, &samplerInfo, nullptr, &out->sampler));
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GFXDevice::destroySampler(const gfx::Sampler *sampler)
|
||||||
|
{
|
||||||
|
vkDestroySampler(pimpl->device.device, sampler->sampler, nullptr);
|
||||||
|
delete sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::Texture* GFXDevice::createTexture(
|
gfx::Texture* GFXDevice::createTexture(
|
||||||
|
Loading…
Reference in New Issue
Block a user