mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +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;
|
||||
|
||||
if (useHWTransform) {
|
||||
// We don't detect clears in this path, so here we can switch framebuffers if necessary.
|
||||
|
||||
int vertexCount = 0;
|
||||
int maxIndex = 0;
|
||||
bool useElements = true;
|
||||
@ -529,7 +531,7 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) {
|
||||
vkCmdSetBlendConstants(cmd_, bc);
|
||||
shaderManager_->UpdateUniforms();
|
||||
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.
|
||||
|
||||
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);
|
||||
|
||||
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 };
|
||||
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
|
||||
// Might want to separate vertices out into a different push buffer in that case.
|
||||
vkCmdBindVertexBuffers(cmd_, 0, 1, buf, offsets);
|
||||
@ -591,6 +593,9 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) {
|
||||
dec_->VertexType(), inds, GE_VTYPE_IDX_16BIT, dec_->GetDecVtxFmt(),
|
||||
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) {
|
||||
VulkanPipelineRasterStateKey pipelineKey;
|
||||
VulkanDynamicState dynState;
|
||||
@ -614,7 +619,7 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) {
|
||||
vkCmdSetBlendConstants(cmd_, bc);
|
||||
shaderManager_->UpdateUniforms();
|
||||
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.
|
||||
|
||||
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?
|
||||
|
||||
// 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_SPLINE, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_Spline },
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "Common/StringUtils.h"
|
||||
#include "GPU/Vulkan/VulkanUtil.h"
|
||||
#include "GPU/Vulkan/PipelineManagerVulkan.h"
|
||||
#include "GPU/Vulkan/ShaderManagerVulkan.h"
|
||||
// #include "GPU/Vulkan/"
|
||||
#include "thin3d/VulkanContext.h"
|
||||
|
||||
@ -285,12 +286,12 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip
|
||||
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;
|
||||
key.raster = rasterKey;
|
||||
key.useHWTransform = useHwTransform;
|
||||
key.vShader = vShader;
|
||||
key.fShader = fShader;
|
||||
key.vShader = vs->GetModule();
|
||||
key.fShader = fs->GetModule();
|
||||
key.vtxDec = vtxDec;
|
||||
auto iter = pipelines_.find(key);
|
||||
if (iter != pipelines_.end()) {
|
||||
@ -299,7 +300,7 @@ VulkanPipeline *PipelineManagerVulkan::GetOrCreatePipeline(VkPipelineLayout layo
|
||||
|
||||
VulkanPipeline *pipeline = CreateVulkanPipeline(
|
||||
vulkan_->GetDevice(), pipelineCache_, layout, vulkan_->GetSurfaceRenderPass(),
|
||||
rasterKey, vtxDec, vShader, fShader, useHwTransform);
|
||||
rasterKey, vtxDec, key.vShader, key.fShader, useHwTransform);
|
||||
pipelines_[key] = pipeline;
|
||||
return pipeline;
|
||||
}
|
||||
|
@ -74,13 +74,15 @@ struct VulkanPipeline {
|
||||
};
|
||||
|
||||
class VulkanContext;
|
||||
class VulkanVertexShader;
|
||||
class VulkanFragmentShader;
|
||||
|
||||
class PipelineManagerVulkan {
|
||||
public:
|
||||
PipelineManagerVulkan(VulkanContext *ctx);
|
||||
~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(); }
|
||||
|
||||
void Clear();
|
||||
|
@ -249,7 +249,7 @@ void ShaderManagerVulkan::BaseUpdateUniforms(int dirtyUniforms) {
|
||||
Matrix4x4 proj_through;
|
||||
proj_through.setOrtho(0.0f, gstate_c.curRTWidth, 0, gstate_c.curRTHeight, 0, 1);
|
||||
ConvertProjMatrixToVulkanThrough(proj_through);
|
||||
CopyMatrix4x4(ub_base.proj, proj_through.getReadPtr());
|
||||
CopyMatrix4x4(ub_base.proj_through, proj_through.getReadPtr());
|
||||
} else {
|
||||
Matrix4x4 flippedMatrix;
|
||||
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.
|
||||
enum {
|
||||
DIRTY_PROJMATRIX = (1 << 0),
|
||||
// 1 << 1 is free
|
||||
DIRTY_PROJTHROUGHMATRIX = (1 << 1),
|
||||
DIRTY_FOGCOLOR = (1 << 2),
|
||||
DIRTY_FOGCOEF = (1 << 3),
|
||||
DIRTY_TEXENV = (1 << 4),
|
||||
@ -82,8 +82,10 @@ enum {
|
||||
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 {
|
||||
float proj[16];
|
||||
float proj_through[16];
|
||||
float view[16];
|
||||
float world[16];
|
||||
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 =
|
||||
R"( mat4 proj_mtx;
|
||||
R"( mat4 proj_mtx;
|
||||
mat4 proj_through_mtx;
|
||||
mat4 view_mtx;
|
||||
mat4 world_mtx;
|
||||
mat4 tex_mtx;
|
||||
|
@ -172,13 +172,13 @@ void ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManager, ShaderManagerV
|
||||
key.depthCompareOp = VK_COMPARE_OP_ALWAYS;
|
||||
key.depthWriteEnable = gstate.isClearModeDepthMask();
|
||||
if (gstate.isClearModeDepthMask()) {
|
||||
// framebufferManager_->SetDepthUpdated();
|
||||
fbManager.SetDepthUpdated();
|
||||
}
|
||||
|
||||
// Color Test
|
||||
bool colorMask = gstate.isClearModeColorMask();
|
||||
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;
|
||||
ConvertStencilFuncState(stencilState);
|
||||
|
@ -34,7 +34,7 @@ struct VulkanPipelineRasterStateKey {
|
||||
unsigned int blendOpAlpha : 3; // VkBlendOp
|
||||
bool logicOpEnable : 1;
|
||||
unsigned int logicOp : 4; // VkLogicOp
|
||||
int colorWriteMask : 4;
|
||||
unsigned int colorWriteMask : 4;
|
||||
|
||||
// Depth/Stencil
|
||||
bool depthTestEnable : 1;
|
||||
|
@ -242,7 +242,7 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer) {
|
||||
WRITE(p, " v_fogdepth = position.w;\n");
|
||||
}
|
||||
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 {
|
||||
// The viewport is used in this case, so need to compensate for that.
|
||||
if (gstate_c.Supports(GPU_ROUND_DEPTH_TO_16BIT)) {
|
||||
|
Loading…
Reference in New Issue
Block a user