Skip to content

Commit

Permalink
Merge pull request #9899 from hrydgard/vulkan-state-opt
Browse files Browse the repository at this point in the history
Vulkan state optimizations
  • Loading branch information
hrydgard committed Aug 14, 2017
2 parents 776c9e3 + 000723f commit 6a2f876
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 50 deletions.
9 changes: 4 additions & 5 deletions GPU/D3D11/StateMappingD3D11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,10 +457,6 @@ void DrawEngineD3D11::ApplyDrawStateLate(bool applyStencilRef, uint8_t stencilRe
textureCache_->ApplyTexture();
}

// Need to do this AFTER ApplyTexture because the process of depallettization can ruin the blend state.
float blendColor[4];
Uint8x4ToFloat4(blendColor, dynState_.blendColor);

// we go through Draw here because it automatically handles screen rotation, as needed in UWP on mobiles.
if (gstate_c.IsDirty(DIRTY_VIEWPORTSCISSOR_STATE)) {
draw_->SetViewports(1, &dynState_.viewport);
Expand All @@ -470,13 +466,16 @@ void DrawEngineD3D11::ApplyDrawStateLate(bool applyStencilRef, uint8_t stencilRe
context_->RSSetState(rasterState_);
}
if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) {
// Need to do this AFTER ApplyTexture because the process of depallettization can ruin the blend state.
float blendColor[4];
Uint8x4ToFloat4(blendColor, dynState_.blendColor);
if (device1_) {
context1_->OMSetBlendState(blendState1_, blendColor, 0xFFFFFFFF);
} else {
context_->OMSetBlendState(blendState_, blendColor, 0xFFFFFFFF);
}
}
if (gstate_c.IsDirty(DIRTY_DEPTHSTENCIL_STATE)) {
if (gstate_c.IsDirty(DIRTY_DEPTHSTENCIL_STATE) || applyStencilRef) {
context_->OMSetDepthStencilState(depthStencilState_, applyStencilRef ? stencilRef : dynState_.stencilRef);
}
gstate_c.Clean(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_BLEND_STATE);
Expand Down
44 changes: 13 additions & 31 deletions GPU/Vulkan/DrawEngineVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,12 @@ void DrawEngineVulkan::DoFlush() {
gpuStats.numFlushes++;

VkCommandBuffer cmd = (VkCommandBuffer)draw_->GetNativeObject(Draw::NativeObject::RENDERPASS_COMMANDBUFFER);
if (cmd != lastCmd_) {
lastPipeline_ = nullptr;
lastCmd_ = cmd;
gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE);
}

VkRenderPass rp = (VkRenderPass)draw_->GetNativeObject(Draw::NativeObject::CURRENT_RENDERPASS);
if (!rp)
Crash();
Expand Down Expand Up @@ -650,19 +656,7 @@ void DrawEngineVulkan::DoFlush() {
}

ConvertStateToVulkanKey(*framebufferManager_, shaderManager_, prim, pipelineKey_, dynState_);
// TODO: Dirty-flag these.
vkCmdSetScissor(cmd, 0, 1, &dynState_.scissor);
vkCmdSetViewport(cmd, 0, 1, &dynState_.viewport);
if (dynState_.useStencil) {
vkCmdSetStencilWriteMask(cmd, VK_STENCIL_FRONT_AND_BACK, dynState_.stencilWriteMask);
vkCmdSetStencilCompareMask(cmd, VK_STENCIL_FRONT_AND_BACK, dynState_.stencilCompareMask);
vkCmdSetStencilReference(cmd, VK_STENCIL_FRONT_AND_BACK, dynState_.stencilRef);
}
if (dynState_.useBlendColor) {
float bc[4];
Uint8x4ToFloat4(bc, dynState_.blendColor);
vkCmdSetBlendConstants(cmd, bc);
}
ApplyDrawStateLate(cmd, false, 0);

dirtyUniforms_ |= shaderManager_->UpdateUniforms();

Expand All @@ -672,7 +666,10 @@ void DrawEngineVulkan::DoFlush() {
// Already logged, let's bail out.
return;
}
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->pipeline); // TODO: Avoid if same as last draw.
if (pipeline != lastPipeline_) {
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->pipeline); // TODO: Avoid if same as last draw.
lastPipeline_ = pipeline;
}

