diff --git a/dlls/d3d10core/d3d10core_private.h b/dlls/d3d10core/d3d10core_private.h index 4297adfba84..a4e29e241f7 100644 --- a/dlls/d3d10core/d3d10core_private.h +++ b/dlls/d3d10core/d3d10core_private.h @@ -191,6 +191,7 @@ struct d3d10_geometry_shader HRESULT d3d10_geometry_shader_init(struct d3d10_geometry_shader *shader, struct d3d10_device *device, const void *byte_code, SIZE_T byte_code_length) DECLSPEC_HIDDEN; +struct d3d10_geometry_shader *unsafe_impl_from_ID3D10GeometryShader(ID3D10GeometryShader *iface) DECLSPEC_HIDDEN; /* ID3D10PixelShader */ struct d3d10_pixel_shader diff --git a/dlls/d3d10core/device.c b/dlls/d3d10core/device.c index 0889f3be80d..0f30a1373e6 100644 --- a/dlls/d3d10core/device.c +++ b/dlls/d3d10core/device.c @@ -260,8 +260,12 @@ static void STDMETHODCALLTYPE d3d10_device_GSSetConstantBuffers(ID3D10Device *if static void STDMETHODCALLTYPE d3d10_device_GSSetShader(ID3D10Device *iface, ID3D10GeometryShader *shader) { - if (shader) FIXME("iface %p, shader %p stub!\n", iface, shader); - else WARN("iface %p, shader %p stub!\n", iface, shader); + struct d3d10_device *device = impl_from_ID3D10Device(iface); + struct d3d10_geometry_shader *gs = unsafe_impl_from_ID3D10GeometryShader(shader); + + TRACE("iface %p, shader %p.\n", iface, shader); + + wined3d_device_set_geometry_shader(device->wined3d_device, gs ? gs->wined3d_shader : NULL); } static void STDMETHODCALLTYPE d3d10_device_IASetPrimitiveTopology(ID3D10Device *iface, diff --git a/dlls/d3d10core/shader.c b/dlls/d3d10core/shader.c index c6803ed3752..4f189e9e09c 100644 --- a/dlls/d3d10core/shader.c +++ b/dlls/d3d10core/shader.c @@ -420,6 +420,15 @@ HRESULT d3d10_geometry_shader_init(struct d3d10_geometry_shader *shader, struct return S_OK; } +struct d3d10_geometry_shader *unsafe_impl_from_ID3D10GeometryShader(ID3D10GeometryShader *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d10_geometry_shader_vtbl); + + return impl_from_ID3D10GeometryShader(iface); +} + static inline struct d3d10_pixel_shader *impl_from_ID3D10PixelShader(ID3D10PixelShader *iface) { return CONTAINING_RECORD(iface, struct d3d10_pixel_shader, ID3D10PixelShader_iface); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index e01048bc1ea..979a248ab5a 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -2993,6 +2993,25 @@ HRESULT CDECL wined3d_device_get_ps_consts_f(const struct wined3d_device *device return WINED3D_OK; } +void CDECL wined3d_device_set_geometry_shader(struct wined3d_device *device, struct wined3d_shader *shader) +{ + struct wined3d_shader *prev = device->updateStateBlock->state.geometry_shader; + + TRACE("device %p, shader %p.\n", device, shader); + + if (shader) + wined3d_shader_incref(shader); + if (prev) + wined3d_shader_decref(prev); + + device->updateStateBlock->state.geometry_shader = shader; + + if (device->isRecordingState || shader == prev) + return; + + device_invalidate_state(device, STATE_GEOMETRY_SHADER); +} + /* Context activation is done by the caller. */ /* Do not call while under the GL lock. */ #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size) diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index c16fa2ab727..23765272874 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -3760,6 +3760,11 @@ void apply_pixelshader(struct wined3d_context *context, const struct wined3d_sta context->load_constants = 1; } +void state_geometry_shader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + context->select_shader = 1; +} + static void shader_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); @@ -5129,6 +5134,7 @@ const struct StateEntryTemplate misc_state_template[] = { { STATE_BASEVERTEXINDEX, { STATE_STREAMSRC, NULL, }, WINED3D_GL_EXT_NONE }, { STATE_FRAMEBUFFER, { STATE_FRAMEBUFFER, context_state_fb }, WINED3D_GL_EXT_NONE }, { STATE_PIXELSHADER, { STATE_PIXELSHADER, context_state_drawbuf},WINED3D_GL_EXT_NONE }, + { STATE_GEOMETRY_SHADER, { STATE_GEOMETRY_SHADER, state_geometry_shader}, WINED3D_GL_EXT_NONE }, {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE }, }; @@ -5789,6 +5795,7 @@ static void validate_state_table(struct StateEntry *state_table) STATE_VERTEXSHADERCONSTANT, STATE_PIXELSHADERCONSTANT, STATE_VSHADER, + STATE_GEOMETRY_SHADER, STATE_PIXELSHADER, STATE_VIEWPORT, STATE_SCISSORRECT, diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 0624694e686..9e008f824c6 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -2335,6 +2335,8 @@ const char *debug_d3dstate(DWORD state) return "STATE_VDECL"; if (STATE_IS_VSHADER(state)) return "STATE_VSHADER"; + if (STATE_IS_GEOMETRY_SHADER(state)) + return "STATE_GEOMETRY_SHADER"; if (STATE_IS_VIEWPORT(state)) return "STATE_VIEWPORT"; if (STATE_IS_VERTEXSHADERCONSTANT(state)) diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 2aaa9ceb8e5..3bfa239c675 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -111,6 +111,7 @@ @ cdecl wined3d_device_set_depth_stencil(ptr ptr) @ cdecl wined3d_device_set_dialog_box_mode(ptr long) @ cdecl wined3d_device_set_gamma_ramp(ptr long long ptr) +@ cdecl wined3d_device_set_geometry_shader(ptr ptr) @ cdecl wined3d_device_set_index_buffer(ptr ptr long) @ cdecl wined3d_device_set_light(ptr long ptr) @ cdecl wined3d_device_set_light_enable(ptr long long) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 56d7f38eece..e52541463f1 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -995,7 +995,10 @@ extern glMultiTexCoordFunc multi_texcoord_funcs[WINED3D_FFP_EMIT_COUNT] DECLSPEC #define STATE_VSHADER (STATE_VDECL + 1) #define STATE_IS_VSHADER(a) ((a) == STATE_VSHADER) -#define STATE_VIEWPORT (STATE_VSHADER + 1) +#define STATE_GEOMETRY_SHADER (STATE_VSHADER + 1) +#define STATE_IS_GEOMETRY_SHADER(a) ((a) == STATE_GEOMETRY_SHADER) + +#define STATE_VIEWPORT (STATE_GEOMETRY_SHADER + 1) #define STATE_IS_VIEWPORT(a) ((a) == STATE_VIEWPORT) #define STATE_VERTEXSHADERCONSTANT (STATE_VIEWPORT + 1) @@ -2296,6 +2299,8 @@ struct wined3d_state INT vs_consts_i[MAX_CONST_I * 4]; float *vs_consts_f; + struct wined3d_shader *geometry_shader; + struct wined3d_shader *pixel_shader; BOOL ps_consts_b[MAX_CONST_B]; INT ps_consts_i[MAX_CONST_I * 4]; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index e201c2ec529..fff8bd9b2bb 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2198,6 +2198,7 @@ void __cdecl wined3d_device_set_depth_stencil(struct wined3d_device *device, str HRESULT __cdecl wined3d_device_set_dialog_box_mode(struct wined3d_device *device, BOOL enable_dialogs); void __cdecl wined3d_device_set_gamma_ramp(const struct wined3d_device *device, UINT swapchain_idx, DWORD flags, const struct wined3d_gamma_ramp *ramp); +void __cdecl wined3d_device_set_geometry_shader(struct wined3d_device *device, struct wined3d_shader *shader); void __cdecl wined3d_device_set_index_buffer(struct wined3d_device *device, struct wined3d_buffer *index_buffer, enum wined3d_format_id format_id); HRESULT __cdecl wined3d_device_set_light(struct wined3d_device *device,