Skip to content

Commit 33c46bf

Browse files
committed
Add: 2D texture creation and mipmap generation
1 parent 344c303 commit 33c46bf

File tree

10 files changed

+915
-93
lines changed

10 files changed

+915
-93
lines changed

src/EOS.h

Lines changed: 100 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,80 @@ namespace EOS
281281
const char* DebugName = "";
282282
};
283283

284+
struct ComponentMapping final
285+
{
286+
Swizzle R = Swizzle::Identity;
287+
Swizzle G = Swizzle::Identity;
288+
Swizzle B = Swizzle::Identity;
289+
Swizzle A = Swizzle::Identity;
290+
291+
bool Identity() const
292+
{
293+
return R == Swizzle::Identity && G == Swizzle::Identity && B == Swizzle::Identity && A == Swizzle::Identity;
294+
}
295+
};
296+
297+
struct Dimensions final
298+
{
299+
uint32_t Width = 1;
300+
uint32_t Height = 1;
301+
uint32_t Depth = 1;
302+
303+
inline Dimensions divide1D(uint32_t v) const
304+
{
305+
return {.Width = Width / v, .Height = Height, .Depth = Depth};
306+
}
307+
308+
inline Dimensions divide2D(uint32_t v) const
309+
{
310+
return {.Width = Width / v, .Height = Height / v, .Depth = Depth};
311+
}
312+
313+
inline Dimensions divide3D(uint32_t v) const
314+
{
315+
return {.Width = Width / v, .Height = Height / v, .Depth = Depth / v};
316+
}
317+
318+
inline bool operator==(const Dimensions& other) const
319+
{
320+
return Width == other.Width && Height == other.Height && Depth == other.Depth;
321+
}
322+
};
323+
324+
struct TextureDescription final
325+
{
326+
EOS::ImageType Type = EOS::ImageType::Image_2D;
327+
Format TextureFormat = Format::Invalid;
328+
Dimensions TextureDimensions = {1, 1, 1};
329+
uint32_t NumberOfLayers = 1;
330+
uint32_t NumberOfMipLevels = 1;
331+
uint32_t NumberOfSamples = 1;
332+
uint8_t Usage = TextureUsageFlags::Sampled;
333+
StorageType Storage = StorageType::Device;
334+
ComponentMapping Swizzle{};
335+
const void* Data = nullptr;
336+
uint32_t DataNumberOfMipLevels = 1; // how many mip-levels we want to upload
337+
bool GenerateMipmaps = false; // generate mip-levels immediately, valid only with non-null data
338+
const char* DebugName = "";
339+
};
340+
341+
struct Offset3D final
342+
{
343+
int32_t X = 0;
344+
int32_t Y = 0;
345+
int32_t Z = 0;
346+
};
347+
348+
struct TextureRangeDescription final
349+
{
350+
Offset3D Offset = {};
351+
Dimensions Dimension = {1, 1, 1};
352+
uint32_t Layer = 0;
353+
uint32_t NumberOfLayers = 1;
354+
uint32_t MipLevel = 0;
355+
uint32_t NumberOfMipLevels = 1;
356+
};
357+
284358
#pragma region INTERFACES
285359
//TODO: instead of interfaces use concept and a forward declare. And then every API implements 1 class of that name with the concept.
286360
//CMake should handle that only 1 type of API is being used at the time.
@@ -350,6 +424,8 @@ namespace EOS
350424
*/
351425
virtual EOS::Holder<BufferHandle> CreateBuffer(const BufferDescription& description) = 0;
352426

427+
virtual EOS::Holder<TextureHandle> CreateTexture(const TextureDescription& description) = 0;
428+
353429
/**
354430
* @brief Handles the destruction of a TextureHandle and what it holds.
355431
* @param handle The handle to the texture you want to destroy.
@@ -370,20 +446,28 @@ namespace EOS
370446
virtual void Destroy(RenderPipelineHandle handle) = 0;
371447

372448
/**
373-
* @brief Handles the destruction of a BufferHandle and what it holds.
374-
* @param handle The handle to the Buffer you want to destroy.
375-
*/
449+
* @brief Handles the destruction of a BufferHandle and what it holds.
450+
* @param handle The handle to the Buffer you want to destroy.
451+
*/
376452
virtual void Destroy(BufferHandle handle) = 0;
377453

378454
/**
379-
* @brief
380-
* @param handle The handle of the buffer we want to upload to.
381-
* @param data The data we want to upload.
382-
* @param size The size of the data we want to upload.
383-
* @param offset The offset it needs to have inside of the buffer.
384-
*/
455+
* @brief Handles the uploading of buffers to the GPU
456+
* @param handle The handle of the buffer we want to upload to.
457+
* @param data The data we want to upload.
458+
* @param size The size of the data we want to upload.
459+
* @param offset The offset it needs to have inside of the buffer.
460+
*/
385461
virtual void Upload(EOS::BufferHandle handle, const void* data, size_t size, size_t offset) = 0;
386462

