Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ struct VulkanDevice::State {
bool imageViewMinLod = false;
bool maintenance8 = false;
bool depthClamp = false;
bool depthBounds = false;
bool depthBiasClamp = false;
bool occlusionQueryPrecise = false;
VkDeviceSize hostImportAlignment = 0;
bool depthRangeUnrestricted = false;
Expand Down Expand Up @@ -821,6 +823,10 @@ VulkanDevice::VulkanDevice(const PresentationWindow* window) : state(std::make_u
// PA_CL_CLIP_CNTL near/far clip disable maps to depth clamping.
enabled.depthClamp = available.depthClamp;
state->depthClamp = enabled.depthClamp == VK_TRUE;
enabled.depthBounds = available.depthBounds;
state->depthBounds = enabled.depthBounds == VK_TRUE;
enabled.depthBiasClamp = available.depthBiasClamp;
state->depthBiasClamp = enabled.depthBiasClamp == VK_TRUE;
enabled.occlusionQueryPrecise = available.occlusionQueryPrecise;
state->occlusionQueryPrecise = enabled.occlusionQueryPrecise == VK_TRUE;
// Recompiled storage-image access declares no format (the guest descriptor decides it).
Expand Down Expand Up @@ -2230,6 +2236,8 @@ Graphics::Context VulkanDevice::buildContext() const {
context.samplerCache = state->samplerCache.get();
context.drawIndirectFirstInstance = state->drawIndirectFirstInstance;
context.multiDrawIndirect = state->multiDrawIndirect;
context.depthBounds = state->depthBounds;
context.depthBiasClamp = state->depthBiasClamp;
context.drawIndirectCount = state->drawIndirectCount;
context.occlusionQueryPrecise = state->occlusionQueryPrecise;
context.emptyBuffer = state->emptyBuffer ? state->emptyBuffer->Handle() : VK_NULL_HANDLE;
Expand Down
4 changes: 4 additions & 0 deletions core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ struct DeviceFunctions {
PFN_vkCmdEndRenderPass cmdEndRenderPass = nullptr;
PFN_vkCmdSetViewport cmdSetViewport = nullptr;
PFN_vkCmdSetScissor cmdSetScissor = nullptr;
PFN_vkCmdSetDepthBounds cmdSetDepthBounds = nullptr;
PFN_vkCmdSetDepthBias cmdSetDepthBias = nullptr;
PFN_vkCmdBindVertexBuffers cmdBindVertexBuffers = nullptr;
PFN_vkCmdBindIndexBuffer cmdBindIndexBuffer = nullptr;
PFN_vkCmdDraw cmdDraw = nullptr;
Expand Down Expand Up @@ -119,6 +121,8 @@ struct Context {
bool multiDrawIndirect = false;
bool drawIndirectCount = false;
bool occlusionQueryPrecise = false;
bool depthBounds = false;
bool depthBiasClamp = false;
VkBuffer emptyBuffer = VK_NULL_HANDLE;
// The device's list of recorded dispatches whose copied written buffers await a CPU write-back
// (VulkanDevice's State::copiedWriters; the draw counterpart is DrawCopiedWriters): an indirect
Expand Down
13 changes: 8 additions & 5 deletions core/libs/prx/libSceAgcDriver/Graphics/include/Pipeline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ class Framebuffer {
VkFramebuffer framebuffer = VK_NULL_HANDLE;
};

// The shader modules, layout, render pass and VkPipeline of one draw configuration. Viewport and
// scissor are dynamic state set at Begin, so pipelines are shared by draws that differ only there
// The shader modules, layout, render pass and VkPipeline of one draw configuration. Viewport,
// scissor, depth bounds and depth bias are dynamic state set at Begin, so pipelines are shared by draws that differ only there
// (see CachedPipeline).
class Pipeline {
public:
Expand All @@ -41,11 +41,11 @@ class Pipeline {
Pipeline& operator=(const Pipeline&) = delete;
VkPipelineLayout Layout() const;
std::shared_ptr<Framebuffer> AcquireFramebuffer(std::span<const VkImageView> targets, std::span<const std::shared_ptr<StorageTexture>> owners, VkExtent2D extent);
// Begins the render pass on the framebuffer, binds the pipeline and sets viewport and scissor.
void Begin(VkCommandBuffer commands, const Framebuffer& framebuffer, VkExtent2D extent, const VkViewport& viewport, const VkRect2D& scissor) const;
// Begins the render pass on the framebuffer, binds the pipeline and sets its dynamic state.
void Begin(VkCommandBuffer commands, const Framebuffer& framebuffer, VkExtent2D extent, const State& state) const;
// The same inside a render pass another pipeline of the same attachments began (compatible by
// construction: the attachment formats alone decide).
void Continue(VkCommandBuffer commands, const VkViewport& viewport, const VkRect2D& scissor) const;
void Continue(VkCommandBuffer commands, const State& state) const;
void PushConstants(VkCommandBuffer commands, VkShaderStageFlags stages, std::span<const std::byte, PipelinePushConstantBytes> bytes) const;
// Forgets the Vulkan objects without destroying them: for entries of a device that is already gone.
void Abandon() noexcept;
Expand All @@ -65,6 +65,8 @@ class Pipeline {
VkPipeline pipeline = VK_NULL_HANDLE;
std::size_t attachments = 0;
std::size_t colorAttachments = 0;
bool depthBounds = false;
bool depthBias = false;
std::vector<CachedFramebuffer> framebuffers;
};

Expand All @@ -81,6 +83,7 @@ std::shared_ptr<Pipeline> CachedPipeline(const Context& context, const State& st
void ClearCachedPipelines(VkDevice device);
// Device limit checks of the viewport, which is dynamic state and so no longer checked by Pipeline.
void ValidateViewport(const Context& context, const VkViewport& viewport);
void ValidateDepthBounds(const Context& context, const State& state);

void ValidateShaderPair(const ShaderRecompiler::RecompileResult& vertex, const ShaderRecompiler::RecompileResult& fragment);
// Returns the color attachment locations the pixel shader writes.
Expand Down
11 changes: 9 additions & 2 deletions core/libs/prx/libSceAgcDriver/Graphics/include/State.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ struct State {
bool depthTest = false;
bool depthWrite = false;
VkCompareOp depthCompare = VK_COMPARE_OP_ALWAYS;
bool depthBoundsTest = false;
float minDepthBounds = 0.0f;
float maxDepthBounds = 1.0f;
bool depthBias = false;
float depthBiasConstant = 0.0f;
float depthBiasSlope = 0.0f;
float depthBiasClamp = 0.0f;
bool stencilTest = false;
VkStencilOpState stencilFront{};
VkStencilOpState stencilBack{};
Expand Down Expand Up @@ -133,14 +140,14 @@ struct DrawKeyRange {
std::uint32_t count;
};
inline constexpr std::array<DrawKeyRange, 45> DrawKeyRegisters{{
{RegisterBank::Context, 0x000, 1}, {RegisterBank::Context, 0x002, 1}, {RegisterBank::Context, 0x007, 1}, {RegisterBank::Context, 0x00a, 4}, {RegisterBank::Context, 0x010, 6}, {RegisterBank::Context, 0x01a, 4},
{RegisterBank::Context, 0x000, 1}, {RegisterBank::Context, 0x002, 1}, {RegisterBank::Context, 0x007, 7}, {RegisterBank::Context, 0x010, 6}, {RegisterBank::Context, 0x01a, 4},
{RegisterBank::Context, 0x080, 4}, {RegisterBank::Context, 0x08c, 4}, {RegisterBank::Context, 0x090, 2}, {RegisterBank::Context, 0x094, 2}, {RegisterBank::Context, 0x0b4, 2}, {RegisterBank::Context, 0x105, 4}, {RegisterBank::Context, 0x10b, 3}, {RegisterBank::Context, 0x10f, 6},
// SPI_PS_INPUT_CNTL_0..31, SPI_PS_INPUT_ENA/ADDR, SPI_PS_IN_CONTROL, SPI_SHADER_POS/Z/COL_FORMAT,
// CB_BLEND0..7_CONTROL, GE_MAX_OUTPUT_PER_SUBGROUP.
{RegisterBank::Context, 0x191, 32}, {RegisterBank::Context, 0x1b3, 2}, {RegisterBank::Context, 0x1b6, 1}, {RegisterBank::Context, 0x1c3, 3}, {RegisterBank::Context, 0x1e0, 8}, {RegisterBank::Context, 0x1ff, 1},
// DB_DEPTH_CONTROL .. PA_CL_VS_OUT_CNTL, PA_SC_MODE_CNTL_0/1, VGT_GS_MODE, VGT_GS_VERT_ITEMSIZE,
// PA_SU_VTX_CNTL, the sample masks, PA_SC_CONSERVATIVE_RASTERIZATION_CNTL.
{RegisterBank::Context, 0x200, 8}, {RegisterBank::Context, 0x292, 2}, {RegisterBank::Context, 0x29b, 1}, {RegisterBank::Context, 0x2ab, 1}, {RegisterBank::Context, 0x2ce, 1}, {RegisterBank::Context, 0x2d5, 2}, {RegisterBank::Context, 0x2db, 2}, {RegisterBank::Context, 0x2f8, 2}, {RegisterBank::Context, 0x30e, 2}, {RegisterBank::Context, 0x313, 1},
{RegisterBank::Context, 0x200, 8}, {RegisterBank::Context, 0x292, 2}, {RegisterBank::Context, 0x29b, 1}, {RegisterBank::Context, 0x2ab, 1}, {RegisterBank::Context, 0x2ce, 1}, {RegisterBank::Context, 0x2d5, 2}, {RegisterBank::Context, 0x2db, 2}, {RegisterBank::Context, 0x2de, 6}, {RegisterBank::Context, 0x2f8, 2}, {RegisterBank::Context, 0x30e, 2}, {RegisterBank::Context, 0x313, 1},
// CB_COLOR0..7_BASE .. DCC_BASE (15 words a slot), CB_COLOR0..7_BASE_EXT, DCC_BASE_EXT, ATTRIB2, ATTRIB3.
{RegisterBank::Context, 0x318, 0x78}, {RegisterBank::Context, 0x390, 8}, {RegisterBank::Context, 0x3a8, 0x18},
// The pixel program address, RSRC2 and user words; the geometry-back user pointer and program
Expand Down
7 changes: 4 additions & 3 deletions core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,7 @@ DrawInputs prepareDrawInputs(const Context& context, const State& state, const P
if (state.stages.tessellation) Require(draw.indexCount % state.stages.tessellation->inputControlPoints == 0, "incomplete tessellation patch");
// Viewport and scissor are dynamic pipeline state, so their limits are checked here per draw.
ValidateViewport(context, state.viewport);
ValidateDepthBounds(context, state);
timer.phase(PhaseValidate);
inputs.maxIndex = draw.indexed ? 0u : draw.firstVertex + draw.indexCount - 1u;
if (draw.indexed) {
Expand Down Expand Up @@ -1269,7 +1270,7 @@ void recordDraw(const Context& context, const State& state, const Pm4::DrawParam
VkDeviceSize argumentOffset = 0;
bool rewritten = false;
if (continued) {
record.pipeline->Continue(commands, state.viewport, state.scissor);
record.pipeline->Continue(commands, state);
} else {
const VkMemoryBarrier before{VK_STRUCTURE_TYPE_MEMORY_BARRIER, nullptr, VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_UNIFORM_READ_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT};
context.Resolved(&DeviceFunctions::cmdPipelineBarrier, "vkCmdPipelineBarrier")(commands, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | inputs.shaderStages, 0, 1, &before, 0, nullptr, 0, nullptr);
Expand All @@ -1279,7 +1280,7 @@ void recordDraw(const Context& context, const State& state, const Pm4::DrawParam
// Earlier recorded work (dispatches, the previous draw) wrote the images in the general
// layout, which a lean draw renders in: no transitions.
APS5_LOG_OUT_DEBUG("Beginning pipeline renderExtent=%ux%u", state.renderExtent.width, state.renderExtent.height);
record.pipeline->Begin(commands, *record.framebuffer, state.renderExtent, state.viewport, state.scissor);
record.pipeline->Begin(commands, *record.framebuffer, state.renderExtent, state);
}
APS5_LOG_CHARS_OUT_DEBUG("Pipeline Begin OK");
if (drawBindings != nullptr) {
Expand Down Expand Up @@ -1716,7 +1717,7 @@ void Draw(const Context& context, const State& state, const Pm4::DrawParameters&
imageBarrier(context, commands, binding.target->Image(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
}
APS5_LOG_OUT_DEBUG("Beginning pipeline renderExtent=%ux%u", state.renderExtent.width, state.renderExtent.height);
pipeline->Begin(commands, *framebuffer, state.renderExtent, state.viewport, state.scissor);
pipeline->Begin(commands, *framebuffer, state.renderExtent, state);
APS5_LOG_CHARS_OUT_DEBUG("Pipeline Begin OK");
resources->Bind(commands, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->Layout());
APS5_LOG_CHARS_OUT_DEBUG("Resources bound");
Expand Down
29 changes: 22 additions & 7 deletions core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ Framebuffer::~Framebuffer() {
if (framebuffer) context.Function<PFN_vkDestroyFramebuffer>("vkDestroyFramebuffer")(context.device, framebuffer, nullptr);
}

void ValidateDepthBounds(const Context& context, const State& state) {
Require(!state.depthBoundsTest || context.depthRangeUnrestricted || (state.minDepthBounds >= 0.0f && state.minDepthBounds <= 1.0f && state.maxDepthBounds >= 0.0f && state.maxDepthBounds <= 1.0f), "depth bounds outside [0, 1] require VK_EXT_depth_range_unrestricted");
}

void ValidateViewport(const Context& context, const VkViewport& viewport) {
Require(std::isfinite(viewport.minDepth) && std::isfinite(viewport.maxDepth), "non-finite viewport depth range");
Require(context.depthRangeUnrestricted || (viewport.minDepth >= 0 && viewport.minDepth <= 1 && viewport.maxDepth >= 0 && viewport.maxDepth <= 1), "viewport depth outside [0, 1] requires VK_EXT_depth_range_unrestricted");
Expand All @@ -41,13 +45,15 @@ void ValidateViewport(const Context& context, const VkViewport& viewport) {
Require(std::min(viewport.y, viewport.y + viewport.height) >= context.limits.viewportBoundsRange[0] && std::max(viewport.y, viewport.y + viewport.height) <= context.limits.viewportBoundsRange[1], "viewport Y exceeds device bounds");
}

Pipeline::Pipeline(const Context& context, const State& state, const VertexInputLayout& vertexInput, const ShaderResources& resources, std::span<const CompiledShader> shaders, VkImageLayout attachmentLayout) : context(context), _modules(shaders.size()), attachments(state.colors.size() + (state.depth ? 1u : 0u)), colorAttachments(state.colors.size()) {
Pipeline::Pipeline(const Context& context, const State& state, const VertexInputLayout& vertexInput, const ShaderResources& resources, std::span<const CompiledShader> shaders, VkImageLayout attachmentLayout) : context(context), _modules(shaders.size()), attachments(state.colors.size() + (state.depth ? 1u : 0u)), colorAttachments(state.colors.size()), depthBounds(state.depth.has_value() && state.depthBoundsTest), depthBias(state.depth.has_value() && state.depthBias) {
// A cached pipeline may outlive its device's teardown (see ClearCachedPipelines); it must not keep
// the buffer pool, which is reset with the device, alive past it.
this->context.bufferPool.reset();
Require(state.blends.size() == state.colors.size(), "blend states do not match decoded color state");
Require(state.colors.size() <= context.limits.maxColorAttachments, "color targets exceed device attachment limits");
Require(state.hasColorTarget || (context.limits.framebufferNoAttachmentsSampleCounts & VK_SAMPLE_COUNT_1_BIT) != 0, "device does not support single-sample rendering without attachments");
Require(!depthBounds || context.depthBounds, "device does not support the depth bounds test");
Require(!depthBias || state.depthBiasClamp == 0.0f || context.depthBiasClamp, "device does not support depth bias clamping");
Require(!state.negativeOneToOne || context.depthClipControl, "negative-one-to-one depth clipping requires VK_EXT_depth_clip_control with depthClipControl enabled");
if (state.rectList) Require(context.tessellationShader && context.limits.maxTessellationPatchSize >= 4, "rect-list requires tessellation with four output control points");
if (state.stages.tessellation) {
Expand Down Expand Up @@ -143,7 +149,9 @@ Pipeline::Pipeline(const Context& context, const State& state, const VertexInput
if (state.negativeOneToOne) viewports.pNext = &depthClip;
viewports.viewportCount = 1;
viewports.scissorCount = 1;
const std::array<VkDynamicState, 2> dynamicStates{VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
std::vector<VkDynamicState> dynamicStates{VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
if (depthBounds) dynamicStates.push_back(VK_DYNAMIC_STATE_DEPTH_BOUNDS);
if (depthBias) dynamicStates.push_back(VK_DYNAMIC_STATE_DEPTH_BIAS);
VkPipelineDynamicStateCreateInfo dynamic{VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO};
dynamic.dynamicStateCount = static_cast<std::uint32_t>(dynamicStates.size());
dynamic.pDynamicStates = dynamicStates.data();
Expand All @@ -152,13 +160,15 @@ Pipeline::Pipeline(const Context& context, const State& state, const VertexInput
raster.depthClampEnable = state.depthClamp && context.depthClamp ? VK_TRUE : VK_FALSE;
raster.cullMode = state.cullMode;
raster.frontFace = state.frontFace;
raster.depthBiasEnable = depthBias;
raster.lineWidth = 1;
VkPipelineMultisampleStateCreateInfo samples{VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO};
samples.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
VkPipelineDepthStencilStateCreateInfo depthStencil{VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO};
depthStencil.depthTestEnable = state.depthTest;
depthStencil.depthWriteEnable = state.depthWrite;
depthStencil.depthCompareOp = state.depthCompare;
depthStencil.depthBoundsTestEnable = depthBounds;
depthStencil.stencilTestEnable = state.stencilTest;
depthStencil.front = state.stencilFront;
depthStencil.back = state.stencilBack;
Expand Down Expand Up @@ -264,19 +274,22 @@ std::shared_ptr<Framebuffer> Pipeline::AcquireFramebuffer(std::span<const VkImag
return framebuffer;
}

void Pipeline::Begin(VkCommandBuffer commands, const Framebuffer& framebuffer, VkExtent2D extent, const VkViewport& viewport, const VkRect2D& scissor) const {
void Pipeline::Begin(VkCommandBuffer commands, const Framebuffer& framebuffer, VkExtent2D extent, const State& state) const {
VkRenderPassBeginInfo begin{VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO};
begin.renderPass = renderPass;
begin.framebuffer = framebuffer.Handle();
begin.renderArea = {{0, 0}, extent};
context.Resolved(&DeviceFunctions::cmdBeginRenderPass, "vkCmdBeginRenderPass")(commands, &begin, VK_SUBPASS_CONTENTS_INLINE);
Continue(commands, viewport, scissor);
Continue(commands, state);
}

void Pipeline::Continue(VkCommandBuffer commands, const VkViewport& viewport, const VkRect2D& scissor) const {
void Pipeline::Continue(VkCommandBuffer commands, const State& state) const {
context.Resolved(&DeviceFunctions::cmdBindPipeline, "vkCmdBindPipeline")(commands, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
context.Resolved(&DeviceFunctions::cmdSetViewport, "vkCmdSetViewport")(commands, 0, 1, &viewport);
context.Resolved(&DeviceFunctions::cmdSetScissor, "vkCmdSetScissor")(commands, 0, 1, &scissor);
context.Resolved(&DeviceFunctions::cmdSetViewport, "vkCmdSetViewport")(commands, 0, 1, &state.viewport);
context.Resolved(&DeviceFunctions::cmdSetScissor, "vkCmdSetScissor")(commands, 0, 1, &state.scissor);
if (depthBias) context.Resolved(&DeviceFunctions::cmdSetDepthBias, "vkCmdSetDepthBias")(commands, state.depthBiasConstant, state.depthBiasClamp, state.depthBiasSlope);
if (!depthBounds) return;
context.Resolved(&DeviceFunctions::cmdSetDepthBounds, "vkCmdSetDepthBounds")(commands, state.minDepthBounds, state.maxDepthBounds);
}

void Pipeline::PushConstants(VkCommandBuffer commands, VkShaderStageFlags stages, std::span<const std::byte, PipelinePushConstantBytes> bytes) const {
Expand Down Expand Up @@ -347,6 +360,8 @@ std::vector<std::byte> pipelineKey(const Context& context, const State& state, c
append(key, state.depthTest);
append(key, state.depthWrite);
append(key, state.depthCompare);
append(key, state.depthBoundsTest);
append(key, state.depthBias);
append(key, state.stencilTest);
append(key, state.stencilFront);
append(key, state.stencilBack);
Expand Down
2 changes: 2 additions & 0 deletions core/libs/prx/libSceAgcDriver/Graphics/src/Resources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ void FillDeviceFunctions(const Context& context, DeviceFunctions& functions) {
functions.cmdEndRenderPass = context.Function<PFN_vkCmdEndRenderPass>("vkCmdEndRenderPass");
functions.cmdSetViewport = context.Function<PFN_vkCmdSetViewport>("vkCmdSetViewport");
functions.cmdSetScissor = context.Function<PFN_vkCmdSetScissor>("vkCmdSetScissor");
functions.cmdSetDepthBounds = context.Function<PFN_vkCmdSetDepthBounds>("vkCmdSetDepthBounds");
functions.cmdSetDepthBias = context.Function<PFN_vkCmdSetDepthBias>("vkCmdSetDepthBias");
functions.cmdBindVertexBuffers = context.Function<PFN_vkCmdBindVertexBuffers>("vkCmdBindVertexBuffers");
functions.cmdBindIndexBuffer = context.Function<PFN_vkCmdBindIndexBuffer>("vkCmdBindIndexBuffer");
functions.cmdDraw = context.Function<PFN_vkCmdDraw>("vkCmdDraw");
Expand Down
Loading
Loading