wined3d: Add basic support for rendering to 3D textures.
Signed-off-by: Józef Kucia <jkucia@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
26b7baa0dd
commit
f424a77375
|
@ -126,7 +126,6 @@ static void context_attach_gl_texture_fbo(struct wined3d_context *context,
|
|||
if (!resource)
|
||||
{
|
||||
gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, attachment, GL_TEXTURE_2D, 0, 0);
|
||||
checkGLcall("glFramebufferTexture2D()");
|
||||
}
|
||||
else if (resource->target == GL_TEXTURE_2D_ARRAY)
|
||||
{
|
||||
|
@ -138,14 +137,24 @@ static void context_attach_gl_texture_fbo(struct wined3d_context *context,
|
|||
|
||||
gl_info->fbo_ops.glFramebufferTextureLayer(fbo_target, attachment,
|
||||
resource->object, resource->level, resource->layer);
|
||||
checkGLcall("glFramebufferTextureLayer()");
|
||||
}
|
||||
else if (resource->target == GL_TEXTURE_3D)
|
||||
{
|
||||
if (!gl_info->fbo_ops.glFramebufferTexture)
|
||||
{
|
||||
FIXME("OpenGL implementation doesn't support glFramebufferTexture().\n");
|
||||
return;
|
||||
}
|
||||
|
||||
gl_info->fbo_ops.glFramebufferTexture(fbo_target, attachment,
|
||||
resource->object, resource->level);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, attachment,
|
||||
resource->target, resource->object, resource->level);
|
||||
checkGLcall("glFramebufferTexture2D()");
|
||||
}
|
||||
checkGLcall("attach texture to fbo");
|
||||
}
|
||||
|
||||
/* Context activation is done by the caller. */
|
||||
|
@ -374,88 +383,93 @@ static inline DWORD context_generate_rt_mask_from_resource(struct wined3d_resour
|
|||
return (1u << 31) | wined3d_texture_get_gl_buffer(texture_from_resource(resource));
|
||||
}
|
||||
|
||||
static inline void context_set_fbo_key_for_surface(const struct wined3d_context *context,
|
||||
struct wined3d_fbo_entry_key *key, UINT idx, struct wined3d_surface *surface,
|
||||
static inline void context_set_fbo_key_for_render_target(const struct wined3d_context *context,
|
||||
struct wined3d_fbo_entry_key *key, unsigned int idx, struct wined3d_rendertarget_info *render_target,
|
||||
DWORD location)
|
||||
{
|
||||
if (!surface || surface->container->resource.format->id == WINED3DFMT_NULL)
|
||||
unsigned int sub_resource_idx = render_target->sub_resource_idx;
|
||||
struct wined3d_resource *resource = render_target->resource;
|
||||
struct wined3d_texture *texture;
|
||||
|
||||
if (!resource || resource->format->id == WINED3DFMT_NULL || resource->type == WINED3D_RTYPE_BUFFER)
|
||||
{
|
||||
if (resource && resource->type == WINED3D_RTYPE_BUFFER)
|
||||
FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type));
|
||||
key->objects[idx].object = 0;
|
||||
key->objects[idx].target = 0;
|
||||
key->objects[idx].level = key->objects[idx].layer = 0;
|
||||
return;
|
||||
}
|
||||
else if (surface->current_renderbuffer)
|
||||
|
||||
texture = wined3d_texture_from_resource(resource);
|
||||
if (resource->type == WINED3D_RTYPE_TEXTURE_2D)
|
||||
{
|
||||
key->objects[idx].object = surface->current_renderbuffer->id;
|
||||
key->objects[idx].target = 0;
|
||||
key->objects[idx].level = key->objects[idx].layer = 0;
|
||||
key->rb_namespace |= 1 << idx;
|
||||
struct wined3d_surface *surface = texture->sub_resources[sub_resource_idx].u.surface;
|
||||
|
||||
if (surface->current_renderbuffer)
|
||||
{
|
||||
key->objects[idx].object = surface->current_renderbuffer->id;
|
||||
key->objects[idx].target = 0;
|
||||
key->objects[idx].level = key->objects[idx].layer = 0;
|
||||
key->rb_namespace |= 1 << idx;
|
||||
return;
|
||||
}
|
||||
|
||||
key->objects[idx].target = surface->texture_target;
|
||||
key->objects[idx].level = surface->texture_level;
|
||||
key->objects[idx].layer = surface->texture_layer;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (location)
|
||||
{
|
||||
case WINED3D_LOCATION_TEXTURE_RGB:
|
||||
key->objects[idx].object = surface_get_texture_name(surface, context, FALSE);
|
||||
key->objects[idx].target = surface->texture_target;
|
||||
key->objects[idx].level = surface->texture_level;
|
||||
key->objects[idx].layer = surface->texture_layer;
|
||||
break;
|
||||
key->objects[idx].target = texture->target;
|
||||
key->objects[idx].level = sub_resource_idx % texture->level_count;
|
||||
key->objects[idx].layer = 0;
|
||||
}
|
||||
|
||||
case WINED3D_LOCATION_TEXTURE_SRGB:
|
||||
key->objects[idx].object = surface_get_texture_name(surface, context, TRUE);
|
||||
key->objects[idx].target = surface->texture_target;
|
||||
key->objects[idx].level = surface->texture_level;
|
||||
key->objects[idx].layer = surface->texture_layer;
|
||||
break;
|
||||
switch (location)
|
||||
{
|
||||
case WINED3D_LOCATION_TEXTURE_RGB:
|
||||
key->objects[idx].object = wined3d_texture_get_texture_name(texture, context, FALSE);
|
||||
break;
|
||||
|
||||
case WINED3D_LOCATION_RB_MULTISAMPLE:
|
||||
key->objects[idx].object = surface->container->rb_multisample;
|
||||
key->objects[idx].target = 0;
|
||||
key->objects[idx].level = key->objects[idx].layer = 0;
|
||||
key->rb_namespace |= 1 << idx;
|
||||
break;
|
||||
case WINED3D_LOCATION_TEXTURE_SRGB:
|
||||
key->objects[idx].object = wined3d_texture_get_texture_name(texture, context, TRUE);
|
||||
break;
|
||||
|
||||
case WINED3D_LOCATION_RB_RESOLVED:
|
||||
key->objects[idx].object = surface->container->rb_resolved;
|
||||
key->objects[idx].target = 0;
|
||||
key->objects[idx].level = key->objects[idx].layer = 0;
|
||||
key->rb_namespace |= 1 << idx;
|
||||
break;
|
||||
}
|
||||
case WINED3D_LOCATION_RB_MULTISAMPLE:
|
||||
key->objects[idx].object = texture->rb_multisample;
|
||||
key->objects[idx].target = 0;
|
||||
key->objects[idx].level = key->objects[idx].layer = 0;
|
||||
key->rb_namespace |= 1 << idx;
|
||||
break;
|
||||
|
||||
case WINED3D_LOCATION_RB_RESOLVED:
|
||||
key->objects[idx].object = texture->rb_resolved;
|
||||
key->objects[idx].target = 0;
|
||||
key->objects[idx].level = key->objects[idx].layer = 0;
|
||||
key->rb_namespace |= 1 << idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void context_generate_fbo_key(const struct wined3d_context *context,
|
||||
struct wined3d_fbo_entry_key *key, struct wined3d_rendertarget_info *render_targets,
|
||||
struct wined3d_surface *depth_stencil, DWORD color_location,
|
||||
struct wined3d_surface *depth_stencil_surface, DWORD color_location,
|
||||
DWORD ds_location)
|
||||
{
|
||||
struct wined3d_rendertarget_info depth_stencil = {0};
|
||||
unsigned int i;
|
||||
|
||||
key->rb_namespace = 0;
|
||||
context_set_fbo_key_for_surface(context, key, 0, depth_stencil, ds_location);
|
||||
if (depth_stencil_surface)
|
||||
{
|
||||
depth_stencil.resource = &depth_stencil_surface->container->resource;
|
||||
depth_stencil.sub_resource_idx = surface_get_sub_resource_idx(depth_stencil_surface);
|
||||
}
|
||||
context_set_fbo_key_for_render_target(context, key, 0, &depth_stencil, ds_location);
|
||||
|
||||
for (i = 0; i < context->gl_info->limits.buffers; ++i)
|
||||
{
|
||||
struct wined3d_surface *surface = NULL;
|
||||
struct wined3d_resource *resource;
|
||||
|
||||
if ((resource = render_targets[i].resource))
|
||||
{
|
||||
if (resource->type == WINED3D_RTYPE_TEXTURE_2D)
|
||||
{
|
||||
struct wined3d_texture *texture = wined3d_texture_from_resource(resource);
|
||||
surface = texture->sub_resources[render_targets[i].sub_resource_idx].u.surface;
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type));
|
||||
}
|
||||
}
|
||||
|
||||
context_set_fbo_key_for_surface(context, key, i + 1, surface, color_location);
|
||||
}
|
||||
context_set_fbo_key_for_render_target(context, key, i + 1, &render_targets[i], color_location);
|
||||
}
|
||||
|
||||
static struct fbo_entry *context_create_fbo_entry(const struct wined3d_context *context,
|
||||
|
|
|
@ -2713,6 +2713,7 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
|
|||
USE_GL_FUNC(glDeleteFramebuffers)
|
||||
USE_GL_FUNC(glDeleteRenderbuffers)
|
||||
USE_GL_FUNC(glFramebufferRenderbuffer)
|
||||
USE_GL_FUNC(glFramebufferTexture)
|
||||
USE_GL_FUNC(glFramebufferTexture1D)
|
||||
USE_GL_FUNC(glFramebufferTexture2D)
|
||||
USE_GL_FUNC(glFramebufferTexture3D)
|
||||
|
@ -3202,6 +3203,7 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
|
|||
USE_GL_FUNC(glEnableVertexAttribArray) /* OpenGL 2.0 */
|
||||
USE_GL_FUNC(glEndQuery) /* OpenGL 1.5 */
|
||||
USE_GL_FUNC(glEndTransformFeedback) /* OpenGL 3.0 */
|
||||
USE_GL_FUNC(glFramebufferTexture) /* OpenGL 3.2 */
|
||||
USE_GL_FUNC(glGenBuffers) /* OpenGL 1.5 */
|
||||
USE_GL_FUNC(glGenQueries) /* OpenGL 1.5 */
|
||||
USE_GL_FUNC(glGenVertexArrays) /* OpenGL 3.0 */
|
||||
|
@ -3331,6 +3333,7 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
|
|||
MAP_GL_FUNCTION(glEnablei, glEnableIndexedEXT);
|
||||
MAP_GL_FUNCTION(glEnableVertexAttribArray, glEnableVertexAttribArrayARB);
|
||||
MAP_GL_FUNCTION(glEndQuery, glEndQueryARB);
|
||||
MAP_GL_FUNCTION(glFramebufferTexture, glFramebufferTextureARB);
|
||||
MAP_GL_FUNCTION(glGenBuffers, glGenBuffersARB);
|
||||
MAP_GL_FUNCTION(glGenQueries, glGenQueriesARB);
|
||||
MAP_GL_FUNCTION(glGetActiveUniform, glGetActiveUniformARB);
|
||||
|
@ -4221,6 +4224,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
|
|||
= gl_info->gl_ops.ext.p_glGetFramebufferAttachmentParameteriv;
|
||||
gl_info->fbo_ops.glBlitFramebuffer = gl_info->gl_ops.ext.p_glBlitFramebuffer;
|
||||
gl_info->fbo_ops.glGenerateMipmap = gl_info->gl_ops.ext.p_glGenerateMipmap;
|
||||
gl_info->fbo_ops.glFramebufferTexture = gl_info->gl_ops.ext.p_glFramebufferTexture;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4253,6 +4257,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
|
|||
|
||||
if (gl_info->supported[ARB_GEOMETRY_SHADER4])
|
||||
{
|
||||
gl_info->fbo_ops.glFramebufferTexture = gl_info->gl_ops.ext.p_glFramebufferTextureARB;
|
||||
gl_info->fbo_ops.glFramebufferTextureLayer = gl_info->gl_ops.ext.p_glFramebufferTextureLayerARB;
|
||||
}
|
||||
if (gl_info->supported[EXT_FRAMEBUFFER_BLIT])
|
||||
|
|
|
@ -2261,6 +2261,8 @@ struct wined3d_fbo_ops
|
|||
void (WINE_GLAPI *glDeleteFramebuffers)(GLsizei n, const GLuint *framebuffers);
|
||||
void (WINE_GLAPI *glGenFramebuffers)(GLsizei n, GLuint *framebuffers);
|
||||
GLenum (WINE_GLAPI *glCheckFramebufferStatus)(GLenum target);
|
||||
void (WINE_GLAPI *glFramebufferTexture)(GLenum target, GLenum attachment,
|
||||
GLuint texture, GLint level);
|
||||
void (WINE_GLAPI *glFramebufferTexture1D)(GLenum target, GLenum attachment,
|
||||
GLenum textarget, GLuint texture, GLint level);
|
||||
void (WINE_GLAPI *glFramebufferTexture2D)(GLenum target, GLenum attachment,
|
||||
|
@ -3980,11 +3982,11 @@ static inline BOOL needs_srgb_write(const struct wined3d_context *context,
|
|||
&& fb->render_targets[0] && fb->render_targets[0]->format_flags & WINED3DFMT_FLAG_SRGB_WRITE;
|
||||
}
|
||||
|
||||
static inline GLuint surface_get_texture_name(const struct wined3d_surface *surface,
|
||||
static inline GLuint wined3d_texture_get_texture_name(const struct wined3d_texture *texture,
|
||||
const struct wined3d_context *context, BOOL srgb)
|
||||
{
|
||||
return srgb && needs_separate_srgb_gl_texture(context, surface->container)
|
||||
? surface->container->texture_srgb.name : surface->container->texture_rgb.name;
|
||||
return srgb && needs_separate_srgb_gl_texture(context, texture)
|
||||
? texture->texture_srgb.name : texture->texture_rgb.name;
|
||||
}
|
||||
|
||||
static inline BOOL can_use_texture_swizzle(const struct wined3d_gl_info *gl_info, const struct wined3d_format *format)
|
||||
|
|
Loading…
Reference in New Issue