GPUMaterial: Add support for different sampler state per image sampler

This bridge between the new sampler state support from GPUTexture and
draw material handling.

The Sampler State is just the one from the texture for now. No change in
logic.
This commit is contained in:
Clément Foucault 2020-06-03 13:35:15 +02:00
parent 866e067d65
commit 91cc1f38ae
5 changed files with 77 additions and 29 deletions

View File

@ -1274,12 +1274,13 @@ static DRWShadingGroup *drw_shgroup_material_create_ex(GPUPass *gpupass, DRWPass
static void drw_shgroup_material_texture(DRWShadingGroup *grp,
GPUMaterialTexture *tex,
const char *name,
eGPUSamplerState state,
int textarget)
{
GPUTexture *gputex = GPU_texture_from_blender(tex->ima, tex->iuser, NULL, textarget);
int loc = GPU_shader_get_texture_binding(grp->shader, name);
drw_shgroup_uniform_create_ex(grp, loc, DRW_UNIFORM_TEXTURE, gputex, GPU_SAMPLER_MAX, 0, 1);
drw_shgroup_uniform_create_ex(grp, loc, DRW_UNIFORM_TEXTURE, gputex, state, 0, 1);
GPUTexture **gputex_ref = BLI_memblock_alloc(DST.vmempool->images);
*gputex_ref = gputex;
@ -1295,11 +1296,14 @@ void DRW_shgroup_add_material_resources(DRWShadingGroup *grp, struct GPUMaterial
if (tex->ima) {
/* Image */
if (tex->tiled_mapping_name[0]) {
drw_shgroup_material_texture(grp, tex, tex->sampler_name, GL_TEXTURE_2D_ARRAY);
drw_shgroup_material_texture(grp, tex, tex->tiled_mapping_name, GL_TEXTURE_1D_ARRAY);
drw_shgroup_material_texture(
grp, tex, tex->sampler_name, tex->sampler_state, GL_TEXTURE_2D_ARRAY);
drw_shgroup_material_texture(
grp, tex, tex->tiled_mapping_name, tex->sampler_state, GL_TEXTURE_1D_ARRAY);
}
else {
drw_shgroup_material_texture(grp, tex, tex->sampler_name, GL_TEXTURE_2D);
drw_shgroup_material_texture(
grp, tex, tex->sampler_name, tex->sampler_state, GL_TEXTURE_2D);
}
}
else if (tex->colorband) {

View File

@ -29,6 +29,8 @@
#include "BLI_sys_types.h" /* for bool */
#include "GPU_texture.h" /* for eGPUSamplerState */
#ifdef __cplusplus
extern "C" {
#endif
@ -138,8 +140,14 @@ typedef enum eGPUMaterialStatus {
GPUNodeLink *GPU_constant(const float *num);
GPUNodeLink *GPU_uniform(const float *num);
GPUNodeLink *GPU_attribute(GPUMaterial *mat, CustomDataType type, const char *name);
GPUNodeLink *GPU_image(GPUMaterial *mat, struct Image *ima, struct ImageUser *iuser);
GPUNodeLink *GPU_image_tiled(GPUMaterial *mat, struct Image *ima, struct ImageUser *iuser);
GPUNodeLink *GPU_image(GPUMaterial *mat,
struct Image *ima,
struct ImageUser *iuser,
eGPUSamplerState sampler_state);
GPUNodeLink *GPU_image_tiled(GPUMaterial *mat,
struct Image *ima,
struct ImageUser *iuser,
eGPUSamplerState sampler_state);
GPUNodeLink *GPU_image_tiled_mapping(GPUMaterial *mat, struct Image *ima, struct ImageUser *iuser);
GPUNodeLink *GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *layer);
GPUNodeLink *GPU_volume_grid(GPUMaterial *mat, const char *name);
@ -229,6 +237,7 @@ typedef struct GPUMaterialTexture {
char sampler_name[32]; /* Name of sampler in GLSL. */
char tiled_mapping_name[32]; /* Name of tile mapping sampler in GLSL. */
int users;
int sampler_state; /* eGPUSamplerState */
} GPUMaterialTexture;
typedef struct GPUMaterialVolumeGrid {

View File

@ -34,6 +34,8 @@
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "GPU_texture.h"
#include "gpu_material_library.h"
#include "gpu_node_graph.h"
@ -298,13 +300,14 @@ static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph,
Image *ima,
ImageUser *iuser,
struct GPUTexture **colorband,
GPUNodeLinkType link_type)
GPUNodeLinkType link_type,
eGPUSamplerState sampler_state)
{
/* Find existing texture. */
int num_textures = 0;
GPUMaterialTexture *tex = graph->textures.first;
for (; tex; tex = tex->next) {
if (tex->ima == ima && tex->colorband == colorband) {
if (tex->ima == ima && tex->colorband == colorband && tex->sampler_state == sampler_state) {
break;
}
num_textures++;
@ -316,6 +319,7 @@ static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph,
tex->ima = ima;
tex->iuser = iuser;
tex->colorband = colorband;
tex->sampler_state = sampler_state;
BLI_snprintf(tex->sampler_name, sizeof(tex->sampler_name), "samp%d", num_textures);
if (ELEM(link_type, GPU_NODE_LINK_IMAGE_TILED, GPU_NODE_LINK_IMAGE_TILED_MAPPING)) {
BLI_snprintf(
@ -389,21 +393,29 @@ GPUNodeLink *GPU_uniform(const float *num)
return link;
}
GPUNodeLink *GPU_image(GPUMaterial *mat, Image *ima, ImageUser *iuser)
GPUNodeLink *GPU_image(GPUMaterial *mat,
Image *ima,
ImageUser *iuser,
eGPUSamplerState sampler_state)
{
GPUNodeGraph *graph = gpu_material_node_graph(mat);
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_IMAGE;
link->texture = gpu_node_graph_add_texture(graph, ima, iuser, NULL, link->link_type);
link->texture = gpu_node_graph_add_texture(
graph, ima, iuser, NULL, link->link_type, sampler_state);
return link;
}
GPUNodeLink *GPU_image_tiled(GPUMaterial *mat, Image *ima, ImageUser *iuser)
GPUNodeLink *GPU_image_tiled(GPUMaterial *mat,
Image *ima,
ImageUser *iuser,
eGPUSamplerState sampler_state)
{
GPUNodeGraph *graph = gpu_material_node_graph(mat);
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_IMAGE_TILED;
link->texture = gpu_node_graph_add_texture(graph, ima, iuser, NULL, link->link_type);
link->texture = gpu_node_graph_add_texture(
graph, ima, iuser, NULL, link->link_type, sampler_state);
return link;
}
@ -412,7 +424,8 @@ GPUNodeLink *GPU_image_tiled_mapping(GPUMaterial *mat, Image *ima, ImageUser *iu
GPUNodeGraph *graph = gpu_material_node_graph(mat);
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_IMAGE_TILED_MAPPING;
link->texture = gpu_node_graph_add_texture(graph, ima, iuser, NULL, link->link_type);
link->texture = gpu_node_graph_add_texture(
graph, ima, iuser, NULL, link->link_type, GPU_SAMPLER_MAX);
return link;
}
@ -424,7 +437,8 @@ GPUNodeLink *GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *ro
GPUNodeGraph *graph = gpu_material_node_graph(mat);
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_COLORBAND;
link->texture = gpu_node_graph_add_texture(graph, NULL, NULL, colorband, link->link_type);
link->texture = gpu_node_graph_add_texture(
graph, NULL, NULL, colorband, link->link_type, GPU_SAMPLER_MAX);
return link;
}

View File

@ -56,6 +56,7 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
bNode *node_original = node->original ? node->original : node;
NodeTexImage *tex_original = node_original->storage;
ImageUser *iuser = &tex_original->iuser;
eGPUSamplerState sampler_state = GPU_SAMPLER_MAX;
GPUNodeLink *outalpha;
@ -78,7 +79,7 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
"node_tex_environment_equirectangular",
in[0].link,
GPU_constant(&clamp_size),
GPU_image(mat, ima, iuser),
GPU_image(mat, ima, iuser, sampler_state),
&in[0].link);
}
else {
@ -93,7 +94,7 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
GPU_link(mat,
"node_tex_image_linear_no_mip",
in[0].link,
GPU_image(mat, ima, iuser),
GPU_image(mat, ima, iuser, sampler_state),
&out[0].link,
&outalpha);
break;
@ -101,7 +102,7 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
GPU_link(mat,
"node_tex_image_nearest",
in[0].link,
GPU_image(mat, ima, iuser),
GPU_image(mat, ima, iuser, sampler_state),
&out[0].link,
&outalpha);
break;
@ -109,7 +110,7 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
GPU_link(mat,
"node_tex_image_cubic",
in[0].link,
GPU_image(mat, ima, iuser),
GPU_image(mat, ima, iuser, sampler_state),
&out[0].link,
&outalpha);
break;

View File

@ -118,6 +118,8 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
node_shader_gpu_tex_mapping(mat, node, in, out);
eGPUSamplerState sampler_state = GPU_SAMPLER_MAX;
if (ima->source == IMA_SRC_TILED) {
/* UDIM tiles needs a samper2DArray and sampler1DArray for tile mapping. */
GPU_stack_link(mat,
@ -125,7 +127,7 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
names_tiled[tex->interpolation],
in,
out,
GPU_image_tiled(mat, ima, iuser),
GPU_image_tiled(mat, ima, iuser, sampler_state),
GPU_image_tiled_mapping(mat, ima, iuser));
}
else {
@ -141,16 +143,18 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
GPU_link(mat, "set_rgb", *texco, &input_coords);
}
if (do_texco_extend) {
GPU_link(mat, "point_texco_clamp", *texco, GPU_image(mat, ima, iuser), texco);
GPU_link(
mat, "point_texco_clamp", *texco, GPU_image(mat, ima, iuser, sampler_state), texco);
}
GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(mat, ima, iuser));
GPU_stack_link(
mat, node, gpu_node_name, in, out, GPU_image(mat, ima, iuser, sampler_state));
break;
case SHD_PROJ_BOX:
vnor = GPU_builtin(GPU_WORLD_NORMAL);
ob_mat = GPU_builtin(GPU_OBJECT_MATRIX);
blend = GPU_uniform(&tex->projection_blend);
gpu_image = GPU_image(mat, ima, iuser);
gpu_image = GPU_image(mat, ima, iuser, sampler_state);
/* equivalent to normal_world_to_object */
GPU_link(mat, "normal_transform_transposed_m4v3", vnor, ob_mat, &norm);
@ -160,8 +164,14 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
GPU_link(mat, "set_rgb", *texco, &input_coords);
in[0].link = input_coords;
}
GPU_link(
mat, gpu_node_name, *texco, norm, GPU_image(mat, ima, iuser), &col1, &col2, &col3);
GPU_link(mat,
gpu_node_name,
*texco,
norm,
GPU_image(mat, ima, iuser, sampler_state),
&col1,
&col2,
&col3);
GPU_stack_link(
mat, node, "node_tex_image_box", in, out, norm, col1, col2, col3, gpu_image, blend);
break;
@ -175,9 +185,11 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
GPU_link(mat, "set_rgb", *texco, &input_coords);
}
if (do_texco_extend) {
GPU_link(mat, "point_texco_clamp", *texco, GPU_image(mat, ima, iuser), texco);
GPU_link(
mat, "point_texco_clamp", *texco, GPU_image(mat, ima, iuser, sampler_state), texco);
}
GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(mat, ima, iuser));
GPU_stack_link(
mat, node, gpu_node_name, in, out, GPU_image(mat, ima, iuser, sampler_state));
break;
case SHD_PROJ_TUBE:
@ -189,9 +201,11 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
GPU_link(mat, "set_rgb", *texco, &input_coords);
}
if (do_texco_extend) {
GPU_link(mat, "point_texco_clamp", *texco, GPU_image(mat, ima, iuser), texco);
GPU_link(
mat, "point_texco_clamp", *texco, GPU_image(mat, ima, iuser, sampler_state), texco);
}
GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(mat, ima, iuser));
GPU_stack_link(
mat, node, gpu_node_name, in, out, GPU_image(mat, ima, iuser, sampler_state));
break;
}
@ -199,7 +213,13 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
if (do_texco_clip) {
gpu_node_name = names_clip[tex->interpolation];
in[0].link = input_coords;
GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(mat, ima, iuser), out[0].link);
GPU_stack_link(mat,
node,
gpu_node_name,
in,
out,
GPU_image(mat, ima, iuser, sampler_state),
out[0].link);
}
}
}