wined3d: Add support for setting multiple viewports.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
8bfb4e8b62
commit
853f6538e4
|
@ -979,7 +979,7 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_RSSetViewports(ID3D11Devic
|
|||
wined3d_vp.max_z = viewports[0].MaxDepth;
|
||||
|
||||
wined3d_mutex_lock();
|
||||
wined3d_device_set_viewport(device->wined3d_device, &wined3d_vp);
|
||||
wined3d_device_set_viewports(device->wined3d_device, 1, &wined3d_vp);
|
||||
wined3d_mutex_unlock();
|
||||
}
|
||||
|
||||
|
@ -4167,7 +4167,7 @@ static void STDMETHODCALLTYPE d3d10_device_RSSetViewports(ID3D10Device1 *iface,
|
|||
wined3d_vp.max_z = viewports[0].MaxDepth;
|
||||
|
||||
wined3d_mutex_lock();
|
||||
wined3d_device_set_viewport(device->wined3d_device, &wined3d_vp);
|
||||
wined3d_device_set_viewports(device->wined3d_device, 1, &wined3d_vp);
|
||||
wined3d_mutex_unlock();
|
||||
}
|
||||
|
||||
|
|
|
@ -1650,7 +1650,7 @@ static HRESULT WINAPI d3d8_device_SetViewport(IDirect3DDevice8 *iface, const D3D
|
|||
vp.min_z = viewport->MinZ;
|
||||
vp.max_z = viewport->MaxZ;
|
||||
|
||||
wined3d_device_set_viewport(device->wined3d_device, &vp);
|
||||
wined3d_device_set_viewports(device->wined3d_device, 1, &vp);
|
||||
wined3d_mutex_unlock();
|
||||
|
||||
return D3D_OK;
|
||||
|
|
|
@ -2068,7 +2068,7 @@ static HRESULT WINAPI d3d9_device_SetViewport(IDirect3DDevice9Ex *iface, const D
|
|||
vp.max_z = viewport->MaxZ;
|
||||
|
||||
wined3d_mutex_lock();
|
||||
wined3d_device_set_viewport(device->wined3d_device, &vp);
|
||||
wined3d_device_set_viewports(device->wined3d_device, 1, &vp);
|
||||
wined3d_mutex_unlock();
|
||||
|
||||
return D3D_OK;
|
||||
|
|
|
@ -5333,7 +5333,7 @@ static HRESULT d3d_device7_SetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *vi
|
|||
vp.min_z = viewport->dvMinZ;
|
||||
vp.max_z = viewport->dvMaxZ;
|
||||
|
||||
wined3d_device_set_viewport(device->wined3d_device, &vp);
|
||||
wined3d_device_set_viewports(device->wined3d_device, 1, &vp);
|
||||
wined3d_mutex_unlock();
|
||||
|
||||
return D3D_OK;
|
||||
|
|
|
@ -611,7 +611,7 @@ static void shader_arb_vs_local_constants(const struct arb_vs_compiled_shader *g
|
|||
unsigned char i;
|
||||
|
||||
/* Upload the position fixup */
|
||||
shader_get_position_fixup(context, state, position_fixup);
|
||||
shader_get_position_fixup(context, state, 1, position_fixup);
|
||||
GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, gl_shader->pos_fixup, position_fixup));
|
||||
|
||||
if (!gl_shader->num_int_consts) return;
|
||||
|
|
|
@ -33,7 +33,7 @@ enum wined3d_cs_op
|
|||
WINED3D_CS_OP_DRAW,
|
||||
WINED3D_CS_OP_FLUSH,
|
||||
WINED3D_CS_OP_SET_PREDICATION,
|
||||
WINED3D_CS_OP_SET_VIEWPORT,
|
||||
WINED3D_CS_OP_SET_VIEWPORTS,
|
||||
WINED3D_CS_OP_SET_SCISSOR_RECT,
|
||||
WINED3D_CS_OP_SET_RENDERTARGET_VIEW,
|
||||
WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW,
|
||||
|
@ -138,10 +138,11 @@ struct wined3d_cs_set_predication
|
|||
BOOL value;
|
||||
};
|
||||
|
||||
struct wined3d_cs_set_viewport
|
||||
struct wined3d_cs_set_viewports
|
||||
{
|
||||
enum wined3d_cs_op opcode;
|
||||
struct wined3d_viewport viewport;
|
||||
unsigned int viewport_count;
|
||||
struct wined3d_viewport viewports[1];
|
||||
};
|
||||
|
||||
struct wined3d_cs_set_scissor_rect
|
||||
|
@ -530,7 +531,7 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *
|
|||
{
|
||||
unsigned int rt_count = cs->device->adapter->gl_info.limits.buffers;
|
||||
const struct wined3d_state *state = &cs->device->state;
|
||||
const struct wined3d_viewport *vp = &state->viewport;
|
||||
const struct wined3d_viewport *vp = &state->viewports[0];
|
||||
struct wined3d_rendertarget_view *view;
|
||||
struct wined3d_cs_clear *op;
|
||||
RECT view_rect;
|
||||
|
@ -961,21 +962,29 @@ void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query
|
|||
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
|
||||
}
|
||||
|
||||
static void wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data)
|
||||
static void wined3d_cs_exec_set_viewports(struct wined3d_cs *cs, const void *data)
|
||||
{
|
||||
const struct wined3d_cs_set_viewport *op = data;
|
||||
const struct wined3d_cs_set_viewports *op = data;
|
||||
|
||||
cs->state.viewport = op->viewport;
|
||||
if (op->viewport_count)
|
||||
memcpy(cs->state.viewports, op->viewports, op->viewport_count * sizeof(*op->viewports));
|
||||
else
|
||||
memset(cs->state.viewports, 0, sizeof(*cs->state.viewports));
|
||||
cs->state.viewport_count = op->viewport_count;
|
||||
device_invalidate_state(cs->device, STATE_VIEWPORT);
|
||||
}
|
||||
|
||||
void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport)
|
||||
void wined3d_cs_emit_set_viewports(struct wined3d_cs *cs, unsigned int viewport_count,
|
||||
const struct wined3d_viewport *viewports)
|
||||
{
|
||||
struct wined3d_cs_set_viewport *op;
|
||||
struct wined3d_cs_set_viewports *op;
|
||||
|
||||
op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
|
||||
op->opcode = WINED3D_CS_OP_SET_VIEWPORT;
|
||||
op->viewport = *viewport;
|
||||
op = cs->ops->require_space(cs, FIELD_OFFSET(struct wined3d_cs_set_viewports, viewports[viewport_count]),
|
||||
WINED3D_CS_QUEUE_DEFAULT);
|
||||
op->opcode = WINED3D_CS_OP_SET_VIEWPORTS;
|
||||
if (viewport_count)
|
||||
memcpy(op->viewports, viewports, viewport_count * sizeof(*viewports));
|
||||
op->viewport_count = viewport_count;
|
||||
|
||||
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
|
||||
}
|
||||
|
@ -2401,7 +2410,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
|
|||
/* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw,
|
||||
/* WINED3D_CS_OP_FLUSH */ wined3d_cs_exec_flush,
|
||||
/* WINED3D_CS_OP_SET_PREDICATION */ wined3d_cs_exec_set_predication,
|
||||
/* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport,
|
||||
/* WINED3D_CS_OP_SET_VIEWPORTS */ wined3d_cs_exec_set_viewports,
|
||||
/* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect,
|
||||
/* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view,
|
||||
/* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view,
|
||||
|
|
|
@ -1910,13 +1910,24 @@ INT CDECL wined3d_device_get_base_vertex_index(const struct wined3d_device *devi
|
|||
return device->state.base_vertex_index;
|
||||
}
|
||||
|
||||
void CDECL wined3d_device_set_viewport(struct wined3d_device *device, const struct wined3d_viewport *viewport)
|
||||
void CDECL wined3d_device_set_viewports(struct wined3d_device *device, unsigned int viewport_count,
|
||||
const struct wined3d_viewport *viewports)
|
||||
{
|
||||
TRACE("device %p, viewport %p.\n", device, viewport);
|
||||
TRACE("x %.8e, y %.8e, w %.8e, h %.8e, min_z %.8e, max_z %.8e.\n",
|
||||
viewport->x, viewport->y, viewport->width, viewport->height, viewport->min_z, viewport->max_z);
|
||||
unsigned int i;
|
||||
|
||||
device->update_state->viewport = *viewport;
|
||||
TRACE("device %p, viewport_count %u, viewports %p.\n", device, viewport_count, viewports);
|
||||
|
||||
for (i = 0; i < viewport_count; ++i)
|
||||
{
|
||||
TRACE("%u: x %.8e, y %.8e, w %.8e, h %.8e, min_z %.8e, max_z %.8e.\n", i, viewports[i].x, viewports[i].y,
|
||||
viewports[i].width, viewports[i].height, viewports[i].min_z, viewports[i].max_z);
|
||||
}
|
||||
|
||||
if (viewport_count)
|
||||
memcpy(device->update_state->viewports, viewports, viewport_count * sizeof(*viewports));
|
||||
else
|
||||
memset(device->update_state->viewports, 0, sizeof(device->update_state->viewports));
|
||||
device->update_state->viewport_count = viewport_count;
|
||||
|
||||
/* Handle recording of state blocks */
|
||||
if (device->recording)
|
||||
|
@ -1926,14 +1937,14 @@ void CDECL wined3d_device_set_viewport(struct wined3d_device *device, const stru
|
|||
return;
|
||||
}
|
||||
|
||||
wined3d_cs_emit_set_viewport(device->cs, viewport);
|
||||
wined3d_cs_emit_set_viewports(device->cs, viewport_count, viewports);
|
||||
}
|
||||
|
||||
void CDECL wined3d_device_get_viewport(const struct wined3d_device *device, struct wined3d_viewport *viewport)
|
||||
{
|
||||
TRACE("device %p, viewport %p.\n", device, viewport);
|
||||
|
||||
*viewport = device->state.viewport;
|
||||
*viewport = device->state.viewports[0];
|
||||
}
|
||||
|
||||
static void resolve_depth_buffer(struct wined3d_device *device)
|
||||
|
@ -4449,19 +4460,19 @@ HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device
|
|||
{
|
||||
struct wined3d_state *state = &device->state;
|
||||
|
||||
state->viewport.x = 0;
|
||||
state->viewport.y = 0;
|
||||
state->viewport.width = view->width;
|
||||
state->viewport.height = view->height;
|
||||
state->viewport.min_z = 0.0f;
|
||||
state->viewport.max_z = 1.0f;
|
||||
wined3d_cs_emit_set_viewport(device->cs, &state->viewport);
|
||||
state->viewports[0].x = 0;
|
||||
state->viewports[0].y = 0;
|
||||
state->viewports[0].width = view->width;
|
||||
state->viewports[0].height = view->height;
|
||||
state->viewports[0].min_z = 0.0f;
|
||||
state->viewports[0].max_z = 1.0f;
|
||||
state->viewport_count = 1;
|
||||
wined3d_cs_emit_set_viewports(device->cs, 1, state->viewports);
|
||||
|
||||
SetRect(&state->scissor_rect, 0, 0, view->width, view->height);
|
||||
wined3d_cs_emit_set_scissor_rect(device->cs, &state->scissor_rect);
|
||||
}
|
||||
|
||||
|
||||
prev = device->fb.render_targets[view_idx];
|
||||
if (view == prev)
|
||||
return WINED3D_OK;
|
||||
|
@ -4961,11 +4972,12 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
|
|||
wined3d_device_set_rendertarget_view(device, 0, view, FALSE);
|
||||
|
||||
/* Note the min_z / max_z is not reset. */
|
||||
state->viewport.x = 0;
|
||||
state->viewport.y = 0;
|
||||
state->viewport.width = view->width;
|
||||
state->viewport.height = view->height;
|
||||
wined3d_cs_emit_set_viewport(device->cs, &state->viewport);
|
||||
state->viewports[0].x = 0;
|
||||
state->viewports[0].y = 0;
|
||||
state->viewports[0].width = view->width;
|
||||
state->viewports[0].height = view->height;
|
||||
state->viewport_count = 1;
|
||||
wined3d_cs_emit_set_viewports(device->cs, 1, state->viewports);
|
||||
|
||||
SetRect(&state->scissor_rect, 0, 0, view->width, view->height);
|
||||
wined3d_cs_emit_set_scissor_rect(device->cs, &state->scissor_rect);
|
||||
|
|
|
@ -1756,7 +1756,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
|
|||
const struct wined3d_shader *pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL];
|
||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
struct shader_glsl_priv *priv = shader_priv;
|
||||
float position_fixup[4];
|
||||
float position_fixup[4 * WINED3D_MAX_VIEWPORTS];
|
||||
DWORD update_mask;
|
||||
|
||||
struct glsl_shader_prog_link *prog = ctx_data->glsl_program;
|
||||
|
@ -1793,9 +1793,11 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
|
|||
|
||||
if (update_mask & WINED3D_SHADER_CONST_POS_FIXUP)
|
||||
{
|
||||
shader_get_position_fixup(context, state, position_fixup);
|
||||
unsigned int fixup_count = state->shader[WINED3D_SHADER_TYPE_GEOMETRY] ?
|
||||
max(state->viewport_count, 1) : 1;
|
||||
shader_get_position_fixup(context, state, fixup_count, position_fixup);
|
||||
if (state->shader[WINED3D_SHADER_TYPE_GEOMETRY])
|
||||
GL_EXTCALL(glUniform4fv(prog->gs.pos_fixup_location, 1, position_fixup));
|
||||
GL_EXTCALL(glUniform4fv(prog->gs.pos_fixup_location, fixup_count, position_fixup));
|
||||
else if (state->shader[WINED3D_SHADER_TYPE_DOMAIN])
|
||||
GL_EXTCALL(glUniform4fv(prog->ds.pos_fixup_location, 1, position_fixup));
|
||||
else
|
||||
|
@ -3806,7 +3808,7 @@ static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_
|
|||
shader_glsl_color_correction(ins, fixup);
|
||||
}
|
||||
|
||||
static void shader_glsl_fixup_position(struct wined3d_string_buffer *buffer)
|
||||
static void shader_glsl_fixup_position(struct wined3d_string_buffer *buffer, BOOL use_viewport_index)
|
||||
{
|
||||
/* Write the final position.
|
||||
*
|
||||
|
@ -3815,8 +3817,16 @@ static void shader_glsl_fixup_position(struct wined3d_string_buffer *buffer)
|
|||
* pos_fixup. pos_fixup.y contains 1.0 or -1.0 to turn the rendering
|
||||
* upside down for offscreen rendering. pos_fixup.x contains 1.0 to allow
|
||||
* a MAD. */
|
||||
shader_addline(buffer, "gl_Position.y = gl_Position.y * pos_fixup.y;\n");
|
||||
shader_addline(buffer, "gl_Position.xy += pos_fixup.zw * gl_Position.ww;\n");
|
||||
if (use_viewport_index)
|
||||
{
|
||||
shader_addline(buffer, "gl_Position.y = gl_Position.y * pos_fixup[gl_ViewportIndex].y;\n");
|
||||
shader_addline(buffer, "gl_Position.xy += pos_fixup[gl_ViewportIndex].zw * gl_Position.ww;\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
shader_addline(buffer, "gl_Position.y = gl_Position.y * pos_fixup.y;\n");
|
||||
shader_addline(buffer, "gl_Position.xy += pos_fixup.zw * gl_Position.ww;\n");
|
||||
}
|
||||
|
||||
/* Z coord [0;1]->[-1;1] mapping, see comment in get_projection_matrix()
|
||||
* in utils.c
|
||||
|
@ -5143,9 +5153,10 @@ static void shader_glsl_emit(const struct wined3d_shader_instruction *ins)
|
|||
{
|
||||
unsigned int stream = ins->handler_idx == WINED3DSIH_EMIT ? 0 : ins->src[0].reg.idx[0].offset;
|
||||
|
||||
shader_addline(ins->ctx->buffer, "gl_ViewportIndex = 0;\n");
|
||||
shader_addline(ins->ctx->buffer, "setup_gs_output(gs_out);\n");
|
||||
if (!ins->ctx->gl_info->supported[ARB_CLIP_CONTROL])
|
||||
shader_glsl_fixup_position(ins->ctx->buffer);
|
||||
shader_glsl_fixup_position(ins->ctx->buffer, TRUE);
|
||||
|
||||
if (!stream)
|
||||
shader_addline(ins->ctx->buffer, "EmitVertex();\n");
|
||||
|
@ -6766,6 +6777,14 @@ static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct w
|
|||
else
|
||||
FIXME("ARB_fragment_layer_viewport is not supported.\n");
|
||||
}
|
||||
else if (input->sysval_semantic == WINED3D_SV_VIEWPORT_ARRAY_INDEX && !semantic_idx)
|
||||
{
|
||||
if (gl_info->supported[ARB_VIEWPORT_ARRAY])
|
||||
shader_addline(buffer, "ps_in[%u]%s = intBitsToFloat(gl_ViewportIndex);\n",
|
||||
input->register_idx, reg_mask);
|
||||
else
|
||||
FIXME("ARB_viewport_array is not supported.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (input->sysval_semantic)
|
||||
|
@ -7057,6 +7076,11 @@ static void shader_glsl_setup_sm3_rasterizer_input(struct shader_glsl_priv *priv
|
|||
shader_addline(buffer, "gl_Layer = floatBitsToInt(outputs[%u])%s;\n",
|
||||
output->register_idx, reg_mask);
|
||||
}
|
||||
else if (output->sysval_semantic == WINED3D_SV_VIEWPORT_ARRAY_INDEX && !semantic_idx)
|
||||
{
|
||||
shader_addline(buffer, "gl_ViewportIndex = floatBitsToInt(outputs[%u])%s;\n",
|
||||
output->register_idx, reg_mask);
|
||||
}
|
||||
else if (output->sysval_semantic == WINED3D_SV_CLIP_DISTANCE)
|
||||
{
|
||||
shader_glsl_generate_clip_or_cull_distances(buffer, output, reg_maps_out->clip_distance_mask);
|
||||
|
@ -7830,7 +7854,7 @@ static void shader_glsl_generate_vs_epilogue(const struct wined3d_gl_info *gl_in
|
|||
shader_addline(buffer, "gl_PointSize = clamp(ffp_point.size, ffp_point.size_min, ffp_point.size_max);\n");
|
||||
|
||||
if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL])
|
||||
shader_glsl_fixup_position(buffer);
|
||||
shader_glsl_fixup_position(buffer, FALSE);
|
||||
}
|
||||
|
||||
/* Context activation is done by the caller. */
|
||||
|
@ -8068,7 +8092,7 @@ static void shader_glsl_generate_ds_epilogue(const struct wined3d_gl_info *gl_in
|
|||
shader_addline(buffer, "setup_ds_output(ds_out);\n");
|
||||
|
||||
if (args->next_shader_type == WINED3D_SHADER_TYPE_PIXEL && !gl_info->supported[ARB_CLIP_CONTROL])
|
||||
shader_glsl_fixup_position(buffer);
|
||||
shader_glsl_fixup_position(buffer, FALSE);
|
||||
}
|
||||
|
||||
static GLuint shader_glsl_generate_domain_shader(const struct wined3d_context *context,
|
||||
|
@ -8193,7 +8217,7 @@ static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context
|
|||
shader_addline(buffer, "in shader_in_out { vec4 reg[%u]; } shader_in[];\n", shader->limits->packed_input);
|
||||
|
||||
if (!gl_info->supported[ARB_CLIP_CONTROL])
|
||||
shader_addline(buffer, "uniform vec4 pos_fixup;\n");
|
||||
shader_addline(buffer, "uniform vec4 pos_fixup[%u];\n", WINED3D_MAX_VIEWPORTS);
|
||||
|
||||
if (is_rasterization_disabled(shader))
|
||||
{
|
||||
|
|
|
@ -4514,21 +4514,24 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine
|
|||
}
|
||||
}
|
||||
|
||||
static void get_viewport(struct wined3d_context *context, const struct wined3d_state *state,
|
||||
struct wined3d_viewport *viewport)
|
||||
static void get_viewports(struct wined3d_context *context, const struct wined3d_state *state,
|
||||
unsigned int viewport_count, struct wined3d_viewport *viewports)
|
||||
{
|
||||
const struct wined3d_rendertarget_view *depth_stencil = state->fb->depth_stencil;
|
||||
const struct wined3d_rendertarget_view *target = state->fb->render_targets[0];
|
||||
unsigned int width, height;
|
||||
unsigned int width, height, i;
|
||||
|
||||
*viewport = state->viewport;
|
||||
|
||||
if (target)
|
||||
for (i = 0; i < viewport_count; ++i)
|
||||
{
|
||||
if (viewport->width > target->width)
|
||||
viewport->width = target->width;
|
||||
if (viewport->height > target->height)
|
||||
viewport->height = target->height;
|
||||
viewports[i] = state->viewports[i];
|
||||
|
||||
if (target)
|
||||
{
|
||||
if (viewports[i].width > target->width)
|
||||
viewports[i].width = target->width;
|
||||
if (viewports[i].height > target->height)
|
||||
viewports[i].height = target->height;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4552,22 +4555,45 @@ static void get_viewport(struct wined3d_context *context, const struct wined3d_s
|
|||
return;
|
||||
}
|
||||
|
||||
viewport->y = height - (viewport->y + viewport->height);
|
||||
for (i = 0; i < viewport_count; ++i)
|
||||
viewports[i].y = height - (viewports[i].y + viewports[i].height);
|
||||
}
|
||||
|
||||
static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
||||
{
|
||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
struct wined3d_viewport vp;
|
||||
|
||||
get_viewport(context, state, &vp);
|
||||
|
||||
gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z);
|
||||
struct wined3d_viewport vp[WINED3D_MAX_VIEWPORTS];
|
||||
|
||||
if (gl_info->supported[ARB_VIEWPORT_ARRAY])
|
||||
GL_EXTCALL(glViewportIndexedf(0, vp.x, vp.y, vp.width, vp.height));
|
||||
{
|
||||
unsigned int i, reset_count = 0;
|
||||
|
||||
get_viewports(context, state, state->viewport_count, vp);
|
||||
for (i = 0; i < state->viewport_count; ++i)
|
||||
{
|
||||
GL_EXTCALL(glDepthRangeIndexed(i, vp[i].min_z, vp[i].max_z));
|
||||
GL_EXTCALL(glViewportIndexedf(i, vp[i].x, vp[i].y, vp[i].width, vp[i].height));
|
||||
}
|
||||
|
||||
if (context->viewport_count > state->viewport_count)
|
||||
reset_count = context->viewport_count - state->viewport_count;
|
||||
|
||||
if (reset_count)
|
||||
{
|
||||
static const GLfloat reset[4 * WINED3D_MAX_VIEWPORTS];
|
||||
static const GLdouble resetd[2 * WINED3D_MAX_VIEWPORTS];
|
||||
|
||||
GL_EXTCALL(glDepthRangeArrayv(state->viewport_count, reset_count, resetd));
|
||||
GL_EXTCALL(glViewportArrayv(state->viewport_count, reset_count, reset));
|
||||
}
|
||||
context->viewport_count = state->viewport_count;
|
||||
}
|
||||
else
|
||||
gl_info->gl_ops.gl.p_glViewport(vp.x, vp.y, vp.width, vp.height);
|
||||
{
|
||||
get_viewports(context, state, 1, vp);
|
||||
gl_info->gl_ops.gl.p_glDepthRange(vp[0].min_z, vp[0].max_z);
|
||||
gl_info->gl_ops.gl.p_glViewport(vp[0].x, vp[0].y, vp[0].width, vp[0].height);
|
||||
}
|
||||
checkGLcall("setting clip space and viewport");
|
||||
}
|
||||
|
||||
|
@ -4578,16 +4604,34 @@ static void viewport_miscpart_cc(struct wined3d_context *context,
|
|||
float pixel_center_offset = context->d3d_info->wined3d_creation_flags
|
||||
& WINED3D_PIXEL_CENTER_INTEGER ? 63.0f / 128.0f : -1.0f / 128.0f;
|
||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
struct wined3d_viewport vp;
|
||||
struct wined3d_viewport vp[WINED3D_MAX_VIEWPORTS];
|
||||
unsigned int i, reset_count = 0;
|
||||
|
||||
get_viewport(context, state, &vp);
|
||||
vp.x += pixel_center_offset;
|
||||
vp.y += pixel_center_offset;
|
||||
|
||||
gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z);
|
||||
get_viewports(context, state, state->viewport_count, vp);
|
||||
|
||||
GL_EXTCALL(glClipControl(context->render_offscreen ? GL_UPPER_LEFT : GL_LOWER_LEFT, GL_ZERO_TO_ONE));
|
||||
GL_EXTCALL(glViewportIndexedf(0, vp.x, vp.y, vp.width, vp.height));
|
||||
|
||||
for (i = 0; i < state->viewport_count; ++i)
|
||||
{
|
||||
vp[i].x += pixel_center_offset;
|
||||
vp[i].y += pixel_center_offset;
|
||||
GL_EXTCALL(glDepthRangeIndexed(i, vp[i].min_z, vp[i].max_z));
|
||||
GL_EXTCALL(glViewportIndexedf(i, vp[i].x, vp[i].y, vp[i].width, vp[i].height));
|
||||
}
|
||||
|
||||
if (context->viewport_count > state->viewport_count)
|
||||
reset_count = context->viewport_count - state->viewport_count;
|
||||
|
||||
if (reset_count)
|
||||
{
|
||||
static const GLfloat reset[4 * WINED3D_MAX_VIEWPORTS];
|
||||
static const GLdouble resetd[2 * WINED3D_MAX_VIEWPORTS];
|
||||
|
||||
GL_EXTCALL(glDepthRangeArrayv(state->viewport_count, reset_count, resetd));
|
||||
GL_EXTCALL(glViewportArrayv(state->viewport_count, reset_count, reset));
|
||||
}
|
||||
context->viewport_count = state->viewport_count;
|
||||
|
||||
checkGLcall("setting clip space and viewport");
|
||||
}
|
||||
|
||||
|
|
|
@ -811,11 +811,15 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock)
|
|||
}
|
||||
|
||||
if (stateblock->changed.viewport
|
||||
&& memcmp(&src_state->viewport, &stateblock->state.viewport, sizeof(stateblock->state.viewport)))
|
||||
&& (src_state->viewport_count != stateblock->state.viewport_count
|
||||
|| memcmp(src_state->viewports, stateblock->state.viewports, src_state->viewport_count * sizeof(stateblock->state.viewports))))
|
||||
{
|
||||
TRACE("Updating viewport.\n");
|
||||
TRACE("Updating viewports.\n");
|
||||
|
||||
stateblock->state.viewport = src_state->viewport;
|
||||
if ((stateblock->state.viewport_count = src_state->viewport_count))
|
||||
memcpy(stateblock->state.viewports, src_state->viewports, sizeof(src_state->viewports));
|
||||
else
|
||||
memset(stateblock->state.viewports, 0, sizeof(*stateblock->state.viewports));
|
||||
}
|
||||
|
||||
if (stateblock->changed.scissorRect && memcmp(&src_state->scissor_rect,
|
||||
|
@ -1055,7 +1059,7 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock)
|
|||
wined3d_device_set_material(device, &stateblock->state.material);
|
||||
|
||||
if (stateblock->changed.viewport)
|
||||
wined3d_device_set_viewport(device, &stateblock->state.viewport);
|
||||
wined3d_device_set_viewports(device, stateblock->state.viewport_count, stateblock->state.viewports);
|
||||
|
||||
if (stateblock->changed.scissorRect)
|
||||
wined3d_device_set_scissor_rect(device, &stateblock->state.scissor_rect);
|
||||
|
|
|
@ -4865,10 +4865,10 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w
|
|||
if (context->last_was_rhw)
|
||||
{
|
||||
/* Transform D3D RHW coordinates to OpenGL clip coordinates. */
|
||||
float x = state->viewport.x;
|
||||
float y = state->viewport.y;
|
||||
float w = state->viewport.width;
|
||||
float h = state->viewport.height;
|
||||
float x = state->viewports[0].x;
|
||||
float y = state->viewports[0].y;
|
||||
float w = state->viewports[0].width;
|
||||
float h = state->viewports[0].height;
|
||||
float x_scale = 2.0f / w;
|
||||
float x_offset = (center_offset - (2.0f * x) - w) / w;
|
||||
float y_scale = flip ? 2.0f / h : 2.0f / -h;
|
||||
|
@ -4892,10 +4892,10 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w
|
|||
else
|
||||
{
|
||||
float y_scale = flip ? -1.0f : 1.0f;
|
||||
float x_offset = center_offset / state->viewport.width;
|
||||
float x_offset = center_offset / state->viewports[0].width;
|
||||
float y_offset = flip
|
||||
? center_offset / state->viewport.height
|
||||
: -center_offset / state->viewport.height;
|
||||
? center_offset / state->viewports[0].height
|
||||
: -center_offset / state->viewports[0].height;
|
||||
float z_scale = clip_control ? 1.0f : 2.0f;
|
||||
float z_offset = clip_control ? 0.0f : -1.0f;
|
||||
const struct wined3d_matrix projection =
|
||||
|
@ -5095,9 +5095,10 @@ void get_pointsize(const struct wined3d_context *context, const struct wined3d_s
|
|||
b.d = state->render_states[WINED3D_RS_POINTSCALE_B];
|
||||
c.d = state->render_states[WINED3D_RS_POINTSCALE_C];
|
||||
|
||||
/* Always use first viewport, this path does not apply to d3d10/11 multiple viewports case. */
|
||||
if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
|
||||
{
|
||||
float scale_factor = state->viewport.height * state->viewport.height;
|
||||
float scale_factor = state->viewports[0].height * state->viewports[0].height;
|
||||
|
||||
out_att[0] = a.f / scale_factor;
|
||||
out_att[1] = b.f / scale_factor;
|
||||
|
|
|
@ -187,7 +187,7 @@
|
|||
@ cdecl wined3d_device_set_unordered_access_view(ptr long ptr long)
|
||||
@ cdecl wined3d_device_set_vertex_declaration(ptr ptr)
|
||||
@ cdecl wined3d_device_set_vertex_shader(ptr ptr)
|
||||
@ cdecl wined3d_device_set_viewport(ptr ptr)
|
||||
@ cdecl wined3d_device_set_viewports(ptr long ptr)
|
||||
@ cdecl wined3d_device_set_vs_cb(ptr long ptr)
|
||||
@ cdecl wined3d_device_set_vs_consts_b(ptr long long ptr)
|
||||
@ cdecl wined3d_device_set_vs_consts_f(ptr long long ptr)
|
||||
|
|
|
@ -1990,6 +1990,8 @@ struct wined3d_context
|
|||
GLfloat fog_coord_value;
|
||||
GLfloat color[4], fogstart, fogend, fogcolor[4];
|
||||
GLuint dummy_arbfp_prog;
|
||||
|
||||
unsigned int viewport_count;
|
||||
};
|
||||
|
||||
struct wined3d_fb_state
|
||||
|
@ -2851,7 +2853,8 @@ struct wined3d_state
|
|||
struct wined3d_matrix transforms[HIGHEST_TRANSFORMSTATE + 1];
|
||||
struct wined3d_vec4 clip_planes[MAX_CLIP_DISTANCES];
|
||||
struct wined3d_material material;
|
||||
struct wined3d_viewport viewport;
|
||||
struct wined3d_viewport viewports[WINED3D_MAX_VIEWPORTS];
|
||||
unsigned int viewport_count;
|
||||
RECT scissor_rect;
|
||||
|
||||
/* Light hashmap. Collisions are handled using linked lists. */
|
||||
|
@ -3604,7 +3607,7 @@ void wined3d_cs_emit_set_unordered_access_view(struct wined3d_cs *cs, enum wined
|
|||
unsigned int initial_count) DECLSPEC_HIDDEN;
|
||||
void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs,
|
||||
struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN;
|
||||
void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) DECLSPEC_HIDDEN;
|
||||
void wined3d_cs_emit_set_viewports(struct wined3d_cs *cs, unsigned int viewport_count, const struct wined3d_viewport *viewports) DECLSPEC_HIDDEN;
|
||||
void wined3d_cs_emit_unload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
|
||||
void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *resource,
|
||||
unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch,
|
||||
|
@ -4107,24 +4110,28 @@ static inline BOOL shader_is_scalar(const struct wined3d_shader_register *reg)
|
|||
}
|
||||
|
||||
static inline void shader_get_position_fixup(const struct wined3d_context *context,
|
||||
const struct wined3d_state *state, float *position_fixup)
|
||||
const struct wined3d_state *state, unsigned int fixup_count, float *position_fixup)
|
||||
{
|
||||
float center_offset;
|
||||
unsigned int i;
|
||||
|
||||
if (context->d3d_info->wined3d_creation_flags & WINED3D_PIXEL_CENTER_INTEGER)
|
||||
center_offset = 63.0f / 64.0f;
|
||||
else
|
||||
center_offset = -1.0f / 64.0f;
|
||||
|
||||
position_fixup[0] = 1.0f;
|
||||
position_fixup[1] = 1.0f;
|
||||
position_fixup[2] = center_offset / state->viewport.width;
|
||||
position_fixup[3] = -center_offset / state->viewport.height;
|
||||
|
||||
if (context->render_offscreen)
|
||||
for (i = 0; i < fixup_count; ++i)
|
||||
{
|
||||
position_fixup[1] *= -1.0f;
|
||||
position_fixup[3] *= -1.0f;
|
||||
position_fixup[4 * i ] = 1.0f;
|
||||
position_fixup[4 * i + 1] = 1.0f;
|
||||
position_fixup[4 * i + 2] = center_offset / state->viewports[i].width;
|
||||
position_fixup[4 * i + 3] = -center_offset / state->viewports[i].height;
|
||||
|
||||
if (context->render_offscreen)
|
||||
{
|
||||
position_fixup[4 * i + 1] *= -1.0f;
|
||||
position_fixup[4 * i + 3] *= -1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1561,6 +1561,8 @@ enum wined3d_shader_byte_code_format
|
|||
#define WINED3D_VIEW_TEXTURE_CUBE 0x00000008
|
||||
#define WINED3D_VIEW_TEXTURE_ARRAY 0x00000010
|
||||
|
||||
#define WINED3D_MAX_VIEWPORTS 16
|
||||
|
||||
struct wined3d_display_mode
|
||||
{
|
||||
UINT width;
|
||||
|
@ -2440,7 +2442,8 @@ void __cdecl wined3d_device_set_unordered_access_view(struct wined3d_device *dev
|
|||
void __cdecl wined3d_device_set_vertex_declaration(struct wined3d_device *device,
|
||||
struct wined3d_vertex_declaration *declaration);
|
||||
void __cdecl wined3d_device_set_vertex_shader(struct wined3d_device *device, struct wined3d_shader *shader);
|
||||
void __cdecl wined3d_device_set_viewport(struct wined3d_device *device, const struct wined3d_viewport *viewport);
|
||||
void __cdecl wined3d_device_set_viewports(struct wined3d_device *device, unsigned int viewport_count,
|
||||
const struct wined3d_viewport *viewports);
|
||||
void __cdecl wined3d_device_set_vs_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer);
|
||||
HRESULT __cdecl wined3d_device_set_vs_consts_b(struct wined3d_device *device,
|
||||
unsigned int start_idx, unsigned int count, const BOOL *constants);
|
||||
|
|
Loading…
Reference in New Issue