mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-09 00:14:56 +00:00
rpcsx-gpu2 -> rpcsx-gpu
This commit is contained in:
parent
b80a70f176
commit
d9415d8ae5
128 changed files with 6 additions and 6 deletions
615
rpcsx-gpu/Renderer.cpp
Normal file
615
rpcsx-gpu/Renderer.cpp
Normal file
|
|
@ -0,0 +1,615 @@
|
|||
#include "Renderer.hpp"
|
||||
#include "Device.hpp"
|
||||
#include "gnm/gnm.hpp"
|
||||
|
||||
#include <amdgpu/tiler.hpp>
|
||||
#include <gnm/constants.hpp>
|
||||
#include <gnm/vulkan.hpp>
|
||||
#include <print>
|
||||
#include <shader/Evaluator.hpp>
|
||||
#include <shader/dialect.hpp>
|
||||
#include <shader/gcn.hpp>
|
||||
#include <shaders/fill_red.frag.h>
|
||||
#include <shaders/rect_list.geom.h>
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace shader;
|
||||
|
||||
namespace gnm {
|
||||
VkRect2D toVkRect2D(amdgpu::PaScRect rect) {
|
||||
return {
|
||||
.offset =
|
||||
{
|
||||
.x = rect.left,
|
||||
.y = rect.top,
|
||||
},
|
||||
.extent =
|
||||
{
|
||||
.width = static_cast<uint32_t>(rect.right - rect.left),
|
||||
.height = static_cast<uint32_t>(rect.bottom - rect.top),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
amdgpu::PaScRect intersection(amdgpu::PaScRect lhs, amdgpu::PaScRect rhs) {
|
||||
if (!lhs.isValid()) {
|
||||
return rhs;
|
||||
}
|
||||
|
||||
if (!rhs.isValid()) {
|
||||
return lhs;
|
||||
}
|
||||
|
||||
amdgpu::PaScRect result{
|
||||
.left = std::max(lhs.left, rhs.left),
|
||||
.top = std::max(lhs.top, rhs.top),
|
||||
.right = std::min(lhs.right, rhs.right),
|
||||
.bottom = std::min(lhs.bottom, rhs.bottom),
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
} // namespace gnm
|
||||
|
||||
static VkShaderEXT getPrimTypeRectGeomShader(amdgpu::Cache &cache) {
|
||||
static VkShaderEXT shader = VK_NULL_HANDLE;
|
||||
if (shader != VK_NULL_HANDLE) {
|
||||
return shader;
|
||||
}
|
||||
|
||||
VkShaderCreateInfoEXT createInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT,
|
||||
.stage = VK_SHADER_STAGE_GEOMETRY_BIT,
|
||||
.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT,
|
||||
.codeSize = sizeof(spirv_rect_list_geom),
|
||||
.pCode = spirv_rect_list_geom,
|
||||
.pName = "main",
|
||||
.setLayoutCount =
|
||||
static_cast<uint32_t>(cache.getGraphicsDescriptorSetLayouts().size()),
|
||||
.pSetLayouts = cache.getGraphicsDescriptorSetLayouts().data()};
|
||||
|
||||
VK_VERIFY(vk::CreateShadersEXT(vk::context->device, 1, &createInfo,
|
||||
vk::context->allocator, &shader));
|
||||
return shader;
|
||||
}
|
||||
|
||||
static VkShaderEXT getFillRedFragShader(amdgpu::Cache &cache) {
|
||||
static VkShaderEXT shader = VK_NULL_HANDLE;
|
||||
if (shader != VK_NULL_HANDLE) {
|
||||
return shader;
|
||||
}
|
||||
|
||||
VkShaderCreateInfoEXT createInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT,
|
||||
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
.codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT,
|
||||
.codeSize = sizeof(spirv_fill_red_frag),
|
||||
.pCode = spirv_fill_red_frag,
|
||||
.pName = "main",
|
||||
.setLayoutCount =
|
||||
static_cast<uint32_t>(cache.getGraphicsDescriptorSetLayouts().size()),
|
||||
.pSetLayouts = cache.getGraphicsDescriptorSetLayouts().data()};
|
||||
|
||||
VK_VERIFY(vk::CreateShadersEXT(vk::context->device, 1, &createInfo,
|
||||
vk::context->allocator, &shader));
|
||||
return shader;
|
||||
}
|
||||
|
||||
static VkPrimitiveTopology toVkPrimitiveType(gnm::PrimitiveType type) {
|
||||
switch (type) {
|
||||
case gnm::PrimitiveType::PointList:
|
||||
return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
|
||||
case gnm::PrimitiveType::LineList:
|
||||
return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
|
||||
case gnm::PrimitiveType::LineStrip:
|
||||
return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
|
||||
case gnm::PrimitiveType::TriList:
|
||||
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
case gnm::PrimitiveType::TriFan:
|
||||
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
|
||||
case gnm::PrimitiveType::TriStrip:
|
||||
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
|
||||
case gnm::PrimitiveType::Patch:
|
||||
return VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
|
||||
case gnm::PrimitiveType::LineListAdjacency:
|
||||
return VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY;
|
||||
case gnm::PrimitiveType::LineStripAdjacency:
|
||||
return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY;
|
||||
case gnm::PrimitiveType::TriListAdjacency:
|
||||
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY;
|
||||
case gnm::PrimitiveType::TriStripAdjacency:
|
||||
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY;
|
||||
case gnm::PrimitiveType::LineLoop:
|
||||
return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP; // FIXME
|
||||
|
||||
case gnm::PrimitiveType::RectList:
|
||||
case gnm::PrimitiveType::QuadList:
|
||||
case gnm::PrimitiveType::QuadStrip:
|
||||
case gnm::PrimitiveType::Polygon:
|
||||
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
|
||||
default:
|
||||
rx::die("toVkPrimitiveType: unexpected primitive type %u",
|
||||
static_cast<unsigned>(type));
|
||||
}
|
||||
}
|
||||
|
||||
void amdgpu::draw(GraphicsPipe &pipe, int vmId, std::uint32_t firstVertex,
|
||||
std::uint32_t vertexCount, std::uint32_t firstInstance,
|
||||
std::uint32_t instanceCount, std::uint64_t indiciesAddress,
|
||||
std::uint32_t indexCount) {
|
||||
if (pipe.uConfig.vgtPrimitiveType == gnm::PrimitiveType::None) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pipe.context.cbColorControl.mode == gnm::CbMode::Disable) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pipe.context.cbColorControl.mode != gnm::CbMode::Normal) {
|
||||
std::println("unimplemented context.cbColorControl.mode = {}",
|
||||
static_cast<int>(pipe.context.cbColorControl.mode));
|
||||
return;
|
||||
}
|
||||
|
||||
if (pipe.context.cbTargetMask.raw == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto cacheTag = pipe.device->getGraphicsTag(vmId, pipe.scheduler);
|
||||
auto targetMask = pipe.context.cbTargetMask.raw;
|
||||
|
||||
VkRenderingAttachmentInfo colorAttachments[8]{};
|
||||
VkBool32 colorBlendEnable[8]{};
|
||||
VkColorBlendEquationEXT colorBlendEquation[8]{};
|
||||
VkColorComponentFlags colorWriteMask[8]{};
|
||||
VkViewport viewPorts[8]{};
|
||||
VkRect2D viewPortScissors[8]{};
|
||||
unsigned renderTargets = 0;
|
||||
|
||||
VkRenderingAttachmentInfo depthAttachment{
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
};
|
||||
VkRenderingAttachmentInfo stencilAttachment{
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
};
|
||||
|
||||
auto depthAccess = Access::None;
|
||||
auto stencilAccess = Access::None;
|
||||
|
||||
if (pipe.context.dbDepthControl.depthEnable) {
|
||||
if (!pipe.context.dbRenderControl.depthClearEnable) {
|
||||
depthAccess |= Access::Read;
|
||||
}
|
||||
if (!pipe.context.dbDepthView.zReadOnly &&
|
||||
pipe.context.dbDepthControl.depthWriteEnable) {
|
||||
depthAccess |= Access::Write;
|
||||
}
|
||||
}
|
||||
|
||||
if (pipe.context.dbDepthControl.stencilEnable) {
|
||||
if (!pipe.context.dbRenderControl.stencilClearEnable) {
|
||||
stencilAccess |= Access::Read;
|
||||
}
|
||||
if (!pipe.context.dbDepthView.stencilReadOnly) {
|
||||
stencilAccess |= Access::Write;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME
|
||||
stencilAccess = Access::None;
|
||||
|
||||
if (depthAccess != Access::None) {
|
||||
auto viewPortScissor = pipe.context.paScScreenScissor;
|
||||
auto viewPortRect = gnm::toVkRect2D(viewPortScissor);
|
||||
|
||||
auto imageView = cacheTag.getImageView(
|
||||
{
|
||||
.readAddress = static_cast<std::uint64_t>(pipe.context.dbZReadBase)
|
||||
<< 8,
|
||||
.writeAddress =
|
||||
static_cast<std::uint64_t>(pipe.context.dbZWriteBase) << 8,
|
||||
.type = gnm::TextureType::Dim2D,
|
||||
.dfmt = gnm::getDataFormat(pipe.context.dbZInfo.format),
|
||||
.nfmt = gnm::getNumericFormat(pipe.context.dbZInfo.format),
|
||||
.extent =
|
||||
{
|
||||
.width = viewPortRect.extent.width,
|
||||
.height = viewPortRect.extent.height,
|
||||
.depth = 1,
|
||||
},
|
||||
.pitch = viewPortRect.extent.width,
|
||||
.kind = ImageKind::Depth,
|
||||
},
|
||||
depthAccess);
|
||||
|
||||
depthAttachment = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
.imageView = imageView.handle,
|
||||
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||
};
|
||||
|
||||
if ((depthAccess & Access::Read) == Access::None) {
|
||||
depthAttachment.clearValue.depthStencil.depth = pipe.context.dbDepthClear;
|
||||
depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
}
|
||||
|
||||
if ((depthAccess & Access::Write) == Access::None) {
|
||||
depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &cbColor : pipe.context.cbColor) {
|
||||
if (targetMask == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (cbColor.info.dfmt == gnm::kDataFormatInvalid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto viewPortScissor = pipe.context.paScScreenScissor;
|
||||
viewPortScissor = gnm::intersection(
|
||||
viewPortScissor, pipe.context.paScVportScissor[renderTargets]);
|
||||
viewPortScissor =
|
||||
gnm::intersection(viewPortScissor, pipe.context.paScWindowScissor);
|
||||
viewPortScissor =
|
||||
gnm::intersection(viewPortScissor, pipe.context.paScGenericScissor);
|
||||
|
||||
auto viewPortRect = gnm::toVkRect2D(viewPortScissor);
|
||||
|
||||
viewPorts[renderTargets].x = viewPortRect.offset.x;
|
||||
viewPorts[renderTargets].y = viewPortRect.offset.y;
|
||||
viewPorts[renderTargets].width = viewPortRect.extent.width;
|
||||
viewPorts[renderTargets].height = viewPortRect.extent.height;
|
||||
viewPorts[renderTargets].minDepth =
|
||||
pipe.context.paScVportZ[renderTargets].min;
|
||||
viewPorts[renderTargets].maxDepth =
|
||||
pipe.context.paScVportZ[renderTargets].max;
|
||||
|
||||
auto vkViewPortScissor = gnm::toVkRect2D(viewPortScissor);
|
||||
viewPortScissors[renderTargets] = vkViewPortScissor;
|
||||
|
||||
ImageKey renderTargetInfo{};
|
||||
renderTargetInfo.type = gnm::TextureType::Dim2D;
|
||||
renderTargetInfo.pitch = vkViewPortScissor.extent.width;
|
||||
renderTargetInfo.readAddress = static_cast<std::uint64_t>(cbColor.base)
|
||||
<< 8;
|
||||
renderTargetInfo.writeAddress = renderTargetInfo.readAddress;
|
||||
renderTargetInfo.extent.width = vkViewPortScissor.extent.width;
|
||||
renderTargetInfo.extent.height = vkViewPortScissor.extent.height;
|
||||
renderTargetInfo.extent.depth = 1;
|
||||
renderTargetInfo.dfmt = cbColor.info.dfmt;
|
||||
renderTargetInfo.nfmt = gnm::toNumericFormat(cbColor.info.nfmt, cbColor.info.dfmt);
|
||||
renderTargetInfo.mipCount = 1;
|
||||
renderTargetInfo.arrayLayerCount = 1;
|
||||
|
||||
renderTargetInfo.tileMode =
|
||||
cbColor.info.linearGeneral
|
||||
? TileMode{.raw = 0}
|
||||
: getDefaultTileModes()[cbColor.attrib.tileModeIndex];
|
||||
|
||||
auto access = Access::None;
|
||||
|
||||
if (!cbColor.info.fastClear) {
|
||||
access |= Access::Read;
|
||||
}
|
||||
if (targetMask & 0xf) {
|
||||
access |= Access::Write;
|
||||
}
|
||||
|
||||
auto imageView = cacheTag.getImageView(renderTargetInfo, access);
|
||||
|
||||
colorAttachments[renderTargets] = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
.imageView = imageView.handle,
|
||||
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.loadOp = cbColor.info.fastClear ? VK_ATTACHMENT_LOAD_OP_CLEAR
|
||||
: VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||
|
||||
.clearValue =
|
||||
{
|
||||
.color =
|
||||
{
|
||||
.uint32 =
|
||||
{
|
||||
cbColor.clearWord0,
|
||||
cbColor.clearWord1,
|
||||
cbColor.clearWord2,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
auto &blendControl = pipe.context.cbBlendControl[renderTargets];
|
||||
|
||||
colorBlendEnable[renderTargets] = blendControl.enable;
|
||||
colorBlendEquation[renderTargets] = VkColorBlendEquationEXT{
|
||||
.srcColorBlendFactor = gnm::toVkBlendFactor(blendControl.colorSrcBlend),
|
||||
.dstColorBlendFactor = gnm::toVkBlendFactor(blendControl.colorDstBlend),
|
||||
.colorBlendOp = gnm::toVkBlendOp(blendControl.colorCombFcn),
|
||||
.srcAlphaBlendFactor =
|
||||
blendControl.separateAlphaBlend
|
||||
? gnm::toVkBlendFactor(blendControl.alphaSrcBlend)
|
||||
: gnm::toVkBlendFactor(blendControl.colorSrcBlend),
|
||||
.dstAlphaBlendFactor =
|
||||
blendControl.separateAlphaBlend
|
||||
? gnm::toVkBlendFactor(blendControl.alphaDstBlend)
|
||||
: gnm::toVkBlendFactor(blendControl.colorDstBlend),
|
||||
.alphaBlendOp = blendControl.separateAlphaBlend
|
||||
? gnm::toVkBlendOp(blendControl.alphaCombFcn)
|
||||
: gnm::toVkBlendOp(blendControl.colorCombFcn),
|
||||
};
|
||||
|
||||
colorWriteMask[renderTargets] =
|
||||
((targetMask & 1) ? VK_COLOR_COMPONENT_R_BIT : 0) |
|
||||
((targetMask & 2) ? VK_COLOR_COMPONENT_G_BIT : 0) |
|
||||
((targetMask & 4) ? VK_COLOR_COMPONENT_B_BIT : 0) |
|
||||
((targetMask & 8) ? VK_COLOR_COMPONENT_A_BIT : 0);
|
||||
|
||||
renderTargets++;
|
||||
targetMask >>= 4;
|
||||
}
|
||||
|
||||
if (renderTargets == 0) {
|
||||
return;
|
||||
}
|
||||
if (indiciesAddress == 0) {
|
||||
indexCount = vertexCount;
|
||||
}
|
||||
|
||||
auto indexBuffer = cacheTag.getIndexBuffer(indiciesAddress, indexCount,
|
||||
pipe.uConfig.vgtPrimitiveType,
|
||||
pipe.uConfig.vgtIndexType);
|
||||
|
||||
auto stages = Cache::kGraphicsStages;
|
||||
VkShaderEXT shaders[stages.size()]{};
|
||||
|
||||
auto pipelineLayout = cacheTag.getGraphicsPipelineLayout();
|
||||
auto descriptorSets = cacheTag.getDescriptorSets();
|
||||
Cache::Shader vertexShader;
|
||||
|
||||
if (pipe.context.vgtShaderStagesEn.vsEn == amdgpu::VsStage::VsReal) {
|
||||
gnm::PrimitiveType vsPrimType = {};
|
||||
if (indexBuffer.handle == VK_NULL_HANDLE &&
|
||||
pipe.uConfig.vgtPrimitiveType != indexBuffer.primType) {
|
||||
vsPrimType = pipe.uConfig.vgtPrimitiveType.value;
|
||||
}
|
||||
|
||||
vertexShader =
|
||||
cacheTag.getVertexShader(gcn::Stage::VsVs, pipe.sh.spiShaderPgmVs,
|
||||
pipe.context, vsPrimType, viewPorts);
|
||||
}
|
||||
|
||||
auto pixelShader =
|
||||
cacheTag.getPixelShader(pipe.sh.spiShaderPgmPs, pipe.context, viewPorts);
|
||||
|
||||
if (pixelShader.handle == nullptr) {
|
||||
shaders[Cache::getStageIndex(VK_SHADER_STAGE_FRAGMENT_BIT)] =
|
||||
getFillRedFragShader(*cacheTag.getCache());
|
||||
}
|
||||
|
||||
shaders[Cache::getStageIndex(VK_SHADER_STAGE_VERTEX_BIT)] =
|
||||
vertexShader.handle;
|
||||
shaders[Cache::getStageIndex(VK_SHADER_STAGE_FRAGMENT_BIT)] =
|
||||
pixelShader.handle;
|
||||
|
||||
if (pipe.uConfig.vgtPrimitiveType == gnm::PrimitiveType::RectList) {
|
||||
shaders[Cache::getStageIndex(VK_SHADER_STAGE_GEOMETRY_BIT)] =
|
||||
getPrimTypeRectGeomShader(*cacheTag.getCache());
|
||||
}
|
||||
|
||||
if (indiciesAddress == 0) {
|
||||
vertexCount = indexBuffer.indexCount;
|
||||
}
|
||||
|
||||
VkRenderingInfo renderInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
|
||||
.renderArea = gnm::toVkRect2D(pipe.context.paScScreenScissor),
|
||||
.layerCount = 1,
|
||||
.colorAttachmentCount = renderTargets,
|
||||
.pColorAttachments = colorAttachments,
|
||||
.pDepthAttachment =
|
||||
depthAccess != Access::None ? &depthAttachment : nullptr,
|
||||
.pStencilAttachment =
|
||||
stencilAccess != Access::None ? &stencilAttachment : nullptr,
|
||||
};
|
||||
|
||||
cacheTag.buildDescriptors(descriptorSets[0]);
|
||||
|
||||
pipe.scheduler.afterSubmit([cacheTag = std::move(cacheTag)] {});
|
||||
|
||||
auto commandBuffer = pipe.scheduler.getCommandBuffer();
|
||||
|
||||
vkCmdBeginRendering(commandBuffer, &renderInfo);
|
||||
vkCmdSetRasterizerDiscardEnable(commandBuffer, VK_FALSE);
|
||||
|
||||
vkCmdSetViewportWithCount(commandBuffer, renderTargets, viewPorts);
|
||||
vkCmdSetScissorWithCount(commandBuffer, renderTargets, viewPortScissors);
|
||||
|
||||
vk::CmdSetColorBlendEnableEXT(commandBuffer, 0, renderTargets,
|
||||
colorBlendEnable);
|
||||
vk::CmdSetColorBlendEquationEXT(commandBuffer, 0, renderTargets,
|
||||
colorBlendEquation);
|
||||
|
||||
vk::CmdSetDepthClampEnableEXT(commandBuffer, VK_FALSE);
|
||||
vkCmdSetDepthCompareOp(commandBuffer,
|
||||
gnm::toVkCompareOp(pipe.context.dbDepthControl.zFunc));
|
||||
vkCmdSetDepthTestEnable(commandBuffer, pipe.context.dbDepthControl.depthEnable
|
||||
? VK_TRUE
|
||||
: VK_FALSE);
|
||||
vkCmdSetDepthWriteEnable(
|
||||
commandBuffer,
|
||||
pipe.context.dbDepthControl.depthWriteEnable ? VK_TRUE : VK_FALSE);
|
||||
vkCmdSetDepthBounds(commandBuffer, pipe.context.dbDepthBoundsMin,
|
||||
pipe.context.dbDepthBoundsMax);
|
||||
vkCmdSetDepthBoundsTestEnable(
|
||||
commandBuffer,
|
||||
pipe.context.dbDepthControl.depthBoundsEnable ? VK_TRUE : VK_FALSE);
|
||||
// vkCmdSetStencilOp(commandBuffer, VK_STENCIL_FACE_FRONT_AND_BACK,
|
||||
// VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP,
|
||||
// VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS);
|
||||
|
||||
vkCmdSetDepthBiasEnable(commandBuffer, VK_FALSE);
|
||||
vkCmdSetDepthBias(commandBuffer, 0, 1, 1);
|
||||
vkCmdSetPrimitiveRestartEnable(commandBuffer, VK_FALSE);
|
||||
|
||||
vk::CmdSetAlphaToOneEnableEXT(commandBuffer, VK_FALSE);
|
||||
|
||||
vk::CmdSetLogicOpEnableEXT(commandBuffer, VK_FALSE);
|
||||
vk::CmdSetLogicOpEXT(commandBuffer, VK_LOGIC_OP_AND);
|
||||
vk::CmdSetPolygonModeEXT(commandBuffer, VK_POLYGON_MODE_FILL);
|
||||
vk::CmdSetRasterizationSamplesEXT(commandBuffer, VK_SAMPLE_COUNT_1_BIT);
|
||||
VkSampleMask sampleMask = ~0;
|
||||
vk::CmdSetSampleMaskEXT(commandBuffer, VK_SAMPLE_COUNT_1_BIT, &sampleMask);
|
||||
vk::CmdSetTessellationDomainOriginEXT(
|
||||
commandBuffer, VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT);
|
||||
vk::CmdSetAlphaToCoverageEnableEXT(commandBuffer, VK_FALSE);
|
||||
vk::CmdSetVertexInputEXT(commandBuffer, 0, nullptr, 0, nullptr);
|
||||
vk::CmdSetColorWriteMaskEXT(commandBuffer, 0, renderTargets, colorWriteMask);
|
||||
|
||||
vkCmdSetStencilCompareMask(commandBuffer, VK_STENCIL_FACE_FRONT_AND_BACK, 0);
|
||||
vkCmdSetStencilWriteMask(commandBuffer, VK_STENCIL_FACE_FRONT_AND_BACK, 0);
|
||||
vkCmdSetStencilReference(commandBuffer, VK_STENCIL_FACE_FRONT_AND_BACK, 0);
|
||||
|
||||
VkCullModeFlags cullMode = VK_CULL_MODE_NONE;
|
||||
if (pipe.context.paSuScModeCntl.cullBack) {
|
||||
cullMode |= VK_CULL_MODE_BACK_BIT;
|
||||
}
|
||||
if (pipe.context.paSuScModeCntl.cullFront) {
|
||||
cullMode |= VK_CULL_MODE_FRONT_BIT;
|
||||
}
|
||||
|
||||
vkCmdSetCullMode(commandBuffer, cullMode);
|
||||
vkCmdSetFrontFace(commandBuffer,
|
||||
gnm::toVkFrontFace(pipe.context.paSuScModeCntl.face));
|
||||
|
||||
vkCmdSetPrimitiveTopology(commandBuffer,
|
||||
toVkPrimitiveType(pipe.uConfig.vgtPrimitiveType));
|
||||
vkCmdSetStencilTestEnable(commandBuffer, VK_FALSE);
|
||||
|
||||
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
pipelineLayout, 0, descriptorSets.size(),
|
||||
descriptorSets.data(), 0, nullptr);
|
||||
|
||||
vk::CmdBindShadersEXT(commandBuffer, stages.size(), stages.data(), shaders);
|
||||
|
||||
if (indexBuffer.handle != VK_NULL_HANDLE) {
|
||||
vkCmdBindIndexBuffer(commandBuffer, indexBuffer.handle, indexBuffer.offset,
|
||||
gnm::toVkIndexType(indexBuffer.indexType));
|
||||
vkCmdDrawIndexed(commandBuffer, indexCount, instanceCount, 0, firstVertex,
|
||||
firstInstance);
|
||||
} else {
|
||||
vkCmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex,
|
||||
firstInstance);
|
||||
}
|
||||
|
||||
vkCmdEndRendering(commandBuffer);
|
||||
pipe.scheduler.submit();
|
||||
}
|
||||
|
||||
void amdgpu::dispatch(Cache &cache, Scheduler &sched,
|
||||
Registers::ComputeConfig &computeConfig,
|
||||
std::uint32_t groupCountX, std::uint32_t groupCountY,
|
||||
std::uint32_t groupCountZ) {
|
||||
auto tag = cache.createComputeTag(sched);
|
||||
auto descriptorSet = tag.getDescriptorSet();
|
||||
auto shader = tag.getShader(computeConfig);
|
||||
auto pipelineLayout = tag.getComputePipelineLayout();
|
||||
tag.buildDescriptors(descriptorSet);
|
||||
|
||||
auto commandBuffer = sched.getCommandBuffer();
|
||||
VkShaderStageFlagBits stages[]{VK_SHADER_STAGE_COMPUTE_BIT};
|
||||
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE,
|
||||
pipelineLayout, 0, 1, &descriptorSet, 0, nullptr);
|
||||
vk::CmdBindShadersEXT(commandBuffer, 1, stages, &shader.handle);
|
||||
vkCmdDispatch(commandBuffer, groupCountX, groupCountY, groupCountZ);
|
||||
sched.submit();
|
||||
}
|
||||
|
||||
void amdgpu::flip(Cache::Tag &cacheTag, VkCommandBuffer commandBuffer,
|
||||
VkExtent2D targetExtent, std::uint64_t address,
|
||||
VkImageView target, VkExtent2D imageExtent, FlipType type,
|
||||
TileMode tileMode, gnm::DataFormat dfmt,
|
||||
gnm::NumericFormat nfmt) {
|
||||
ImageKey framebuffer{};
|
||||
framebuffer.readAddress = address;
|
||||
framebuffer.type = gnm::TextureType::Dim2D;
|
||||
framebuffer.dfmt = dfmt;
|
||||
framebuffer.nfmt = nfmt;
|
||||
framebuffer.tileMode = tileMode;
|
||||
framebuffer.extent.width = imageExtent.width;
|
||||
framebuffer.extent.height = imageExtent.height;
|
||||
framebuffer.extent.depth = 1;
|
||||
framebuffer.pitch = imageExtent.width;
|
||||
framebuffer.mipCount = 1;
|
||||
framebuffer.arrayLayerCount = 1;
|
||||
|
||||
SamplerKey framebufferSampler = {
|
||||
.magFilter = VK_FILTER_LINEAR,
|
||||
.minFilter = VK_FILTER_LINEAR,
|
||||
};
|
||||
|
||||
auto imageView = cacheTag.getImageView(framebuffer, Access::Read);
|
||||
auto sampler = cacheTag.getSampler(framebufferSampler);
|
||||
|
||||
VkRenderingAttachmentInfo colorAttachments[1]{{
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
.imageView = target,
|
||||
.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||
}};
|
||||
|
||||
VkViewport viewPort{};
|
||||
viewPort.width = targetExtent.width;
|
||||
viewPort.height = targetExtent.height;
|
||||
|
||||
float imageAspectRatio = float(imageExtent.width) / imageExtent.height;
|
||||
float targetAspectRatio = float(targetExtent.width) / targetExtent.height;
|
||||
|
||||
auto aspectDiff = imageAspectRatio / targetAspectRatio;
|
||||
|
||||
if (aspectDiff > 1) {
|
||||
viewPort.height = targetExtent.height / aspectDiff;
|
||||
viewPort.y = (targetExtent.height - viewPort.height) / 2;
|
||||
} else if (aspectDiff < 1) {
|
||||
viewPort.width = targetExtent.width * aspectDiff;
|
||||
viewPort.x = (targetExtent.width - viewPort.width) / 2;
|
||||
}
|
||||
|
||||
VkRect2D viewPortScissors[1]{{
|
||||
{},
|
||||
targetExtent,
|
||||
}};
|
||||
|
||||
VkRenderingInfo renderInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
|
||||
.renderArea =
|
||||
{
|
||||
.offset = {},
|
||||
.extent = targetExtent,
|
||||
},
|
||||
.layerCount = 1,
|
||||
.colorAttachmentCount = 1,
|
||||
.pColorAttachments = colorAttachments,
|
||||
};
|
||||
|
||||
commandBuffer = cacheTag.getScheduler().getCommandBuffer();
|
||||
|
||||
vkCmdBeginRendering(commandBuffer, &renderInfo);
|
||||
|
||||
cacheTag.getDevice()->flipPipeline.bind(cacheTag.getScheduler(), type,
|
||||
imageView.handle, sampler.handle);
|
||||
|
||||
vkCmdSetViewportWithCount(commandBuffer, 1, &viewPort);
|
||||
vkCmdSetScissorWithCount(commandBuffer, 1, viewPortScissors);
|
||||
|
||||
vkCmdDraw(commandBuffer, 6, 1, 0, 0);
|
||||
vkCmdEndRendering(commandBuffer);
|
||||
cacheTag.getScheduler().submit();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue