mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 21:39:52 +00:00
Vulkan: Don't try to overlap proj with proj_through, will need a different approach.
Also, assorted bugfixes.
This commit is contained in:
parent
5f71b5b3ec
commit
1677697735
@ -494,6 +494,8 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) {
|
|||||||
uint32_t vbOffset = 0;
|
uint32_t vbOffset = 0;
|
||||||
|
|
||||||
if (useHWTransform) {
|
if (useHWTransform) {
|
||||||
|
// We don't detect clears in this path, so here we can switch framebuffers if necessary.
|
||||||
|
|
||||||
int vertexCount = 0;
|
int vertexCount = 0;
|
||||||
int maxIndex = 0;
|
int maxIndex = 0;
|
||||||
bool useElements = true;
|
bool useElements = true;
|
||||||
@ -529,7 +531,7 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) {
|
|||||||
vkCmdSetBlendConstants(cmd_, bc);
|
vkCmdSetBlendConstants(cmd_, bc);
|
||||||
shaderManager_->UpdateUniforms();
|
shaderManager_->UpdateUniforms();
|
||||||
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, useHWTransform);
|
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, useHWTransform);
|
||||||
VulkanPipeline *pipeline = pipelineManager_->GetOrCreatePipeline(pipelineLayout_, pipelineKey, dec_, vshader->GetModule(), fshader->GetModule(), true);
|
VulkanPipeline *pipeline = pipelineManager_->GetOrCreatePipeline(pipelineLayout_, pipelineKey, dec_, vshader, fshader, true);
|
||||||
vkCmdBindPipeline(cmd_, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->pipeline); // TODO: Avoid if same as last draw.
|
vkCmdBindPipeline(cmd_, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->pipeline); // TODO: Avoid if same as last draw.
|
||||||
|
|
||||||
if (pipeline->uniformBlocks & UB_VS_FS_BASE) {
|
if (pipeline->uniformBlocks & UB_VS_FS_BASE) {
|
||||||
@ -548,11 +550,11 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) {
|
|||||||
};
|
};
|
||||||
vkCmdBindDescriptorSets(cmd_, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout_, 0, 1, &ds, 3, dynamicUBOOffsets);
|
vkCmdBindDescriptorSets(cmd_, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout_, 0, 1, &ds, 3, dynamicUBOOffsets);
|
||||||
|
|
||||||
vbOffset = (uint32_t)frame->pushData->Push(decoded, vertexCount * dec_->GetDecVtxFmt().stride);
|
vbOffset = (uint32_t)frame->pushData->PushAligned(decoded, vertexCount * dec_->GetDecVtxFmt().stride, 16);
|
||||||
|
|
||||||
VkDeviceSize offsets[1] = { vbOffset };
|
VkDeviceSize offsets[1] = { vbOffset };
|
||||||
if (useElements) {
|
if (useElements) {
|
||||||
ibOffset = (uint32_t)frame->pushData->Push(decIndex, 2 * indexGen.VertexCount());
|
ibOffset = (uint32_t)frame->pushData->PushAligned(decIndex, 2 * indexGen.VertexCount(), 16);
|
||||||
// TODO: Avoid rebinding vertex/index buffers if the vertex size stays the same by using the offset arguments
|
// TODO: Avoid rebinding vertex/index buffers if the vertex size stays the same by using the offset arguments
|
||||||
// Might want to separate vertices out into a different push buffer in that case.
|
// Might want to separate vertices out into a different push buffer in that case.
|
||||||
vkCmdBindVertexBuffers(cmd_, 0, 1, buf, offsets);
|
vkCmdBindVertexBuffers(cmd_, 0, 1, buf, offsets);
|
||||||
@ -591,6 +593,9 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) {
|
|||||||
dec_->VertexType(), inds, GE_VTYPE_IDX_16BIT, dec_->GetDecVtxFmt(),
|
dec_->VertexType(), inds, GE_VTYPE_IDX_16BIT, dec_->GetDecVtxFmt(),
|
||||||
maxIndex, framebufferManager_, textureCache_, transformed, transformedExpanded, drawBuffer, numTrans, drawIndexed, &result, 1.0f);
|
maxIndex, framebufferManager_, textureCache_, transformed, transformedExpanded, drawBuffer, numTrans, drawIndexed, &result, 1.0f);
|
||||||
|
|
||||||
|
// Only here, where we know whether to clear or to draw primitives, should we actually set the current framebuffer! Because that gives use the opportunity
|
||||||
|
// to use a "pre-clear" render pass, for high efficiency on tilers.
|
||||||
|
|
||||||
if (result.action == SW_DRAW_PRIMITIVES) {
|
if (result.action == SW_DRAW_PRIMITIVES) {
|
||||||
VulkanPipelineRasterStateKey pipelineKey;
|
VulkanPipelineRasterStateKey pipelineKey;
|
||||||
VulkanDynamicState dynState;
|
VulkanDynamicState dynState;
|
||||||
@ -614,7 +619,7 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) {
|
|||||||
vkCmdSetBlendConstants(cmd_, bc);
|
vkCmdSetBlendConstants(cmd_, bc);
|
||||||
shaderManager_->UpdateUniforms();
|
shaderManager_->UpdateUniforms();
|
||||||
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, useHWTransform);
|
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, useHWTransform);
|
||||||
VulkanPipeline *pipeline = pipelineManager_->GetOrCreatePipeline(pipelineLayout_, pipelineKey, dec_, vshader->GetModule(), fshader->GetModule(), false);
|
VulkanPipeline *pipeline = pipelineManager_->GetOrCreatePipeline(pipelineLayout_, pipelineKey, dec_, vshader, fshader, false);
|
||||||
vkCmdBindPipeline(cmd_, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->pipeline); // TODO: Avoid if same as last draw.
|
vkCmdBindPipeline(cmd_, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->pipeline); // TODO: Avoid if same as last draw.
|
||||||
|
|
||||||
if (pipeline->uniformBlocks & UB_VS_FS_BASE) {
|
if (pipeline->uniformBlocks & UB_VS_FS_BASE) {
|
||||||
|
@ -320,7 +320,7 @@ static const CommandTableEntry commandTable[] = {
|
|||||||
{ GE_CMD_BOUNDINGBOX, FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_BoundingBox }, // + FLUSHBEFORE when we implement... or not, do we need to?
|
{ GE_CMD_BOUNDINGBOX, FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_BoundingBox }, // + FLUSHBEFORE when we implement... or not, do we need to?
|
||||||
|
|
||||||
// Changing the vertex type requires us to flush.
|
// Changing the vertex type requires us to flush.
|
||||||
{ GE_CMD_VERTEXTYPE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, DIRTY_PROJMATRIX, &GPU_Vulkan::Execute_VertexType },
|
{ GE_CMD_VERTEXTYPE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPU_Vulkan::Execute_VertexType },
|
||||||
|
|
||||||
{ GE_CMD_BEZIER, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_Bezier },
|
{ GE_CMD_BEZIER, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_Bezier },
|
||||||
{ GE_CMD_SPLINE, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_Spline },
|
{ GE_CMD_SPLINE, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_Spline },
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "Common/StringUtils.h"
|
#include "Common/StringUtils.h"
|
||||||
#include "GPU/Vulkan/VulkanUtil.h"
|
#include "GPU/Vulkan/VulkanUtil.h"
|
||||||
#include "GPU/Vulkan/PipelineManagerVulkan.h"
|
#include "GPU/Vulkan/PipelineManagerVulkan.h"
|
||||||
|
#include "GPU/Vulkan/ShaderManagerVulkan.h"
|
||||||
// #include "GPU/Vulkan/"
|
// #include "GPU/Vulkan/"
|
||||||
#include "thin3d/VulkanContext.h"
|
#include "thin3d/VulkanContext.h"
|
||||||
|
|
||||||
@ -285,12 +286,12 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip
|
|||||||
return vulkanPipeline;
|
return vulkanPipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
VulkanPipeline *PipelineManagerVulkan::GetOrCreatePipeline(VkPipelineLayout layout, const VulkanPipelineRasterStateKey &rasterKey, const VertexDecoder *vtxDec, VkShaderModule vShader, VkShaderModule fShader, bool useHwTransform) {
|
VulkanPipeline *PipelineManagerVulkan::GetOrCreatePipeline(VkPipelineLayout layout, const VulkanPipelineRasterStateKey &rasterKey, const VertexDecoder *vtxDec, VulkanVertexShader *vs, VulkanFragmentShader *fs, bool useHwTransform) {
|
||||||
VulkanPipelineKey key;
|
VulkanPipelineKey key;
|
||||||
key.raster = rasterKey;
|
key.raster = rasterKey;
|
||||||
key.useHWTransform = useHwTransform;
|
key.useHWTransform = useHwTransform;
|
||||||
key.vShader = vShader;
|
key.vShader = vs->GetModule();
|
||||||
key.fShader = fShader;
|
key.fShader = fs->GetModule();
|
||||||
key.vtxDec = vtxDec;
|
key.vtxDec = vtxDec;
|
||||||
auto iter = pipelines_.find(key);
|
auto iter = pipelines_.find(key);
|
||||||
if (iter != pipelines_.end()) {
|
if (iter != pipelines_.end()) {
|
||||||
@ -299,7 +300,7 @@ VulkanPipeline *PipelineManagerVulkan::GetOrCreatePipeline(VkPipelineLayout layo
|
|||||||
|
|
||||||
VulkanPipeline *pipeline = CreateVulkanPipeline(
|
VulkanPipeline *pipeline = CreateVulkanPipeline(
|
||||||
vulkan_->GetDevice(), pipelineCache_, layout, vulkan_->GetSurfaceRenderPass(),
|
vulkan_->GetDevice(), pipelineCache_, layout, vulkan_->GetSurfaceRenderPass(),
|
||||||
rasterKey, vtxDec, vShader, fShader, useHwTransform);
|
rasterKey, vtxDec, key.vShader, key.fShader, useHwTransform);
|
||||||
pipelines_[key] = pipeline;
|
pipelines_[key] = pipeline;
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
@ -74,13 +74,15 @@ struct VulkanPipeline {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class VulkanContext;
|
class VulkanContext;
|
||||||
|
class VulkanVertexShader;
|
||||||
|
class VulkanFragmentShader;
|
||||||
|
|
||||||
class PipelineManagerVulkan {
|
class PipelineManagerVulkan {
|
||||||
public:
|
public:
|
||||||
PipelineManagerVulkan(VulkanContext *ctx);
|
PipelineManagerVulkan(VulkanContext *ctx);
|
||||||
~PipelineManagerVulkan();
|
~PipelineManagerVulkan();
|
||||||
|
|
||||||
VulkanPipeline *GetOrCreatePipeline(VkPipelineLayout layout, const VulkanPipelineRasterStateKey &rasterKey, const VertexDecoder *vtxDec, VkShaderModule vShader, VkShaderModule fShader, bool useHwTransform);
|
VulkanPipeline *GetOrCreatePipeline(VkPipelineLayout layout, const VulkanPipelineRasterStateKey &rasterKey, const VertexDecoder *vtxDec, VulkanVertexShader *vs, VulkanFragmentShader *fs, bool useHwTransform);
|
||||||
int GetNumPipelines() const { return (int)pipelines_.size(); }
|
int GetNumPipelines() const { return (int)pipelines_.size(); }
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
|
@ -249,7 +249,7 @@ void ShaderManagerVulkan::BaseUpdateUniforms(int dirtyUniforms) {
|
|||||||
Matrix4x4 proj_through;
|
Matrix4x4 proj_through;
|
||||||
proj_through.setOrtho(0.0f, gstate_c.curRTWidth, 0, gstate_c.curRTHeight, 0, 1);
|
proj_through.setOrtho(0.0f, gstate_c.curRTWidth, 0, gstate_c.curRTHeight, 0, 1);
|
||||||
ConvertProjMatrixToVulkanThrough(proj_through);
|
ConvertProjMatrixToVulkanThrough(proj_through);
|
||||||
CopyMatrix4x4(ub_base.proj, proj_through.getReadPtr());
|
CopyMatrix4x4(ub_base.proj_through, proj_through.getReadPtr());
|
||||||
} else {
|
} else {
|
||||||
Matrix4x4 flippedMatrix;
|
Matrix4x4 flippedMatrix;
|
||||||
memcpy(&flippedMatrix, gstate.projMatrix, 16 * sizeof(float));
|
memcpy(&flippedMatrix, gstate.projMatrix, 16 * sizeof(float));
|
||||||
|
@ -34,7 +34,7 @@ void ConvertProjMatrixToVulkan(Matrix4x4 & in);
|
|||||||
// Pretty much full. Will need more bits for more fine grained dirty tracking for lights.
|
// Pretty much full. Will need more bits for more fine grained dirty tracking for lights.
|
||||||
enum {
|
enum {
|
||||||
DIRTY_PROJMATRIX = (1 << 0),
|
DIRTY_PROJMATRIX = (1 << 0),
|
||||||
// 1 << 1 is free
|
DIRTY_PROJTHROUGHMATRIX = (1 << 1),
|
||||||
DIRTY_FOGCOLOR = (1 << 2),
|
DIRTY_FOGCOLOR = (1 << 2),
|
||||||
DIRTY_FOGCOEF = (1 << 3),
|
DIRTY_FOGCOEF = (1 << 3),
|
||||||
DIRTY_TEXENV = (1 << 4),
|
DIRTY_TEXENV = (1 << 4),
|
||||||
@ -82,8 +82,10 @@ enum {
|
|||||||
DIRTY_ALL = 0xFFFFFFFF
|
DIRTY_ALL = 0xFFFFFFFF
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: Split into two structs, one for software transform and one for hardware transform, to save space.
|
||||||
struct UB_VS_FS_Base {
|
struct UB_VS_FS_Base {
|
||||||
float proj[16];
|
float proj[16];
|
||||||
|
float proj_through[16];
|
||||||
float view[16];
|
float view[16];
|
||||||
float world[16];
|
float world[16];
|
||||||
float tex[16]; // not that common, may want to break out
|
float tex[16]; // not that common, may want to break out
|
||||||
@ -104,7 +106,8 @@ struct UB_VS_FS_Base {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const char *ub_baseStr =
|
static const char *ub_baseStr =
|
||||||
R"( mat4 proj_mtx;
|
R"( mat4 proj_mtx;
|
||||||
|
mat4 proj_through_mtx;
|
||||||
mat4 view_mtx;
|
mat4 view_mtx;
|
||||||
mat4 world_mtx;
|
mat4 world_mtx;
|
||||||
mat4 tex_mtx;
|
mat4 tex_mtx;
|
||||||
|
@ -172,13 +172,13 @@ void ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManager, ShaderManagerV
|
|||||||
key.depthCompareOp = VK_COMPARE_OP_ALWAYS;
|
key.depthCompareOp = VK_COMPARE_OP_ALWAYS;
|
||||||
key.depthWriteEnable = gstate.isClearModeDepthMask();
|
key.depthWriteEnable = gstate.isClearModeDepthMask();
|
||||||
if (gstate.isClearModeDepthMask()) {
|
if (gstate.isClearModeDepthMask()) {
|
||||||
// framebufferManager_->SetDepthUpdated();
|
fbManager.SetDepthUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Color Test
|
// Color Test
|
||||||
bool colorMask = gstate.isClearModeColorMask();
|
bool colorMask = gstate.isClearModeColorMask();
|
||||||
bool alphaMask = gstate.isClearModeAlphaMask();
|
bool alphaMask = gstate.isClearModeAlphaMask();
|
||||||
key.colorWriteMask = (colorMask ? (VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_A_BIT) : 0) | (alphaMask ? VK_COLOR_COMPONENT_A_BIT : 0);
|
key.colorWriteMask = (colorMask ? (VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT) : 0) | (alphaMask ? VK_COLOR_COMPONENT_A_BIT : 0);
|
||||||
|
|
||||||
GenericStencilFuncState stencilState;
|
GenericStencilFuncState stencilState;
|
||||||
ConvertStencilFuncState(stencilState);
|
ConvertStencilFuncState(stencilState);
|
||||||
|
@ -34,7 +34,7 @@ struct VulkanPipelineRasterStateKey {
|
|||||||
unsigned int blendOpAlpha : 3; // VkBlendOp
|
unsigned int blendOpAlpha : 3; // VkBlendOp
|
||||||
bool logicOpEnable : 1;
|
bool logicOpEnable : 1;
|
||||||
unsigned int logicOp : 4; // VkLogicOp
|
unsigned int logicOp : 4; // VkLogicOp
|
||||||
int colorWriteMask : 4;
|
unsigned int colorWriteMask : 4;
|
||||||
|
|
||||||
// Depth/Stencil
|
// Depth/Stencil
|
||||||
bool depthTestEnable : 1;
|
bool depthTestEnable : 1;
|
||||||
|
@ -242,7 +242,7 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer) {
|
|||||||
WRITE(p, " v_fogdepth = position.w;\n");
|
WRITE(p, " v_fogdepth = position.w;\n");
|
||||||
}
|
}
|
||||||
if (isModeThrough) {
|
if (isModeThrough) {
|
||||||
WRITE(p, " gl_Position = base.proj_mtx * vec4(position.xyz, 1.0);\n");
|
WRITE(p, " gl_Position = base.proj_through_mtx * vec4(position.xyz, 1.0);\n");
|
||||||
} else {
|
} else {
|
||||||
// The viewport is used in this case, so need to compensate for that.
|
// The viewport is used in this case, so need to compensate for that.
|
||||||
if (gstate_c.Supports(GPU_ROUND_DEPTH_TO_16BIT)) {
|
if (gstate_c.Supports(GPU_ROUND_DEPTH_TO_16BIT)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user