ReactOS 0.4.17-dev-966-gf06eace
context.c
Go to the documentation of this file.
1/*
2 * Context and render target management in wined3d
3 *
4 * Copyright 2002-2004 Jason Edmeades
5 * Copyright 2002-2004 Raphael Junqueira
6 * Copyright 2004 Christian Costa
7 * Copyright 2005 Oliver Stieber
8 * Copyright 2006, 2008 Henri Verbeet
9 * Copyright 2007-2011, 2013 Stefan Dösinger for CodeWeavers
10 * Copyright 2009-2011 Henri Verbeet for CodeWeavers
11 *
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
27#include "wined3d_private.h"
28
31
33{
34 unsigned int i;
35
36 for (i = 0; i < device->context_count; ++i)
37 {
38 struct wined3d_context *context = device->contexts[i];
39
40 if (&context->current_rt.texture->resource == resource)
41 {
42 context->current_rt.texture = NULL;
43 context->current_rt.sub_resource_idx = 0;
44 }
45 }
46}
47
49{
50}
51
52/* This is used when a context for render target A is active, but a separate context is
53 * needed to access the WGL framebuffer for render target B. Re-acquire a context for rt
54 * A to avoid breaking caller code. */
56{
57 if (texture && (context->current_rt.texture != texture || context->current_rt.sub_resource_idx != sub_resource_idx))
58 {
61 }
62
64}
65
67{
68 DWORD representative = context->state_table[state_id].representative - STATE_COMPUTE_OFFSET;
69 unsigned int index, shift;
70
71 index = representative / (sizeof(*context->dirty_compute_states) * CHAR_BIT);
72 shift = representative & (sizeof(*context->dirty_compute_states) * CHAR_BIT - 1);
73 context->dirty_compute_states[index] |= (1u << shift);
74}
75
76void context_invalidate_state(struct wined3d_context *context, unsigned int state_id)
77{
78 unsigned int representative = context->state_table[state_id].representative;
79 unsigned int index, shift;
80
81 if (!representative)
82 ERR("Invalidating representative 0, state_id %u.\n", state_id);
83
84 index = representative / (sizeof(*context->dirty_graphics_states) * CHAR_BIT);
85 shift = representative & ((sizeof(*context->dirty_graphics_states) * CHAR_BIT) - 1);
86 context->dirty_graphics_states[index] |= (1u << shift);
87}
88
90{
91 struct wined3d_device *device = swapchain->device;
93
94 context->d3d_info = &device->adapter->d3d_info;
95 context->state_table = device->state_table;
96
97 /* Mark all states dirty to force a proper initialization of the states on
98 * the first use of the context. Compute states do not need initialization. */
99 for (state = 0; state <= STATE_HIGHEST; ++state)
100 {
101 if (context->state_table[state].representative && !STATE_IS_COMPUTE(state))
103 }
104
105 context->device = device;
106 context->swapchain = swapchain;
107 context->current_rt.texture = swapchain->front_buffer;
108 context->current_rt.sub_resource_idx = 0;
109
110 context->shader_update_mask = (1u << WINED3D_SHADER_TYPE_PIXEL)
116
117 context->update_primitive_type = 1;
118 context->update_patch_vertex_count = 1;
119 context->update_multisample_state = 1;
120}
121
123{
124 TRACE("context_no3d %p, swapchain %p.\n", context_no3d, swapchain);
125
126 wined3d_context_init(context_no3d, swapchain);
127
128 return WINED3D_OK;
129}
130
131static BOOL fixed_get_input(BYTE usage, BYTE usage_idx, unsigned int *regnum)
132{
134 *regnum = WINED3D_FFP_POSITION;
136 *regnum = WINED3D_FFP_BLENDWEIGHT;
138 *regnum = WINED3D_FFP_BLENDINDICES;
140 *regnum = WINED3D_FFP_NORMAL;
142 *regnum = WINED3D_FFP_PSIZE;
144 *regnum = WINED3D_FFP_DIFFUSE;
145 else if (usage == WINED3D_DECL_USAGE_COLOR && usage_idx == 1)
146 *regnum = WINED3D_FFP_SPECULAR;
149 else
150 {
151 WARN("Unsupported input stream [usage=%s, usage_idx=%u].\n", debug_d3ddeclusage(usage), usage_idx);
152 *regnum = ~0u;
153 return FALSE;
154 }
155
156 return TRUE;
157}
158
159/* Context activation is done by the caller. */
161 const struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info)
162{
163 /* We need to deal with frequency data! */
164 BOOL use_vshader = use_vs(state) || (d3d_info->ffp_hlsl && state->shader[WINED3D_SHADER_TYPE_VERTEX]);
165 struct wined3d_vertex_declaration *declaration = state->vertex_declaration;
166 unsigned int i;
167
168 stream_info->use_map = 0;
169 stream_info->swizzle_map = 0;
170 stream_info->position_transformed = 0;
171
172 if (!declaration)
173 return;
174
175 stream_info->position_transformed = declaration->position_transformed;
176
177 /* Translate the declaration into strided data. */
178 for (i = 0; i < declaration->element_count; ++i)
179 {
180 const struct wined3d_vertex_declaration_element *element = &declaration->elements[i];
181 const struct wined3d_stream_state *stream = &state->streams[element->input_slot];
182 BOOL stride_used;
183 unsigned int idx;
184
185 TRACE("%p Element %p (%u of %u).\n", declaration->elements,
186 element, i + 1, declaration->element_count);
187
188 if (!stream->buffer)
189 continue;
190
191 TRACE("offset %u input_slot %u usage_idx %d.\n", element->offset, element->input_slot, element->usage_idx);
192
193 if (use_vshader)
194 {
195 if (element->output_slot == WINED3D_OUTPUT_SLOT_UNUSED)
196 {
197 stride_used = FALSE;
198 }
199 else if (element->output_slot == WINED3D_OUTPUT_SLOT_SEMANTIC)
200 {
201 /* TODO: Assuming vertexdeclarations are usually used with the
202 * same or a similar shader, it might be worth it to store the
203 * last used output slot and try that one first. */
205 element->usage, element->usage_idx, &idx);
206 }
207 else
208 {
209 idx = element->output_slot;
210 stride_used = TRUE;
211 }
212 }
213 else
214 {
215 stride_used = fixed_get_input(element->usage, element->usage_idx, &idx);
216 }
217
218 if (stride_used)
219 {
220 TRACE("Load %s array %u [usage %s, usage_idx %u, "
221 "input_slot %u, offset %u, stride %u, format %s, class %s, step_rate %u].\n",
222 use_vshader ? "shader": "fixed function", idx,
223 debug_d3ddeclusage(element->usage), element->usage_idx, element->input_slot,
224 element->offset, stream->stride, debug_d3dformat(element->format->id),
225 debug_d3dinput_classification(element->input_slot_class), element->instance_data_step_rate);
226
227 stream_info->elements[idx].format = element->format;
228 stream_info->elements[idx].data.buffer_object = 0;
229 stream_info->elements[idx].data.addr = (BYTE *)NULL + stream->offset + element->offset;
230 stream_info->elements[idx].stride = stream->stride;
231 stream_info->elements[idx].stream_idx = element->input_slot;
233 {
234 stream_info->elements[idx].divisor = 1;
235 stream_info->elements[idx].instanced = true;
236 }
237 else if (element->input_slot_class == WINED3D_INPUT_PER_INSTANCE_DATA)
238 {
239 stream_info->elements[idx].divisor = element->instance_data_step_rate;
240 stream_info->elements[idx].instanced = true;
241 }
242 else
243 {
244 stream_info->elements[idx].divisor = 0;
245 stream_info->elements[idx].instanced = false;
246 }
247
248 if (!d3d_info->vertex_bgra && element->format->id == WINED3DFMT_B8G8R8A8_UNORM)
249 {
250 stream_info->swizzle_map |= 1u << idx;
251 }
252 stream_info->use_map |= 1u << idx;
253 }
254 }
255}
256
257/* Context activation is done by the caller. */
259{
260 struct wined3d_stream_info *stream_info = &context->stream_info;
261 const struct wined3d_d3d_info *d3d_info = context->d3d_info;
262 DWORD prev_all_vbo = stream_info->all_vbo;
263 unsigned int i;
265
267
268 stream_info->all_vbo = 1;
269 map = stream_info->use_map;
270 while (map)
271 {
274 struct wined3d_buffer *buffer;
275
277 element = &stream_info->elements[i];
278 buffer = state->streams[element->stream_idx].buffer;
279
280 /* We can't use VBOs if the base vertex index is negative. OpenGL
281 * doesn't accept negative offsets (or rather offsets bigger than the
282 * VBO, because the pointer is unsigned), so use system memory
283 * sources. In most sane cases the pointer - offset will still be > 0,
284 * otherwise it will wrap around to some big value. Hope that with the
285 * indices the driver wraps it back internally. If not,
286 * draw_primitive_immediate_mode() is needed, including a vertex buffer
287 * path. */
288 if (state->load_base_vertex_index < 0)
289 {
290 WARN_(d3d_perf)("load_base_vertex_index is < 0 (%d), not using VBOs.\n",
291 state->load_base_vertex_index);
292 element->data.buffer_object = 0;
294 if ((UINT_PTR)element->data.addr < -state->load_base_vertex_index * element->stride)
295 FIXME("System memory vertex data load offset is negative!\n");
296 }
297 else
298 {
301 element->data.buffer_object = data.buffer_object;
302 element->data.addr += (ULONG_PTR)data.addr;
303 }
304
305 if (!element->data.buffer_object)
306 stream_info->all_vbo = 0;
307
308 TRACE("Load array %u %s.\n", i, debug_bo_address(&element->data));
309 }
310
311 if (prev_all_vbo != stream_info->all_vbo)
313}
static int state
Definition: maze.c:121
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
Definition: _map.h:48
BYTE usage_idx
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT32 uint32_t
Definition: types.h:75
void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context *context, const struct wined3d_state *state)
Definition: buffer.c:484
DWORD wined3d_buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_context *context, struct wined3d_bo_address *data)
Definition: buffer.c:369
void * wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context)
Definition: buffer.c:362
static BOOL fixed_get_input(BYTE usage, BYTE usage_idx, unsigned int *regnum)
Definition: context.c:131
void context_invalidate_compute_state(struct wined3d_context *context, DWORD state_id)
Definition: context.c:66
void context_invalidate_state(struct wined3d_context *context, unsigned int state_id)
Definition: context.c:76
void wined3d_context_cleanup(struct wined3d_context *context)
Definition: context.c:48
void wined3d_context_init(struct wined3d_context *context, struct wined3d_swapchain *swapchain)
Definition: context.c:89
void context_update_stream_info(struct wined3d_context *context, const struct wined3d_state *state)
Definition: context.c:258
void context_resource_released(const struct wined3d_device *device, struct wined3d_resource *resource)
Definition: context.c:32
HRESULT wined3d_context_no3d_init(struct wined3d_context *context_no3d, struct wined3d_swapchain *swapchain)
Definition: context.c:122
void context_restore(struct wined3d_context *context, struct wined3d_texture *texture, unsigned int sub_resource_idx)
Definition: context.c:55
void wined3d_stream_info_from_declaration(struct wined3d_stream_info *stream_info, const struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info)
Definition: context.c:160
bool vshader_get_input(const struct wined3d_shader *shader, uint8_t usage_req, uint8_t usage_idx_req, unsigned int *regnum)
Definition: shader.c:2766
const char * debug_d3dformat(enum wined3d_format_id format_id)
Definition: utils.c:4605
const char * debug_d3dinput_classification(enum wined3d_input_classification classification)
Definition: utils.c:4978
unsigned int idx
Definition: utils.c:40
const char * debug_bo_address(const struct wined3d_bo_address *address)
Definition: utils.c:4600
const char * debug_d3ddeclusage(enum wined3d_decl_usage usage)
Definition: utils.c:4952
#define CHAR_BIT
Definition: cabinet.h:45
#define WINE_DECLARE_DEBUG_CHANNEL(x)
Definition: compat.h:45
#define ULONG_PTR
Definition: config.h:101
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLenum GLuint texture
Definition: glext.h:6295
GLuint buffer
Definition: glext.h:5915
GLuint index
Definition: glext.h:6031
GLsizeiptr const GLvoid GLenum usage
Definition: glext.h:5919
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
if(dx< 0)
Definition: linetemp.h:194
static void stream_info(IStream *stream, HGLOBAL *hmem, int *size, int *pos)
#define shift
Definition: input.c:3280
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
#define WARN_(ch,...)
Definition: debug.h:157
#define TRACE(s)
Definition: solgame.cpp:4
Definition: http.c:7252
Definition: devices.h:37
Definition: parse.h:23
struct wined3d_swapchain * swapchain
unsigned int sub_resource_idx
struct wined3d_texture * front_buffer
struct wined3d_device * device
@ WINED3D_DECL_USAGE_BLEND_INDICES
Definition: wined3d.h:809
@ WINED3D_DECL_USAGE_NORMAL
Definition: wined3d.h:810
@ WINED3D_DECL_USAGE_PSIZE
Definition: wined3d.h:811
@ WINED3D_DECL_USAGE_BLEND_WEIGHT
Definition: wined3d.h:808
@ WINED3D_DECL_USAGE_POSITION
Definition: wined3d.h:807
@ WINED3D_DECL_USAGE_COLOR
Definition: wined3d.h:817
@ WINED3D_DECL_USAGE_POSITIONT
Definition: wined3d.h:816
@ WINED3D_DECL_USAGE_TEXCOORD
Definition: wined3d.h:812
#define WINED3DDP_MAXTEXCOORD
Definition: wined3d.h:907
static int wined3d_bit_scan(unsigned int *x)
Definition: wined3d.h:2982
#define WINED3D_OK
Definition: wined3d.h:33
#define WINED3DSTREAMSOURCE_INSTANCEDATA
Definition: wined3d.h:1015
#define WINED3D_OUTPUT_SLOT_UNUSED
Definition: wined3d.h:1574
@ WINED3DFMT_B8G8R8A8_UNORM
Definition: wined3d.h:244
#define WINED3D_OUTPUT_SLOT_SEMANTIC
Definition: wined3d.h:1573
@ WINED3D_SHADER_TYPE_HULL
Definition: wined3d.h:844
@ WINED3D_SHADER_TYPE_PIXEL
Definition: wined3d.h:841
@ WINED3D_SHADER_TYPE_GEOMETRY
Definition: wined3d.h:843
@ WINED3D_SHADER_TYPE_DOMAIN
Definition: wined3d.h:845
@ WINED3D_SHADER_TYPE_COMPUTE
Definition: wined3d.h:848
@ WINED3D_SHADER_TYPE_VERTEX
Definition: wined3d.h:842
@ WINED3D_INPUT_PER_INSTANCE_DATA
Definition: wined3d.h:1827
#define STATE_HIGHEST
@ WINED3D_FFP_PSIZE
@ WINED3D_FFP_SPECULAR
@ WINED3D_FFP_POSITION
@ WINED3D_FFP_NORMAL
@ WINED3D_FFP_BLENDWEIGHT
@ WINED3D_FFP_DIFFUSE
@ WINED3D_FFP_BLENDINDICES
@ WINED3D_FFP_TEXCOORD0
static BOOL use_vs(const struct wined3d_state *state)
static void context_release(struct wined3d_context *context)
#define STATE_IS_COMPUTE(a)
#define STATE_COMPUTE_OFFSET
#define STATE_INDEXBUFFER
static struct wined3d_context * context_acquire(struct wined3d_device *device, struct wined3d_texture *texture, unsigned int sub_resource_idx)
unsigned char BYTE
Definition: xxhash.c:193