Implement Maxwell3D Point Sprite Size

Implements register state that corresponds to the size of a single point sprite in Maxwell 3D, this is emitted by the shader compiler in the preamble but needs to be only applied if the input topology is a point primitive and it is invalid to set the point size in any other case.
This commit is contained in:
PixelyIon 2022-05-07 03:22:21 +05:30
parent 874a6a2a6c
commit ad989750fc
2 changed files with 23 additions and 0 deletions

View File

@ -1064,6 +1064,10 @@ namespace skyline::gpu::interconnect {
if (!pipelineStage.enabled)
continue;
auto fixedPointSize{runtimeInfo.fixed_state_point_size};
if (fixedPointSize && pipelineStage.vkStage != vk::ShaderStageFlagBits::eVertex && pipelineStage.vkStage != vk::ShaderStageFlagBits::eGeometry)
runtimeInfo.fixed_state_point_size.reset(); // Only vertex/geometry stages are allowed to have a point size
if (pipelineStage.needsRecompile || bindings.unified != pipelineStage.bindingBase || pipelineStage.previousStageStores.mask != runtimeInfo.previous_stage_stores.mask) {
pipelineStage.previousStageStores = runtimeInfo.previous_stage_stores;
pipelineStage.bindingBase = bindings.unified;
@ -1071,6 +1075,8 @@ namespace skyline::gpu::interconnect {
pipelineStage.bindingLast = bindings.unified;
}
runtimeInfo.fixed_state_point_size = fixedPointSize;
auto &program{pipelineStage.program->program};
runtimeInfo.previous_stage_stores = program.info.stores;
if (program.is_geometry_passthrough)
@ -1844,6 +1850,7 @@ namespace skyline::gpu::interconnect {
/* Input Assembly */
private:
vk::PipelineInputAssemblyStateCreateInfo inputAssemblyState{};
float pointSpriteSize{}; //!< The size of a point sprite to be defined in the shader
void ValidatePrimitiveRestartState() {
if (inputAssemblyState.primitiveRestartEnable) {
@ -1907,6 +1914,12 @@ namespace skyline::gpu::interconnect {
inputAssemblyState.topology = vkTopology;
needsQuadConversion = isQuad;
if (shaderTopology == ShaderCompiler::InputTopology::Points)
UpdateRuntimeInformation(runtimeInfo.fixed_state_point_size, std::make_optional(pointSpriteSize), maxwell3d::PipelineStage::Vertex, maxwell3d::PipelineStage::Geometry);
else if (runtimeInfo.input_topology == ShaderCompiler::InputTopology::Points)
UpdateRuntimeInformation(runtimeInfo.fixed_state_point_size, std::optional<float>{}, maxwell3d::PipelineStage::Vertex, maxwell3d::PipelineStage::Geometry);
UpdateRuntimeInformation(runtimeInfo.input_topology, shaderTopology, maxwell3d::PipelineStage::Geometry);
}
@ -1914,6 +1927,12 @@ namespace skyline::gpu::interconnect {
inputAssemblyState.primitiveRestartEnable = enable;
}
void SetPointSpriteSize(float size) {
pointSpriteSize = size;
if (runtimeInfo.input_topology == ShaderCompiler::InputTopology::Points)
UpdateRuntimeInformation(runtimeInfo.fixed_state_point_size, std::make_optional(size), maxwell3d::PipelineStage::Vertex, maxwell3d::PipelineStage::Geometry);
}
/* Tessellation */
private:
vk::PipelineTessellationStateCreateInfo tessellationState{};

View File

@ -101,6 +101,10 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
static_assert(type::RenderTargetCount == 8 && type::RenderTargetCount < BOOST_PP_LIMIT_REPEAT);
#undef RENDER_TARGET_ARRAY
ENGINE_CASE(pointSpriteSize, {
context.SetPointSpriteSize(pointSpriteSize);
})
ENGINE_CASE(depthTargetEnable, {
context.SetDepthRenderTargetEnabled(depthTargetEnable);
})