UpdateUBOs(frame);

Expand Down Expand Up @@ -751,23 +748,8 @@ void DrawEngineVulkan::DoFlush() {
}

ConvertStateToVulkanKey(*framebufferManager_, shaderManager_, prim, pipelineKey_, dynState_);
// TODO: Dirty-flag these.
vkCmdSetScissor(cmd, 0, 1, &dynState_.scissor);
vkCmdSetViewport(cmd, 0, 1, &dynState_.viewport);
if (dynState_.useStencil) {
vkCmdSetStencilWriteMask(cmd, VK_STENCIL_FRONT_AND_BACK, dynState_.stencilWriteMask);
vkCmdSetStencilCompareMask(cmd, VK_STENCIL_FRONT_AND_BACK, dynState_.stencilCompareMask);
}
if (result.setStencil) {
vkCmdSetStencilReference(cmd, VK_STENCIL_FRONT_AND_BACK, result.stencilValue);
} else if (dynState_.useStencil) {
vkCmdSetStencilReference(cmd, VK_STENCIL_FRONT_AND_BACK, dynState_.stencilRef);
}
if (dynState_.useBlendColor) {
float bc[4];
Uint8x4ToFloat4(bc, dynState_.blendColor);
vkCmdSetBlendConstants(cmd, bc);
}
ApplyDrawStateLate(cmd, result.setStencil, result.stencilValue);

dirtyUniforms_ |= shaderManager_->UpdateUniforms();

shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, useHWTransform);
Expand Down
5 changes: 4 additions & 1 deletion GPU/Vulkan/DrawEngineVulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ typedef u32 ReliableHashType;

class VulkanContext;
class VulkanPushBuffer;
struct VulkanPipeline;

