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 {
|
||||
std::unique_ptr<GFXDevice> gfxdev;
|
||||
gfx::DrawBuffer* drawBuffer = nullptr;
|
||||
|
||||
/* uniforms for engine globals */
|
||||
const gfx::DescriptorSetLayout* setZeroLayout;
|
||||
const gfx::DescriptorSet* setZero;
|
||||
struct SetZeroBuffer {
|
||||
glm::mat4 proj;
|
||||
};
|
||||
const gfx::Image* myImage = nullptr;
|
||||
const gfx::Sampler* mySampler = nullptr;
|
||||
|
||||
gfx::UniformBuffer* setZeroBuffer;
|
||||
/* uniforms for per-frame data */
|
||||
const gfx::DescriptorSetLayout* setOneLayout;
|
||||
|
@ -17,6 +17,7 @@ namespace engine::gfx {
|
||||
struct DescriptorSetLayout;
|
||||
struct DescriptorSet;
|
||||
struct Image;
|
||||
struct Sampler;
|
||||
|
||||
enum class MSAALevel {
|
||||
MSAA_OFF,
|
||||
|
@ -38,7 +38,7 @@ namespace engine {
|
||||
gfx::DescriptorSet* allocateDescriptorSet(const gfx::DescriptorSetLayout* layout);
|
||||
// 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 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);
|
||||
void destroyUniformBuffer(const gfx::UniformBuffer* descriptorBuffer);
|
||||
@ -50,6 +50,10 @@ namespace engine {
|
||||
void destroyBuffer(const gfx::Buffer* buffer);
|
||||
|
||||
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(
|
||||
const void* imageData,
|
||||
|
@ -7,7 +7,7 @@ layout(location = 3) in vec3 fragLightPos;
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
//layout(set = 1, binding = 0) uniform sampler2D texSampler;
|
||||
layout(set = 0, binding = 1) uniform sampler2D texSampler;
|
||||
|
||||
void main() {
|
||||
|
||||
@ -15,8 +15,7 @@ void main() {
|
||||
vec3 lightColor = vec3(1.0, 1.0, 1.0);
|
||||
vec3 ambientColor = vec3(1.0, 1.0, 1.0);
|
||||
float ambientStrength = 0.05;
|
||||
//vec3 baseColor = vec3(texture(texSampler, fragUV));
|
||||
vec3 baseColor = vec3(mod(fragUV.x, 1.0), mod(fragUV.y, 1.0), 0.0);
|
||||
vec3 baseColor = vec3(texture(texSampler, fragUV));
|
||||
vec3 emission = vec3(0.0, 0.0, 0.0);
|
||||
|
||||
// code
|
||||
|
@ -76,22 +76,33 @@ namespace engine {
|
||||
// initialise the render data
|
||||
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.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(layoutBindings);
|
||||
renderData.setZeroLayout = gfx()->createDescriptorSetLayout(setZeroLayoutBindings);
|
||||
renderData.setZero = gfx()->allocateDescriptorSet(renderData.setZeroLayout);
|
||||
RenderData::SetZeroBuffer initialSetZeroData{
|
||||
.proj = glm::perspectiveZO(glm::radians(70.0f), 1024.0f / 768.0f, 0.1f, 1000.0f),
|
||||
};
|
||||
renderData.setZeroBuffer = gfx()->createUniformBuffer(sizeof(RenderData::SetZeroBuffer), &initialSetZeroData);
|
||||
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::SetOneBuffer initialSetOneData{
|
||||
.view = glm::mat4{ 1.0f },
|
||||
@ -144,6 +155,9 @@ namespace engine {
|
||||
{
|
||||
gfx()->destroyUniformBuffer(renderData.setOneBuffer);
|
||||
gfx()->destroyDescriptorSetLayout(renderData.setOneLayout);
|
||||
|
||||
gfx()->destroySampler(renderData.mySampler);
|
||||
gfx()->destroyImage(renderData.myImage);
|
||||
gfx()->destroyUniformBuffer(renderData.setZeroBuffer);
|
||||
gfx()->destroyDescriptorSetLayout(renderData.setZeroLayout);
|
||||
}
|
||||
|
@ -94,6 +94,16 @@ namespace engine {
|
||||
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 {
|
||||
|
||||
};
|
||||
@ -362,7 +372,9 @@ namespace engine {
|
||||
.format = VK_FORMAT_R8G8B8A8_SRGB,
|
||||
.properties = VkFormatProperties{
|
||||
.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 = {},
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
|
||||
VkDescriptorImageInfo imageInfo{};
|
||||
imageInfo.sampler = VK_NULL_HANDLE;
|
||||
imageInfo.imageView = VK_NULL_HANDLE;
|
||||
imageInfo.sampler = sampler->sampler;
|
||||
imageInfo.imageView = image->view;
|
||||
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
|
||||
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)
|
||||
{
|
||||
(void)w;
|
||||
(void)h;
|
||||
(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(
|
||||
|
Loading…
Reference in New Issue
Block a user