#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"
#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 *
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;
* 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);
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];
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;
/* 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;
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 {
/* 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);
}
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];
}
}
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
};