コード例 #1
0
ファイル: gx2_cbpool.cpp プロジェクト: CarlKenner/decaf-emu
uint32_t
endUserCommandBuffer(uint32_t *buffer)
{
   auto core = coreinit::OSGetCoreId();
   auto &cb = sActiveBuffer[core];

   decaf_check(cb);

   decaf_check(cb->displayList);

   if (buffer != cb->buffer) {
      // HACK: FAST Racing Neo shows this behaviour, gx2.rpl seems to not really care about what pointer
      // you pass into GX2EndDisplayList, so it's possible this is perfectly valid behaviour and the error
      // an application one, and not one caused by us.
      gLog->warn("Display list passed to GX2EndDisplayList did not match one passed to GX2BeginDisplayList");
   }

   // Pad and get its size
   padCommandBuffer(cb);
   auto usedSize = cb->curSize;

   // Release the buffer object to the pool
   freeBufferObj(sActiveBuffer[core]);
   sActiveBuffer[core] = nullptr;

   // Allocate a new buffer!
   if (core == getMainCoreId()) {
      sActiveBuffer[core] = allocateCommandBuffer(0x100);
   }

   return usedSize;
}
コード例 #2
0
Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
{
	const VkCommandBufferAllocateInfo bufferAllocateParams =
	{
		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,		// VkStructureType			sType;
		DE_NULL,											// const void*				pNext;
		commandPool,										// VkCommandPool			commandPool;
		VK_COMMAND_BUFFER_LEVEL_PRIMARY,					// VkCommandBufferLevel		level;
		1u,													// deUint32					bufferCount;
	};
	return allocateCommandBuffer(vk, device, &bufferAllocateParams);
}
コード例 #3
0
ファイル: gx2_cbpool.cpp プロジェクト: Invertex/decaf-emu
void
initCommandBufferPool(virtual_ptr<uint32_t> base, uint32_t size, uint32_t itemSize)
{
   auto core = coreinit::OSGetCoreId();
   assert(gx2::internal::getMainCoreId() == core);

   gCommandBufferPool.base = base;
   gCommandBufferPool.size = size;
   gCommandBufferPool.itemSize = itemSize;
   gCommandBufferPool.items.resize(size / gCommandBufferPool.itemSize);
   gActiveBuffer[core] = allocateCommandBuffer();
}
コード例 #4
0
ファイル: gx2_cbpool.cpp プロジェクト: Invertex/decaf-emu
pm4::Buffer *
getCommandBuffer(uint32_t size)
{
   auto core = coreinit::OSGetCoreId();
   auto &active = gActiveBuffer[core];

   if (!active) {
      active = allocateCommandBuffer();
   } else if (active->curSize + size > active->maxSize) {
      active = flushCommandBuffer(active);
   }

   return active;
}
コード例 #5
0
ファイル: gx2_cbpool.cpp プロジェクト: CarlKenner/decaf-emu
void
initCommandBufferPool(uint32_t *base,
                      uint32_t size)
{
   auto core = coreinit::OSGetCoreId();
   decaf_check(gx2::internal::getMainCoreId() == core);

   sBufferPoolBase = base;
   sBufferPoolEnd = sBufferPoolBase + size;
   sBufferPoolHeadPtr = sBufferPoolBase;
   sBufferPoolTailPtr = nullptr;

   sActiveBuffer[core] = allocateCommandBuffer(0x100);
}
コード例 #6
0
ファイル: gx2_cbpool.cpp プロジェクト: Invertex/decaf-emu
pm4::Buffer *
flushCommandBuffer(pm4::Buffer *cb)
{
   auto core = coreinit::OSGetCoreId();

   if (!cb) {
      cb = gActiveBuffer[core];
   } else if (cb != gActiveBuffer[core]) {
      throw std::logic_error("Attempting to flush non-active buffer");
   }

   if (!cb) {
      return nullptr;
   }

   if (cb->userBuffer) {
      void *newList = nullptr;
      uint32_t newSize = 0;

      // End the active display list
      GX2EndDisplayList(cb->buffer);

      // Ask user to allocate new display list
      std::tie(newList, newSize) = displayListOverrun(cb->buffer, cb->curSize * 4);

      if (!newList || !newSize) {
         throw std::logic_error("Unable to handle display list overrun");
      }

      // Begin new display list, it will update gActiveBuffer
      GX2BeginDisplayList(newList, newSize);
   } else {
      // Send buffer to our driver!
      gpu::queueCommandBuffer(cb);

      // Allocate new buffer
      gActiveBuffer[core] = allocateCommandBuffer();
   }

   return gActiveBuffer[core];
}
コード例 #7
0
ファイル: gx2_cbpool.cpp プロジェクト: CarlKenner/decaf-emu
pm4::Buffer *
flushCommandBuffer(uint32_t neededSize)
{
   auto core = coreinit::OSGetCoreId();
   auto cb = sActiveBuffer[core];

   decaf_check(cb);

   if (cb->displayList) {
      void *newList = nullptr;
      uint32_t newSize = 0;

      // End the active display list
      padCommandBuffer(cb);

      // Ask user to allocate new display list
      std::tie(newList, newSize) = displayListOverrun(cb->buffer, cb->curSize * 4, neededSize * 4);

      if (!newList || !newSize) {
         decaf_abort("Unable to handle display list overrun");
      }

      // Record the new information returned from the application
      cb->buffer = reinterpret_cast<uint32_t *>(newList);
      cb->curSize = 0;
      cb->maxSize = newSize / 4;

      return cb;
   }

   // Flush the existing buffer
   flushActiveCommandBuffer();

   // Allocate new buffer
   sActiveBuffer[core] = allocateCommandBuffer(neededSize);

   return sActiveBuffer[core];
}
コード例 #8
0
            bool VKRenderPass::VBuildCommandList() 
            {
                if (!allocateCommandBuffer())
                    return false;

                if (m_instanceBlock.buffer != VK_NULL_HANDLE)
                    DeleteUniformBuffer(m_device, m_instanceBlock);

                //Create block of data for instance variables
                if (m_instanceDataSize > 0)
                {
                    if (!CreateUniformBuffer(m_device, m_instanceDataSize, m_instanceData, &m_instanceBlock))
                        return false;
                }

                //Setup the order of the commands we will issue in the command list
                BuildRenderRequestHeirarchy();

                VkResult err;

                VKRenderer* renderer = VKRenderer::RendererInstance;

                VkCommandBufferInheritanceInfo inheritanceInfo = {};
                inheritanceInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
                inheritanceInfo.pNext = nullptr;
                inheritanceInfo.renderPass = VK_NULL_HANDLE;
                inheritanceInfo.subpass = 0;
                inheritanceInfo.framebuffer = VK_NULL_HANDLE;
                inheritanceInfo.occlusionQueryEnable = VK_FALSE;
                inheritanceInfo.queryFlags = 0;
                inheritanceInfo.pipelineStatistics = 0;

                VkCommandBufferBeginInfo beginInfo = {};
                beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
                beginInfo.pNext = nullptr;
                beginInfo.flags = 0;
                beginInfo.pInheritanceInfo = &inheritanceInfo;

                //Get the current clear color from the renderer
                VkClearValue clearColor = renderer->GetClearColor();

                std::vector<VkClearValue> clearValues;
                for (size_t i = 0; i < m_outputRenderTargets.size(); i++)
                {
                    VKRenderTargetHandle vkTarget= m_outputRenderTargets[i].DynamicCastHandle<VKRenderTarget>();

                    const VkClearValue* targetClearColor = vkTarget->GetClearColor();
                    //If a clear color is provided by the render target, lets use that
                    if (targetClearColor == nullptr)
                        clearValues.push_back(clearColor);
                    else
                        clearValues.push_back(*targetClearColor);
                }
                clearValues.push_back({1.0f, 0.0f});

                VkRenderPassBeginInfo renderPassBeginInfo = {};
                renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
                renderPassBeginInfo.pNext = nullptr;
                renderPassBeginInfo.renderPass = m_renderPass;
                renderPassBeginInfo.framebuffer = m_framebuffer;
                renderPassBeginInfo.renderArea.offset.x = 0;
                renderPassBeginInfo.renderArea.offset.y = 0;
                renderPassBeginInfo.renderArea.extent.width = m_width;
                renderPassBeginInfo.renderArea.extent.height = m_height;
                renderPassBeginInfo.clearValueCount = static_cast<uint32_t>(clearValues.size());
                renderPassBeginInfo.pClearValues = clearValues.data();

                VkViewport viewport = {};
                viewport.width = static_cast<float>(m_width);
                viewport.height = static_cast<float>(m_height);
                viewport.minDepth = 0.0f;
                viewport.maxDepth = 1.0f;

                VkRect2D scissor = {};
                scissor.extent.width = m_width;
                scissor.extent.height = m_height;
                scissor.offset.x = 0;
                scissor.offset.y = 0;
                
                err = vkBeginCommandBuffer(m_commandBuffer, &beginInfo);
                assert(!err);
                if (err != VK_SUCCESS)
                {
                    HT_DEBUG_PRINTF("VKRenderPass::VBuildCommandList(): Failed to build command buffer.\n");
                    return false;
                }

                /*
                    BEGIN BUFFER COMMANDS
                */

                vkCmdBeginRenderPass(m_commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);

                vkCmdSetViewport(m_commandBuffer, 0, 1, &viewport);
                vkCmdSetScissor(m_commandBuffer, 0, 1, &scissor);

                std::map<IPipelineHandle, std::vector<RenderableInstances>>::iterator iterator;

                for (iterator = m_pipelineList.begin(); iterator != m_pipelineList.end(); iterator++)
                {
                    VKPipelineHandle pipeline = iterator->first.DynamicCastHandle<VKPipeline>();

                    //Calculate inverse view proj
                    Math::Matrix4 invViewProj = Math::MMMatrixTranspose(Math::MMMatrixInverse(m_view));

                    m_view = Math::MMMatrixTranspose(m_view);
                    m_proj = Math::MMMatrixTranspose(m_proj);

                    pipeline->VSetMatrix4("pass.0proj", m_proj);
                    pipeline->VSetMatrix4("pass.1view", m_view);
                    pipeline->VSetMatrix4("pass.2invViewProj", invViewProj);
                    pipeline->VSetInt("pass.3width", m_width);
                    pipeline->VSetInt("pass.4height", m_height);
                    pipeline->VUpdate();

                    VkPipeline vkPipeline = pipeline->GetVKPipeline();
                    VkPipelineLayout vkPipelineLayout = renderer->GetVKRootLayoutHandle()->VKGetPipelineLayout();

                    vkCmdBindPipeline(m_commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vkPipeline);
                    pipeline->SendPushConstants(m_commandBuffer, vkPipelineLayout);

                    //Bind input textures
                    if(m_inputTargetDescriptorSets.size() > 0)
                        vkCmdBindDescriptorSets(m_commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vkPipelineLayout, m_firstInputTargetSetIndex,
                            static_cast<uint32_t>(m_inputTargetDescriptorSets.size()), m_inputTargetDescriptorSets.data(), 0, nullptr);

                    std::vector<RenderableInstances> renderables = iterator->second;

                    VkDeviceSize offsets[] = { 0 };

                    for (uint32_t i = 0; i < renderables.size(); i++)
                    {
                        Renderable renderable = renderables[i].renderable;
                        uint32_t count = renderables[i].count;

                        VKMaterialHandle material = renderable.material.DynamicCastHandle<VKMaterial>();
                        VKMeshHandle     mesh = renderable.mesh.DynamicCastHandle<VKMesh>();
                    
                        std::vector<VkDescriptorSet> descriptorSets = material->GetVKDescriptorSets();
                        
                        //Bind material descriptor sets
                        vkCmdBindDescriptorSets(m_commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
                            vkPipelineLayout, 0, static_cast<uint32_t>(descriptorSets.size()), descriptorSets.data(), 0, nullptr);
                    
                        //Bind instance buffer
                        if(m_instanceDataSize > 0)
                            vkCmdBindVertexBuffers(m_commandBuffer, 1, 1, &m_instanceBlock.buffer, offsets);

                        UniformBlock_vk vertBlock = mesh->GetVertexBlock();
                        UniformBlock_vk indexBlock = mesh->GetIndexBlock();
                        uint32_t indexCount = mesh->GetIndexCount();

                        vkCmdBindVertexBuffers(m_commandBuffer, 0, 1, &vertBlock.buffer, offsets);
                        vkCmdBindIndexBuffer(m_commandBuffer, indexBlock.buffer, 0, VK_INDEX_TYPE_UINT32);
                        
                        vkCmdDrawIndexed(m_commandBuffer, indexCount, count, 0, 0, 0);
                    }
                }

                vkCmdEndRenderPass(m_commandBuffer);

                /*
                    END BUFFER COMMANDS
                */

                //Blit to render targets
                for (size_t i = 0; i < m_outputRenderTargets.size(); i++)
                {
                    VKRenderTargetHandle renderTarget = m_outputRenderTargets[i].DynamicCastHandle<VKRenderTarget>();

                    if (!renderTarget->Blit(m_commandBuffer, m_colorImages[i]))
                        return false;
                }
                
                err = vkEndCommandBuffer(m_commandBuffer);
                assert(!err);
                if (err != VK_SUCCESS)
                {
                    HT_DEBUG_PRINTF("VKRenderPass::VBuildCommandList(): Failed to end command buffer.\n");
                    return false;
                }

                //Delete instance data
                delete[] m_instanceData;
                m_instanceData = nullptr;
                m_instanceDataSize = 0;

                return true;
            }