Skip to content

Commit

Permalink
checkpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
lamarrr committed Oct 22, 2023
1 parent 9691273 commit 0b19e02
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 81 deletions.
123 changes: 42 additions & 81 deletions ashura/include/ashura/gfx.h
Original file line number Diff line number Diff line change
Expand Up @@ -615,15 +615,23 @@ enum class InputRate : u8
Instance = 1
};

enum class MemoryOps : u8
// write access -> wait on all previous reads, transient reads, and transient writes
// transient write access -> wait on all previous reads, writes, transient reads, and transient writes
// transient read access -> wait on all previous reads, writes, transient reads, and transient writes
// read-only access -> wait only all previous writes, transient reads, and transient writes
//
// buffers have no transient accesses
//
enum class MemoryAccess : u8
{
None = 0,
Read = 1,
Write = 2,
ReadWrite = Read | Write
None = 0,
Read = 1,
Write = 2,
TransientRead = 4,
TransientWrite = 8
};

STX_DEFINE_ENUM_BIT_OPS(MemoryOps)
STX_DEFINE_ENUM_BIT_OPS(MemoryAccess)

enum class Access : u64
{
Expand Down Expand Up @@ -659,33 +667,6 @@ enum class Access : u64

STX_DEFINE_ENUM_BIT_OPS(Access)

constexpr MemoryOps get_memory_ops(Access access)
{
MemoryOps ops = MemoryOps::None;

if ((access &
(Access::IndirectCommandRead | Access::IndexRead | Access::VertexAttributeRead |
Access::UniformRead | Access::InputAttachmentRead | Access::ShaderRead |
Access::ColorAttachmentRead | Access::DepthStencilAttachmentRead | Access::TransferRead |
Access::HostRead | Access::MemoryRead | Access::VideoDecodeRead | Access::VideoEncodeRead |
Access::AccelerationStructureRead | Access::FragmentDensityMapRead |
Access::ColorAttachmentReadNonCoherent | Access::DescriptorBufferRead |
Access::ShaderBindingTableRead)) != Access::None)
{
ops |= MemoryOps::Read;
}

if ((access &
(Access::ShaderWrite | Access::ColorAttachmentWrite | Access::DepthStencilAttachmentWrite |
Access::TransferWrite | Access::HostWrite | Access::MemoryWrite | Access::VideoDecodeWrite |
Access::VideoEncodeWrite | Access::AccelerationStructureWrite)) != Access::None)
{
ops |= MemoryOps::Write;
}

return ops;
}

enum class ShaderStages : u32
{
None = 0x00000000,
Expand Down Expand Up @@ -765,30 +746,6 @@ enum class DescriptorType : u8
InputAttachment = 10
};

enum class AccessSequence : u8
{
None = 0,
NoneAfterRead = 1,
NoneAfterWrite = 2,
ReadAfterWrite = 3
};

struct BufferAccess
{
PipelineStages stages = PipelineStages::None;
Access access = Access::None;
};

struct ImageAccess
{
PipelineStages stages = PipelineStages::None;
Access access = Access::None;
ImageLayout layout = ImageLayout::Undefined;
};

BufferAccess to_pipeline_access(BufferBindings bindings, PipelineStages stages);
ImageAccess to_pipeline_access(ImageBindings bindings, PipelineStages stages);

struct Viewport
{
Rect area;
Expand Down Expand Up @@ -891,9 +848,6 @@ struct RenderPassAttachment
StoreOp store_op = StoreOp::Store;
LoadOp stencil_load_op = LoadOp::Load; // how to use stencil components
StoreOp stencil_store_op = StoreOp::Store;

ImageAccess get_color_image_access() const;
ImageAccess get_depth_stencil_image_access() const;
};

struct RenderPassDesc
Expand Down Expand Up @@ -1209,25 +1163,34 @@ struct QueueImageMemoryBarrier
Access dst_access = Access::None;
};

// TODO(lamarrr): access coalescing, i.e. resource used multiple times within the same wave
// i.e. multiple accesses in descriptor bindings???? read and write
//
struct BufferState
struct BufferSyncScope
{
BufferAccess access[2] = {};
AccessSequence sequence = AccessSequence::None;
MemoryAccess access = MemoryAccess::None;
ImageLayout layout = ImageLayout::Undefined;
BufferBindings bindings = BufferBindings::None;

bool sync(BufferAccess request, QueueBufferMemoryBarrier &barrier);
void on_drain();
constexpr void reset()
{
access = MemoryAccess::None;
}

u8 sync(MemoryAccess memory_access, Access access, PipelineStages stages,
QueueBufferMemoryBarrier barrier[2]);
};

