In Direct3D 10+, the render target at index 0 can be set to NULL.
Signed-off-by: Józef Kucia jkucia@codeweavers.com ---
Also, a more complex logic may be needed for acquiring context for no attachments draw calls.
There is a potential issue in the code: the assumption that the render target is a texture, but it is a bug in the current code.
--- dlls/wined3d/context.c | 53 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 15 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 4282cfb94d01..534f05a9f0bd 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -3157,6 +3157,7 @@ void context_state_fb(struct wined3d_context *context, const struct wined3d_stat { DWORD rt_mask = find_draw_buffers_mask(context, state); const struct wined3d_fb_state *fb = state->fb; + DWORD color_location = 0; DWORD *cur_mask;
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) @@ -3173,18 +3174,20 @@ void context_state_fb(struct wined3d_context *context, const struct wined3d_stat memset(context->blit_targets, 0, sizeof(context->blit_targets)); for (i = 0; i < context->gl_info->limits.buffers; ++i) { - if (fb->render_targets[i]) - { - context->blit_targets[i].gl_view = fb->render_targets[i]->gl_view; - context->blit_targets[i].resource = fb->render_targets[i]->resource; - context->blit_targets[i].sub_resource_idx = fb->render_targets[i]->sub_resource_idx; - context->blit_targets[i].layer_count = fb->render_targets[i]->layer_count; - } + if (!fb->render_targets[i]) + continue; + + context->blit_targets[i].gl_view = fb->render_targets[i]->gl_view; + context->blit_targets[i].resource = fb->render_targets[i]->resource; + context->blit_targets[i].sub_resource_idx = fb->render_targets[i]->sub_resource_idx; + context->blit_targets[i].layer_count = fb->render_targets[i]->layer_count; + + if (!color_location) + color_location = fb->render_targets[i]->resource->draw_binding; } context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets, wined3d_rendertarget_view_get_surface(fb->depth_stencil), - fb->render_targets[0] ? fb->render_targets[0]->resource->draw_binding : 0, - fb->depth_stencil ? fb->depth_stencil->resource->draw_binding : 0); + color_location, fb->depth_stencil ? fb->depth_stencil->resource->draw_binding : 0); } }
@@ -4774,6 +4777,31 @@ static GLenum gl_tfb_primitive_type_from_d3d(enum wined3d_primitive_type primiti } }
+static struct wined3d_context *context_acquire_for_draw_call(const struct wined3d_device *device, + const struct wined3d_fb_state *fb) +{ + struct wined3d_texture *texture = NULL; + struct wined3d_rendertarget_view *rtv; + unsigned int sub_resource_idx = 0; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(fb->render_targets); ++i) + { + if ((rtv = fb->render_targets[i])) + break; + } + if (!rtv) + rtv = fb->depth_stencil; + + if (rtv) + { + texture = wined3d_texture_from_resource(rtv->resource); + sub_resource_idx = rtv->sub_resource_idx; + } + + return context_acquire(device, texture, sub_resource_idx); +} + /* Routine common to the draw primitive and draw indexed primitive routines */ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *state, const struct wined3d_draw_parameters *parameters) @@ -4792,12 +4820,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s if (!parameters->indirect && !parameters->u.direct.index_count) return;
- if (!(rtv = fb->render_targets[0])) - rtv = fb->depth_stencil; - if (rtv) - context = context_acquire(device, wined3d_texture_from_resource(rtv->resource), rtv->sub_resource_idx); - else - context = context_acquire(device, NULL, 0); + context = context_acquire_for_draw_call(device, fb); if (!context->valid) { context_release(context);