463+
/**
464+
* @brief Handles the uploading of textures to the GPU
465+
* @param handle The handle of the texture we want to upload
466+
* @param range The description of how many mips, layers ... we want to upload.
467+
* @param data The actual data of the texture we want to upload.
468+
*/
469+
virtual void Upload(EOS::TextureHandle handle, const TextureRangeDescription& range, const void* data) = 0;
470+
387471
protected:
388472
IContext() = default;
389473
};
@@ -592,6 +676,13 @@ void cmdPushConstants(const EOS::ICommandBuffer& commandBuffer, const Struct& da
592676
cmdPushConstants(commandBuffer, &data, sizeof(Struct), offset);
593677
}
594678

679+
/**
680+
* @brief
681+
* @param commandBuffer
682+
* @param depthState
683+
*/
684+
void cmdSetDepthState(const EOS::ICommandBuffer& commandBuffer, const EOS::DepthState& depthState);
685+
595686
/**
596687
* @brief Adds a debug marker that is visible in debug software.
597688
* @param commandBuffer The commandbuffer we want to record into.

src/enums.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ namespace EOS
174174
ClockWise
175175
};
176176

177-
enum class Format : uint8_t
177+
enum Format : uint8_t
178178
{
179179
Invalid = 0,
180180

@@ -320,7 +320,7 @@ namespace EOS
320320
Index = 0x01,
321321
Vertex = 0x02,
322322
Uniform = 0x04,
323-
Storage = 0x08,
323+
StorageFlag = 0x08,
324324
Indirect = 0x10,
325325
ShaderBindingTable = 0x20,
326326
AccelStructBuildInputReadOnly = 0x40,
@@ -333,4 +333,22 @@ namespace EOS
333333
UI16,
334334
UI32,
335335
};
336+
337+
enum TextureUsageFlags : uint8_t
338+
{
339+
Sampled = 0x00,
340+
Storage = 0x01,
341+
Attachment = 0x2,
342+
};
343+
344+
enum Swizzle : uint8_t
345+
{
346+
Identity = 0,
347+
Zero,
348+
One,
349+
R,
350+
G,
351+
B,
352+
A,
353+
};
336354
}

src/logger.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include <spdlog/sinks/basic_file_sink.h>
66
#include <spdlog/sinks/callback_sink.h>
77
#include <spdlog/fmt/bundled/ranges.h>
8-
8+
#include <assert.h>
99
#include "defines.h"
1010
#include "spdlog/sinks/rotating_file_sink.h"
1111

src/main.cpp

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,19 @@ int main()
6464
EOS::Holder<EOS::ShaderModuleHandle> shaderHandleVert = EOS::LoadShader(context, shaderCompiler, "triangleVert");
6565
EOS::Holder<EOS::ShaderModuleHandle> shaderHandleFrag = EOS::LoadShader(context, shaderCompiler, "triangleFrag");
6666

67-
6867
constexpr EOS::VertexInputData vdesc
6968
{
7069
.Attributes = { { .Location = 0, .Format = EOS::VertexFormat::Float3, .Offset = 0 } },
7170
.InputBindings = { { .Stride = sizeof(glm::vec3) } },
7271
};
7372

73+
EOS::Holder<EOS::TextureHandle> depthTexture = context->CreateTexture({
74+
.Type = EOS::ImageType::Image_2D,
75+
.TextureFormat = EOS::Format::Z_F32,
76+
.TextureDimensions = {static_cast<uint32_t>(window->Width), static_cast<uint32_t>(window->Height)},
77+
.Usage = EOS::TextureUsageFlags::Attachment,
78+
.DebugName = "Depth Buffer",
79+
});
7480

7581
//It would be nice if these pipeline descriptions would be stored as JSON/XML into the material system
7682
EOS::RenderPipelineDescription renderPipelineDescription
@@ -79,19 +85,16 @@ int main()
7985
.VertexShader = shaderHandleVert,
8086
.FragmentShader = shaderHandleFrag,
8187
.ColorAttachments = {{ .ColorFormat = context->GetSwapchainFormat()}},
82-
88+
.DepthFormat = EOS::Format::Z_F32, //TODO depthTexture->Format
89+
.PipelineCullMode = EOS::CullMode::Back,
90+
.DebugName = "Basic Render Pipeline"
8391
};
84-
8592
EOS::Holder<EOS::RenderPipelineHandle> renderPipelineHandle = context->CreateRenderPipeline(renderPipelineDescription);
8693

8794
std::vector<glm::vec3> positions;
8895
std::vector<uint32_t> indices;
89-
90-
//TODO: Copy over data to bin
9196
LoadModel("../data/rubber_duck/scene.gltf", positions, indices);
9297

93-
94-
9598
EOS::Holder<EOS::BufferHandle> vertexBuffer = context->CreateBuffer(
9699
{
97100
.Usage = EOS::BufferUsageFlags::Vertex,
@@ -101,7 +104,6 @@ int main()
101104
.DebugName = "Buffer: vertex"
102105
});
103106

104-
105107
EOS::Holder<EOS::BufferHandle> indexBuffer = context->CreateBuffer(
106108
{
107109
.Usage = EOS::BufferUsageFlags::Index,
@@ -118,31 +120,54 @@ int main()
118120
{
119121
continue; // Or sleep
120122
}
121-
122123
const float aspectRatio = static_cast<float>(window->Width) / static_cast<float>(window->Height);
123124

124-
//TODO: There is no depth texture available in the vertex stage to handle Depth Comparrison
125+
//glm::mat4 model = glm::rotate(glm::mat4(1.0f), glm::radians( static_cast<float>(glfwGetTime() * 20.0f) ), glm::vec3(1, 0, 0));
126+
//constexpr glm::mat4 view = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, -0.5f, -1.5f));
127+
//const glm::mat4 projection = glm::perspective(glm::radians(65.0f), aspectRatio, 0.1f, 1000.0f);
128+
129+
using glm::mat4;
130+
using glm::vec3;
125131

126-
glm::mat4 model = glm::rotate(glm::mat4(1.0f), glm::radians( static_cast<float>(glfwGetTime() * 10.0f) ), glm::vec3(1, 0, 0));
127-
constexpr glm::mat4 view = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, -0.5f, -1.5f));
128-
const glm::mat4 projection = glm::perspective(glm::radians(65.0f), aspectRatio, 0.1f, 1000.0f);
129-
const glm::mat4 mvp = projection * view * model;
132+
const mat4 m = glm::rotate(mat4(1.0f), glm::radians(-90.0f), vec3(1, 0, 0));
133+
const mat4 v = glm::rotate(glm::translate(mat4(1.0f), vec3(0.0f, -0.5f, -1.5f)), (float)glfwGetTime(), vec3(0.0f, 1.0f, 0.0f));
134+
const mat4 p = glm::perspective(45.0f, aspectRatio, 0.1f, 1000.0f);
135+
const glm::mat4 mvp = p * v * m;
130136

131137
EOS::ICommandBuffer& cmdBuffer = context->AcquireCommandBuffer();
132138
cmdPipelineBarrier(cmdBuffer, {}, {{context->GetSwapChainTexture(), EOS::ResourceState::Undefined, EOS::ResourceState::Present}});
133139

134-
EOS::Framebuffer framebuffer = {.Color = {{.Texture = context->GetSwapChainTexture()}}};
135-
EOS::RenderPass renderPass{ .Color = { { .LoadOpState = EOS::LoadOp::Clear, .ClearColor = { 0.36f, 0.4f, 1.0f, 0.28f } } }};
140+
EOS::Framebuffer framebuffer
141+
{
142+
.Color = {{.Texture = context->GetSwapChainTexture()}},
143+
.DepthStencil = { .Texture = depthTexture },
144+
.DebugName = "Basic Color Depth Framebuffer"
145+
};
146+
147+
EOS::RenderPass renderPass
148+
{
149+
.Color { { .LoadOpState = EOS::LoadOp::Clear, .ClearColor = { 0.36f, 0.4f, 1.0f, 0.28f } } },
150+
.Depth{ .LoadOpState = EOS::LoadOp::Clear, .ClearDepth = 1.0f }
151+
};
152+
153+
EOS::DepthState depthState
154+
{
155+
.CompareOpState = EOS::CompareOp::Less,
156+
.IsDepthWriteEnabled = true,
157+
};
158+
136159
cmdBeginRendering(cmdBuffer, renderPass, framebuffer);
160+
{
137161
cmdPushMarker(cmdBuffer, "Render Duck", 0xff0000ff);
138-
cmdBindVertexBuffer(cmdBuffer, 0, vertexBuffer);
139-
cmdBindIndexBuffer(cmdBuffer, indexBuffer, EOS::IndexFormat::UI32);
140-
cmdBindRenderPipeline(cmdBuffer, renderPipelineHandle);
141-
cmdPushConstants(cmdBuffer, mvp);
142-
cmdDrawIndexed(cmdBuffer, indices.size());
162+
cmdBindVertexBuffer(cmdBuffer, 0, vertexBuffer);
163+
cmdBindIndexBuffer(cmdBuffer, indexBuffer, EOS::IndexFormat::UI32);
164+
cmdBindRenderPipeline(cmdBuffer, renderPipelineHandle);
165+
cmdPushConstants(cmdBuffer, mvp);
166+
cmdSetDepthState(cmdBuffer, depthState);
167+
cmdDrawIndexed(cmdBuffer, indices.size());
143168
cmdPopMarker(cmdBuffer);
169+
}
144170
cmdEndRendering(cmdBuffer);
145-
146171
context->Submit(cmdBuffer, context->GetSwapChainTexture());
147172
}
148173

src/shaders/triangleVert.slang

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ public struct PerFrameData
99
[shader("vertex")]
1010
void main( uint vertexID : SV_VertexID, float3 inPos : POSITION, out float4 outPosition : SV_Position, out float3 outColor : COLOR0)
1111
{
12-
outPosition = mul(perFrameData.MVP, float4(inPos, 1.0));
12+
outPosition = mul(float4(inPos, 1.0), perFrameData.MVP);
1313
outColor = inPos.xzy;
1414
}

0 commit comments

Comments
 (0)