Commit 072dc0db by Alexis Hetu Committed by Alexis Hétu

Basic commands required to draw a simple triangle test

This cl adds the code needed to record and submit the minimal subset of commands required to run a simple triangle example. The commands themselves are still unimplemented. Bug b/116336664 Change-Id: Id0109980225a64a2bb3599a89a5495091926c635 Reviewed-on: https://swiftshader-review.googlesource.com/c/22168Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarCorentin Wallez <cwallez@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent c0f92f23
...@@ -17,30 +17,169 @@ ...@@ -17,30 +17,169 @@
namespace vk namespace vk
{ {
class CommandBuffer::Command
{
public:
// FIXME (b/119421344): change the commandBuffer argument to a CommandBuffer state
virtual void play(CommandBuffer* commandBuffer) = 0;
virtual ~Command() {}
};
class BeginRenderPass : public CommandBuffer::Command
{
public:
BeginRenderPass(VkRenderPass pRenderPass, VkFramebuffer pFramebuffer, VkRect2D pRenderArea,
uint32_t pClearValueCount, const VkClearValue* pClearValues) :
renderPass(pRenderPass), framebuffer(pFramebuffer), renderArea(pRenderArea),
clearValueCount(pClearValueCount)
{
// FIXME (b/119409619): use an allocator here so we can control all memory allocations
clearValues = new VkClearValue[clearValueCount];
memcpy(clearValues, pClearValues, clearValueCount * sizeof(VkClearValue));
}
~BeginRenderPass() override
{
delete clearValues;
}
protected:
void play(CommandBuffer* commandBuffer)
{
UNIMPLEMENTED();
}
private:
VkRenderPass renderPass;
VkFramebuffer framebuffer;
VkRect2D renderArea;
uint32_t clearValueCount;
VkClearValue* clearValues;
};
class EndRenderPass : public CommandBuffer::Command
{
public:
EndRenderPass()
{
}
protected:
void play(CommandBuffer* commandBuffer)
{
UNIMPLEMENTED();
}
private:
};
class PipelineBind : public CommandBuffer::Command
{
public:
PipelineBind(VkPipelineBindPoint pPipelineBindPoint, VkPipeline pPipeline) :
pipelineBindPoint(pPipelineBindPoint), pipeline(pPipeline)
{
}
protected:
void play(CommandBuffer* commandBuffer)
{
UNIMPLEMENTED();
}
private:
VkPipelineBindPoint pipelineBindPoint;
VkPipeline pipeline;
};
struct VertexBufferBind : public CommandBuffer::Command
{
VertexBufferBind(uint32_t pBinding, const VkBuffer pBuffer, const VkDeviceSize pOffset) :
binding(pBinding), buffer(pBuffer), offset(pOffset)
{
}
void play(CommandBuffer* commandBuffer)
{
UNIMPLEMENTED();
}
uint32_t binding;
const VkBuffer buffer;
const VkDeviceSize offset;
};
struct Draw : public CommandBuffer::Command
{
Draw(uint32_t pVertexCount) : vertexCount(pVertexCount)
{
}
void play(CommandBuffer* commandBuffer)
{
UNIMPLEMENTED();
}
uint32_t vertexCount;
};
struct ImageToBufferCopy : public CommandBuffer::Command
{
ImageToBufferCopy(VkImage pSrcImage, VkBuffer pDstBuffer, const VkBufferImageCopy& pRegion) :
srcImage(pSrcImage), dstBuffer(pDstBuffer), region(pRegion)
{
}
void play(CommandBuffer* commandBuffer)
{
UNIMPLEMENTED();
}
private:
VkImage srcImage;
VkBuffer dstBuffer;
const VkBufferImageCopy region;
};
CommandBuffer::CommandBuffer(VkCommandBufferLevel pLevel) : level(pLevel) CommandBuffer::CommandBuffer(VkCommandBufferLevel pLevel) : level(pLevel)
{ {
// FIXME (b/119409619): replace this vector by an allocator so we can control all memory allocations
commands = new std::vector<std::unique_ptr<Command> >();
pipelines[VK_PIPELINE_BIND_POINT_GRAPHICS] = VK_NULL_HANDLE; pipelines[VK_PIPELINE_BIND_POINT_GRAPHICS] = VK_NULL_HANDLE;
pipelines[VK_PIPELINE_BIND_POINT_COMPUTE] = VK_NULL_HANDLE; pipelines[VK_PIPELINE_BIND_POINT_COMPUTE] = VK_NULL_HANDLE;
} }
void CommandBuffer::destroy(const VkAllocationCallbacks* pAllocator) void CommandBuffer::destroy(const VkAllocationCallbacks* pAllocator)
{ {
deleteCommands();
}
void CommandBuffer::deleteCommands()
{
// FIXME (b/119409619): replace this vector by an allocator so we can control all memory allocations
delete commands;
} }
VkResult CommandBuffer::begin(VkCommandBufferUsageFlags flags, const VkCommandBufferInheritanceInfo* pInheritanceInfo) VkResult CommandBuffer::begin(VkCommandBufferUsageFlags flags, const VkCommandBufferInheritanceInfo* pInheritanceInfo)
{ {
ASSERT((state != RECORDING) && (state != PENDING));
if((flags != VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT) || pInheritanceInfo)
{
UNIMPLEMENTED();
}
state = RECORDING; state = RECORDING;
UNIMPLEMENTED();
return VK_SUCCESS; return VK_SUCCESS;
} }
VkResult CommandBuffer::end() VkResult CommandBuffer::end()
{ {
state = EXECUTABLE; ASSERT(state == RECORDING);
UNIMPLEMENTED(); state = EXECUTABLE;
return VK_SUCCESS; return VK_SUCCESS;
} }
...@@ -49,18 +188,24 @@ VkResult CommandBuffer::reset(VkCommandPoolResetFlags flags) ...@@ -49,18 +188,24 @@ VkResult CommandBuffer::reset(VkCommandPoolResetFlags flags)
{ {
ASSERT(state != PENDING); ASSERT(state != PENDING);
UNIMPLEMENTED(); deleteCommands();
// FIXME: put command buffer back to the initial state
state = INITIAL; state = INITIAL;
return VK_SUCCESS; return VK_SUCCESS;
} }
void CommandBuffer::beginRenderPass(VkRenderPass renderPass, VkFramebuffer framebuffer, VkRect2D renderArea, void CommandBuffer::beginRenderPass(VkRenderPass renderPass, VkFramebuffer framebuffer, VkRect2D renderArea,
uint32_t clearValueCount, const VkClearValue* pClearValues, VkSubpassContents contents) uint32_t clearValueCount, const VkClearValue* clearValues, VkSubpassContents contents)
{ {
UNIMPLEMENTED(); ASSERT(state == RECORDING);
if(contents != VK_SUBPASS_CONTENTS_INLINE)
{
UNIMPLEMENTED();
}
commands->push_back(std::make_unique<BeginRenderPass>(renderPass, framebuffer, renderArea, clearValueCount, clearValues));
} }
void CommandBuffer::nextSubpass(VkSubpassContents contents) void CommandBuffer::nextSubpass(VkSubpassContents contents)
...@@ -70,7 +215,7 @@ void CommandBuffer::nextSubpass(VkSubpassContents contents) ...@@ -70,7 +215,7 @@ void CommandBuffer::nextSubpass(VkSubpassContents contents)
void CommandBuffer::endRenderPass() void CommandBuffer::endRenderPass()
{ {
UNIMPLEMENTED(); commands->push_back(std::make_unique<EndRenderPass>());
} }
void CommandBuffer::executeCommands(uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers) void CommandBuffer::executeCommands(uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers)
...@@ -100,7 +245,12 @@ void CommandBuffer::pipelineBarrier(VkPipelineStageFlags srcStageMask, VkPipelin ...@@ -100,7 +245,12 @@ void CommandBuffer::pipelineBarrier(VkPipelineStageFlags srcStageMask, VkPipelin
void CommandBuffer::bindPipeline(VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline) void CommandBuffer::bindPipeline(VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline)
{ {
pipelines[pipelineBindPoint] = pipeline; if(pipelineBindPoint != VK_PIPELINE_BIND_POINT_GRAPHICS)
{
UNIMPLEMENTED();
}
commands->push_back(std::make_unique<PipelineBind>(pipelineBindPoint, pipeline));
} }
void CommandBuffer::bindVertexBuffers(uint32_t firstBinding, uint32_t bindingCount, void CommandBuffer::bindVertexBuffers(uint32_t firstBinding, uint32_t bindingCount,
...@@ -108,8 +258,7 @@ void CommandBuffer::bindVertexBuffers(uint32_t firstBinding, uint32_t bindingCou ...@@ -108,8 +258,7 @@ void CommandBuffer::bindVertexBuffers(uint32_t firstBinding, uint32_t bindingCou
{ {
for(uint32_t i = firstBinding; i < (firstBinding + bindingCount); ++i) for(uint32_t i = firstBinding; i < (firstBinding + bindingCount); ++i)
{ {
vertexInputBindings[i].buffer = pBuffers[i]; commands->push_back(std::make_unique<VertexBufferBind>(i, pBuffers[i], pOffsets[i]));
vertexInputBindings[i].offset = pOffsets[i];
} }
} }
...@@ -276,7 +425,12 @@ void CommandBuffer::copyBufferToImage(VkBuffer srcBuffer, VkImage dstImage, VkIm ...@@ -276,7 +425,12 @@ void CommandBuffer::copyBufferToImage(VkBuffer srcBuffer, VkImage dstImage, VkIm
void CommandBuffer::copyImageToBuffer(VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, void CommandBuffer::copyImageToBuffer(VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer,
uint32_t regionCount, const VkBufferImageCopy* pRegions) uint32_t regionCount, const VkBufferImageCopy* pRegions)
{ {
UNIMPLEMENTED(); ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
for(uint32_t i = 0; i < regionCount; i++)
{
commands->push_back(std::make_unique<ImageToBufferCopy>(srcImage, dstBuffer, pRegions[i]));
}
} }
void CommandBuffer::updateBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData) void CommandBuffer::updateBuffer(VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData)
...@@ -333,7 +487,12 @@ void CommandBuffer::waitEvents(uint32_t eventCount, const VkEvent* pEvents, VkPi ...@@ -333,7 +487,12 @@ void CommandBuffer::waitEvents(uint32_t eventCount, const VkEvent* pEvents, VkPi
void CommandBuffer::draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) void CommandBuffer::draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
{ {
UNIMPLEMENTED(); if(instanceCount > 1 || firstVertex != 0 || firstInstance != 0)
{
UNIMPLEMENTED();
}
commands->push_back(std::make_unique<Draw>(vertexCount));
} }
void CommandBuffer::drawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) void CommandBuffer::drawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)
...@@ -356,7 +515,10 @@ void CommandBuffer::submit() ...@@ -356,7 +515,10 @@ void CommandBuffer::submit()
// Perform recorded work // Perform recorded work
state = PENDING; state = PENDING;
UNIMPLEMENTED(); for(auto& command : *commands)
{
command->play(this);
}
// After work is completed // After work is completed
state = EXECUTABLE; state = EXECUTABLE;
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include "VkConfig.h" #include "VkConfig.h"
#include "VkObject.hpp" #include "VkObject.hpp"
#include <memory>
#include <vector>
namespace vk namespace vk
{ {
...@@ -109,7 +111,10 @@ public: ...@@ -109,7 +111,10 @@ public:
void submit(); void submit();
class Command;
private: private:
void deleteCommands();
enum State { INITIAL, RECORDING, EXECUTABLE, PENDING, INVALID }; enum State { INITIAL, RECORDING, EXECUTABLE, PENDING, INVALID };
State state = INITIAL; State state = INITIAL;
VkCommandBufferLevel level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; VkCommandBufferLevel level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
...@@ -121,6 +126,9 @@ private: ...@@ -121,6 +126,9 @@ private:
VkDeviceSize offset; VkDeviceSize offset;
}; };
VertexInputBindings vertexInputBindings[MAX_VERTEX_INPUT_BINDINGS]; VertexInputBindings vertexInputBindings[MAX_VERTEX_INPUT_BINDINGS];
// FIXME (b/119409619): replace this vector by an allocator so we can control all memory allocations
std::vector<std::unique_ptr<Command>>* commands;
}; };
using DispatchableCommandBuffer = DispatchableObject<CommandBuffer, VkCommandBuffer>; using DispatchableCommandBuffer = DispatchableObject<CommandBuffer, VkCommandBuffer>;
......
...@@ -12,7 +12,9 @@ ...@@ -12,7 +12,9 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "VkCommandBuffer.hpp"
#include "VkQueue.hpp" #include "VkQueue.hpp"
#include "VkSemaphore.hpp"
namespace vk namespace vk
{ {
...@@ -21,4 +23,31 @@ Queue::Queue(uint32_t pFamilyIndex, float pPriority) : familyIndex(pFamilyIndex) ...@@ -21,4 +23,31 @@ Queue::Queue(uint32_t pFamilyIndex, float pPriority) : familyIndex(pFamilyIndex)
{ {
} }
void Queue::submit(uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence)
{
if(fence != VK_NULL_HANDLE)
{
UNIMPLEMENTED();
}
for(uint32_t i = 0; i < submitCount; i++)
{
auto& submitInfo = pSubmits[i];
for(uint32_t j = 0; j < submitInfo.waitSemaphoreCount; j++)
{
vk::Cast(submitInfo.pWaitSemaphores[j])->wait(submitInfo.pWaitDstStageMask[j]);
}
for(uint32_t j = 0; j < submitInfo.commandBufferCount; j++)
{
vk::Cast(submitInfo.pCommandBuffers[j])->submit();
}
for(uint32_t j = 0; j < submitInfo.signalSemaphoreCount; j++)
{
vk::Cast(submitInfo.pSignalSemaphores[j])->signal();
}
}
}
} // namespace vk } // namespace vk
\ No newline at end of file
...@@ -34,6 +34,8 @@ public: ...@@ -34,6 +34,8 @@ public:
return reinterpret_cast<VkQueue>(this); return reinterpret_cast<VkQueue>(this);
} }
void submit(uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence);
private: private:
uint32_t familyIndex = 0; uint32_t familyIndex = 0;
float priority = 0.0f; float priority = 0.0f;
......
...@@ -427,8 +427,11 @@ VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue(VkDevice device, uint32_t queueFamil ...@@ -427,8 +427,11 @@ VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue(VkDevice device, uint32_t queueFamil
VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence) VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence)
{ {
TRACE("()"); TRACE("(VkQueue queue = 0x%X, uint32_t submitCount = %d, const VkSubmitInfo* pSubmits = 0x%X, VkFence fence = 0x%X)",
UNIMPLEMENTED(); queue, submitCount, pSubmits, fence);
vk::Cast(queue)->submit(submitCount, pSubmits, fence);
return VK_SUCCESS; return VK_SUCCESS;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment