mirror of https://github.com/xemu-project/xemu.git
nv2a/vk: Set line width state dynamically
This commit is contained in:
parent
d8afb35c40
commit
df1ac31eb2
|
@ -20,6 +20,7 @@
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/fast-hash.h"
|
#include "qemu/fast-hash.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
void pgraph_vk_draw_begin(NV2AState *d)
|
void pgraph_vk_draw_begin(NV2AState *d)
|
||||||
{
|
{
|
||||||
|
@ -810,21 +811,13 @@ static void create_pipeline(PGRAPHState *pg)
|
||||||
// FIXME: Handle in shader?
|
// FIXME: Handle in shader?
|
||||||
}
|
}
|
||||||
|
|
||||||
float lineWidth = 1.0f;
|
|
||||||
if(r->physical_device_features.wideLines == VK_TRUE)
|
|
||||||
{
|
|
||||||
lineWidth = MIN(r->device_props.limits.lineWidthRange[1],
|
|
||||||
MAX(r->device_props.limits.lineWidthRange[0],
|
|
||||||
(float)pg->surface_scale_factor));
|
|
||||||
}
|
|
||||||
|
|
||||||
VkPipelineRasterizationStateCreateInfo rasterizer = {
|
VkPipelineRasterizationStateCreateInfo rasterizer = {
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
|
||||||
.depthClampEnable = VK_TRUE,
|
.depthClampEnable = VK_TRUE,
|
||||||
.rasterizerDiscardEnable = VK_FALSE,
|
.rasterizerDiscardEnable = VK_FALSE,
|
||||||
.polygonMode = pgraph_polygon_mode_vk_map[r->shader_binding->state
|
.polygonMode = pgraph_polygon_mode_vk_map[r->shader_binding->state
|
||||||
.polygon_front_mode],
|
.polygon_front_mode],
|
||||||
.lineWidth = lineWidth,
|
.lineWidth = 1.0f,
|
||||||
.frontFace = (pgraph_reg_r(pg, NV_PGRAPH_SETUPRASTER) &
|
.frontFace = (pgraph_reg_r(pg, NV_PGRAPH_SETUPRASTER) &
|
||||||
NV_PGRAPH_SETUPRASTER_FRONTFACE) ?
|
NV_PGRAPH_SETUPRASTER_FRONTFACE) ?
|
||||||
VK_FRONT_FACE_COUNTER_CLOCKWISE :
|
VK_FRONT_FACE_COUNTER_CLOCKWISE :
|
||||||
|
@ -953,12 +946,23 @@ static void create_pipeline(PGRAPHState *pg)
|
||||||
.blendConstants[3] = blend_constant[3],
|
.blendConstants[3] = blend_constant[3],
|
||||||
};
|
};
|
||||||
|
|
||||||
VkDynamicState dynamic_states[2] = { VK_DYNAMIC_STATE_VIEWPORT,
|
VkDynamicState dynamic_states[3] = { VK_DYNAMIC_STATE_VIEWPORT,
|
||||||
VK_DYNAMIC_STATE_SCISSOR };
|
VK_DYNAMIC_STATE_SCISSOR };
|
||||||
|
int num_dynamic_states = 2;
|
||||||
|
|
||||||
|
snode->has_dynamic_line_width =
|
||||||
|
(r->physical_device_features.wideLines == VK_TRUE)
|
||||||
|
&& (r->shader_binding->state.polygon_front_mode == POLY_MODE_LINE ||
|
||||||
|
r->shader_binding->state.primitive_mode == PRIM_TYPE_LINES ||
|
||||||
|
r->shader_binding->state.primitive_mode == PRIM_TYPE_LINE_LOOP ||
|
||||||
|
r->shader_binding->state.primitive_mode == PRIM_TYPE_LINE_STRIP);
|
||||||
|
if (snode->has_dynamic_line_width) {
|
||||||
|
dynamic_states[num_dynamic_states++] = VK_DYNAMIC_STATE_LINE_WIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
VkPipelineDynamicStateCreateInfo dynamic_state = {
|
VkPipelineDynamicStateCreateInfo dynamic_state = {
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
|
||||||
.dynamicStateCount = ARRAY_SIZE(dynamic_states),
|
.dynamicStateCount = num_dynamic_states,
|
||||||
.pDynamicStates = dynamic_states,
|
.pDynamicStates = dynamic_states,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1428,6 +1432,21 @@ static void begin_pre_draw(PGRAPHState *pg)
|
||||||
pgraph_vk_ensure_command_buffer(pg);
|
pgraph_vk_ensure_command_buffer(pg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float clamp_line_width_to_device_limits(PGRAPHState *pg, float width)
|
||||||
|
{
|
||||||
|
PGRAPHVkState *r = pg->vk_renderer_state;
|
||||||
|
|
||||||
|
float min_width = r->device_props.limits.lineWidthRange[0];
|
||||||
|
float max_width = r->device_props.limits.lineWidthRange[1];
|
||||||
|
float granularity = r->device_props.limits.lineWidthGranularity;
|
||||||
|
|
||||||
|
if (granularity != 0.0f) {
|
||||||
|
float steps = roundf((width - min_width) / granularity);
|
||||||
|
width = min_width + steps * granularity;
|
||||||
|
}
|
||||||
|
return fminf(fmaxf(min_width, width), max_width);
|
||||||
|
}
|
||||||
|
|
||||||
static void begin_draw(PGRAPHState *pg)
|
static void begin_draw(PGRAPHState *pg)
|
||||||
{
|
{
|
||||||
PGRAPHVkState *r = pg->vk_renderer_state;
|
PGRAPHVkState *r = pg->vk_renderer_state;
|
||||||
|
@ -1499,6 +1518,12 @@ static void begin_draw(PGRAPHState *pg)
|
||||||
.extent.height = scissor_height,
|
.extent.height = scissor_height,
|
||||||
};
|
};
|
||||||
vkCmdSetScissor(r->command_buffer, 0, 1, &scissor);
|
vkCmdSetScissor(r->command_buffer, 0, 1, &scissor);
|
||||||
|
|
||||||
|
if (r->pipeline_binding->has_dynamic_line_width) {
|
||||||
|
float line_width =
|
||||||
|
clamp_line_width_to_device_limits(pg, pg->surface_scale_factor);
|
||||||
|
vkCmdSetLineWidth(r->command_buffer, line_width);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pg->clearing) {
|
if (!pg->clearing) {
|
||||||
|
|
|
@ -77,6 +77,7 @@ typedef struct PipelineBinding {
|
||||||
VkPipeline pipeline;
|
VkPipeline pipeline;
|
||||||
VkRenderPass render_pass;
|
VkRenderPass render_pass;
|
||||||
unsigned int draw_time;
|
unsigned int draw_time;
|
||||||
|
bool has_dynamic_line_width;
|
||||||
} PipelineBinding;
|
} PipelineBinding;
|
||||||
|
|
||||||
enum Buffer {
|
enum Buffer {
|
||||||
|
|
Loading…
Reference in New Issue