Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 09a6c0283a | |||
| 3784d0fdec |
@@ -27,8 +27,8 @@ Buffer::Buffer(Device& device, vk::DeviceSize instanceSize, u32 instanceCount,
|
||||
memoryPropertyFlags{memoryPropertyFlags} {
|
||||
alignmentSize = getAlignment(instanceSize, minOffsetAlignment);
|
||||
bufferSize = alignmentSize * instanceCount;
|
||||
device.createBuffer(bufferSize, usageFlags, memoryPropertyFlags, buffer,
|
||||
allocation);
|
||||
device.createBuffer(bufferSize, this->usageFlags, this->memoryPropertyFlags,
|
||||
this->buffer, this->allocation, this->info);
|
||||
}
|
||||
|
||||
Buffer::~Buffer() {
|
||||
@@ -62,6 +62,9 @@ void Buffer::writeToBuffer(void* data, vk::DeviceSize size,
|
||||
if (size == VK_WHOLE_SIZE) {
|
||||
memcpy(mapped, data, bufferSize);
|
||||
} else {
|
||||
SOPHIA_ASSERT(offset + size <= bufferSize,
|
||||
"write of {} bytes at offset {} overflows buffer of {} bytes",
|
||||
size, offset, bufferSize);
|
||||
char* memOffset = (char*)mapped;
|
||||
memOffset += offset;
|
||||
memcpy(memOffset, data, size);
|
||||
|
||||
@@ -36,9 +36,10 @@ class Buffer {
|
||||
vk::DescriptorBufferInfo descriptorInfoForIndex(int index);
|
||||
vk::Result invalidateIndex(int index);
|
||||
|
||||
vk::Buffer getBuffer() const { return buffer; }
|
||||
void* getMappedMemory() const { return mapped; }
|
||||
uint32_t getInstanceCount() const { return instanceCount; }
|
||||
void* getMappedMemory() const { return this->mapped; }
|
||||
vk::Buffer getBuffer() const { return this->buffer; }
|
||||
const VmaAllocationInfo& getAllocationInfo() const { return this->info; }
|
||||
u32 getInstanceCount() const { return instanceCount; }
|
||||
vk::DeviceSize getInstanceSize() const { return instanceSize; }
|
||||
vk::DeviceSize getAlignmentSize() const { return alignmentSize; }
|
||||
vk::BufferUsageFlags getUsageFlags() const { return usageFlags; }
|
||||
@@ -55,9 +56,10 @@ class Buffer {
|
||||
void* mapped = nullptr;
|
||||
vk::Buffer buffer = VK_NULL_HANDLE;
|
||||
VmaAllocation allocation = VK_NULL_HANDLE;
|
||||
VmaAllocationInfo info;
|
||||
|
||||
vk::DeviceSize bufferSize;
|
||||
uint32_t instanceCount;
|
||||
u32 instanceCount;
|
||||
vk::DeviceSize instanceSize;
|
||||
vk::DeviceSize alignmentSize;
|
||||
vk::BufferUsageFlags usageFlags;
|
||||
|
||||
@@ -184,7 +184,8 @@ vk::Format Device::findSupportedFormat(
|
||||
|
||||
void Device::createBuffer(vk::DeviceSize size, vk::BufferUsageFlags usage,
|
||||
vk::MemoryPropertyFlags properties,
|
||||
vk::Buffer& buffer, VmaAllocation& allocation) {
|
||||
vk::Buffer& buffer, VmaAllocation& allocation,
|
||||
VmaAllocationInfo& info) {
|
||||
vk::BufferCreateInfo bufferInfo = {};
|
||||
bufferInfo.size = size;
|
||||
bufferInfo.usage = usage;
|
||||
@@ -196,7 +197,7 @@ void Device::createBuffer(vk::DeviceSize size, vk::BufferUsageFlags usage,
|
||||
VkBuffer rawBuffer = VK_NULL_HANDLE;
|
||||
VkResult result = vmaCreateBuffer(
|
||||
this->allocator, &static_cast<const VkBufferCreateInfo&>(bufferInfo),
|
||||
&allocInfo, &rawBuffer, &allocation, nullptr);
|
||||
&allocInfo, &rawBuffer, &allocation, &info);
|
||||
if (result != VK_SUCCESS) {
|
||||
log::fatal("failed to create buffer. Error: {}",
|
||||
vk::to_string(static_cast<vk::Result>(result)));
|
||||
|
||||
@@ -69,7 +69,7 @@ class Device {
|
||||
|
||||
void createBuffer(vk::DeviceSize size, vk::BufferUsageFlags usage,
|
||||
vk::MemoryPropertyFlags properties, vk::Buffer& buffer,
|
||||
VmaAllocation& allocation);
|
||||
VmaAllocation& allocation, VmaAllocationInfo& info);
|
||||
|
||||
vk::CommandBuffer beginSingleTimeCommands();
|
||||
|
||||
|
||||
@@ -226,11 +226,12 @@ std::unique_ptr<Image> Image::Builder::build() {
|
||||
|
||||
vk::Buffer stagingBuffer;
|
||||
VmaAllocation stagingAllocation;
|
||||
this->device.createBuffer(this->initialDataSize,
|
||||
vk::BufferUsageFlagBits::eTransferSrc,
|
||||
vk::MemoryPropertyFlagBits::eHostVisible |
|
||||
vk::MemoryPropertyFlagBits::eHostCoherent,
|
||||
stagingBuffer, stagingAllocation);
|
||||
VmaAllocationInfo stagingAllocationInfo;
|
||||
this->device.createBuffer(
|
||||
this->initialDataSize, vk::BufferUsageFlagBits::eTransferSrc,
|
||||
vk::MemoryPropertyFlagBits::eHostVisible |
|
||||
vk::MemoryPropertyFlagBits::eHostCoherent,
|
||||
stagingBuffer, stagingAllocation, stagingAllocationInfo);
|
||||
|
||||
void* mapped = nullptr;
|
||||
vmaMapMemory(allocator, stagingAllocation, &mapped);
|
||||
|
||||
+85
-6
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <sophia/components.hpp>
|
||||
#include <sophia/scene_registry.hpp>
|
||||
#include <sophia/scene_view.hpp>
|
||||
#include <tracy/Tracy.hpp>
|
||||
@@ -12,13 +13,24 @@
|
||||
#include "renderer/render_graph.hpp"
|
||||
#include "renderer/scene_renderer.hpp"
|
||||
#include "resources/resource_registry.hpp"
|
||||
#include "vulkan/buffer.hpp"
|
||||
#include "vulkan/device.hpp"
|
||||
#include "vulkan/shader.hpp"
|
||||
#include "window.hpp"
|
||||
|
||||
constexpr uint32_t WIDTH = 1280;
|
||||
constexpr uint32_t HEIGHT = 720;
|
||||
constexpr const char* NAME = "sandbox";
|
||||
|
||||
void immediate_submit(sophia::Device& device,
|
||||
std::function<void(VkCommandBuffer cmd)>&& function) {
|
||||
auto command = device.beginSingleTimeCommands();
|
||||
function(command);
|
||||
device.endSingleTimeCommands(command);
|
||||
}
|
||||
|
||||
#include "material.hpp"
|
||||
|
||||
int main() {
|
||||
sophia::Window window{WIDTH, HEIGHT, NAME};
|
||||
sophia::Device device{&window};
|
||||
@@ -30,10 +42,55 @@ int main() {
|
||||
sophia::SceneRenderer sceneRenderer{sceneRegistry, resourceRegistry, device,
|
||||
renderContext.getImageFormat()};
|
||||
|
||||
sophia::SceneHandle sceneHandle = sceneRegistry.create();
|
||||
sophia::Scene& scene = sceneRegistry.get(sceneHandle);
|
||||
sophia::Entity camera = scene.createCamera();
|
||||
|
||||
// {
|
||||
// auto& transform = camera.getComponent<sophia::TransformComponent>();
|
||||
// transform.position.z += 60;
|
||||
// }
|
||||
|
||||
sophia::SceneView view;
|
||||
view.scene = sceneRegistry.create();
|
||||
view.scene = sceneHandle;
|
||||
view.clearColor = {0.01f, 0.01f, 0.02f, 1.0f};
|
||||
view.camera = sceneRegistry.get(view.scene).createCamera();
|
||||
view.camera = camera;
|
||||
|
||||
auto vertexShader = sophia::Shader::Builder()
|
||||
.fromGLSL(SANDBOX_SHADER_DIR "/triangle.vert")
|
||||
.setStage(sophia::ShaderStage::VERTEX)
|
||||
.build();
|
||||
auto fragmentShader = sophia::Shader::Builder()
|
||||
.fromGLSL(SANDBOX_SHADER_DIR "/triangle.frag")
|
||||
.setStage(sophia::ShaderStage::FRAGMENT)
|
||||
.build();
|
||||
vk::Format depthFormat = resourceRegistry.renderTargetPool.getDepthFormat();
|
||||
sophia::Material material{device, std::move(vertexShader),
|
||||
std::move(fragmentShader),
|
||||
renderContext.getImageFormat(), depthFormat};
|
||||
|
||||
struct TriangleVertex {
|
||||
sophia::vec4 vertex;
|
||||
sophia::vec4 color;
|
||||
};
|
||||
|
||||
TriangleVertex verticies[] = {
|
||||
{{-1.f, 1.f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 0.0f}},
|
||||
{{1.f, 1.f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 0.0f}},
|
||||
{{0.f, -1.f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f, 0.0f}}};
|
||||
sophia::u32 triangleVerticiesCount = 3;
|
||||
|
||||
sophia::Buffer triangleBuffer{device, sizeof(TriangleVertex),
|
||||
triangleVerticiesCount,
|
||||
vk::BufferUsageFlagBits::eShaderDeviceAddress,
|
||||
vk::MemoryPropertyFlagBits::eHostVisible |
|
||||
vk::MemoryPropertyFlagBits::eHostCoherent};
|
||||
triangleBuffer.map();
|
||||
|
||||
triangleBuffer.writeToBuffer(verticies);
|
||||
|
||||
vk::DeviceAddress address =
|
||||
device.get()->getBufferAddress({triangleBuffer.getBuffer()});
|
||||
|
||||
while (!window.shouldClose()) {
|
||||
glfwPollEvents();
|
||||
@@ -52,7 +109,7 @@ int main() {
|
||||
renderContext.getCurrentDepthImage(), sophia::Access::DepthWrite);
|
||||
|
||||
graph.addPass(
|
||||
"scene",
|
||||
"sandbox",
|
||||
[&](sophia::RenderGraph::PassBuilder& pass) {
|
||||
const sophia::vec4& c = view.clearColor;
|
||||
pass.writeColor(color, vk::AttachmentLoadOp::eClear,
|
||||
@@ -60,11 +117,33 @@ int main() {
|
||||
pass.writeDepth(depth, vk::AttachmentLoadOp::eClear);
|
||||
},
|
||||
[&](vk::CommandBuffer commandBuffer) {
|
||||
ZoneScopedN("scene pass");
|
||||
sceneRenderer.render(commandBuffer, view, view.camera,
|
||||
renderContext.getExtent());
|
||||
ZoneScopedN("main sandbox pass");
|
||||
material.bind(commandBuffer);
|
||||
sophia::Material::PushConstants push;
|
||||
push.data0 = address;
|
||||
|
||||
commandBuffer.pushConstants(
|
||||
material.getLayout(), vk::ShaderStageFlagBits::eVertex, 0,
|
||||
sizeof(sophia::Material::PushConstants), &push);
|
||||
commandBuffer.draw(3, 1, 0, 0);
|
||||
});
|
||||
|
||||
/*
|
||||
graph.addPass(
|
||||
"scene",
|
||||
[&](sophia::RenderGraph::PassBuilder& pass) {
|
||||
const sophia::vec4& c = view.clearColor;
|
||||
pass.writeColor(color, vk::AttachmentLoadOp::eClear,
|
||||
{c.r, c.g, c.b, c.a});
|
||||
pass.writeDepth(depth, vk::AttachmentLoadOp::eClear);
|
||||
},
|
||||
[&](vk::CommandBuffer commandBuffer) {
|
||||
ZoneScopedN("scene pass");
|
||||
sceneRenderer.render(commandBuffer, view, view.camera,
|
||||
renderContext.getExtent());
|
||||
});
|
||||
*/
|
||||
|
||||
graph.execute(commandBuffer);
|
||||
|
||||
renderContext.endFrame();
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#include "material.hpp"
|
||||
|
||||
#include <sophia/util/logger.hpp>
|
||||
|
||||
namespace sophia {
|
||||
|
||||
Material::Material(Device& device, std::unique_ptr<Shader> vertexShader,
|
||||
std::unique_ptr<Shader> fragmentShader,
|
||||
vk::Format colorFormat, vk::Format depthFormat) {
|
||||
createPipelineLayout(device);
|
||||
this->pipeline = GraphicsPipeline::Builder(device)
|
||||
.setVertexShader(*vertexShader)
|
||||
.setFragmentShader(*fragmentShader)
|
||||
.setPipelineLayout(this->pipelineLayout.get())
|
||||
.setColorAttachmentFormats({colorFormat})
|
||||
.setDepthAttachmentFormat(depthFormat)
|
||||
.setDepthTest(true, true)
|
||||
.setCullMode(vk::CullModeFlagBits::eBack)
|
||||
.build();
|
||||
}
|
||||
|
||||
Material::~Material() { log::trace("destroyed sophia::Material"); }
|
||||
|
||||
void Material::createPipelineLayout(Device& device) {
|
||||
vk::PushConstantRange pushConstantRange{};
|
||||
pushConstantRange.stageFlags = vk::ShaderStageFlagBits::eVertex;
|
||||
pushConstantRange.offset = 0;
|
||||
pushConstantRange.size = sizeof(PushConstants);
|
||||
|
||||
vk::PipelineLayoutCreateInfo pipelineLayoutInfo = {};
|
||||
pipelineLayoutInfo.setLayoutCount = 0;
|
||||
pipelineLayoutInfo.pushConstantRangeCount = 1;
|
||||
pipelineLayoutInfo.pPushConstantRanges = &pushConstantRange;
|
||||
|
||||
try {
|
||||
this->pipelineLayout =
|
||||
device.get()->createPipelineLayoutUnique(pipelineLayoutInfo);
|
||||
log::trace("created vk::PipelineLayout");
|
||||
} catch (const vk::SystemError& err) {
|
||||
log::fatal("failed to create vk::PipelineLayout");
|
||||
throw std::runtime_error("failed to create vk::PipelineLayout");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sophia
|
||||
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <sophia/math.hpp>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
#include "vulkan/device.hpp"
|
||||
#include "vulkan/pipelines/graphics_pipeline.hpp"
|
||||
#include "vulkan/shader.hpp"
|
||||
|
||||
namespace sophia {
|
||||
|
||||
class Material {
|
||||
public:
|
||||
struct PushConstants {
|
||||
vk::DeviceAddress data0;
|
||||
u64 padding;
|
||||
vec4 data1;
|
||||
vec4 data2;
|
||||
vec4 data3;
|
||||
};
|
||||
|
||||
Material(const Material&) = delete;
|
||||
Material& operator=(const Material&) = delete;
|
||||
|
||||
Material(Device& device, std::unique_ptr<Shader> vertexShader,
|
||||
std::unique_ptr<Shader> fragmentShader, vk::Format colorFormat,
|
||||
vk::Format depthFormat);
|
||||
~Material();
|
||||
|
||||
void bind(vk::CommandBuffer commandBuffer) const {
|
||||
pipeline->bind(commandBuffer);
|
||||
}
|
||||
vk::PipelineLayout getLayout() const { return pipelineLayout.get(); }
|
||||
|
||||
private:
|
||||
void createPipelineLayout(Device& device);
|
||||
|
||||
vk::UniquePipelineLayout pipelineLayout;
|
||||
std::unique_ptr<GraphicsPipeline> pipeline;
|
||||
};
|
||||
|
||||
struct MaterialInstance {
|
||||
Material* material;
|
||||
};
|
||||
|
||||
// !NOTE: eventually add ecs support for ecs
|
||||
// struct MaterialComponent {
|
||||
// MaterialInstanceHandle handle;
|
||||
// };
|
||||
|
||||
} // namespace sophia
|
||||
@@ -0,0 +1,3 @@
|
||||
#include "renderer.hpp"
|
||||
|
||||
namespace sophia {} // namespace sophia
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <sophia/math.hpp>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
#include "material.hpp"
|
||||
|
||||
namespace sophia {
|
||||
|
||||
struct RenderObject {
|
||||
uint32_t indexCount;
|
||||
uint32_t firstIndex;
|
||||
vk::Buffer indexBuffer;
|
||||
|
||||
MaterialInstance* material;
|
||||
|
||||
mat4 transform;
|
||||
VkDeviceAddress vertexBufferAddress;
|
||||
};
|
||||
|
||||
class Renderer {
|
||||
public:
|
||||
private:
|
||||
};
|
||||
|
||||
} // namespace sophia
|
||||
@@ -0,0 +1,13 @@
|
||||
#version 450
|
||||
|
||||
//shader input
|
||||
layout (location = 0) in vec3 inColor;
|
||||
|
||||
//output write
|
||||
layout (location = 0) out vec4 outFragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
//return red
|
||||
outFragColor = vec4(inColor,1.0f);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#version 450
|
||||
#extension GL_EXT_buffer_reference : require
|
||||
|
||||
struct TriangleVertex {
|
||||
vec4 vertex;
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
layout(buffer_reference, std430) readonly buffer TriangleVertexBuffer {
|
||||
TriangleVertex vertices[];
|
||||
};
|
||||
|
||||
layout( push_constant ) uniform constants {
|
||||
TriangleVertexBuffer triangleBuffer;
|
||||
vec2 padding;
|
||||
vec4 data1;
|
||||
vec4 data2;
|
||||
vec4 data3;
|
||||
} PushConstants;
|
||||
|
||||
layout (location = 0) out vec3 outColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
//const array of positions for the triangle
|
||||
const vec3 positions[3] = vec3[3](
|
||||
vec3(-1.f,1.f, 0.0f),
|
||||
vec3(1.f,1.f, 0.0f),
|
||||
vec3(0.f,-1.f, 0.0f)
|
||||
);
|
||||
|
||||
//const array of colors for the triangle
|
||||
const vec3 colors[3] = vec3[3](
|
||||
vec3(1.0f, 0.0f, 0.0f), //red
|
||||
vec3(0.0f, 1.0f, 0.0f), //green
|
||||
vec3(00.f, 0.0f, 1.0f) //blue
|
||||
);
|
||||
|
||||
// Load vertex data from device address
|
||||
TriangleVertex v = PushConstants.triangleBuffer.vertices[gl_VertexIndex];
|
||||
|
||||
// output the position of each vertex
|
||||
gl_Position = vec4(v.vertex.xyz, 1.0);
|
||||
outColor = vec3(v.color.xyz);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#version 460
|
||||
|
||||
//size of a workgroup for compute
|
||||
layout (local_size_x = 16, local_size_y = 16) in;
|
||||
|
||||
//descriptor bindings for the pipeline
|
||||
layout(rgba16f,set = 0, binding = 0) uniform image2D image;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 texelCoord = ivec2(gl_GlobalInvocationID.xy);
|
||||
ivec2 size = imageSize(image);
|
||||
|
||||
if(texelCoord.x < size.x && texelCoord.y < size.y)
|
||||
{
|
||||
vec4 color = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
if(gl_LocalInvocationID.x != 0 && gl_LocalInvocationID.y != 0)
|
||||
{
|
||||
color.x = float(texelCoord.x)/(size.x);
|
||||
color.y = float(texelCoord.y)/(size.y);
|
||||
}
|
||||
|
||||
imageStore(image, texelCoord, color);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user