struct DrawEngineVulkanStats {
int pushUBOSpaceUsed;
Expand Down Expand Up @@ -127,7 +128,7 @@ class DrawEngineVulkan : public DrawEngineCommon {

private:
struct FrameData;
void ApplyDrawStateLate();
void ApplyDrawStateLate(VkCommandBuffer cmd, bool applyStencilRef, uint8_t stencilRef);
void ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManager, ShaderManagerVulkan *shaderManager, int prim, VulkanPipelineRasterStateKey &key, VulkanDynamicState &dynState);

void InitDeviceObjects();
Expand All @@ -146,6 +147,8 @@ class DrawEngineVulkan : public DrawEngineCommon {
// We use a single descriptor set layout for all PSP draws.
VkDescriptorSetLayout descriptorSetLayout_;
VkPipelineLayout pipelineLayout_;
VkCommandBuffer lastCmd_ = VK_NULL_HANDLE;
VulkanPipeline *lastPipeline_;

struct DescriptorSetKey {
VkImageView imageView_;
Expand Down
30 changes: 25 additions & 5 deletions GPU/Vulkan/StateMappingVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "Common/Vulkan/VulkanLoader.h"

#include "math/dataconv.h"
#include "GPU/Math3D.h"
#include "GPU/GPUState.h"
#include "GPU/ge_constants.h"
Expand Down Expand Up @@ -132,7 +133,6 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag
bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE;

if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) {
gstate_c.Clean(DIRTY_BLEND_STATE);
// Unfortunately, this isn't implemented yet.
gstate_c.SetAllowShaderBlend(false);
if (gstate.isModeClear()) {
Expand Down Expand Up @@ -235,7 +235,6 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag
}

if (gstate_c.IsDirty(DIRTY_RASTER_STATE)) {
gstate_c.Clean(DIRTY_RASTER_STATE);
if (gstate.isModeClear()) {
key.cullMode = VK_CULL_MODE_NONE;
} else {
Expand All @@ -246,7 +245,6 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag
}

if (gstate_c.IsDirty(DIRTY_DEPTHSTENCIL_STATE)) {
gstate_c.Clean(DIRTY_DEPTHSTENCIL_STATE);
if (gstate.isModeClear()) {
key.depthTestEnable = true;
key.depthCompareOp = VK_COMPARE_OP_ALWAYS;
Expand Down Expand Up @@ -328,7 +326,6 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag
}

if (gstate_c.IsDirty(DIRTY_VIEWPORTSCISSOR_STATE)) {
gstate_c.Clean(DIRTY_VIEWPORTSCISSOR_STATE);
ViewportAndScissor vpAndScissor;
ConvertViewportAndScissor(useBufferedRendering,
fbManager.GetRenderWidth(), fbManager.GetRenderHeight(),
Expand Down Expand Up @@ -373,7 +370,7 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag
}


void DrawEngineVulkan::ApplyDrawStateLate() {
void DrawEngineVulkan::ApplyDrawStateLate(VkCommandBuffer cmd, bool applyStencilRef, uint8_t stencilRef) {
// At this point, we know if the vertices are full alpha or not.
// TODO: Set the nearest/linear here (since we correctly know if alpha/color tests are needed)?
if (!gstate.isModeClear()) {
Expand All @@ -388,4 +385,27 @@ void DrawEngineVulkan::ApplyDrawStateLate() {
}
*/
}

if (gstate_c.IsDirty(DIRTY_VIEWPORTSCISSOR_STATE)) {
vkCmdSetScissor(cmd, 0, 1, &dynState_.scissor);
vkCmdSetViewport(cmd, 0, 1, &dynState_.viewport);
}
if (gstate_c.IsDirty(DIRTY_DEPTHSTENCIL_STATE)) {
if (dynState_.useStencil) {
vkCmdSetStencilWriteMask(cmd, VK_STENCIL_FRONT_AND_BACK, dynState_.stencilWriteMask);
vkCmdSetStencilCompareMask(cmd, VK_STENCIL_FRONT_AND_BACK, dynState_.stencilCompareMask);
if (!applyStencilRef) {
vkCmdSetStencilReference(cmd, VK_STENCIL_FRONT_AND_BACK, dynState_.stencilRef);
}
}
}
if (applyStencilRef) {
vkCmdSetStencilReference(cmd, VK_STENCIL_FRONT_AND_BACK, stencilRef);
}
if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) {
float bc[4];
Uint8x4ToFloat4(bc, dynState_.blendColor);
vkCmdSetBlendConstants(cmd, bc);
}
gstate_c.Clean(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE);
}
14 changes: 7 additions & 7 deletions GPU/ge_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,11 @@ enum GECommand {
GE_CMD_TGENMATRIXNUMBER = 0x40,
GE_CMD_TGENMATRIXDATA = 0x41,
GE_CMD_VIEWPORTXSCALE = 0x42,
GE_CMD_VIEWPORTYSCALE,
GE_CMD_VIEWPORTZSCALE,
GE_CMD_VIEWPORTXCENTER,
GE_CMD_VIEWPORTYCENTER,
GE_CMD_VIEWPORTZCENTER,
GE_CMD_VIEWPORTYSCALE = 0x43,
GE_CMD_VIEWPORTZSCALE = 0x44,
GE_CMD_VIEWPORTXCENTER = 0x45,
GE_CMD_VIEWPORTYCENTER = 0x46,
GE_CMD_VIEWPORTZCENTER = 0x47,
GE_CMD_TEXSCALEU = 0x48,
GE_CMD_TEXSCALEV = 0x49,
GE_CMD_TEXOFFSETU = 0x4A,
Expand Down Expand Up @@ -182,8 +182,8 @@ enum GECommand {
GE_CMD_TEXBUFWIDTH5,
GE_CMD_TEXBUFWIDTH6,
GE_CMD_TEXBUFWIDTH7,
GE_CMD_CLUTADDR=0xB0,
GE_CMD_CLUTADDRUPPER,
GE_CMD_CLUTADDR = 0xB0,
GE_CMD_CLUTADDRUPPER = 0xB1,
GE_CMD_TRANSFERSRC,
GE_CMD_TRANSFERSRCW,
GE_CMD_TRANSFERDST,
Expand Down
2 changes: 1 addition & 1 deletion ext/native/math/dataconv.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include <inttypes.h>
#include <cstdint>
#include <cstring>

#ifdef _M_SSE
Expand Down

0 comments on commit 6a2f876

Please sign in to comment.