wined3d: Create GL sampler objects for wined3d sampler objects.
This commit is contained in:
parent
5231113fc7
commit
c6232e1d11
|
@ -657,7 +657,7 @@ HRESULT d3d10_sampler_state_init(struct d3d10_sampler_state *state, struct d3d10
|
|||
wined3d_desc.comparison_func = wined3d_cmp_func_from_d3d10core(desc->ComparisonFunc);
|
||||
wined3d_desc.srgb_decode = FALSE;
|
||||
|
||||
if (FAILED(hr = wined3d_sampler_create(&wined3d_desc, state, &state->wined3d_sampler)))
|
||||
if (FAILED(hr = wined3d_sampler_create(device->wined3d_device, &wined3d_desc, state, &state->wined3d_sampler)))
|
||||
{
|
||||
WARN("Failed to create wined3d sampler, hr %#x.\n", hr);
|
||||
return hr;
|
||||
|
|
|
@ -1920,6 +1920,8 @@ static void SetupForBlit(const struct wined3d_device *device, struct wined3d_con
|
|||
context_invalidate_state(context, STATE_SAMPLER(sampler));
|
||||
}
|
||||
}
|
||||
if (gl_info->supported[ARB_SAMPLER_OBJECTS])
|
||||
GL_EXTCALL(glBindSampler(0, 0));
|
||||
context_active_texture(context, gl_info, 0);
|
||||
|
||||
sampler = context->rev_tex_unit_map[0];
|
||||
|
|
|
@ -479,6 +479,13 @@ ULONG CDECL wined3d_device_incref(struct wined3d_device *device)
|
|||
return refcount;
|
||||
}
|
||||
|
||||
static void device_leftover_sampler(struct wine_rb_entry *entry, void *context)
|
||||
{
|
||||
struct wined3d_sampler *sampler = WINE_RB_ENTRY_VALUE(entry, struct wined3d_sampler, entry);
|
||||
|
||||
ERR("Leftover sampler %p.\n", sampler);
|
||||
}
|
||||
|
||||
ULONG CDECL wined3d_device_decref(struct wined3d_device *device)
|
||||
{
|
||||
ULONG refcount = InterlockedDecrement(&device->ref);
|
||||
|
@ -522,6 +529,8 @@ ULONG CDECL wined3d_device_decref(struct wined3d_device *device)
|
|||
DestroyCursor(device->hardwareCursor);
|
||||
device->hardwareCursor = 0;
|
||||
|
||||
wine_rb_destroy(&device->samplers, device_leftover_sampler, NULL);
|
||||
|
||||
wined3d_decref(device->wined3d);
|
||||
device->wined3d = NULL;
|
||||
HeapFree(GetProcessHeap(), 0, device);
|
||||
|
@ -1020,6 +1029,14 @@ err_out:
|
|||
return hr;
|
||||
}
|
||||
|
||||
static void device_free_sampler(struct wine_rb_entry *entry, void *context)
|
||||
{
|
||||
struct wined3d_sampler *sampler = WINE_RB_ENTRY_VALUE(entry, struct wined3d_sampler, entry);
|
||||
struct wined3d_device *device = context;
|
||||
|
||||
wine_rb_remove(&device->samplers, &sampler->desc);
|
||||
}
|
||||
|
||||
HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device)
|
||||
{
|
||||
struct wined3d_resource *resource, *cursor;
|
||||
|
@ -1054,6 +1071,8 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device)
|
|||
resource->resource_ops->resource_unload(resource);
|
||||
}
|
||||
|
||||
wine_rb_for_each_entry(&device->samplers, device_free_sampler, device);
|
||||
|
||||
/* Destroy the depth blt resources, they will be invalid after the reset. Also free shader
|
||||
* private data, it might contain opengl pointers
|
||||
*/
|
||||
|
@ -4658,6 +4677,8 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
|
|||
swapchain_update_render_to_fbo(swapchain);
|
||||
swapchain_update_draw_bindings(swapchain);
|
||||
|
||||
wine_rb_for_each_entry(&device->samplers, device_free_sampler, device);
|
||||
|
||||
if (reset_state && device->d3d_initialized)
|
||||
hr = create_primary_opengl_context(device, swapchain);
|
||||
|
||||
|
@ -4850,6 +4871,21 @@ struct wined3d_surface * CDECL wined3d_device_get_surface_from_dc(const struct w
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int wined3d_sampler_compare(const void *key, const struct wine_rb_entry *entry)
|
||||
{
|
||||
const struct wined3d_sampler *sampler = WINE_RB_ENTRY_VALUE(entry, struct wined3d_sampler, entry);
|
||||
|
||||
return memcmp(&sampler->desc, key, sizeof(sampler->desc));
|
||||
}
|
||||
|
||||
static const struct wine_rb_functions wined3d_sampler_rb_functions =
|
||||
{
|
||||
wined3d_rb_alloc,
|
||||
wined3d_rb_realloc,
|
||||
wined3d_rb_free,
|
||||
wined3d_sampler_compare,
|
||||
};
|
||||
|
||||
HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
|
||||
UINT adapter_idx, enum wined3d_device_type device_type, HWND focus_window, DWORD flags,
|
||||
BYTE surface_alignment, struct wined3d_device_parent *device_parent)
|
||||
|
@ -4881,12 +4917,19 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
|
|||
|
||||
fragment_pipeline = adapter->fragment_pipe;
|
||||
|
||||
if (wine_rb_init(&device->samplers, &wined3d_sampler_rb_functions) == -1)
|
||||
{
|
||||
ERR("Failed to initialize sampler rbtree.\n");
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if (vertex_pipeline->vp_states && fragment_pipeline->states
|
||||
&& FAILED(hr = compile_state_table(device->StateTable, device->multistate_funcs,
|
||||
&adapter->gl_info, &adapter->d3d_info, vertex_pipeline,
|
||||
fragment_pipeline, misc_state_template)))
|
||||
{
|
||||
ERR("Failed to compile state table, hr %#x.\n", hr);
|
||||
wine_rb_destroy(&device->samplers, NULL, NULL);
|
||||
wined3d_decref(device->wined3d);
|
||||
return hr;
|
||||
}
|
||||
|
@ -4916,6 +4959,7 @@ err:
|
|||
{
|
||||
HeapFree(GetProcessHeap(), 0, device->multistate_funcs[i]);
|
||||
}
|
||||
wine_rb_destroy(&device->samplers, NULL, NULL);
|
||||
wined3d_decref(device->wined3d);
|
||||
return hr;
|
||||
}
|
||||
|
|
|
@ -135,6 +135,7 @@ static const struct wined3d_extension_map gl_extension_map[] =
|
|||
{"GL_ARB_point_parameters", ARB_POINT_PARAMETERS },
|
||||
{"GL_ARB_point_sprite", ARB_POINT_SPRITE },
|
||||
{"GL_ARB_provoking_vertex", ARB_PROVOKING_VERTEX },
|
||||
{"GL_ARB_sampler_objects", ARB_SAMPLER_OBJECTS },
|
||||
{"GL_ARB_shader_bit_encoding", ARB_SHADER_BIT_ENCODING },
|
||||
{"GL_ARB_shader_objects", ARB_SHADER_OBJECTS },
|
||||
{"GL_ARB_shader_texture_lod", ARB_SHADER_TEXTURE_LOD },
|
||||
|
@ -2517,6 +2518,21 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
|
|||
USE_GL_FUNC(glPointParameterfvARB)
|
||||
/* GL_ARB_provoking_vertex */
|
||||
USE_GL_FUNC(glProvokingVertex)
|
||||
/* GL_ARB_sampler_objects */
|
||||
USE_GL_FUNC(glGenSamplers)
|
||||
USE_GL_FUNC(glDeleteSamplers)
|
||||
USE_GL_FUNC(glIsSampler)
|
||||
USE_GL_FUNC(glBindSampler)
|
||||
USE_GL_FUNC(glSamplerParameteri)
|
||||
USE_GL_FUNC(glSamplerParameterf)
|
||||
USE_GL_FUNC(glSamplerParameteriv)
|
||||
USE_GL_FUNC(glSamplerParameterfv)
|
||||
USE_GL_FUNC(glSamplerParameterIiv)
|
||||
USE_GL_FUNC(glSamplerParameterIuiv)
|
||||
USE_GL_FUNC(glGetSamplerParameteriv)
|
||||
USE_GL_FUNC(glGetSamplerParameterfv)
|
||||
USE_GL_FUNC(glGetSamplerParameterIiv)
|
||||
USE_GL_FUNC(glGetSamplerParameterIuiv)
|
||||
/* GL_ARB_shader_objects */
|
||||
USE_GL_FUNC(glAttachObjectARB)
|
||||
USE_GL_FUNC(glBindAttribLocationARB)
|
||||
|
|
|
@ -6604,7 +6604,7 @@ static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct s
|
|||
if (gl_info->supported[EXT_GPU_SHADER4] && gl_info->supported[ARB_SHADER_BIT_ENCODING]
|
||||
&& gl_info->supported[ARB_GEOMETRY_SHADER4] && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 50)
|
||||
&& gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX] && gl_info->supported[ARB_DRAW_INSTANCED]
|
||||
&& gl_info->supported[ARB_TEXTURE_RG])
|
||||
&& gl_info->supported[ARB_TEXTURE_RG] && gl_info->supported[ARB_SAMPLER_OBJECTS])
|
||||
shader_model = 4;
|
||||
/* ARB_shader_texture_lod or EXT_gpu_shader4 is required for the SM3
|
||||
* texldd and texldl instructions. */
|
||||
|
|
|
@ -36,11 +36,20 @@ ULONG CDECL wined3d_sampler_incref(struct wined3d_sampler *sampler)
|
|||
ULONG CDECL wined3d_sampler_decref(struct wined3d_sampler *sampler)
|
||||
{
|
||||
ULONG refcount = InterlockedDecrement(&sampler->refcount);
|
||||
const struct wined3d_gl_info *gl_info;
|
||||
struct wined3d_context *context;
|
||||
|
||||
TRACE("%p decreasing refcount to %u.\n", sampler, refcount);
|
||||
|
||||
if (!refcount)
|
||||
{
|
||||
context = context_acquire(sampler->device, NULL);
|
||||
gl_info = context->gl_info;
|
||||
GL_EXTCALL(glDeleteSamplers(1, &sampler->name));
|
||||
context_release(context);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, sampler);
|
||||
}
|
||||
|
||||
return refcount;
|
||||
}
|
||||
|
@ -52,25 +61,74 @@ void * CDECL wined3d_sampler_get_parent(const struct wined3d_sampler *sampler)
|
|||
return sampler->parent;
|
||||
}
|
||||
|
||||
static void wined3d_sampler_init(struct wined3d_sampler *sampler,
|
||||
static void wined3d_sampler_init(struct wined3d_sampler *sampler, struct wined3d_device *device,
|
||||
const struct wined3d_sampler_desc *desc, void *parent)
|
||||
{
|
||||
const struct wined3d_gl_info *gl_info;
|
||||
struct wined3d_context *context;
|
||||
|
||||
sampler->refcount = 1;
|
||||
sampler->device = device;
|
||||
sampler->parent = parent;
|
||||
sampler->desc = *desc;
|
||||
|
||||
context = context_acquire(device, NULL);
|
||||
gl_info = context->gl_info;
|
||||
|
||||
GL_EXTCALL(glGenSamplers(1, &sampler->name));
|
||||
GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_WRAP_S,
|
||||
gl_info->wrap_lookup[desc->address_u - WINED3D_TADDRESS_WRAP]));
|
||||
GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_WRAP_T,
|
||||
gl_info->wrap_lookup[desc->address_v - WINED3D_TADDRESS_WRAP]));
|
||||
GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_WRAP_R,
|
||||
gl_info->wrap_lookup[desc->address_w - WINED3D_TADDRESS_WRAP]));
|
||||
GL_EXTCALL(glSamplerParameterfv(sampler->name, GL_TEXTURE_BORDER_COLOR, &desc->border_color[0]));
|
||||
GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_MAG_FILTER,
|
||||
wined3d_gl_mag_filter(desc->mag_filter)));
|
||||
GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_MIN_FILTER,
|
||||
wined3d_gl_min_mip_filter(desc->min_filter, desc->mip_filter)));
|
||||
GL_EXTCALL(glSamplerParameterf(sampler->name, GL_TEXTURE_LOD_BIAS, desc->lod_bias));
|
||||
GL_EXTCALL(glSamplerParameterf(sampler->name, GL_TEXTURE_MIN_LOD, desc->min_lod));
|
||||
GL_EXTCALL(glSamplerParameterf(sampler->name, GL_TEXTURE_MAX_LOD, desc->max_lod));
|
||||
if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
|
||||
GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_MAX_ANISOTROPY_EXT, desc->max_anisotropy));
|
||||
if (desc->compare)
|
||||
GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE));
|
||||
GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_COMPARE_FUNC,
|
||||
wined3d_gl_compare_func(desc->comparison_func)));
|
||||
if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE] && !desc->srgb_decode)
|
||||
GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT));
|
||||
checkGLcall("sampler creation");
|
||||
|
||||
TRACE("Created sampler %u.\n", sampler->name);
|
||||
|
||||
context_release(context);
|
||||
}
|
||||
|
||||
HRESULT CDECL wined3d_sampler_create(const struct wined3d_sampler_desc *desc,
|
||||
HRESULT CDECL wined3d_sampler_create(struct wined3d_device *device, const struct wined3d_sampler_desc *desc,
|
||||
void *parent, struct wined3d_sampler **sampler)
|
||||
{
|
||||
struct wined3d_sampler *object;
|
||||
|
||||
TRACE("desc %p, parent %p, sampler %p.\n", desc, parent, sampler);
|
||||
TRACE("device %p, desc %p, parent %p, sampler %p.\n", device, desc, parent, sampler);
|
||||
|
||||
if (!device->adapter->gl_info.supported[ARB_SAMPLER_OBJECTS])
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
|
||||
if (desc->address_u < WINED3D_TADDRESS_WRAP || desc->address_u > WINED3D_TADDRESS_MIRROR_ONCE
|
||||
|| desc->address_v < WINED3D_TADDRESS_WRAP || desc->address_v > WINED3D_TADDRESS_MIRROR_ONCE
|
||||
|| desc->address_w < WINED3D_TADDRESS_WRAP || desc->address_w > WINED3D_TADDRESS_MIRROR_ONCE)
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
|
||||
if (desc->mag_filter < WINED3D_TEXF_POINT || desc->mag_filter > WINED3D_TEXF_LINEAR
|
||||
|| desc->min_filter < WINED3D_TEXF_POINT || desc->min_filter > WINED3D_TEXF_LINEAR
|
||||
|| desc->mip_filter > WINED3D_TEXF_LINEAR)
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
|
||||
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
wined3d_sampler_init(object, desc, parent);
|
||||
wined3d_sampler_init(object, device, desc, parent);
|
||||
|
||||
TRACE("Created sampler %p.\n", object);
|
||||
*sampler = object;
|
||||
|
|
|
@ -234,7 +234,7 @@ static void state_zwritenable(struct wined3d_context *context, const struct wine
|
|||
}
|
||||
}
|
||||
|
||||
static GLenum gl_compare_func(enum wined3d_cmp_func f)
|
||||
GLenum wined3d_gl_compare_func(enum wined3d_cmp_func f)
|
||||
{
|
||||
switch (f)
|
||||
{
|
||||
|
@ -262,7 +262,7 @@ static GLenum gl_compare_func(enum wined3d_cmp_func f)
|
|||
|
||||
static void state_zfunc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
||||
{
|
||||
GLenum depth_func = gl_compare_func(state->render_states[WINED3D_RS_ZFUNC]);
|
||||
GLenum depth_func = wined3d_gl_compare_func(state->render_states[WINED3D_RS_ZFUNC]);
|
||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
|
||||
if (!depth_func) return;
|
||||
|
@ -566,7 +566,7 @@ static void state_alpha(struct wined3d_context *context, const struct wined3d_st
|
|||
else
|
||||
{
|
||||
ref = ((float)state->render_states[WINED3D_RS_ALPHAREF]) / 255.0f;
|
||||
glParm = gl_compare_func(state->render_states[WINED3D_RS_ALPHAFUNC]);
|
||||
glParm = wined3d_gl_compare_func(state->render_states[WINED3D_RS_ALPHAFUNC]);
|
||||
}
|
||||
if (glParm)
|
||||
{
|
||||
|
@ -835,9 +835,9 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_
|
|||
|
||||
onesided_enable = state->render_states[WINED3D_RS_STENCILENABLE];
|
||||
twosided_enable = state->render_states[WINED3D_RS_TWOSIDEDSTENCILMODE];
|
||||
if (!(func = gl_compare_func(state->render_states[WINED3D_RS_STENCILFUNC])))
|
||||
if (!(func = wined3d_gl_compare_func(state->render_states[WINED3D_RS_STENCILFUNC])))
|
||||
func = GL_ALWAYS;
|
||||
if (!(func_ccw = gl_compare_func(state->render_states[WINED3D_RS_CCW_STENCILFUNC])))
|
||||
if (!(func_ccw = wined3d_gl_compare_func(state->render_states[WINED3D_RS_CCW_STENCILFUNC])))
|
||||
func_ccw = GL_ALWAYS;
|
||||
ref = state->render_states[WINED3D_RS_STENCILREF];
|
||||
mask = state->render_states[WINED3D_RS_STENCILMASK];
|
||||
|
@ -3709,8 +3709,42 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state
|
|||
unsigned int base_level;
|
||||
|
||||
wined3d_sampler_desc_from_sampler_states(&desc, gl_info, sampler_states, texture);
|
||||
|
||||
wined3d_texture_bind(texture, context, srgb);
|
||||
wined3d_texture_apply_sampler_desc(texture, &desc, gl_info);
|
||||
if (!gl_info->supported[ARB_SAMPLER_OBJECTS])
|
||||
{
|
||||
wined3d_texture_apply_sampler_desc(texture, &desc, gl_info);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct wined3d_device *device = context->swapchain->device;
|
||||
struct wined3d_sampler *sampler;
|
||||
struct wine_rb_entry *entry;
|
||||
|
||||
if ((entry = wine_rb_get(&device->samplers, &desc)))
|
||||
{
|
||||
sampler = WINE_RB_ENTRY_VALUE(entry, struct wined3d_sampler, entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FAILED(wined3d_sampler_create(device, &desc, NULL, &sampler)))
|
||||
{
|
||||
ERR("Failed to create sampler.\n");
|
||||
sampler = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wine_rb_put(&device->samplers, &desc, &sampler->entry) == -1)
|
||||
ERR("Failed to insert sampler.\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (sampler)
|
||||
{
|
||||
GL_EXTCALL(glBindSampler(sampler_idx, sampler->name));
|
||||
checkGLcall("glBindSampler");
|
||||
}
|
||||
}
|
||||
|
||||
if (texture->flags & WINED3D_TEXTURE_COND_NP2)
|
||||
base_level = 0;
|
||||
|
|
|
@ -194,7 +194,7 @@
|
|||
@ cdecl wined3d_rendertarget_view_incref(ptr)
|
||||
@ cdecl wined3d_rendertarget_view_set_parent(ptr ptr)
|
||||
|
||||
@ cdecl wined3d_sampler_create(ptr ptr ptr)
|
||||
@ cdecl wined3d_sampler_create(ptr ptr ptr ptr)
|
||||
@ cdecl wined3d_sampler_decref(ptr)
|
||||
@ cdecl wined3d_sampler_get_parent(ptr)
|
||||
@ cdecl wined3d_sampler_incref(ptr)
|
||||
|
|
|
@ -71,6 +71,7 @@ enum wined3d_gl_extension
|
|||
ARB_POINT_PARAMETERS,
|
||||
ARB_POINT_SPRITE,
|
||||
ARB_PROVOKING_VERTEX,
|
||||
ARB_SAMPLER_OBJECTS,
|
||||
ARB_SHADER_BIT_ENCODING,
|
||||
ARB_SHADER_OBJECTS,
|
||||
ARB_SHADER_TEXTURE_LOD,
|
||||
|
|
|
@ -1994,6 +1994,7 @@ struct wined3d_device
|
|||
|
||||
struct list resources; /* a linked list to track resources created by the device */
|
||||
struct list shaders; /* a linked list to track shaders (pixel and vertex) */
|
||||
struct wine_rb_tree samplers;
|
||||
|
||||
/* Render Target Support */
|
||||
struct wined3d_fb_state fb;
|
||||
|
@ -2388,9 +2389,12 @@ void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) D
|
|||
|
||||
struct wined3d_sampler
|
||||
{
|
||||
struct wine_rb_entry entry;
|
||||
LONG refcount;
|
||||
struct wined3d_device *device;
|
||||
void *parent;
|
||||
struct wined3d_sampler_desc desc;
|
||||
GLuint name;
|
||||
};
|
||||
|
||||
struct wined3d_vertex_declaration_element
|
||||
|
|
|
@ -2452,7 +2452,7 @@ void * __cdecl wined3d_rendertarget_view_get_sub_resource_parent(const struct wi
|
|||
ULONG __cdecl wined3d_rendertarget_view_incref(struct wined3d_rendertarget_view *view);
|
||||
void __cdecl wined3d_rendertarget_view_set_parent(struct wined3d_rendertarget_view *view, void *parent);
|
||||
|
||||
HRESULT __cdecl wined3d_sampler_create(const struct wined3d_sampler_desc *desc,
|
||||
HRESULT __cdecl wined3d_sampler_create(struct wined3d_device *device, const struct wined3d_sampler_desc *desc,
|
||||
void *parent, struct wined3d_sampler **sampler);
|
||||
ULONG __cdecl wined3d_sampler_decref(struct wined3d_sampler *sampler);
|
||||
void * __cdecl wined3d_sampler_get_parent(const struct wined3d_sampler *sampler);
|
||||
|
|
Loading…
Reference in New Issue