struct ImageState
struct ImageSyncScope
{
ImageAccess access[2] = {};
AccessSequence sequence = AccessSequence::None;
MemoryAccess access = MemoryAccess::None;
ImageLayout layout = ImageLayout::Undefined;
ImageBindings bindings = ImageBindings::None;

constexpr void reset()
{
access = MemoryAccess::None;
}

bool sync(ImageAccess request, QueueImageMemoryBarrier &barrier);
void on_drain();
bool sync(MemoryAccess memory_access, Access access, PipelineStages stages, ImageLayout layout,
QueueImageMemoryBarrier &barrier);
};

struct StencilFaceState
Expand All @@ -1250,10 +1213,9 @@ struct RenderState

struct BufferResource
{
BufferDesc desc;
BufferState state;
BufferBindings bindings = BufferBindings::None;
Buffer handle = nullptr;
BufferDesc desc;
BufferSyncScope sync_scope;
Buffer handle = nullptr;
};

struct BufferViewResource
Expand All @@ -1264,10 +1226,9 @@ struct BufferViewResource

struct ImageResource
{
ImageDesc desc;
ImageState state;
ImageBindings bindings = ImageBindings::None;
Image handle = nullptr;
ImageDesc desc;
ImageSyncScope sync_scope;
Image handle = nullptr;
};

struct ImageViewResource
Expand Down
74 changes: 74 additions & 0 deletions ashura/src/gfx.cc
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,80 @@ ImageAccess RenderPassAttachment::get_depth_stencil_image_access() const
.layout = layout};
}

u8 BufferSyncScope::sync(MemoryAccess memory_access, Access access, PipelineStages stages,
QueueBufferMemoryBarrier barriers[2])
{
// TODO(lamarrr): upon write, clear all??? and reset to write, that way there will be no read | write case, since only trigger is write
u8 num_barriers = 0;
if (this->access == MemoryAccess::Write)
{
// RAW
if ((memory_access & MemoryAccess::Read) != MemoryAccess::None)
{
barriers[num_barriers].src_access = Access::MemoryWrite;
barriers[num_barriers].src_stages = PipelineStages::BottomOfPipe;
barriers[num_barriers].dst_access = Access::MemoryRead;
barriers[num_barriers].dst_stages = stages;
barriers[num_barriers].offset = 0;
barriers[num_barriers].size = WHOLE_SIZE;
num_barriers++;
}

// WAW
if ((memory_access & MemoryAccess::Write) != MemoryAccess::None)
{
barriers[num_barriers].src_access = Access::MemoryWrite;
barriers[num_barriers].src_stages = PipelineStages::BottomOfPipe;
barriers[num_barriers].dst_access = Access::MemoryWrite;
barriers[num_barriers].dst_stages = stages;
barriers[num_barriers].offset = 0;
barriers[num_barriers].size = WHOLE_SIZE;
num_barriers++;
}

this->access |= memory_access;
return num_barriers;
}
else if (this->access == MemoryAccess::Read)
{
if ((memory_access & MemoryAccess::Write) != MemoryAccess::None)
{
// WAR
barriers[num_barriers].src_access = Access::MemoryRead;
barriers[num_barriers].src_stages = PipelineStages::BottomOfPipe;
barriers[num_barriers].dst_access = access;
if((memory_access & MemoryAccess::Read)!= MemoryAccess::None){
barriers[num_barriers].dst_stages = stages;
} else{
barriers[num_barriers].dst_stages = stages;
}
barriers[num_barriers].offset = 0;
barriers[num_barriers].size = WHOLE_SIZE;
this->access |= memory_access;
}
else
{
// RAR
this->access |= memory_access;
return false;
}
}
else if (this->access == (MemoryAccess::Read | MemoryAccess::Write))
{


}
else
{
return 0;
}
}

bool ImageSyncScope::sync(MemoryAccess memory_access, Access access, PipelineStages stages,
ImageLayout layout, QueueImageMemoryBarrier &barrier)
{
}

// TODO(lamarrr): index buffer can be used from a generated compute stage, will our graph handle
// this? we need to check for read/write compatibility
// TODO(lamarrr): on every device idle, we can reset resource states.
Expand Down

0 comments on commit 0b19e02

Please sign in to comment.