X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fsvga%2Fsvga_state_sampler.c;h=bbfd889e9f407d6b65acdb9d3c98b7abc288e5eb;hb=ba37d408da30d87b6848d76242d9d797dbef80a0;hp=482449ecc663ce0195a4a10e22eebbecd25eb11b;hpb=1ee181b3548a93b19474de5a13cfade208056996;p=mesa.git diff --git a/src/gallium/drivers/svga/svga_state_sampler.c b/src/gallium/drivers/svga/svga_state_sampler.c index 482449ecc66..bbfd889e9f4 100644 --- a/src/gallium/drivers/svga/svga_state_sampler.c +++ b/src/gallium/drivers/svga/svga_state_sampler.c @@ -30,7 +30,7 @@ #include "pipe/p_defines.h" #include "util/u_bitmask.h" -#include "util/u_format.h" +#include "util/format/u_format.h" #include "util/u_inlines.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -44,7 +44,7 @@ #include "svga_shader.h" #include "svga_state.h" #include "svga_surface.h" - +#include "svga3d_surfacedefs.h" /** Get resource handle for a texture or buffer */ static inline struct svga_winsys_surface * @@ -131,7 +131,7 @@ svga_validate_pipe_sampler_view(struct svga_context *svga, if (sv->id == SVGA3D_INVALID_ID) { struct svga_screen *ss = svga_screen(svga->pipe.screen); struct pipe_resource *texture = sv->base.texture; - struct svga_winsys_surface *surface = svga_resource_handle(texture); + struct svga_winsys_surface *surface; SVGA3dSurfaceFormat format; SVGA3dResourceType resourceDim; SVGA3dShaderResourceViewDesc viewDesc; @@ -141,20 +141,32 @@ svga_validate_pipe_sampler_view(struct svga_context *svga, * create a BGRA view (and vice versa). */ if (viewFormat == PIPE_FORMAT_B8G8R8X8_UNORM && - texture->format == PIPE_FORMAT_B8G8R8A8_UNORM) { + svga_texture_device_format_has_alpha(texture)) { viewFormat = PIPE_FORMAT_B8G8R8A8_UNORM; } else if (viewFormat == PIPE_FORMAT_B8G8R8A8_UNORM && - texture->format == PIPE_FORMAT_B8G8R8X8_UNORM) { + !svga_texture_device_format_has_alpha(texture)) { viewFormat = PIPE_FORMAT_B8G8R8X8_UNORM; } - format = svga_translate_format(ss, viewFormat, - PIPE_BIND_SAMPLER_VIEW); - assert(format != SVGA3D_FORMAT_INVALID); + if (texture->target == PIPE_BUFFER) { + unsigned pf_flags; + svga_translate_texture_buffer_view_format(viewFormat, + &format, + &pf_flags); + surface = svga_buffer_handle(svga, texture, PIPE_BIND_SAMPLER_VIEW); + } + else { + format = svga_translate_format(ss, viewFormat, + PIPE_BIND_SAMPLER_VIEW); + + /* Convert the format to a sampler-friendly format, if needed */ + format = svga_sampler_format(format); - /* Convert the format to a sampler-friendly format, if needed */ - format = svga_sampler_format(format); + surface = svga_texture(texture)->handle; + } + + assert(format != SVGA3D_FORMAT_INVALID); if (texture->target == PIPE_BUFFER) { unsigned elem_size = util_format_get_blocksize(sv->base.format); @@ -225,15 +237,14 @@ svga_validate_pipe_sampler_view(struct svga_context *svga, static enum pipe_error -update_sampler_resources(struct svga_context *svga, unsigned dirty) +update_sampler_resources(struct svga_context *svga, uint64_t dirty) { enum pipe_error ret = PIPE_OK; enum pipe_shader_type shader; - if (!svga_have_vgpu10(svga)) - return PIPE_OK; + assert(svga_have_vgpu10(svga)); - for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) { + for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_TESS_EVAL; shader++) { SVGA3dShaderResourceViewId ids[PIPE_MAX_SAMPLERS]; struct svga_winsys_surface *surfaces[PIPE_MAX_SAMPLERS]; struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; @@ -278,14 +289,54 @@ update_sampler_resources(struct svga_context *svga, unsigned dirty) if (count != svga->state.hw_draw.num_sampler_views[shader] || memcmp(sampler_views, svga->state.hw_draw.sampler_views[shader], count * sizeof(sampler_views[0])) != 0) { - ret = SVGA3D_vgpu10_SetShaderResources(svga->swc, - svga_shader_type(shader), - 0, /* startView */ - nviews, - ids, - surfaces); - if (ret != PIPE_OK) - return ret; + SVGA3dShaderResourceViewId *pIds = ids; + struct svga_winsys_surface **pSurf = surfaces; + unsigned numSR = 0; + + /* Loop through the sampler view list to only emit + * the sampler views that are not already in the + * corresponding entries in the device's + * shader resource list. + */ + for (i = 0; i < nviews; i++) { + boolean emit; + + emit = sampler_views[i] == + svga->state.hw_draw.sampler_views[shader][i]; + + if (!emit && i == nviews-1) { + /* Include the last sampler view in the next emit + * if it is different. + */ + emit = TRUE; + numSR++; + i++; + } + + if (emit) { + /* numSR can only be 0 if the first entry of the list + * is the same as the one in the device list. + * In this case, * there is nothing to send yet. + */ + if (numSR) { + ret = SVGA3D_vgpu10_SetShaderResources( + svga->swc, + svga_shader_type(shader), + i - numSR, /* startView */ + numSR, + pIds, + pSurf); + + if (ret != PIPE_OK) + return ret; + } + pIds += (numSR + 1); + pSurf += (numSR + 1); + numSR = 0; + } + else + numSR++; + } /* Save referenced sampler views in the hw draw state. */ svga->state.hw_draw.num_sampler_views[shader] = count; @@ -300,7 +351,8 @@ update_sampler_resources(struct svga_context *svga, unsigned dirty) /* Handle polygon stipple sampler view */ if (svga->curr.rast->templ.poly_stipple_enable) { - const unsigned unit = svga->state.hw_draw.fs->pstipple_sampler_unit; + const unsigned unit = + svga_fs_variant(svga->state.hw_draw.fs)->pstipple_sampler_unit; struct svga_pipe_sampler_view *sv = svga->polygon_stipple.sampler_view; struct svga_winsys_surface *surface; @@ -336,23 +388,37 @@ struct svga_tracked_state svga_hw_sampler_bindings = { static enum pipe_error -update_samplers(struct svga_context *svga, unsigned dirty ) +update_samplers(struct svga_context *svga, uint64_t dirty ) { enum pipe_error ret = PIPE_OK; enum pipe_shader_type shader; - if (!svga_have_vgpu10(svga)) - return PIPE_OK; + assert(svga_have_vgpu10(svga)); - for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) { + for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_TESS_EVAL; shader++) { const unsigned count = svga->curr.num_samplers[shader]; SVGA3dSamplerId ids[PIPE_MAX_SAMPLERS]; unsigned i; unsigned nsamplers; for (i = 0; i < count; i++) { + bool fs_shadow = false; + + /* _NEW_FS */ + if (shader == PIPE_SHADER_FRAGMENT) { + struct svga_fs_variant *fs = + svga_fs_variant(svga->state.hw_draw.fs); + /* If the fragment shader is doing the shadow comparison + * for this texture unit, don't enable shadow compare in + * the texture sampler state. + */ + if (fs && (fs->fs_shadow_compare_units & (1 << i))) { + fs_shadow = true; + } + } + if (svga->curr.sampler[shader][i]) { - ids[i] = svga->curr.sampler[shader][i]->id; + ids[i] = svga->curr.sampler[shader][i]->id[fs_shadow]; assert(ids[i] != SVGA3D_INVALID_ID); } else { @@ -386,7 +452,8 @@ update_samplers(struct svga_context *svga, unsigned dirty ) /* Handle polygon stipple sampler texture */ if (svga->curr.rast->templ.poly_stipple_enable) { - const unsigned unit = svga->state.hw_draw.fs->pstipple_sampler_unit; + const unsigned unit = + svga_fs_variant(svga->state.hw_draw.fs)->pstipple_sampler_unit; struct svga_sampler_state *sampler = svga->polygon_stipple.sampler; assert(sampler); @@ -395,18 +462,18 @@ update_samplers(struct svga_context *svga, unsigned dirty ) } if (svga->state.hw_draw.samplers[PIPE_SHADER_FRAGMENT][unit] - != sampler->id) { + != sampler->id[0]) { ret = SVGA3D_vgpu10_SetSamplers(svga->swc, 1, /* count */ unit, /* start */ SVGA3D_SHADERTYPE_PS, - &sampler->id); + &sampler->id[0]); if (ret != PIPE_OK) return ret; /* save the polygon stipple sampler in the hw draw state */ svga->state.hw_draw.samplers[PIPE_SHADER_FRAGMENT][unit] = - sampler->id; + sampler->id[0]; } } @@ -416,8 +483,8 @@ update_samplers(struct svga_context *svga, unsigned dirty ) struct svga_tracked_state svga_hw_sampler = { "texture sampler emit", - (SVGA_NEW_SAMPLER | - SVGA_NEW_STIPPLE | - SVGA_NEW_TEXTURE_FLAGS), + (SVGA_NEW_FS | + SVGA_NEW_SAMPLER | + SVGA_NEW_STIPPLE), update_samplers };